8137134: invokespecial on indirect super interface is generated by Java adapter generator

Reviewed-by: attila, hannesw
This commit is contained in:
Athijegannathan Sundararajan 2015-09-25 16:01:54 +05:30
parent ef8d5d8323
commit 1a8570ad75
6 changed files with 150 additions and 2 deletions

View File

@ -1634,7 +1634,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
@Override
void consumeStack() {
dynamicCall(2 + argsCount, getCallSiteFlags(), origCallee.getName());
dynamicCall(2 + argsCount, getCallSiteFlags(), null);
}
}.emit();
return false;

View File

@ -203,6 +203,8 @@ final class JavaAdapterBytecodeGenerator {
// 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 @@ final class JavaAdapterBytecodeGenerator {
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 @@ final class JavaAdapterBytecodeGenerator {
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 @@ final class JavaAdapterBytecodeGenerator {
// 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);
}

View File

@ -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());

View File

@ -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

View File

@ -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";
}
}

View File

@ -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";
}
}