8137134: invokespecial on indirect super interface is generated by Java adapter generator
Reviewed-by: attila, hannesw
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java Tue Sep 22 14:00:54 2015 +0530
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java Fri Sep 25 16:01:54 2015 +0530
@@ -1634,7 +1634,7 @@
@Override
void consumeStack() {
- dynamicCall(2 + argsCount, getCallSiteFlags(), origCallee.getName());
+ dynamicCall(2 + argsCount, getCallSiteFlags(), null);
}
}.emit();
return false;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java Tue Sep 22 14:00:54 2015 +0530
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java Fri Sep 25 16:01:54 2015 +0530
@@ -203,6 +203,8 @@
// This is the superclass for our generated adapter.
private final Class<?> superClass;
+ // Interfaces implemented by our generated adapter.
+ private final List<Class<?>> interfaces;
// Class loader used as the parent for the class loader we'll create to load the generated class. It will be a class
// loader that has the visibility of all original types (class to extend and interfaces to implement) and of the
// Nashorn classes.
@@ -254,6 +256,7 @@
assert interfaces != null;
this.superClass = superClass;
+ this.interfaces = interfaces;
this.classOverride = classOverride;
this.commonLoader = commonLoader;
cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS) {
@@ -1031,6 +1034,24 @@
endMethod(mv);
}
+ // find the appropriate super type to use for invokespecial on the given interface
+ private Class<?> findInvokespecialOwnerFor(final Class<?> cl) {
+ assert Modifier.isInterface(cl.getModifiers()) : cl + " is not an interface";
+
+ if (cl.isAssignableFrom(superClass)) {
+ return superClass;
+ }
+
+ for (final Class<?> iface : interfaces) {
+ if (cl.isAssignableFrom(iface)) {
+ return iface;
+ }
+ }
+
+ // we better that interface that extends the given interface!
+ throw new AssertionError("can't find the class/interface that extends " + cl);
+ }
+
private void emitSuperCall(final InstructionAdapter mv, final Class<?> owner, final String name, final String methodDesc) {
mv.visitVarInsn(ALOAD, 0);
int nextParam = 1;
@@ -1042,7 +1063,9 @@
// default method - non-abstract, interface method
if (Modifier.isInterface(owner.getModifiers())) {
- mv.invokespecial(Type.getInternalName(owner), name, methodDesc, false);
+ // we should call default method on the immediate "super" type - not on (possibly)
+ // the indirectly inherited interface class!
+ mv.invokespecial(Type.getInternalName(findInvokespecialOwnerFor(owner)), name, methodDesc, false);
} else {
mv.invokespecial(superClassName, name, methodDesc, false);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8137134.js Fri Sep 25 16:01:54 2015 +0530
@@ -0,0 +1,55 @@
+/*
+ * 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-8137134: invokespecial on indirect super interface is generated by Java adapter generator
+ *
+ * @test
+ * @run
+ */
+
+var B = Java.type("jdk.nashorn.test.models.B");
+var b1 = new B() {}
+print(b1.a());
+print(b1.b());
+
+var b2 = new B() {
+ b: function() {
+ return "from B.b in script";
+ }
+};
+
+print(b2.a());
+print(b2.b());
+
+var b3 = new B() {
+ a: function() {
+ return "from A.a in script";
+ },
+ b: function() {
+ return "from B.b in script";
+ }
+};
+
+print(b3.a());
+print(b3.b());
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8137134.js.EXPECTED Fri Sep 25 16:01:54 2015 +0530
@@ -0,0 +1,6 @@
+from A.a
+from B.b
+from A.a
+from B.b in script
+from A.a in script
+from B.b in script
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/src/jdk/nashorn/test/models/A.java Fri Sep 25 16:01:54 2015 +0530
@@ -0,0 +1,32 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package jdk.nashorn.test.models;
+
+public interface A {
+ default String a() {
+ return "from A.a";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/src/jdk/nashorn/test/models/B.java Fri Sep 25 16:01:54 2015 +0530
@@ -0,0 +1,32 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package jdk.nashorn.test.models;
+
+public interface B extends A {
+ default String b() {
+ return "from B.b";
+ }
+}