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();
|