|  | // Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file | 
|  | // for details. All rights reserved. Use of this source code is governed by a | 
|  | // BSD-style license that can be found in the LICENSE file. | 
|  | package invokecustom; | 
|  |  | 
|  | import java.io.IOException; | 
|  | import java.io.InputStream; | 
|  | import java.io.OutputStream; | 
|  | import java.lang.invoke.CallSite; | 
|  | import java.lang.invoke.MethodHandle; | 
|  | import java.lang.invoke.MethodHandles; | 
|  | import java.lang.invoke.MethodType; | 
|  | import java.nio.file.Files; | 
|  | import java.nio.file.Path; | 
|  | import java.nio.file.Paths; | 
|  | import org.objectweb.asm.ClassReader; | 
|  | import org.objectweb.asm.ClassVisitor; | 
|  | import org.objectweb.asm.ClassWriter; | 
|  | import org.objectweb.asm.Handle; | 
|  | import org.objectweb.asm.MethodVisitor; | 
|  | import org.objectweb.asm.Opcodes; | 
|  | import org.objectweb.asm.Type; | 
|  |  | 
|  | public class TestGenerator { | 
|  |  | 
|  | private final Path classNamePath; | 
|  |  | 
|  | public static void main(String[] args) throws IOException { | 
|  | assert args.length == 1; | 
|  | TestGenerator testGenerator = new TestGenerator(Paths.get(args[0], | 
|  | TestGenerator.class.getPackage().getName(), InvokeCustom.class.getSimpleName() + ".class")); | 
|  | testGenerator.generateTests(); | 
|  | } | 
|  |  | 
|  | public TestGenerator(Path classNamePath) { | 
|  | this.classNamePath = classNamePath; | 
|  | } | 
|  |  | 
|  | private void generateTests() throws IOException { | 
|  | try (InputStream input = Files.newInputStream(classNamePath)) { | 
|  | ClassReader cr = new ClassReader(input); | 
|  | ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); | 
|  | cr.accept( | 
|  | new ClassVisitor(Opcodes.ASM7, cw) { | 
|  | @Override | 
|  | public void visitEnd() { | 
|  | generateMethodTest1(cw); | 
|  | generateMethodTest2(cw); | 
|  | generateMethodTest3(cw); | 
|  | generateMethodTest4(cw); | 
|  | generateMethodTest5(cw); | 
|  | generateMethodTest6(cw); | 
|  | generateMethodTest7(cw); | 
|  | generateMethodTest8(cw); | 
|  | generateMethodTest9(cw); | 
|  | generateMethodTest10(cw); | 
|  | generateMethodTest11(cw); | 
|  | generateMethodTest12(cw); | 
|  | generateMethodTest13(cw); | 
|  | generateMethodTest14(cw); | 
|  | generateMethodMain(cw); | 
|  | super.visitEnd(); | 
|  | } | 
|  | }, 0); | 
|  | try (OutputStream output = Files.newOutputStream(classNamePath)) { | 
|  | output.write(cw.toByteArray()); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /* generate main method that only call all test methods. */ | 
|  | private void generateMethodMain(ClassVisitor cv) { | 
|  | MethodVisitor mv = cv.visitMethod( | 
|  | Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test1", "()V", false); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test2", "()V", false); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test3", "()V", false); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test4", "()V", false); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test5", "()V", false); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test6", "()V", false); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test7", "()V", false); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test8", "()V", false); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test9", "()V", false); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test10", "()V", false); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test11", "()V", false); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test12", "()V", false); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test13", "()V", false); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "test14", "()V", false); | 
|  | mv.visitInsn(Opcodes.RETURN); | 
|  | mv.visitMaxs(-1, -1); | 
|  | } | 
|  |  | 
|  | /** | 
|  | *  Generate test with an invokedynamic, a static bootstrap method without extra args and no arg | 
|  | *  to the target method. | 
|  | */ | 
|  | private void generateMethodTest1(ClassVisitor cv) { | 
|  | MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test1", "()V", | 
|  | null, null); | 
|  | MethodType mt = | 
|  | MethodType.methodType( | 
|  | CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class); | 
|  | Handle bootstrap = new Handle( Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), | 
|  | "bsmLookupStatic", mt.toMethodDescriptorString(), false); | 
|  | mv.visitInvokeDynamicInsn("targetMethodTest1", "()V", bootstrap); | 
|  | mv.visitInsn(Opcodes.RETURN); | 
|  | mv.visitMaxs(-1, -1); | 
|  | } | 
|  |  | 
|  | /** | 
|  | *  Generate test with an invokedynamic, a static bootstrap method without extra args and | 
|  | *  args to the target method. | 
|  | */ | 
|  | private void generateMethodTest2(ClassVisitor cv) { | 
|  | MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test2", "()V", | 
|  | null, null); | 
|  | MethodType mt = MethodType.methodType( | 
|  | CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class); | 
|  | Handle bootstrap = new Handle( Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), | 
|  | "bsmLookupStatic", mt.toMethodDescriptorString(), false); | 
|  | mv.visitLdcInsn(new Boolean(true)); | 
|  | mv.visitLdcInsn(new Byte((byte) 127)); | 
|  | mv.visitLdcInsn(new Character('c')); | 
|  | mv.visitLdcInsn(new Short((short) 1024)); | 
|  | mv.visitLdcInsn(new Integer(123456)); | 
|  | mv.visitLdcInsn(new Float(1.2f)); | 
|  | mv.visitLdcInsn(new Long(123456789)); | 
|  | mv.visitLdcInsn(new Double(3.5123456789)); | 
|  | mv.visitLdcInsn("String"); | 
|  | mv.visitInvokeDynamicInsn("targetMethodTest2", "(ZBCSIFJDLjava/lang/String;)V", bootstrap); | 
|  | mv.visitInsn(Opcodes.RETURN); | 
|  | mv.visitMaxs(-1, -1); | 
|  | } | 
|  |  | 
|  | /** | 
|  | *  Generate test with an invokedynamic, a static bootstrap method with extra args and no arg | 
|  | *  to the target method. | 
|  | */ | 
|  | private void generateMethodTest3(ClassVisitor cv) { | 
|  | MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test3", "()V", | 
|  | null, null); | 
|  | MethodType mt = MethodType.methodType( | 
|  | CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, int.class, | 
|  | long.class, float.class, double.class); | 
|  | Handle bootstrap = new Handle( Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), | 
|  | "bsmLookupStaticWithExtraArgs", mt.toMethodDescriptorString(), false); | 
|  | mv.visitInvokeDynamicInsn("targetMethodTest3", "()V", bootstrap, new Integer(1), | 
|  | new Long(123456789), new Float(123.456), new Double(123456.789123)); | 
|  | mv.visitInsn(Opcodes.RETURN); | 
|  | mv.visitMaxs(-1, -1); | 
|  | } | 
|  |  | 
|  | /** | 
|  | *  Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a | 
|  | *  MethodHandle of kind invokespecial. | 
|  | */ | 
|  | private void generateMethodTest4(ClassVisitor cv) { | 
|  | MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test4", "()V", | 
|  | null, null); | 
|  | MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, | 
|  | MethodType.class, MethodHandle.class); | 
|  | Handle bootstrap = new Handle( Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), | 
|  | "bsmCreateCallSite", mt.toMethodDescriptorString(), false); | 
|  | mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); | 
|  | mv.visitInsn(Opcodes.DUP); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); | 
|  | mv.visitInvokeDynamicInsn("targetMethodTest5", "(Linvokecustom/InvokeCustom;)V", bootstrap, | 
|  | new Handle( Opcodes.H_INVOKESPECIAL, Type.getInternalName(Super.class), | 
|  | "targetMethodTest5", "()V", false)); | 
|  | mv.visitInsn(Opcodes.RETURN); | 
|  | mv.visitMaxs(-1, -1); | 
|  | } | 
|  |  | 
|  | /** | 
|  | *  Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a | 
|  | *  MethodHandle of kind invoke interface. The target method is a default method into an interface | 
|  | *  that shadows another default method from a super interface. | 
|  | */ | 
|  | private void generateMethodTest5(ClassVisitor cv) { | 
|  | MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test5", "()V", | 
|  | null, null); | 
|  | MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, | 
|  | MethodType.class, MethodHandle.class); | 
|  | Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), | 
|  | "bsmCreateCallSite", mt.toMethodDescriptorString(), false); | 
|  | mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); | 
|  | mv.visitInsn(Opcodes.DUP); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); | 
|  | mv.visitInvokeDynamicInsn("targetMethodTest6", "(Linvokecustom/I;)V", bootstrap, | 
|  | new Handle(Opcodes.H_INVOKEINTERFACE, Type.getInternalName(I.class), | 
|  | "targetMethodTest6", "()V", true)); | 
|  | mv.visitInsn(Opcodes.RETURN); | 
|  | mv.visitMaxs(-1, -1); | 
|  | } | 
|  |  | 
|  | /** | 
|  | *  Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a | 
|  | *  MethodHandle of kind invoke interface. The target method is a default method into an interface | 
|  | *  that is at the end of a chain of interfaces. | 
|  | */ | 
|  | private void generateMethodTest6(ClassVisitor cv) { | 
|  | MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test6", "()V", | 
|  | null, null); | 
|  | MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, | 
|  | MethodType.class, MethodHandle.class); | 
|  | Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), | 
|  | "bsmCreateCallSite", mt.toMethodDescriptorString(), false); | 
|  | mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); | 
|  | mv.visitInsn(Opcodes.DUP); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); | 
|  | mv.visitInvokeDynamicInsn("targetMethodTest7", "(Linvokecustom/J;)V", bootstrap, | 
|  | new Handle(Opcodes.H_INVOKEINTERFACE, Type.getInternalName(J.class), | 
|  | "targetMethodTest7", "()V", true)); | 
|  | mv.visitInsn(Opcodes.RETURN); | 
|  | mv.visitMaxs(-1, -1); | 
|  | } | 
|  |  | 
|  | /** | 
|  | *  Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a | 
|  | *  MethodHandle of kind invoke interface. The target method is a method into an interface | 
|  | *  that is shadowed by another definition into a sub interfaces. | 
|  | */ | 
|  | private void generateMethodTest7(ClassVisitor cv) { | 
|  | MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test7", "()V", | 
|  | null, null); | 
|  | MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, | 
|  | MethodType.class, MethodHandle.class); | 
|  | Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), | 
|  | "bsmCreateCallSite", mt.toMethodDescriptorString(), false); | 
|  | mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); | 
|  | mv.visitInsn(Opcodes.DUP); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); | 
|  | mv.visitInvokeDynamicInsn("targetMethodTest8", "(Linvokecustom/J;)V", bootstrap, | 
|  | new Handle(Opcodes.H_INVOKEINTERFACE, Type.getInternalName(J.class), | 
|  | "targetMethodTest8", "()V", true)); | 
|  | mv.visitInsn(Opcodes.RETURN); | 
|  | mv.visitMaxs(-1, -1); | 
|  | } | 
|  |  | 
|  | /** | 
|  | *  Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a | 
|  | *  MethodHandle of kind invoke virtual. The target method is a method into an interface that is | 
|  | *  not shadowed by an implementation into a classes implementing the interface. | 
|  | */ | 
|  | private void generateMethodTest8(ClassVisitor cv) { | 
|  | MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test8", "()V", | 
|  | null, null); | 
|  | MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, | 
|  | MethodType.class, MethodHandle.class); | 
|  | Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), | 
|  | "bsmCreateCallSite", mt.toMethodDescriptorString(), false); | 
|  | mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); | 
|  | mv.visitInsn(Opcodes.DUP); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); | 
|  | mv.visitInvokeDynamicInsn("targetMethodTest9", "(Linvokecustom/InvokeCustom;)V", bootstrap, | 
|  | new Handle(Opcodes.H_INVOKEVIRTUAL, Type.getInternalName(InvokeCustom.class), | 
|  | "targetMethodTest9", "()V", false)); | 
|  | mv.visitInsn(Opcodes.RETURN); | 
|  | mv.visitMaxs(-1, -1); | 
|  | } | 
|  |  | 
|  | /** | 
|  | *  Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a | 
|  | *  MethodHandle of kind invoke virtual. The target method is a method into a class implementing | 
|  | *  an abstract method and that shadows a default method from an interface. | 
|  | */ | 
|  | private void generateMethodTest9(ClassVisitor cv) { | 
|  | MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test9", "()V", | 
|  | null, null); | 
|  | MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, | 
|  | MethodType.class, MethodHandle.class); | 
|  | Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), | 
|  | "bsmCreateCallSite", mt.toMethodDescriptorString(), false); | 
|  | mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); | 
|  | mv.visitInsn(Opcodes.DUP); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); | 
|  | mv.visitInvokeDynamicInsn("targetMethodTest10", "(Linvokecustom/InvokeCustom;)V", bootstrap, | 
|  | new Handle(Opcodes.H_INVOKEVIRTUAL, Type.getInternalName(InvokeCustom.class), | 
|  | "targetMethodTest10", "()V", false)); | 
|  | mv.visitInsn(Opcodes.RETURN); | 
|  | mv.visitMaxs(-1, -1); | 
|  | } | 
|  |  | 
|  | /** | 
|  | *  Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a | 
|  | *  MethodHandle of kind get static. The method handle read a static field from a class. | 
|  | */ | 
|  | private void generateMethodTest10(ClassVisitor cv) { | 
|  | MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test10", "()V", | 
|  | null, null); | 
|  | MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, | 
|  | MethodType.class, MethodHandle.class); | 
|  | Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), | 
|  | "bsmCreateCallSite", mt.toMethodDescriptorString(), false); | 
|  | mv.visitFieldInsn(Opcodes.GETSTATIC, | 
|  | "java/lang/System", | 
|  | "out", | 
|  | "Ljava/io/PrintStream;"); | 
|  | mv.visitInvokeDynamicInsn("staticField1", "()Ljava/lang/String;", bootstrap, | 
|  | new Handle(Opcodes.H_GETSTATIC, Type.getInternalName(InvokeCustom.class), | 
|  | "staticField1", "Ljava/lang/String;", false)); | 
|  | mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, | 
|  | "java/io/PrintStream", | 
|  | "println", | 
|  | "(Ljava/lang/String;)V", false); | 
|  | mv.visitInsn(Opcodes.RETURN); | 
|  | mv.visitMaxs(-1, -1); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a | 
|  | * MethodHandle of kind put static. The method handle write a static field in a class and then | 
|  | * print its value. | 
|  | */ | 
|  | private void generateMethodTest11(ClassVisitor cv) { | 
|  | MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test11", "()V", | 
|  | null, null); | 
|  | MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, | 
|  | MethodType.class, MethodHandle.class); | 
|  | Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), | 
|  | "bsmCreateCallSite", mt.toMethodDescriptorString(), false); | 
|  | mv.visitLdcInsn("Write static field"); | 
|  | mv.visitInvokeDynamicInsn("staticField1", "(Ljava/lang/String;)V", bootstrap, | 
|  | new Handle(Opcodes.H_PUTSTATIC, Type.getInternalName(InvokeCustom.class), | 
|  | "staticField1", "Ljava/lang/String;", false)); | 
|  | mv.visitFieldInsn(Opcodes.GETSTATIC, | 
|  | "java/lang/System", | 
|  | "out", | 
|  | "Ljava/io/PrintStream;"); | 
|  | mv.visitFieldInsn(Opcodes.GETSTATIC, | 
|  | Type.getInternalName(InvokeCustom.class), | 
|  | "staticField1", | 
|  | "Ljava/lang/String;"); | 
|  | mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, | 
|  | "java/io/PrintStream", | 
|  | "println", | 
|  | "(Ljava/lang/String;)V", false); | 
|  | mv.visitInsn(Opcodes.RETURN); | 
|  | mv.visitMaxs(-1, -1); | 
|  | } | 
|  |  | 
|  | /** | 
|  | *  Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a | 
|  | *  MethodHandle of kind get instance. The method handle read an instance field from a class. | 
|  | */ | 
|  | private void generateMethodTest12(ClassVisitor cv) { | 
|  | MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test12", "()V", | 
|  | null, null); | 
|  | MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, | 
|  | MethodType.class, MethodHandle.class); | 
|  | Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), | 
|  | "bsmCreateCallSite", mt.toMethodDescriptorString(), false); | 
|  | mv.visitFieldInsn(Opcodes.GETSTATIC, | 
|  | "java/lang/System", | 
|  | "out", | 
|  | "Ljava/io/PrintStream;"); | 
|  | mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); | 
|  | mv.visitInsn(Opcodes.DUP); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); | 
|  | mv.visitInvokeDynamicInsn("instanceField1", "(Linvokecustom/InvokeCustom;)Ljava/lang/String;", | 
|  | bootstrap, new Handle(Opcodes.H_GETFIELD, Type.getInternalName(InvokeCustom.class), | 
|  | "instanceField1", "Ljava/lang/String;", false)); | 
|  | mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, | 
|  | "java/io/PrintStream", | 
|  | "println", | 
|  | "(Ljava/lang/String;)V", false); | 
|  | mv.visitInsn(Opcodes.RETURN); | 
|  | mv.visitMaxs(-1, -1); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a | 
|  | * MethodHandle of kind put instance. The method handle write an instance field in a class and | 
|  | * then print its value. | 
|  | */ | 
|  | private void generateMethodTest13(ClassVisitor cv) { | 
|  | MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test13", "()V", | 
|  | null, null); | 
|  | MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, | 
|  | MethodType.class, MethodHandle.class); | 
|  | Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), | 
|  | "bsmCreateCallSite", mt.toMethodDescriptorString(), false); | 
|  | mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); | 
|  | mv.visitInsn(Opcodes.DUP); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); | 
|  | mv.visitVarInsn(Opcodes.ASTORE, 0); | 
|  | mv.visitVarInsn(Opcodes.ALOAD, 0); | 
|  | mv.visitLdcInsn("Write instance field"); | 
|  | mv.visitInvokeDynamicInsn("instanceField1", "(Linvokecustom/InvokeCustom;Ljava/lang/String;)V", | 
|  | bootstrap, new Handle(Opcodes.H_PUTFIELD, Type.getInternalName(InvokeCustom.class), | 
|  | "instanceField1", "Ljava/lang/String;", false)); | 
|  | mv.visitFieldInsn(Opcodes.GETSTATIC, | 
|  | "java/lang/System", | 
|  | "out", | 
|  | "Ljava/io/PrintStream;"); | 
|  | mv.visitVarInsn(Opcodes.ALOAD, 0); | 
|  | mv.visitFieldInsn(Opcodes.GETFIELD, | 
|  | Type.getInternalName(InvokeCustom.class), | 
|  | "instanceField1", | 
|  | "Ljava/lang/String;"); | 
|  | mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, | 
|  | "java/io/PrintStream", | 
|  | "println", | 
|  | "(Ljava/lang/String;)V", false); | 
|  | mv.visitInsn(Opcodes.RETURN); | 
|  | mv.visitMaxs(-1, -1); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a | 
|  | * MethodHandle of kind invoke instance taking an argument and returning a result. This should | 
|  | * work through renaming. | 
|  | */ | 
|  | private void generateMethodTest14(ClassVisitor cv) { | 
|  | MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test14", "()V", | 
|  | null, null); | 
|  | MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, | 
|  | MethodType.class, MethodHandle.class); | 
|  | Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), | 
|  | "bsmCreateCallSite", mt.toMethodDescriptorString(), false); | 
|  | mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); | 
|  | mv.visitInsn(Opcodes.DUP); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); | 
|  | mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(ClassWithLongName.class)); | 
|  | mv.visitInsn(Opcodes.DUP); | 
|  | mv.visitMethodInsn( | 
|  | Opcodes.INVOKESPECIAL, | 
|  | Type.getInternalName(ClassWithLongName.class), | 
|  | "<init>", | 
|  | "()V", | 
|  | false); | 
|  | mv.visitInvokeDynamicInsn( | 
|  | "targetMethodTest11", | 
|  | "(Linvokecustom/InvokeCustom;Linvokecustom/ClassWithLongName;)" | 
|  | + "Linvokecustom/AnotherClassWithALongName;", | 
|  | bootstrap, | 
|  | new Handle( | 
|  | Opcodes.H_INVOKEVIRTUAL, | 
|  | Type.getInternalName(InvokeCustom.class), | 
|  | "targetMethodTest11", | 
|  | "(Linvokecustom/ClassWithLongName;)Linvokecustom/AnotherClassWithALongName;", | 
|  | false)); | 
|  | mv.visitInsn(Opcodes.RETURN); | 
|  | mv.visitMaxs(-1, -1); | 
|  | } | 
|  | } |