< prev index next >

src/java.base/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java

Print this page
rev 58565 : 8238358: Implementation of JEP 371: Hidden Classes
Reviewed-by: duke
Contributed-by: mandy.chung@oracle.com, lois.foltan@oracle.com, david.holmes@oracle.com, harold.seigel@oracle.com, serguei.spitsyn@oracle.com, alex.buckley@oracle.com, jamsheed.c.m@oracle.com

*** 49,58 **** --- 49,59 ---- * public static void main(String[] args) { * JJ<Integer> iii = (new CC())::impl; * System.out.printf(">>> %s\n", iii.foo(44)); * }} */ + final MethodHandles.Lookup caller; final Class<?> targetClass; // The class calling the meta-factory via invokedynamic "class X" final MethodType invokedType; // The type of the invoked method "(CC)II" final Class<?> samBase; // The type of the returned instance "interface JJ" final String samMethodName; // Name of the SAM method "foo" final MethodType samMethodType; // Type of the SAM method "(Object)Object"
*** 118,127 **** --- 119,129 ---- if ((caller.lookupModes() & MethodHandles.Lookup.PRIVATE) == 0) { throw new LambdaConversionException(String.format( "Invalid caller: %s", caller.lookupClass().getName())); } + this.caller = caller; this.targetClass = caller.lookupClass(); this.invokedType = invokedType; this.samBase = invokedType.returnType();
*** 141,152 **** this.implIsInstanceMethod = true; break; case REF_invokeSpecial: // JDK-8172817: should use referenced class here, but we don't know what it was this.implClass = implInfo.getDeclaringClass(); - this.implKind = REF_invokeSpecial; this.implIsInstanceMethod = true; break; case REF_invokeStatic: case REF_newInvokeSpecial: // JDK-8172817: should use referenced class here for invokestatic, but we don't know what it was this.implClass = implInfo.getDeclaringClass(); --- 143,166 ---- this.implIsInstanceMethod = true; break; case REF_invokeSpecial: // JDK-8172817: should use referenced class here, but we don't know what it was this.implClass = implInfo.getDeclaringClass(); this.implIsInstanceMethod = true; + + // Classes compiled prior to dynamic nestmate support invokes a private instance + // method with REF_invokeSpecial. + // + // invokespecial should only be used to invoke private nestmate constructors. + // The lambda proxy class will be defined as a nestmate of targetClass. + // If the method to be invoked is an instance method of targetClass, then + // convert to use invokevirtual or invokeinterface. + if (targetClass == implClass && !implInfo.getName().equals("<init>")) { + this.implKind = implClass.isInterface() ? REF_invokeInterface : REF_invokeVirtual; + } else { + this.implKind = REF_invokeSpecial; + } break; case REF_invokeStatic: case REF_newInvokeSpecial: // JDK-8172817: should use referenced class here for invokestatic, but we don't know what it was this.implClass = implInfo.getDeclaringClass();
< prev index next >