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 /**
|