I recently have been making changes in the JVM around invokespecial, specifically related to ensuring detection for the following structural constraints:
See (JVMS draft 0.7.0) 4.9.2 Structural Constraints,
"Each invokespecial instruction must name an instance initialization method (2.0) or
must reference a method in the current class or interface, a method in a superclass of the
current class or interface, or a method in a direct superinterface of the current class or interface."
Testing my changes, I noticed two new failing tests in JCK lang. They are:
http://jre.sfbay.sun.com/java/re/jck/8/qac/latest/binaries/JCK-runtime-8/tests/lang/LMBD/lmbd073/lmbd07302m2/lmbd07302m2_rt.html
http://jre.sfbay.sun.com/java/re/jck/8/qac/latest/binaries/JCK-runtime-8/tests/lang/LMBD/lmbd073/lmbd07302m11/lmbd07302m11_rt.html
Each test contains code like the following
interface TestedInterface extends Parent1, Parent2 {
default int test () {
SAM sam = Parent1.super::test;
return sam.method();
}
}
The metafactory code generated for the "SAM sam = Parent1.super::test;" statement is as follows dumped from jdis:
invokedynamic InvokeDynamic REF_invokeStatic:java/lang/invoke/LambdaMetafactory.metafactory:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;":method:"(LTestedInterface;)LSAM;" MethodType "()I", MethodHandle REF_invokeSpecial:TestedInterface.lambda$MR$test$test$cafb6dc6$1:"()I", MethodType "()I";
I suspect that the above InvokeSpecial bytecode looks suspicious. Shouldn't it be an REF_InvokeSpecial:Parent1.lambda$MR$... not an REF_InvokeSpecial:TestedInterface.lambda$MR$...?
See (JVMS draft 0.7.0) 4.9.2 Structural Constraints,
"Each invokespecial instruction must name an instance initialization method (2.0) or
must reference a method in the current class or interface, a method in a superclass of the
current class or interface, or a method in a direct superinterface of the current class or interface."
Testing my changes, I noticed two new failing tests in JCK lang. They are:
http://jre.sfbay.sun.com/java/re/jck/8/qac/latest/binaries/JCK-runtime-8/tests/lang/LMBD/lmbd073/lmbd07302m2/lmbd07302m2_rt.html
http://jre.sfbay.sun.com/java/re/jck/8/qac/latest/binaries/JCK-runtime-8/tests/lang/LMBD/lmbd073/lmbd07302m11/lmbd07302m11_rt.html
Each test contains code like the following
interface TestedInterface extends Parent1, Parent2 {
default int test () {
SAM sam = Parent1.super::test;
return sam.method();
}
}
The metafactory code generated for the "SAM sam = Parent1.super::test;" statement is as follows dumped from jdis:
invokedynamic InvokeDynamic REF_invokeStatic:java/lang/invoke/LambdaMetafactory.metafactory:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;":method:"(LTestedInterface;)LSAM;" MethodType "()I", MethodHandle REF_invokeSpecial:TestedInterface.lambda$MR$test$test$cafb6dc6$1:"()I", MethodType "()I";
I suspect that the above InvokeSpecial bytecode looks suspicious. Shouldn't it be an REF_InvokeSpecial:Parent1.lambda$MR$... not an REF_InvokeSpecial:TestedInterface.lambda$MR$...?