< prev index next >

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

Print this page

327     private static final MethodTypeDesc MTD_void_String = MethodTypeDesc.of(CD_void, CD_String);
328     private static final String TARGET_NAME = "target";
329     private static final String TYPE_NAME = "interfaceType";
330     private static final String ENSURE_ORIGINAL_LOOKUP = "ensureOriginalLookup";
331 
332     /**
333      * Creates an implementation class file for a given interface. One implementation class is
334      * defined for each interface.
335      *
336      * @param ifaceDesc the given interface
337      * @param methodName the name of the single abstract method
338      * @param methods the information for implementation methods
339      * @return the bytes of the implementation classes
340      */
341     private static byte[] createTemplate(ClassLoader loader, ClassDesc proxyDesc, ClassDesc ifaceDesc,
342                                          String methodName, List<MethodInfo> methods) {
343         return ClassFile.of(ClassHierarchyResolverOption.of(ClassHierarchyResolver.ofClassLoading(loader == null ?
344                         ClassLoaders.platformClassLoader() : loader)))
345                         .build(proxyDesc, clb -> {
346             clb.withSuperclass(CD_Object)
347                .withFlags(ACC_FINAL | ACC_SYNTHETIC)
348                .withInterfaceSymbols(ifaceDesc)
349                // static and instance fields
350                .withField(TYPE_NAME, CD_Class, ACC_PRIVATE | ACC_STATIC | ACC_FINAL)
351                .withField(TARGET_NAME, CD_MethodHandle, ACC_PRIVATE | ACC_FINAL);
352             for (var mi : methods) {
353                 clb.withField(mi.fieldName, CD_MethodHandle, ACC_PRIVATE | ACC_FINAL);
354             }
355 
356             // <clinit>
357             clb.withMethodBody(CLASS_INIT_NAME, MTD_void, ACC_STATIC, cob -> {
358                 cob.loadConstant(ifaceDesc)
359                    .putstatic(proxyDesc, TYPE_NAME, CD_Class)
360                    .return_();
361             });
362 
363             // <init>(Lookup, MethodHandle target, MethodHandle callerBoundTarget)
364             clb.withMethodBody(INIT_NAME, MTD_void_Lookup_MethodHandle_MethodHandle, 0, cob -> {
365                 // call ensureOriginalLookup to verify the given Lookup has access
366                 cob.aload(1)
367                    .invokestatic(proxyDesc, ENSURE_ORIGINAL_LOOKUP, MTD_void_Lookup)

327     private static final MethodTypeDesc MTD_void_String = MethodTypeDesc.of(CD_void, CD_String);
328     private static final String TARGET_NAME = "target";
329     private static final String TYPE_NAME = "interfaceType";
330     private static final String ENSURE_ORIGINAL_LOOKUP = "ensureOriginalLookup";
331 
332     /**
333      * Creates an implementation class file for a given interface. One implementation class is
334      * defined for each interface.
335      *
336      * @param ifaceDesc the given interface
337      * @param methodName the name of the single abstract method
338      * @param methods the information for implementation methods
339      * @return the bytes of the implementation classes
340      */
341     private static byte[] createTemplate(ClassLoader loader, ClassDesc proxyDesc, ClassDesc ifaceDesc,
342                                          String methodName, List<MethodInfo> methods) {
343         return ClassFile.of(ClassHierarchyResolverOption.of(ClassHierarchyResolver.ofClassLoading(loader == null ?
344                         ClassLoaders.platformClassLoader() : loader)))
345                         .build(proxyDesc, clb -> {
346             clb.withSuperclass(CD_Object)
347                .withFlags(ACC_SUPER | ACC_FINAL | ACC_SYNTHETIC)
348                .withInterfaceSymbols(ifaceDesc)
349                // static and instance fields
350                .withField(TYPE_NAME, CD_Class, ACC_PRIVATE | ACC_STATIC | ACC_FINAL)
351                .withField(TARGET_NAME, CD_MethodHandle, ACC_PRIVATE | ACC_FINAL);
352             for (var mi : methods) {
353                 clb.withField(mi.fieldName, CD_MethodHandle, ACC_PRIVATE | ACC_FINAL);
354             }
355 
356             // <clinit>
357             clb.withMethodBody(CLASS_INIT_NAME, MTD_void, ACC_STATIC, cob -> {
358                 cob.loadConstant(ifaceDesc)
359                    .putstatic(proxyDesc, TYPE_NAME, CD_Class)
360                    .return_();
361             });
362 
363             // <init>(Lookup, MethodHandle target, MethodHandle callerBoundTarget)
364             clb.withMethodBody(INIT_NAME, MTD_void_Lookup_MethodHandle_MethodHandle, 0, cob -> {
365                 // call ensureOriginalLookup to verify the given Lookup has access
366                 cob.aload(1)
367                    .invokestatic(proxyDesc, ENSURE_ORIGINAL_LOOKUP, MTD_void_Lookup)
< prev index next >