143 MethodTypeForm.LF_EX_INVOKER,
144 MethodTypeForm.LF_GEN_LINKER,
145 MethodTypeForm.LF_GEN_INVOKER
146 };
147 for (int i = 0; i < methodTypes.length; i++) {
148 // generate methods representing invokers of the specified type
149 if (dedupSet.add(methodTypes[i])) {
150 for (int type : types) {
151 LambdaForm invokerForm = Invokers.invokeHandleForm(methodTypes[i],
152 /*customized*/false, type);
153 forms.add(invokerForm);
154 names.add(invokerForm.kind.defaultLambdaName);
155 }
156 }
157 }
158 return generateCodeBytesForLFs(className,
159 names.toArray(new String[0]),
160 forms.toArray(new LambdaForm[0]));
161 }
162
163 /*
164 * Generate customized code for a set of LambdaForms of specified types into
165 * a class with a specified name.
166 */
167 private static byte[] generateCodeBytesForLFs(String className,
168 String[] names, LambdaForm[] forms) {
169
170 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
171 cw.visit(Opcodes.V1_8, Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
172 className, null, InvokerBytecodeGenerator.INVOKER_SUPER_NAME, null);
173 cw.visitSource(className.substring(className.lastIndexOf('/') + 1), null);
174
175 for (int i = 0; i < forms.length; i++) {
176 addMethod(className, names[i], forms[i],
177 forms[i].methodType(), cw);
178 }
179 return cw.toByteArray();
180 }
181
182 private static void addMethod(String className, String methodName, LambdaForm form,
|
143 MethodTypeForm.LF_EX_INVOKER,
144 MethodTypeForm.LF_GEN_LINKER,
145 MethodTypeForm.LF_GEN_INVOKER
146 };
147 for (int i = 0; i < methodTypes.length; i++) {
148 // generate methods representing invokers of the specified type
149 if (dedupSet.add(methodTypes[i])) {
150 for (int type : types) {
151 LambdaForm invokerForm = Invokers.invokeHandleForm(methodTypes[i],
152 /*customized*/false, type);
153 forms.add(invokerForm);
154 names.add(invokerForm.kind.defaultLambdaName);
155 }
156 }
157 }
158 return generateCodeBytesForLFs(className,
159 names.toArray(new String[0]),
160 forms.toArray(new LambdaForm[0]));
161 }
162
163 static byte[] generateCallSiteHolderClassBytes(String className,
164 MethodType[] methodTypes) {
165
166 HashSet<MethodType> dedupSet = new HashSet<>();
167 ArrayList<LambdaForm> forms = new ArrayList<>();
168 ArrayList<String> names = new ArrayList<>();
169
170 for (int i = 0; i < methodTypes.length; i++) {
171 // generate methods representing invokers of the specified type
172 if (dedupSet.add(methodTypes[i])) {
173 LambdaForm callSiteForm = Invokers.callSiteForm(methodTypes[i], true);
174 forms.add(callSiteForm);
175 names.add(callSiteForm.kind.defaultLambdaName);
176
177 LambdaForm methodHandleForm = Invokers.callSiteForm(methodTypes[i], false);
178 forms.add(methodHandleForm);
179 names.add(methodHandleForm.kind.defaultLambdaName);
180 }
181 }
182 return generateCodeBytesForLFs(className,
183 names.toArray(new String[0]),
184 forms.toArray(new LambdaForm[0]));
185 }
186
187 /*
188 * Generate customized code for a set of LambdaForms of specified types into
189 * a class with a specified name.
190 */
191 private static byte[] generateCodeBytesForLFs(String className,
192 String[] names, LambdaForm[] forms) {
193
194 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
195 cw.visit(Opcodes.V1_8, Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
196 className, null, InvokerBytecodeGenerator.INVOKER_SUPER_NAME, null);
197 cw.visitSource(className.substring(className.lastIndexOf('/') + 1), null);
198
199 for (int i = 0; i < forms.length; i++) {
200 addMethod(className, names[i], forms[i],
201 forms[i].methodType(), cw);
202 }
203 return cw.toByteArray();
204 }
205
206 private static void addMethod(String className, String methodName, LambdaForm form,
|