8008687: MethodHandle code: allow static and invokespecial calls to interface methods
Summary: Changes to support invocation of lambda methods compiled either as static interface methods and or private instance methods.
Reviewed-by: jrose, twisti
--- a/jdk/src/share/classes/java/lang/invoke/MemberName.java Fri May 10 10:12:58 2013 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MemberName.java Mon May 13 12:26:28 2013 -0700
@@ -236,6 +236,8 @@
assert(MethodHandleNatives.refKindIsMethod(refKind));
if (clazz.isInterface())
assert(refKind == REF_invokeInterface ||
+ refKind == REF_invokeStatic ||
+ refKind == REF_invokeSpecial ||
refKind == REF_invokeVirtual && isObjectPublicMethod());
} else {
assert(false);
@@ -268,7 +270,7 @@
assert(refKind == REF_invokeSpecial) : this;
return true;
}
- assert(false) : this;
+ assert(false) : this+" != "+MethodHandleNatives.refKindName((byte)originalRefKind);
return true;
}
private boolean staticIsConsistent() {
@@ -485,14 +487,19 @@
if (this.type == null)
this.type = new Object[] { m.getReturnType(), m.getParameterTypes() };
if (wantSpecial) {
+ assert(!isAbstract()) : this;
if (getReferenceKind() == REF_invokeVirtual)
changeReferenceKind(REF_invokeSpecial, REF_invokeVirtual);
+ else if (getReferenceKind() == REF_invokeInterface)
+ // invokeSpecial on a default method
+ changeReferenceKind(REF_invokeSpecial, REF_invokeInterface);
}
}
public MemberName asSpecial() {
switch (getReferenceKind()) {
case REF_invokeSpecial: return this;
case REF_invokeVirtual: return clone().changeReferenceKind(REF_invokeSpecial, REF_invokeVirtual);
+ case REF_invokeInterface: return clone().changeReferenceKind(REF_invokeSpecial, REF_invokeInterface);
case REF_newInvokeSpecial: return clone().changeReferenceKind(REF_invokeSpecial, REF_newInvokeSpecial);
}
throw new IllegalArgumentException(this.toString());