# HG changeset patch # User attila # Date 1435051008 -7200 # Node ID 62097549ae94285a629ff6dcb7216c898a4c87fc # Parent 43d0179ee9de3bfffae3417f09e07eb6d8efc963 8129410: Java adapters with class-level overrides should preserve variable arity constructors Reviewed-by: lagergren, sundar diff -r 43d0179ee9de -r 62097549ae94 nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java Wed Jul 05 20:38:50 2017 +0200 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java Tue Jun 23 11:16:48 2015 +0200 @@ -106,7 +106,9 @@ *
  • * If the adapter being generated can have class-level overrides, constructors taking same arguments as the superclass * constructors are created. These constructors simply delegate to the superclass constructor. They are simply used to - * create instances of the adapter class, with no instance-level overrides, as they don't have them. + * create instances of the adapter class, with no instance-level overrides, as they don't have them. If the original + * class' constructor was variable arity, the adapter constructor will also be variable arity. Protected constructors + * are exposed as public. *
  • * *

    @@ -190,7 +192,6 @@ private static final int MAX_GENERATED_TYPE_NAME_LENGTH = 255; private static final String CLASS_INIT = ""; - static final String CONVERTER_INIT = ""; // Method name prefix for invoking super-methods static final String SUPER_PREFIX = "super$"; @@ -494,7 +495,8 @@ final Type[] argTypes = originalCtorType.getArgumentTypes(); // All constructors must be public, even if in the superclass they were protected. - final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC, INIT, + final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC | + (ctor.isVarArgs() ? ACC_VARARGS : 0), INIT, Type.getMethodDescriptor(originalCtorType.getReturnType(), argTypes), null, null)); mv.visitCode(); @@ -543,7 +545,8 @@ System.arraycopy(originalArgTypes, 0, newArgTypes, 0, argLen); // All constructors must be public, even if in the superclass they were protected. - // Existing super constructor (this, args...) triggers generating (this, scriptObj, args...). + // Existing super constructor (this, args...) triggers generating (this, args..., scriptObj). + // Any variable arity constructors become fixed-arity with explicit array arguments. final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC, INIT, Type.getMethodDescriptor(originalCtorType.getReturnType(), newArgTypes), null, null)); @@ -593,7 +596,7 @@ if (! fromFunction) { newArgTypes[argLen] = OBJECT_TYPE; final InstructionAdapter mv2 = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC, INIT, - Type.getMethodDescriptor(originalCtorType.getReturnType(), newArgTypes), null, null)); + Type.getMethodDescriptor(originalCtorType.getReturnType(), newArgTypes), null, null)); generateOverridingConstructorWithObjectParam(mv2, ctor, originalCtorType.getDescriptor()); } } diff -r 43d0179ee9de -r 62097549ae94 nashorn/test/script/basic/JDK-8129410.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8129410.js Tue Jun 23 11:16:48 2015 +0200 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8129410: Java adapters with class-level overrides should preserve variable arity constructors + * + * @test + * @run + */ + +var VarArgConstructor = Java.type("jdk.nashorn.test.models.VarArgConstructor"); +var VarArgConstructorExtended = Java.extend(VarArgConstructor, {}); + +// If the fix didn't work we wouldn't even get past the constructor invocation +// as it'd complain there's no matching arity constructor. +var newExtended = new VarArgConstructorExtended(1, true, "a", "b"); + +// Assert the expected constructor was invoked. +Assert.assertEquals("vararg", newExtended.indicator);