< prev index next >

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

Print this page




 177         }
 178     }
 179 
 180     /**
 181      * Build the CallSite. Generate a class file which implements the functional
 182      * interface, define the class, if there are no parameters create an instance
 183      * of the class which the CallSite will return, otherwise, generate handles
 184      * which will call the class' constructor.
 185      *
 186      * @return a CallSite, which, when invoked, will return an instance of the
 187      * functional interface
 188      * @throws ReflectiveOperationException
 189      * @throws LambdaConversionException If properly formed functional interface
 190      * is not found
 191      */
 192     @Override
 193     CallSite buildCallSite() throws LambdaConversionException {
 194         final Class<?> innerClass = spinInnerClass();
 195         if (invokedType.parameterCount() == 0) {
 196             final Constructor<?>[] ctrs = AccessController.doPrivileged(
 197                     new PrivilegedAction<Constructor<?>[]>() {
 198                 @Override
 199                 public Constructor<?>[] run() {
 200                     Constructor<?>[] ctrs = innerClass.getDeclaredConstructors();
 201                     if (ctrs.length == 1) {
 202                         // The lambda implementing inner class constructor is private, set
 203                         // it accessible (by us) before creating the constant sole instance
 204                         ctrs[0].setAccessible(true);
 205                     }
 206                     return ctrs;
 207                 }
 208                     });
 209             if (ctrs.length != 1) {
 210                 throw new LambdaConversionException("Expected one lambda constructor for "
 211                         + innerClass.getCanonicalName() + ", got " + ctrs.length);
 212             }
 213 
 214             try {
 215                 Object inst = ctrs[0].newInstance();
 216                 return new ConstantCallSite(MethodHandles.constant(samBase, inst));
 217             }


 294                 mv = cw.visitMethod(ACC_PUBLIC|ACC_BRIDGE, samMethodName,
 295                                     mt.toMethodDescriptorString(), null, null);
 296                 mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true);
 297                 new ForwardingMethodGenerator(mv).generate(mt);
 298             }
 299         }
 300 
 301         if (isSerializable)
 302             generateSerializationFriendlyMethods();
 303         else if (accidentallySerializable)
 304             generateSerializationHostileMethods();
 305 
 306         cw.visitEnd();
 307 
 308         // Define the generated class in this VM.
 309 
 310         final byte[] classBytes = cw.toByteArray();
 311 
 312         // If requested, dump out to a file for debugging purposes
 313         if (dumper != null) {
 314             AccessController.doPrivileged(new PrivilegedAction<Void>() {
 315                 @Override
 316                 public Void run() {
 317                     dumper.dumpClass(lambdaClassName, classBytes);
 318                     return null;
 319                 }
 320             }, null,
 321             new FilePermission("<<ALL FILES>>", "read, write"),
 322             // createDirectories may need it
 323             new PropertyPermission("user.dir", "read"));
 324         }
 325 
 326         return UNSAFE.defineAnonymousClass(targetClass, classBytes, null);
 327     }
 328 
 329     /**
 330      * Generate the factory method for the class
 331      */
 332     private void generateFactory() {
 333         MethodVisitor m = cw.visitMethod(ACC_PRIVATE | ACC_STATIC, NAME_FACTORY, invokedType.toMethodDescriptorString(), null, null);
 334         m.visitCode();




 177         }
 178     }
 179 
 180     /**
 181      * Build the CallSite. Generate a class file which implements the functional
 182      * interface, define the class, if there are no parameters create an instance
 183      * of the class which the CallSite will return, otherwise, generate handles
 184      * which will call the class' constructor.
 185      *
 186      * @return a CallSite, which, when invoked, will return an instance of the
 187      * functional interface
 188      * @throws ReflectiveOperationException
 189      * @throws LambdaConversionException If properly formed functional interface
 190      * is not found
 191      */
 192     @Override
 193     CallSite buildCallSite() throws LambdaConversionException {
 194         final Class<?> innerClass = spinInnerClass();
 195         if (invokedType.parameterCount() == 0) {
 196             final Constructor<?>[] ctrs = AccessController.doPrivileged(
 197                     new PrivilegedAction<>() {
 198                 @Override
 199                 public Constructor<?>[] run() {
 200                     Constructor<?>[] ctrs = innerClass.getDeclaredConstructors();
 201                     if (ctrs.length == 1) {
 202                         // The lambda implementing inner class constructor is private, set
 203                         // it accessible (by us) before creating the constant sole instance
 204                         ctrs[0].setAccessible(true);
 205                     }
 206                     return ctrs;
 207                 }
 208                     });
 209             if (ctrs.length != 1) {
 210                 throw new LambdaConversionException("Expected one lambda constructor for "
 211                         + innerClass.getCanonicalName() + ", got " + ctrs.length);
 212             }
 213 
 214             try {
 215                 Object inst = ctrs[0].newInstance();
 216                 return new ConstantCallSite(MethodHandles.constant(samBase, inst));
 217             }


 294                 mv = cw.visitMethod(ACC_PUBLIC|ACC_BRIDGE, samMethodName,
 295                                     mt.toMethodDescriptorString(), null, null);
 296                 mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true);
 297                 new ForwardingMethodGenerator(mv).generate(mt);
 298             }
 299         }
 300 
 301         if (isSerializable)
 302             generateSerializationFriendlyMethods();
 303         else if (accidentallySerializable)
 304             generateSerializationHostileMethods();
 305 
 306         cw.visitEnd();
 307 
 308         // Define the generated class in this VM.
 309 
 310         final byte[] classBytes = cw.toByteArray();
 311 
 312         // If requested, dump out to a file for debugging purposes
 313         if (dumper != null) {
 314             AccessController.doPrivileged(new PrivilegedAction<>() {
 315                 @Override
 316                 public Void run() {
 317                     dumper.dumpClass(lambdaClassName, classBytes);
 318                     return null;
 319                 }
 320             }, null,
 321             new FilePermission("<<ALL FILES>>", "read, write"),
 322             // createDirectories may need it
 323             new PropertyPermission("user.dir", "read"));
 324         }
 325 
 326         return UNSAFE.defineAnonymousClass(targetClass, classBytes, null);
 327     }
 328 
 329     /**
 330      * Generate the factory method for the class
 331      */
 332     private void generateFactory() {
 333         MethodVisitor m = cw.visitMethod(ACC_PRIVATE | ACC_STATIC, NAME_FACTORY, invokedType.toMethodDescriptorString(), null, null);
 334         m.visitCode();


< prev index next >