src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
Print this page
rev 9538 : generates MH link to static factory for lambdas
rev 9539 : fix bytecode loading constructor parameters
rev 9540 : whitespace cleaning
*** 47,56 ****
--- 47,57 ----
private static final int CLASSFILE_VERSION = 51;
private static final String METHOD_DESCRIPTOR_VOID = Type.getMethodDescriptor(Type.VOID_TYPE);
private static final String NAME_MAGIC_ACCESSOR_IMPL = "java/lang/invoke/MagicLambdaImpl";
private static final String NAME_CTOR = "<init>";
+ private static final String NAME_FACTORY = "get$Lambda";
//Serialization support
private static final String NAME_SERIALIZED_LAMBDA = "java/lang/invoke/SerializedLambda";
private static final String DESCR_METHOD_WRITE_REPLACE = "()Ljava/lang/Object;";
private static final String NAME_METHOD_WRITE_REPLACE = "writeReplace";
*** 190,202 ****
});
Object inst = ctrs[0].newInstance();
return new ConstantCallSite(MethodHandles.constant(samBase, inst));
} else {
return new ConstantCallSite(
! MethodHandles.Lookup.IMPL_LOOKUP
! .findConstructor(innerClass, constructorType)
! .asType(constructorType.changeReturnType(samBase)));
}
}
/**
* Generate a class file which implements the functional
--- 191,201 ----
});
Object inst = ctrs[0].newInstance();
return new ConstantCallSite(MethodHandles.constant(samBase, inst));
} else {
return new ConstantCallSite(
! MethodHandles.Lookup.IMPL_LOOKUP.findStatic(innerClass, NAME_FACTORY, invokedType));
}
}
/**
* Generate a class file which implements the functional
*** 232,241 ****
--- 231,244 ----
fv.visitEnd();
}
generateConstructor();
+ if (invokedType.parameterCount() != 0) {
+ generateFactory();
+ }
+
// Forward the SAM method
String methodDescriptor = samMethodType.toMethodDescriptorString();
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, samMethodName,
methodDescriptor, null, null);
new ForwardingMethodGenerator(mv).generate(methodDescriptor);
*** 287,296 ****
--- 290,317 ----
classBytes, 0, classBytes.length,
loader, pd);
}
/**
+ * Generate the factory method for the class
+ */
+ private void generateFactory() {
+ MethodVisitor m = cw.visitMethod(ACC_PRIVATE | ACC_STATIC, NAME_FACTORY, invokedType.toMethodDescriptorString(), null, null);
+ m.visitCode();
+ m.visitTypeInsn(NEW, lambdaClassName);
+ m.visitInsn(Opcodes.DUP);
+ for (int typeIndex = 0, varIndex = 0; typeIndex < argTypes.length; typeIndex++) {
+ m.visitVarInsn(argTypes[typeIndex].getOpcode(ILOAD), varIndex);
+ varIndex += argTypes[typeIndex].getSize();
+ }
+ m.visitMethodInsn(INVOKESPECIAL, lambdaClassName, NAME_CTOR, constructorDesc);
+ m.visitInsn(ARETURN);
+ m.visitMaxs(-1, -1);
+ m.visitEnd();
+ }
+
+ /**
* Generate the constructor for the class
*/
private void generateConstructor() {
// Generate constructor
MethodVisitor ctor = cw.visitMethod(ACC_PRIVATE, NAME_CTOR,