45 * Code generation backend for LambdaForm.
46 * <p>
47 * @author John Rose, JSR 292 EG
48 */
49 class InvokerBytecodeGenerator {
50 /** Define class names for convenience. */
51 private static final String MH = "java/lang/invoke/MethodHandle";
52 private static final String MHI = "java/lang/invoke/MethodHandleImpl";
53 private static final String LF = "java/lang/invoke/LambdaForm";
54 private static final String LFN = "java/lang/invoke/LambdaForm$Name";
55 private static final String CLS = "java/lang/Class";
56 private static final String OBJ = "java/lang/Object";
57 private static final String OBJARY = "[Ljava/lang/Object;";
58
59 private static final String LF_SIG = "L" + LF + ";";
60 private static final String LFN_SIG = "L" + LFN + ";";
61 private static final String LL_SIG = "(L" + OBJ + ";)L" + OBJ + ";";
62 private static final String CLL_SIG = "(L" + CLS + ";L" + OBJ + ";)L" + OBJ + ";";
63
64 /** Name of its super class*/
65 private static final String superName = LF;
66
67 /** Name of new class */
68 private final String className;
69
70 /** Name of the source file (for stack trace printing). */
71 private final String sourceFile;
72
73 private final LambdaForm lambdaForm;
74 private final String invokerName;
75 private final MethodType invokerType;
76
77 /** Info about local variables in compiled lambda form */
78 private final int[] localsMap; // index
79 private final BasicType[] localTypes; // basic type
80 private final Class<?>[] localClasses; // type
81
82 /** ASM bytecode generation. */
83 private ClassWriter cw;
84 private MethodVisitor mv;
85
86 private static final MemberName.Factory MEMBERNAME_FACTORY = MemberName.getFactory();
87 private static final Class<?> HOST_CLASS = LambdaForm.class;
88
89 /** Main constructor; other constructors delegate to this one. */
90 private InvokerBytecodeGenerator(LambdaForm lambdaForm, int localsMapSize,
91 String className, String invokerName, MethodType invokerType) {
92 if (invokerName.contains(".")) {
93 int p = invokerName.indexOf('.');
94 className = invokerName.substring(0, p);
95 invokerName = invokerName.substring(p+1);
96 }
97 if (DUMP_CLASS_FILES) {
98 className = makeDumpableClassName(className);
99 }
100 this.className = superName + "$" + className;
101 this.sourceFile = "LambdaForm$" + className;
102 this.lambdaForm = lambdaForm;
103 this.invokerName = invokerName;
104 this.invokerType = invokerType;
105 this.localsMap = new int[localsMapSize+1];
106 // last entry of localsMap is count of allocated local slots
107 this.localTypes = new BasicType[localsMapSize+1];
108 this.localClasses = new Class<?>[localsMapSize+1];
109 }
110
111 /** For generating LambdaForm interpreter entry points. */
112 private InvokerBytecodeGenerator(String className, String invokerName, MethodType invokerType) {
113 this(null, invokerType.parameterCount(),
114 className, invokerName, invokerType);
115 // Create an array to map name indexes to locals indexes.
116 localTypes[localTypes.length - 1] = V_TYPE;
117 for (int i = 0; i < localsMap.length; i++) {
118 localsMap[i] = invokerType.parameterSlotCount() - invokerType.parameterSlotDepth(i);
119 if (i < invokerType.parameterCount())
120 localTypes[i] = basicType(invokerType.parameterType(i));
|
45 * Code generation backend for LambdaForm.
46 * <p>
47 * @author John Rose, JSR 292 EG
48 */
49 class InvokerBytecodeGenerator {
50 /** Define class names for convenience. */
51 private static final String MH = "java/lang/invoke/MethodHandle";
52 private static final String MHI = "java/lang/invoke/MethodHandleImpl";
53 private static final String LF = "java/lang/invoke/LambdaForm";
54 private static final String LFN = "java/lang/invoke/LambdaForm$Name";
55 private static final String CLS = "java/lang/Class";
56 private static final String OBJ = "java/lang/Object";
57 private static final String OBJARY = "[Ljava/lang/Object;";
58
59 private static final String LF_SIG = "L" + LF + ";";
60 private static final String LFN_SIG = "L" + LFN + ";";
61 private static final String LL_SIG = "(L" + OBJ + ";)L" + OBJ + ";";
62 private static final String CLL_SIG = "(L" + CLS + ";L" + OBJ + ";)L" + OBJ + ";";
63
64 /** Name of its super class*/
65 private static final String superName = OBJ;
66
67 /** Name of new class */
68 private final String className;
69
70 /** Name of the source file (for stack trace printing). */
71 private final String sourceFile;
72
73 private final LambdaForm lambdaForm;
74 private final String invokerName;
75 private final MethodType invokerType;
76
77 /** Info about local variables in compiled lambda form */
78 private final int[] localsMap; // index
79 private final BasicType[] localTypes; // basic type
80 private final Class<?>[] localClasses; // type
81
82 /** ASM bytecode generation. */
83 private ClassWriter cw;
84 private MethodVisitor mv;
85
86 private static final MemberName.Factory MEMBERNAME_FACTORY = MemberName.getFactory();
87 private static final Class<?> HOST_CLASS = LambdaForm.class;
88
89 /** Main constructor; other constructors delegate to this one. */
90 private InvokerBytecodeGenerator(LambdaForm lambdaForm, int localsMapSize,
91 String className, String invokerName, MethodType invokerType) {
92 if (invokerName.contains(".")) {
93 int p = invokerName.indexOf('.');
94 className = invokerName.substring(0, p);
95 invokerName = invokerName.substring(p+1);
96 }
97 if (DUMP_CLASS_FILES) {
98 className = makeDumpableClassName(className);
99 }
100 this.className = LF + "$" + className;
101 this.sourceFile = "LambdaForm$" + className;
102 this.lambdaForm = lambdaForm;
103 this.invokerName = invokerName;
104 this.invokerType = invokerType;
105 this.localsMap = new int[localsMapSize+1];
106 // last entry of localsMap is count of allocated local slots
107 this.localTypes = new BasicType[localsMapSize+1];
108 this.localClasses = new Class<?>[localsMapSize+1];
109 }
110
111 /** For generating LambdaForm interpreter entry points. */
112 private InvokerBytecodeGenerator(String className, String invokerName, MethodType invokerType) {
113 this(null, invokerType.parameterCount(),
114 className, invokerName, invokerType);
115 // Create an array to map name indexes to locals indexes.
116 localTypes[localTypes.length - 1] = V_TYPE;
117 for (int i = 0; i < localsMap.length; i++) {
118 localsMap[i] = invokerType.parameterSlotCount() - invokerType.parameterSlotDepth(i);
119 if (i < invokerType.parameterCount())
120 localTypes[i] = basicType(invokerType.parameterType(i));
|