blob: a4cd89a602077a73ad6925d3b3a43cfd980a1e0e [file] [log] [blame]
Mads Ager418d1ca2017-05-22 09:35:49 +02001// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4package invokecustom;
5
Mads Ager418d1ca2017-05-22 09:35:49 +02006import java.io.IOException;
Rico Windc0016d12017-10-26 13:39:32 +02007import java.io.InputStream;
8import java.io.OutputStream;
Mads Ager418d1ca2017-05-22 09:35:49 +02009import java.lang.invoke.CallSite;
10import java.lang.invoke.MethodHandle;
11import java.lang.invoke.MethodHandles;
12import java.lang.invoke.MethodType;
Rico Windc0016d12017-10-26 13:39:32 +020013import java.nio.file.Files;
Mads Ager418d1ca2017-05-22 09:35:49 +020014import java.nio.file.Path;
15import java.nio.file.Paths;
16import org.objectweb.asm.ClassReader;
17import org.objectweb.asm.ClassVisitor;
18import org.objectweb.asm.ClassWriter;
19import org.objectweb.asm.Handle;
20import org.objectweb.asm.MethodVisitor;
21import org.objectweb.asm.Opcodes;
22import org.objectweb.asm.Type;
23
Ian Zerny85cc9f42021-08-31 15:39:26 +020024// TODO(b/167145686): Migrate these tests to the new setup ala
25// InvokeDynamicVirtualDispatchToDefaultInterfaceMethodTest
Mads Ager418d1ca2017-05-22 09:35:49 +020026public class TestGenerator {
27
28 private final Path classNamePath;
29
30 public static void main(String[] args) throws IOException {
31 assert args.length == 1;
32 TestGenerator testGenerator = new TestGenerator(Paths.get(args[0],
33 TestGenerator.class.getPackage().getName(), InvokeCustom.class.getSimpleName() + ".class"));
34 testGenerator.generateTests();
35 }
36
37 public TestGenerator(Path classNamePath) {
38 this.classNamePath = classNamePath;
39 }
40
41 private void generateTests() throws IOException {
Rico Windc0016d12017-10-26 13:39:32 +020042 try (InputStream input = Files.newInputStream(classNamePath)) {
43 ClassReader cr = new ClassReader(input);
44 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
45 cr.accept(
clementbera6c91c652019-04-15 17:28:42 +020046 new ClassVisitor(Opcodes.ASM7, cw) {
Rico Windc0016d12017-10-26 13:39:32 +020047 @Override
48 public void visitEnd() {
49 generateMethodTest1(cw);
50 generateMethodTest2(cw);
51 generateMethodTest3(cw);
52 generateMethodTest4(cw);
53 generateMethodTest5(cw);
54 generateMethodTest6(cw);
55 generateMethodTest7(cw);
56 generateMethodTest8(cw);
Rico Windc0016d12017-10-26 13:39:32 +020057 generateMethodTest10(cw);
58 generateMethodTest11(cw);
59 generateMethodTest12(cw);
60 generateMethodTest13(cw);
Mads Agerab4dc702018-09-24 09:43:52 +020061 generateMethodTest14(cw);
Rico Windc0016d12017-10-26 13:39:32 +020062 generateMethodMain(cw);
63 super.visitEnd();
64 }
65 }, 0);
66 try (OutputStream output = Files.newOutputStream(classNamePath)) {
67 output.write(cw.toByteArray());
68 }
69 }
Mads Ager418d1ca2017-05-22 09:35:49 +020070 }
71
72 /* generate main method that only call all test methods. */
73 private void generateMethodMain(ClassVisitor cv) {
74 MethodVisitor mv = cv.visitMethod(
75 Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
76 mv.visitMethodInsn(
77 Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test1", "()V", false);
78 mv.visitMethodInsn(
79 Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test2", "()V", false);
80 mv.visitMethodInsn(
81 Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test3", "()V", false);
82 mv.visitMethodInsn(
83 Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test4", "()V", false);
84 mv.visitMethodInsn(
85 Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test5", "()V", false);
86 mv.visitMethodInsn(
87 Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test6", "()V", false);
88 mv.visitMethodInsn(
89 Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test7", "()V", false);
90 mv.visitMethodInsn(
91 Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test8", "()V", false);
92 mv.visitMethodInsn(
Mads Ager418d1ca2017-05-22 09:35:49 +020093 Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test10", "()V", false);
94 mv.visitMethodInsn(
95 Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test11", "()V", false);
96 mv.visitMethodInsn(
97 Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test12", "()V", false);
98 mv.visitMethodInsn(
99 Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test13", "()V", false);
Mads Agerab4dc702018-09-24 09:43:52 +0200100 mv.visitMethodInsn(
101 Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test14", "()V", false);
Mads Ager418d1ca2017-05-22 09:35:49 +0200102 mv.visitInsn(Opcodes.RETURN);
103 mv.visitMaxs(-1, -1);
104 }
105
106 /**
107 * Generate test with an invokedynamic, a static bootstrap method without extra args and no arg
108 * to the target method.
109 */
110 private void generateMethodTest1(ClassVisitor cv) {
111 MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test1", "()V",
112 null, null);
113 MethodType mt =
114 MethodType.methodType(
115 CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
116 Handle bootstrap = new Handle( Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class),
117 "bsmLookupStatic", mt.toMethodDescriptorString(), false);
118 mv.visitInvokeDynamicInsn("targetMethodTest1", "()V", bootstrap);
119 mv.visitInsn(Opcodes.RETURN);
120 mv.visitMaxs(-1, -1);
121 }
122
123 /**
124 * Generate test with an invokedynamic, a static bootstrap method without extra args and
125 * args to the target method.
126 */
127 private void generateMethodTest2(ClassVisitor cv) {
128 MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test2", "()V",
129 null, null);
130 MethodType mt = MethodType.methodType(
131 CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
132 Handle bootstrap = new Handle( Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class),
133 "bsmLookupStatic", mt.toMethodDescriptorString(), false);
134 mv.visitLdcInsn(new Boolean(true));
135 mv.visitLdcInsn(new Byte((byte) 127));
136 mv.visitLdcInsn(new Character('c'));
137 mv.visitLdcInsn(new Short((short) 1024));
138 mv.visitLdcInsn(new Integer(123456));
139 mv.visitLdcInsn(new Float(1.2f));
140 mv.visitLdcInsn(new Long(123456789));
141 mv.visitLdcInsn(new Double(3.5123456789));
142 mv.visitLdcInsn("String");
143 mv.visitInvokeDynamicInsn("targetMethodTest2", "(ZBCSIFJDLjava/lang/String;)V", bootstrap);
144 mv.visitInsn(Opcodes.RETURN);
145 mv.visitMaxs(-1, -1);
146 }
147
148 /**
149 * Generate test with an invokedynamic, a static bootstrap method with extra args and no arg
150 * to the target method.
151 */
152 private void generateMethodTest3(ClassVisitor cv) {
153 MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test3", "()V",
154 null, null);
155 MethodType mt = MethodType.methodType(
156 CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, int.class,
157 long.class, float.class, double.class);
158 Handle bootstrap = new Handle( Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class),
159 "bsmLookupStaticWithExtraArgs", mt.toMethodDescriptorString(), false);
160 mv.visitInvokeDynamicInsn("targetMethodTest3", "()V", bootstrap, new Integer(1),
161 new Long(123456789), new Float(123.456), new Double(123456.789123));
162 mv.visitInsn(Opcodes.RETURN);
163 mv.visitMaxs(-1, -1);
164 }
165
166 /**
167 * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a
168 * MethodHandle of kind invokespecial.
169 */
170 private void generateMethodTest4(ClassVisitor cv) {
171 MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test4", "()V",
172 null, null);
173 MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,
174 MethodType.class, MethodHandle.class);
175 Handle bootstrap = new Handle( Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class),
176 "bsmCreateCallSite", mt.toMethodDescriptorString(), false);
177 mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class));
178 mv.visitInsn(Opcodes.DUP);
179 mv.visitMethodInsn(
180 Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false);
181 mv.visitInvokeDynamicInsn("targetMethodTest5", "(Linvokecustom/InvokeCustom;)V", bootstrap,
182 new Handle( Opcodes.H_INVOKESPECIAL, Type.getInternalName(Super.class),
183 "targetMethodTest5", "()V", false));
184 mv.visitInsn(Opcodes.RETURN);
185 mv.visitMaxs(-1, -1);
186 }
187
188 /**
189 * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a
190 * MethodHandle of kind invoke interface. The target method is a default method into an interface
191 * that shadows another default method from a super interface.
192 */
193 private void generateMethodTest5(ClassVisitor cv) {
194 MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test5", "()V",
195 null, null);
196 MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,
197 MethodType.class, MethodHandle.class);
198 Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class),
mikaelpeltiera05d3d52017-08-21 15:03:22 +0200199 "bsmCreateCallSite", mt.toMethodDescriptorString(), false);
Mads Ager418d1ca2017-05-22 09:35:49 +0200200 mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class));
201 mv.visitInsn(Opcodes.DUP);
202 mv.visitMethodInsn(
203 Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false);
204 mv.visitInvokeDynamicInsn("targetMethodTest6", "(Linvokecustom/I;)V", bootstrap,
205 new Handle(Opcodes.H_INVOKEINTERFACE, Type.getInternalName(I.class),
206 "targetMethodTest6", "()V", true));
207 mv.visitInsn(Opcodes.RETURN);
208 mv.visitMaxs(-1, -1);
209 }
210
211 /**
212 * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a
213 * MethodHandle of kind invoke interface. The target method is a default method into an interface
214 * that is at the end of a chain of interfaces.
215 */
216 private void generateMethodTest6(ClassVisitor cv) {
217 MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test6", "()V",
218 null, null);
219 MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,
220 MethodType.class, MethodHandle.class);
221 Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class),
mikaelpeltiera05d3d52017-08-21 15:03:22 +0200222 "bsmCreateCallSite", mt.toMethodDescriptorString(), false);
Mads Ager418d1ca2017-05-22 09:35:49 +0200223 mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class));
224 mv.visitInsn(Opcodes.DUP);
225 mv.visitMethodInsn(
226 Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false);
227 mv.visitInvokeDynamicInsn("targetMethodTest7", "(Linvokecustom/J;)V", bootstrap,
228 new Handle(Opcodes.H_INVOKEINTERFACE, Type.getInternalName(J.class),
229 "targetMethodTest7", "()V", true));
230 mv.visitInsn(Opcodes.RETURN);
231 mv.visitMaxs(-1, -1);
232 }
233
234 /**
235 * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a
236 * MethodHandle of kind invoke interface. The target method is a method into an interface
237 * that is shadowed by another definition into a sub interfaces.
238 */
239 private void generateMethodTest7(ClassVisitor cv) {
240 MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test7", "()V",
241 null, null);
242 MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,
243 MethodType.class, MethodHandle.class);
244 Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class),
mikaelpeltiera05d3d52017-08-21 15:03:22 +0200245 "bsmCreateCallSite", mt.toMethodDescriptorString(), false);
Mads Ager418d1ca2017-05-22 09:35:49 +0200246 mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class));
247 mv.visitInsn(Opcodes.DUP);
248 mv.visitMethodInsn(
249 Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false);
250 mv.visitInvokeDynamicInsn("targetMethodTest8", "(Linvokecustom/J;)V", bootstrap,
251 new Handle(Opcodes.H_INVOKEINTERFACE, Type.getInternalName(J.class),
252 "targetMethodTest8", "()V", true));
253 mv.visitInsn(Opcodes.RETURN);
254 mv.visitMaxs(-1, -1);
255 }
256
257 /**
258 * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a
259 * MethodHandle of kind invoke virtual. The target method is a method into an interface that is
260 * not shadowed by an implementation into a classes implementing the interface.
261 */
262 private void generateMethodTest8(ClassVisitor cv) {
263 MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test8", "()V",
264 null, null);
265 MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,
266 MethodType.class, MethodHandle.class);
267 Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class),
mikaelpeltiera05d3d52017-08-21 15:03:22 +0200268 "bsmCreateCallSite", mt.toMethodDescriptorString(), false);
Mads Ager418d1ca2017-05-22 09:35:49 +0200269 mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class));
270 mv.visitInsn(Opcodes.DUP);
271 mv.visitMethodInsn(
272 Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false);
273 mv.visitInvokeDynamicInsn("targetMethodTest9", "(Linvokecustom/InvokeCustom;)V", bootstrap,
274 new Handle(Opcodes.H_INVOKEVIRTUAL, Type.getInternalName(InvokeCustom.class),
275 "targetMethodTest9", "()V", false));
276 mv.visitInsn(Opcodes.RETURN);
277 mv.visitMaxs(-1, -1);
278 }
279
280 /**
281 * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a
Mads Ager418d1ca2017-05-22 09:35:49 +0200282 * MethodHandle of kind get static. The method handle read a static field from a class.
283 */
284 private void generateMethodTest10(ClassVisitor cv) {
285 MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test10", "()V",
286 null, null);
287 MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,
288 MethodType.class, MethodHandle.class);
289 Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class),
mikaelpeltiera05d3d52017-08-21 15:03:22 +0200290 "bsmCreateCallSite", mt.toMethodDescriptorString(), false);
Mads Ager418d1ca2017-05-22 09:35:49 +0200291 mv.visitFieldInsn(Opcodes.GETSTATIC,
292 "java/lang/System",
293 "out",
294 "Ljava/io/PrintStream;");
295 mv.visitInvokeDynamicInsn("staticField1", "()Ljava/lang/String;", bootstrap,
296 new Handle(Opcodes.H_GETSTATIC, Type.getInternalName(InvokeCustom.class),
297 "staticField1", "Ljava/lang/String;", false));
298 mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
299 "java/io/PrintStream",
300 "println",
301 "(Ljava/lang/String;)V", false);
302 mv.visitInsn(Opcodes.RETURN);
303 mv.visitMaxs(-1, -1);
304 }
305
306 /**
307 * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a
308 * MethodHandle of kind put static. The method handle write a static field in a class and then
309 * print its value.
310 */
311 private void generateMethodTest11(ClassVisitor cv) {
312 MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test11", "()V",
313 null, null);
314 MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,
315 MethodType.class, MethodHandle.class);
316 Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class),
mikaelpeltiera05d3d52017-08-21 15:03:22 +0200317 "bsmCreateCallSite", mt.toMethodDescriptorString(), false);
Mads Ager418d1ca2017-05-22 09:35:49 +0200318 mv.visitLdcInsn("Write static field");
319 mv.visitInvokeDynamicInsn("staticField1", "(Ljava/lang/String;)V", bootstrap,
320 new Handle(Opcodes.H_PUTSTATIC, Type.getInternalName(InvokeCustom.class),
321 "staticField1", "Ljava/lang/String;", false));
322 mv.visitFieldInsn(Opcodes.GETSTATIC,
323 "java/lang/System",
324 "out",
325 "Ljava/io/PrintStream;");
326 mv.visitFieldInsn(Opcodes.GETSTATIC,
327 Type.getInternalName(InvokeCustom.class),
328 "staticField1",
329 "Ljava/lang/String;");
330 mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
331 "java/io/PrintStream",
332 "println",
333 "(Ljava/lang/String;)V", false);
334 mv.visitInsn(Opcodes.RETURN);
335 mv.visitMaxs(-1, -1);
336 }
337
338 /**
339 * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a
340 * MethodHandle of kind get instance. The method handle read an instance field from a class.
341 */
342 private void generateMethodTest12(ClassVisitor cv) {
343 MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test12", "()V",
344 null, null);
345 MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,
346 MethodType.class, MethodHandle.class);
347 Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class),
mikaelpeltiera05d3d52017-08-21 15:03:22 +0200348 "bsmCreateCallSite", mt.toMethodDescriptorString(), false);
Mads Ager418d1ca2017-05-22 09:35:49 +0200349 mv.visitFieldInsn(Opcodes.GETSTATIC,
350 "java/lang/System",
351 "out",
352 "Ljava/io/PrintStream;");
353 mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class));
354 mv.visitInsn(Opcodes.DUP);
355 mv.visitMethodInsn(
356 Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false);
357 mv.visitInvokeDynamicInsn("instanceField1", "(Linvokecustom/InvokeCustom;)Ljava/lang/String;",
358 bootstrap, new Handle(Opcodes.H_GETFIELD, Type.getInternalName(InvokeCustom.class),
359 "instanceField1", "Ljava/lang/String;", false));
360 mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
361 "java/io/PrintStream",
362 "println",
363 "(Ljava/lang/String;)V", false);
364 mv.visitInsn(Opcodes.RETURN);
365 mv.visitMaxs(-1, -1);
366 }
367
368 /**
369 * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a
370 * MethodHandle of kind put instance. The method handle write an instance field in a class and
371 * then print its value.
372 */
373 private void generateMethodTest13(ClassVisitor cv) {
374 MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test13", "()V",
375 null, null);
376 MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,
377 MethodType.class, MethodHandle.class);
378 Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class),
mikaelpeltiera05d3d52017-08-21 15:03:22 +0200379 "bsmCreateCallSite", mt.toMethodDescriptorString(), false);
Mads Ager418d1ca2017-05-22 09:35:49 +0200380 mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class));
381 mv.visitInsn(Opcodes.DUP);
382 mv.visitMethodInsn(
383 Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false);
384 mv.visitVarInsn(Opcodes.ASTORE, 0);
385 mv.visitVarInsn(Opcodes.ALOAD, 0);
386 mv.visitLdcInsn("Write instance field");
387 mv.visitInvokeDynamicInsn("instanceField1", "(Linvokecustom/InvokeCustom;Ljava/lang/String;)V",
388 bootstrap, new Handle(Opcodes.H_PUTFIELD, Type.getInternalName(InvokeCustom.class),
389 "instanceField1", "Ljava/lang/String;", false));
390 mv.visitFieldInsn(Opcodes.GETSTATIC,
391 "java/lang/System",
392 "out",
393 "Ljava/io/PrintStream;");
394 mv.visitVarInsn(Opcodes.ALOAD, 0);
395 mv.visitFieldInsn(Opcodes.GETFIELD,
396 Type.getInternalName(InvokeCustom.class),
397 "instanceField1",
398 "Ljava/lang/String;");
399 mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
400 "java/io/PrintStream",
401 "println",
402 "(Ljava/lang/String;)V", false);
403 mv.visitInsn(Opcodes.RETURN);
404 mv.visitMaxs(-1, -1);
405 }
Mads Agerab4dc702018-09-24 09:43:52 +0200406
407 /**
408 * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a
409 * MethodHandle of kind invoke instance taking an argument and returning a result. This should
410 * work through renaming.
411 */
412 private void generateMethodTest14(ClassVisitor cv) {
413 MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test14", "()V",
414 null, null);
415 MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,
416 MethodType.class, MethodHandle.class);
417 Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class),
418 "bsmCreateCallSite", mt.toMethodDescriptorString(), false);
419 mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class));
420 mv.visitInsn(Opcodes.DUP);
421 mv.visitMethodInsn(
422 Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false);
423 mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(ClassWithLongName.class));
424 mv.visitInsn(Opcodes.DUP);
425 mv.visitMethodInsn(
426 Opcodes.INVOKESPECIAL,
427 Type.getInternalName(ClassWithLongName.class),
428 "<init>",
429 "()V",
430 false);
431 mv.visitInvokeDynamicInsn(
432 "targetMethodTest11",
433 "(Linvokecustom/InvokeCustom;Linvokecustom/ClassWithLongName;)"
434 + "Linvokecustom/AnotherClassWithALongName;",
435 bootstrap,
436 new Handle(
437 Opcodes.H_INVOKEVIRTUAL,
438 Type.getInternalName(InvokeCustom.class),
439 "targetMethodTest11",
440 "(Linvokecustom/ClassWithLongName;)Linvokecustom/AnotherClassWithALongName;",
441 false));
442 mv.visitInsn(Opcodes.RETURN);
443 mv.visitMaxs(-1, -1);
444 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200445}