< prev index next >

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

Print this page

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

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

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                 cob.aload(0)
366                    .invokespecial(CD_Object, INIT_NAME, MTD_void)
367                    // call ensureOriginalLookup to verify the given Lookup has access

 34 import java.lang.reflect.Modifier;
 35 import java.lang.reflect.UndeclaredThrowableException;
 36 import java.util.ArrayList;
 37 import java.util.Arrays;
 38 import java.util.HashSet;
 39 import java.util.List;
 40 import java.util.Objects;
 41 import java.util.Set;
 42 import java.util.concurrent.atomic.AtomicInteger;
 43 import java.util.stream.Stream;
 44 
 45 import jdk.internal.access.JavaLangReflectAccess;
 46 import jdk.internal.access.SharedSecrets;
 47 import java.lang.classfile.ClassHierarchyResolver;
 48 import java.lang.classfile.ClassFile;
 49 import java.lang.classfile.CodeBuilder;
 50 import java.lang.classfile.TypeKind;
 51 
 52 import jdk.internal.constant.ConstantUtils;
 53 import jdk.internal.loader.ClassLoaders;
 54 import jdk.internal.misc.PreviewFeatures;
 55 import jdk.internal.module.Modules;
 56 import jdk.internal.util.ClassFileDumper;
 57 import jdk.internal.util.ReferencedKeySet;
 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

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_SUPER | 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
< prev index next >