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,