Tue, 23 Jun 2015 11:16:48 +0200
8129410: Java adapters with class-level overrides should preserve variable arity constructors
Reviewed-by: lagergren, sundar
1.1 --- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java Thu Jun 18 19:20:53 2015 +0530 1.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java Tue Jun 23 11:16:48 2015 +0200 1.3 @@ -106,7 +106,9 @@ 1.4 * <li> 1.5 * If the adapter being generated can have class-level overrides, constructors taking same arguments as the superclass 1.6 * constructors are created. These constructors simply delegate to the superclass constructor. They are simply used to 1.7 - * create instances of the adapter class, with no instance-level overrides, as they don't have them. 1.8 + * create instances of the adapter class, with no instance-level overrides, as they don't have them. If the original 1.9 + * class' constructor was variable arity, the adapter constructor will also be variable arity. Protected constructors 1.10 + * are exposed as public. 1.11 * </li> 1.12 * </ul> 1.13 * </p><p> 1.14 @@ -190,7 +192,6 @@ 1.15 private static final int MAX_GENERATED_TYPE_NAME_LENGTH = 255; 1.16 1.17 private static final String CLASS_INIT = "<clinit>"; 1.18 - static final String CONVERTER_INIT = "<converter-init>"; 1.19 1.20 // Method name prefix for invoking super-methods 1.21 static final String SUPER_PREFIX = "super$"; 1.22 @@ -494,7 +495,8 @@ 1.23 final Type[] argTypes = originalCtorType.getArgumentTypes(); 1.24 1.25 // All constructors must be public, even if in the superclass they were protected. 1.26 - final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC, INIT, 1.27 + final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC | 1.28 + (ctor.isVarArgs() ? ACC_VARARGS : 0), INIT, 1.29 Type.getMethodDescriptor(originalCtorType.getReturnType(), argTypes), null, null)); 1.30 1.31 mv.visitCode(); 1.32 @@ -543,7 +545,8 @@ 1.33 System.arraycopy(originalArgTypes, 0, newArgTypes, 0, argLen); 1.34 1.35 // All constructors must be public, even if in the superclass they were protected. 1.36 - // Existing super constructor <init>(this, args...) triggers generating <init>(this, scriptObj, args...). 1.37 + // Existing super constructor <init>(this, args...) triggers generating <init>(this, args..., scriptObj). 1.38 + // Any variable arity constructors become fixed-arity with explicit array arguments. 1.39 final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC, INIT, 1.40 Type.getMethodDescriptor(originalCtorType.getReturnType(), newArgTypes), null, null)); 1.41 1.42 @@ -593,7 +596,7 @@ 1.43 if (! fromFunction) { 1.44 newArgTypes[argLen] = OBJECT_TYPE; 1.45 final InstructionAdapter mv2 = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC, INIT, 1.46 - Type.getMethodDescriptor(originalCtorType.getReturnType(), newArgTypes), null, null)); 1.47 + Type.getMethodDescriptor(originalCtorType.getReturnType(), newArgTypes), null, null)); 1.48 generateOverridingConstructorWithObjectParam(mv2, ctor, originalCtorType.getDescriptor()); 1.49 } 1.50 }
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/script/basic/JDK-8129410.js Tue Jun 23 11:16:48 2015 +0200 2.3 @@ -0,0 +1,39 @@ 2.4 +/* 2.5 + * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. 2.11 + * 2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.15 + * version 2 for more details (a copy is included in the LICENSE file that 2.16 + * accompanied this code). 2.17 + * 2.18 + * You should have received a copy of the GNU General Public License version 2.19 + * 2 along with this work; if not, write to the Free Software Foundation, 2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.21 + * 2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.23 + * or visit www.oracle.com if you need additional information or have any 2.24 + * questions. 2.25 + */ 2.26 + 2.27 +/** 2.28 + * JDK-8129410: Java adapters with class-level overrides should preserve variable arity constructors 2.29 + * 2.30 + * @test 2.31 + * @run 2.32 + */ 2.33 + 2.34 +var VarArgConstructor = Java.type("jdk.nashorn.test.models.VarArgConstructor"); 2.35 +var VarArgConstructorExtended = Java.extend(VarArgConstructor, {}); 2.36 + 2.37 +// If the fix didn't work we wouldn't even get past the constructor invocation 2.38 +// as it'd complain there's no matching arity constructor. 2.39 +var newExtended = new VarArgConstructorExtended(1, true, "a", "b"); 2.40 + 2.41 +// Assert the expected constructor was invoked. 2.42 +Assert.assertEquals("vararg", newExtended.indicator);