8008687: MethodHandle code: allow static and invokespecial calls to interface methods
authorbharadwaj
Mon, 13 May 2013 12:26:28 -0700
changeset 17461 84860231159b
parent 17455 2b7c7aa53a38
child 17462 c1bfafc15e02
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
jdk/src/share/classes/java/lang/invoke/MemberName.java
--- 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());