< prev index next >

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

Print this page

 36 import java.util.ArrayList;
 37 import java.util.Arrays;
 38 import java.util.Collections;
 39 import java.util.HashSet;
 40 import java.util.List;
 41 import java.util.Objects;
 42 import java.util.Set;
 43 import java.util.WeakHashMap;
 44 import java.util.concurrent.atomic.AtomicInteger;
 45 import java.util.stream.Stream;
 46 
 47 import jdk.internal.access.JavaLangReflectAccess;
 48 import jdk.internal.access.SharedSecrets;
 49 import java.lang.classfile.ClassHierarchyResolver;
 50 import java.lang.classfile.ClassFile;
 51 import java.lang.classfile.CodeBuilder;
 52 import java.lang.classfile.TypeKind;
 53 
 54 import jdk.internal.constant.ConstantUtils;
 55 import jdk.internal.loader.ClassLoaders;

 56 import jdk.internal.module.Modules;
 57 import jdk.internal.util.ClassFileDumper;
 58 
 59 import static java.lang.constant.ConstantDescs.*;
 60 import static java.lang.invoke.MethodHandleStatics.*;
 61 import static java.lang.invoke.MethodType.methodType;
 62 import static java.lang.module.ModuleDescriptor.Modifier.SYNTHETIC;
 63 import static java.lang.classfile.ClassFile.*;
 64 import static jdk.internal.constant.ConstantUtils.*;
 65 
 66 /**
 67  * This class consists exclusively of static methods that help adapt
 68  * method handles to other JVM types, such as interfaces.
 69  *
 70  * @since 1.7
 71  */
 72 public final class MethodHandleProxies {
 73 
 74     private MethodHandleProxies() { }  // do not instantiate
 75 

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

 36 import java.util.ArrayList;
 37 import java.util.Arrays;
 38 import java.util.Collections;
 39 import java.util.HashSet;
 40 import java.util.List;
 41 import java.util.Objects;
 42 import java.util.Set;
 43 import java.util.WeakHashMap;
 44 import java.util.concurrent.atomic.AtomicInteger;
 45 import java.util.stream.Stream;
 46 
 47 import jdk.internal.access.JavaLangReflectAccess;
 48 import jdk.internal.access.SharedSecrets;
 49 import java.lang.classfile.ClassHierarchyResolver;
 50 import java.lang.classfile.ClassFile;
 51 import java.lang.classfile.CodeBuilder;
 52 import java.lang.classfile.TypeKind;
 53 
 54 import jdk.internal.constant.ConstantUtils;
 55 import jdk.internal.loader.ClassLoaders;
 56 import jdk.internal.misc.PreviewFeatures;
 57 import jdk.internal.module.Modules;
 58 import jdk.internal.util.ClassFileDumper;
 59 
 60 import static java.lang.constant.ConstantDescs.*;
 61 import static java.lang.invoke.MethodHandleStatics.*;
 62 import static java.lang.invoke.MethodType.methodType;
 63 import static java.lang.module.ModuleDescriptor.Modifier.SYNTHETIC;
 64 import static java.lang.classfile.ClassFile.*;
 65 import static jdk.internal.constant.ConstantUtils.*;
 66 
 67 /**
 68  * This class consists exclusively of static methods that help adapt
 69  * method handles to other JVM types, such as interfaces.
 70  *
 71  * @since 1.7
 72  */
 73 public final class MethodHandleProxies {
 74 
 75     private MethodHandleProxies() { }  // do not instantiate
 76 

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