< prev index next >

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

Print this page




  26 package java.lang.invoke;
  27 
  28 import jdk.internal.org.objectweb.asm.*;
  29 import sun.invoke.util.BytecodeDescriptor;
  30 import sun.security.action.GetPropertyAction;
  31 import sun.security.action.GetBooleanAction;
  32 
  33 import java.io.FilePermission;
  34 import java.io.Serializable;
  35 import java.lang.invoke.MethodHandles.Lookup;
  36 import java.lang.reflect.Constructor;
  37 import java.lang.reflect.Modifier;
  38 import java.security.AccessController;
  39 import java.security.PrivilegedAction;
  40 import java.util.LinkedHashSet;
  41 import java.util.concurrent.atomic.AtomicInteger;
  42 import java.util.PropertyPermission;
  43 import java.util.Set;
  44 
  45 import static java.lang.invoke.MethodHandles.Lookup.ClassOption.NESTMATE;

  46 import static jdk.internal.org.objectweb.asm.Opcodes.*;
  47 
  48 /**
  49  * Lambda metafactory implementation which dynamically creates an
  50  * inner-class-like class per lambda callsite.
  51  *
  52  * @see LambdaMetafactory
  53  */
  54 /* package */ final class InnerClassLambdaMetafactory extends AbstractValidatingLambdaMetafactory {
  55     private static final int CLASSFILE_VERSION = 52;
  56     private static final String METHOD_DESCRIPTOR_VOID = Type.getMethodDescriptor(Type.VOID_TYPE);
  57     private static final String JAVA_LANG_OBJECT = "java/lang/Object";
  58     private static final String NAME_CTOR = "<init>";
  59 
  60     //Serialization support
  61     private static final String NAME_SERIALIZED_LAMBDA = "java/lang/invoke/SerializedLambda";
  62     private static final String NAME_NOT_SERIALIZABLE_EXCEPTION = "java/io/NotSerializableException";
  63     private static final String DESCR_METHOD_WRITE_REPLACE = "()Ljava/lang/Object;";
  64     private static final String DESCR_METHOD_WRITE_OBJECT = "(Ljava/io/ObjectOutputStream;)V";
  65     private static final String DESCR_METHOD_READ_OBJECT = "(Ljava/io/ObjectInputStream;)V";


 330         cw.visitEnd();
 331 
 332         // Define the generated class in this VM.
 333 
 334         final byte[] classBytes = cw.toByteArray();
 335         // If requested, dump out to a file for debugging purposes
 336         if (dumper != null) {
 337             AccessController.doPrivileged(new PrivilegedAction<>() {
 338                 @Override
 339                 public Void run() {
 340                     dumper.dumpClass(lambdaClassName, classBytes);
 341                     return null;
 342                 }
 343             }, null,
 344             new FilePermission("<<ALL FILES>>", "read, write"),
 345             // createDirectories may need it
 346             new PropertyPermission("user.dir", "read"));
 347         }
 348         try {
 349             // this class is linked at the indy callsite; so define a hidden nestmate
 350             Lookup lookup = caller.defineHiddenClass(classBytes, !disableEagerInitialization, NESTMATE);
 351             if (useImplMethodHandle) {
 352                 // If the target class invokes a method reference this::m which is
 353                 // resolved to a protected method inherited from a superclass in a different
 354                 // package, the target class does not have a bridge and this method reference
 355                 // has been changed from public to protected after the target class was compiled.
 356                 // This lambda proxy class has no access to the resolved method.
 357                 // So this workaround by passing the live implMethod method handle
 358                 // to the proxy class to invoke directly.
 359                 MethodHandle mh = lookup.findStaticSetter(lookup.lookupClass(), NAME_FIELD_IMPL_METHOD, MethodHandle.class);
 360                 mh.invokeExact(implMethod);
 361             }
 362             return lookup.lookupClass();
 363         } catch (IllegalAccessException e) {
 364             throw new LambdaConversionException("Exception defining lambda proxy class", e);
 365         } catch (Throwable t) {
 366             throw new InternalError(t);
 367         }
 368     }
 369 
 370     /**




  26 package java.lang.invoke;
  27 
  28 import jdk.internal.org.objectweb.asm.*;
  29 import sun.invoke.util.BytecodeDescriptor;
  30 import sun.security.action.GetPropertyAction;
  31 import sun.security.action.GetBooleanAction;
  32 
  33 import java.io.FilePermission;
  34 import java.io.Serializable;
  35 import java.lang.invoke.MethodHandles.Lookup;
  36 import java.lang.reflect.Constructor;
  37 import java.lang.reflect.Modifier;
  38 import java.security.AccessController;
  39 import java.security.PrivilegedAction;
  40 import java.util.LinkedHashSet;
  41 import java.util.concurrent.atomic.AtomicInteger;
  42 import java.util.PropertyPermission;
  43 import java.util.Set;
  44 
  45 import static java.lang.invoke.MethodHandles.Lookup.ClassOption.NESTMATE;
  46 import static java.lang.invoke.MethodHandles.Lookup.ClassOption.STRONG;
  47 import static jdk.internal.org.objectweb.asm.Opcodes.*;
  48 
  49 /**
  50  * Lambda metafactory implementation which dynamically creates an
  51  * inner-class-like class per lambda callsite.
  52  *
  53  * @see LambdaMetafactory
  54  */
  55 /* package */ final class InnerClassLambdaMetafactory extends AbstractValidatingLambdaMetafactory {
  56     private static final int CLASSFILE_VERSION = 52;
  57     private static final String METHOD_DESCRIPTOR_VOID = Type.getMethodDescriptor(Type.VOID_TYPE);
  58     private static final String JAVA_LANG_OBJECT = "java/lang/Object";
  59     private static final String NAME_CTOR = "<init>";
  60 
  61     //Serialization support
  62     private static final String NAME_SERIALIZED_LAMBDA = "java/lang/invoke/SerializedLambda";
  63     private static final String NAME_NOT_SERIALIZABLE_EXCEPTION = "java/io/NotSerializableException";
  64     private static final String DESCR_METHOD_WRITE_REPLACE = "()Ljava/lang/Object;";
  65     private static final String DESCR_METHOD_WRITE_OBJECT = "(Ljava/io/ObjectOutputStream;)V";
  66     private static final String DESCR_METHOD_READ_OBJECT = "(Ljava/io/ObjectInputStream;)V";


 331         cw.visitEnd();
 332 
 333         // Define the generated class in this VM.
 334 
 335         final byte[] classBytes = cw.toByteArray();
 336         // If requested, dump out to a file for debugging purposes
 337         if (dumper != null) {
 338             AccessController.doPrivileged(new PrivilegedAction<>() {
 339                 @Override
 340                 public Void run() {
 341                     dumper.dumpClass(lambdaClassName, classBytes);
 342                     return null;
 343                 }
 344             }, null,
 345             new FilePermission("<<ALL FILES>>", "read, write"),
 346             // createDirectories may need it
 347             new PropertyPermission("user.dir", "read"));
 348         }
 349         try {
 350             // this class is linked at the indy callsite; so define a hidden nestmate
 351             Lookup lookup = caller.defineHiddenClass(classBytes, !disableEagerInitialization, NESTMATE, STRONG);
 352             if (useImplMethodHandle) {
 353                 // If the target class invokes a method reference this::m which is
 354                 // resolved to a protected method inherited from a superclass in a different
 355                 // package, the target class does not have a bridge and this method reference
 356                 // has been changed from public to protected after the target class was compiled.
 357                 // This lambda proxy class has no access to the resolved method.
 358                 // So this workaround by passing the live implMethod method handle
 359                 // to the proxy class to invoke directly.
 360                 MethodHandle mh = lookup.findStaticSetter(lookup.lookupClass(), NAME_FIELD_IMPL_METHOD, MethodHandle.class);
 361                 mh.invokeExact(implMethod);
 362             }
 363             return lookup.lookupClass();
 364         } catch (IllegalAccessException e) {
 365             throw new LambdaConversionException("Exception defining lambda proxy class", e);
 366         } catch (Throwable t) {
 367             throw new InternalError(t);
 368         }
 369     }
 370 
 371     /**


< prev index next >