76 private static final String SOURCE_PREFIX = "LambdaForm$";
77
78 /** Name of its super class*/
79 static final String INVOKER_SUPER_NAME = OBJ;
80
81 /** Name of new class */
82 private final String className;
83
84 private final LambdaForm lambdaForm;
85 private final String invokerName;
86 private final MethodType invokerType;
87
88 /** Info about local variables in compiled lambda form */
89 private int[] localsMap; // index
90 private Class<?>[] localClasses; // type
91
92 /** ASM bytecode generation. */
93 private ClassWriter cw;
94 private MethodVisitor mv;
95
96 private static final MemberName.Factory MEMBERNAME_FACTORY = MemberName.getFactory();
97 private static final Class<?> HOST_CLASS = LambdaForm.class;
98
99 /** Main constructor; other constructors delegate to this one. */
100 private InvokerBytecodeGenerator(LambdaForm lambdaForm, int localsMapSize,
101 String className, String invokerName, MethodType invokerType) {
102 int p = invokerName.indexOf('.');
103 if (p > -1) {
104 className = invokerName.substring(0, p);
105 invokerName = invokerName.substring(p + 1);
106 }
107 if (DUMP_CLASS_FILES) {
108 className = makeDumpableClassName(className);
109 }
110 this.className = className;
111 this.lambdaForm = lambdaForm;
112 this.invokerName = invokerName;
113 this.invokerType = invokerType;
114 this.localsMap = new int[localsMapSize+1]; // last entry of localsMap is count of allocated local slots
115 this.localClasses = new Class<?>[localsMapSize+1];
585 }
586
587 /**
588 * Emits an actual return instruction conforming to the given return type.
589 */
590 private void emitReturnInsn(BasicType type) {
591 int opcode;
592 switch (type) {
593 case I_TYPE: opcode = Opcodes.IRETURN; break;
594 case J_TYPE: opcode = Opcodes.LRETURN; break;
595 case F_TYPE: opcode = Opcodes.FRETURN; break;
596 case D_TYPE: opcode = Opcodes.DRETURN; break;
597 case L_TYPE: opcode = Opcodes.ARETURN; break;
598 case V_TYPE: opcode = Opcodes.RETURN; break;
599 default:
600 throw new InternalError("unknown return type: " + type);
601 }
602 mv.visitInsn(opcode);
603 }
604
605 private static String getInternalName(Class<?> c) {
606 if (c == Object.class) return OBJ;
607 else if (c == Object[].class) return OBJARY;
608 else if (c == Class.class) return CLS;
609 else if (c == MethodHandle.class) return MH;
610 assert(VerifyAccess.isTypeVisible(c, Object.class)) : c.getName();
611 return c.getName().replace('.', '/');
612 }
613
614 private static MemberName resolveFrom(String name, MethodType type, Class<?> holder) {
615 MemberName member = new MemberName(holder, name, type, REF_invokeStatic);
616 MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, holder);
617 if (TRACE_RESOLVE) {
618 System.out.println("[LF_RESOLVE] " + holder.getName() + " " + name + " " +
619 shortenSignature(basicTypeSignature(type)) + (resolvedMember != null ? " (success)" : " (fail)") );
620 }
621 return resolvedMember;
622 }
623
624 private static MemberName lookupPregenerated(LambdaForm form, MethodType invokerType) {
625 if (form.customized != null) {
626 // No pre-generated version for customized LF
627 return null;
628 }
629 String name = form.kind.methodName;
630 switch (form.kind) {
631 case BOUND_REINVOKER: {
|
76 private static final String SOURCE_PREFIX = "LambdaForm$";
77
78 /** Name of its super class*/
79 static final String INVOKER_SUPER_NAME = OBJ;
80
81 /** Name of new class */
82 private final String className;
83
84 private final LambdaForm lambdaForm;
85 private final String invokerName;
86 private final MethodType invokerType;
87
88 /** Info about local variables in compiled lambda form */
89 private int[] localsMap; // index
90 private Class<?>[] localClasses; // type
91
92 /** ASM bytecode generation. */
93 private ClassWriter cw;
94 private MethodVisitor mv;
95
96 /** Single element internal class name lookup cache. */
97 private Class<?> lastClass;
98 private String lastInternalName;
99
100 private static final MemberName.Factory MEMBERNAME_FACTORY = MemberName.getFactory();
101 private static final Class<?> HOST_CLASS = LambdaForm.class;
102
103 /** Main constructor; other constructors delegate to this one. */
104 private InvokerBytecodeGenerator(LambdaForm lambdaForm, int localsMapSize,
105 String className, String invokerName, MethodType invokerType) {
106 int p = invokerName.indexOf('.');
107 if (p > -1) {
108 className = invokerName.substring(0, p);
109 invokerName = invokerName.substring(p + 1);
110 }
111 if (DUMP_CLASS_FILES) {
112 className = makeDumpableClassName(className);
113 }
114 this.className = className;
115 this.lambdaForm = lambdaForm;
116 this.invokerName = invokerName;
117 this.invokerType = invokerType;
118 this.localsMap = new int[localsMapSize+1]; // last entry of localsMap is count of allocated local slots
119 this.localClasses = new Class<?>[localsMapSize+1];
589 }
590
591 /**
592 * Emits an actual return instruction conforming to the given return type.
593 */
594 private void emitReturnInsn(BasicType type) {
595 int opcode;
596 switch (type) {
597 case I_TYPE: opcode = Opcodes.IRETURN; break;
598 case J_TYPE: opcode = Opcodes.LRETURN; break;
599 case F_TYPE: opcode = Opcodes.FRETURN; break;
600 case D_TYPE: opcode = Opcodes.DRETURN; break;
601 case L_TYPE: opcode = Opcodes.ARETURN; break;
602 case V_TYPE: opcode = Opcodes.RETURN; break;
603 default:
604 throw new InternalError("unknown return type: " + type);
605 }
606 mv.visitInsn(opcode);
607 }
608
609 private String getInternalName(Class<?> c) {
610 if (c == Object.class) return OBJ;
611 else if (c == Object[].class) return OBJARY;
612 else if (c == Class.class) return CLS;
613 else if (c == MethodHandle.class) return MH;
614 assert(VerifyAccess.isTypeVisible(c, Object.class)) : c.getName();
615
616 if (c == lastClass) {
617 return lastInternalName;
618 }
619 lastClass = c;
620 return lastInternalName = c.getName().replace('.', '/');
621 }
622
623 private static MemberName resolveFrom(String name, MethodType type, Class<?> holder) {
624 MemberName member = new MemberName(holder, name, type, REF_invokeStatic);
625 MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, holder);
626 if (TRACE_RESOLVE) {
627 System.out.println("[LF_RESOLVE] " + holder.getName() + " " + name + " " +
628 shortenSignature(basicTypeSignature(type)) + (resolvedMember != null ? " (success)" : " (fail)") );
629 }
630 return resolvedMember;
631 }
632
633 private static MemberName lookupPregenerated(LambdaForm form, MethodType invokerType) {
634 if (form.customized != null) {
635 // No pre-generated version for customized LF
636 return null;
637 }
638 String name = form.kind.methodName;
639 switch (form.kind) {
640 case BOUND_REINVOKER: {
|