< prev index next >

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

Print this page

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

 58 import jdk.internal.module.Modules;
 59 import jdk.internal.reflect.CallerSensitive;
 60 import jdk.internal.reflect.Reflection;
 61 import jdk.internal.util.ClassFileDumper;
 62 import sun.reflect.misc.ReflectUtil;
 63 
 64 import static java.lang.constant.ConstantDescs.*;
 65 import static java.lang.invoke.MethodHandleStatics.*;
 66 import static java.lang.invoke.MethodType.methodType;
 67 import static java.lang.module.ModuleDescriptor.Modifier.SYNTHETIC;
 68 import static java.lang.classfile.ClassFile.*;
 69 import static jdk.internal.constant.ConstantUtils.*;
 70 
 71 /**
 72  * This class consists exclusively of static methods that help adapt
 73  * method handles to other JVM types, such as interfaces.
 74  *
 75  * @since 1.7
 76  */
 77 public class MethodHandleProxies {

359     private static final MethodTypeDesc MTD_void_String = MethodTypeDesc.of(CD_void, CD_String);
360     private static final String TARGET_NAME = "target";
361     private static final String TYPE_NAME = "interfaceType";
362     private static final String ENSURE_ORIGINAL_LOOKUP = "ensureOriginalLookup";
363 
364     /**
365      * Creates an implementation class file for a given interface. One implementation class is
366      * defined for each interface.
367      *
368      * @param ifaceDesc the given interface
369      * @param methodName the name of the single abstract method
370      * @param methods the information for implementation methods
371      * @return the bytes of the implementation classes
372      */
373     private static byte[] createTemplate(ClassLoader loader, ClassDesc proxyDesc, ClassDesc ifaceDesc,
374                                          String methodName, List<MethodInfo> methods) {
375         return ClassFile.of(ClassHierarchyResolverOption.of(ClassHierarchyResolver.ofClassLoading(loader == null ?
376                         ClassLoaders.platformClassLoader() : loader)))
377                         .build(proxyDesc, clb -> {
378             clb.withSuperclass(CD_Object)
379                .withFlags(ACC_FINAL | ACC_SYNTHETIC)
380                .withInterfaceSymbols(ifaceDesc)
381                // static and instance fields
382                .withField(TYPE_NAME, CD_Class, ACC_PRIVATE | ACC_STATIC | ACC_FINAL)
383                .withField(TARGET_NAME, CD_MethodHandle, ACC_PRIVATE | ACC_FINAL);
384             for (var mi : methods) {
385                 clb.withField(mi.fieldName, CD_MethodHandle, ACC_PRIVATE | ACC_FINAL);
386             }
387 
388             // <clinit>
389             clb.withMethodBody(CLASS_INIT_NAME, MTD_void, ACC_STATIC, cob -> {
390                 cob.loadConstant(ifaceDesc)
391                    .putstatic(proxyDesc, TYPE_NAME, CD_Class)
392                    .return_();
393             });
394 
395             // <init>(Lookup, MethodHandle target, MethodHandle callerBoundTarget)
396             clb.withMethodBody(INIT_NAME, MTD_void_Lookup_MethodHandle_MethodHandle, 0, cob -> {
397                 cob.aload(0)
398                    .invokespecial(CD_Object, INIT_NAME, MTD_void)
399                    // call ensureOriginalLookup to verify the given Lookup has access

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

360     private static final MethodTypeDesc MTD_void_String = MethodTypeDesc.of(CD_void, CD_String);
361     private static final String TARGET_NAME = "target";
362     private static final String TYPE_NAME = "interfaceType";
363     private static final String ENSURE_ORIGINAL_LOOKUP = "ensureOriginalLookup";
364 
365     /**
366      * Creates an implementation class file for a given interface. One implementation class is
367      * defined for each interface.
368      *
369      * @param ifaceDesc the given interface
370      * @param methodName the name of the single abstract method
371      * @param methods the information for implementation methods
372      * @return the bytes of the implementation classes
373      */
374     private static byte[] createTemplate(ClassLoader loader, ClassDesc proxyDesc, ClassDesc ifaceDesc,
375                                          String methodName, List<MethodInfo> methods) {
376         return ClassFile.of(ClassHierarchyResolverOption.of(ClassHierarchyResolver.ofClassLoading(loader == null ?
377                         ClassLoaders.platformClassLoader() : loader)))
378                         .build(proxyDesc, clb -> {
379             clb.withSuperclass(CD_Object)
380                .withFlags((PreviewFeatures.isEnabled() ? ACC_IDENTITY  : 0) | ACC_FINAL | ACC_SYNTHETIC)
381                .withInterfaceSymbols(ifaceDesc)
382                // static and instance fields
383                .withField(TYPE_NAME, CD_Class, ACC_PRIVATE | ACC_STATIC | ACC_FINAL)
384                .withField(TARGET_NAME, CD_MethodHandle, ACC_PRIVATE | ACC_FINAL);
385             for (var mi : methods) {
386                 clb.withField(mi.fieldName, CD_MethodHandle, ACC_PRIVATE | ACC_FINAL);
387             }
388 
389             // <clinit>
390             clb.withMethodBody(CLASS_INIT_NAME, MTD_void, ACC_STATIC, cob -> {
391                 cob.loadConstant(ifaceDesc)
392                    .putstatic(proxyDesc, TYPE_NAME, CD_Class)
393                    .return_();
394             });
395 
396             // <init>(Lookup, MethodHandle target, MethodHandle callerBoundTarget)
397             clb.withMethodBody(INIT_NAME, MTD_void_Lookup_MethodHandle_MethodHandle, 0, cob -> {
398                 cob.aload(0)
399                    .invokespecial(CD_Object, INIT_NAME, MTD_void)
400                    // call ensureOriginalLookup to verify the given Lookup has access
< prev index next >