List of usage examples for org.objectweb.asm MethodVisitor visitMethodInsn
public void visitMethodInsn(final int opcode, final String owner, final String name, final String descriptor, final boolean isInterface)
From source file:com.gmail.socraticphoenix.occurence.wrappers.BytecodeEventListenerGeneration.java
License:Open Source License
public static String listener(EventListener eventListener, Class eventClass, Object listener, Method method, ClassVisitor visitor) {/*from w ww . j a va2s . co m*/ Type listenerType = Type.getType(listener.getClass()); Type eventType = Type.getType(eventClass); String internalImplName = listenerType.getInternalName() + "$listener$" + method.getName() + "$" + BytecodeEventListenerGeneration.index++; String simpleName = listener.getClass().getName() + "#" + method.getName() + "(" + Stream.of(method.getParameters()).map(p -> p.getType().getSimpleName()) .reduce((a, b) -> a + ", " + b).orElse("") + ")"; visitor.visit(V1_8, ACC_PUBLIC | ACC_SYNTHETIC | ACC_FINAL, internalImplName, null, BytecodeEventListenerGeneration.objectType.getInternalName(), new String[] { BytecodeEventListenerGeneration.eventWrapperType.getInternalName() }); visitor.visitField(ACC_PRIVATE | ACC_FINAL, "listener", listenerType.getDescriptor(), null, null) .visitEnd(); MethodVisitor constructor = visitor.visitMethod(ACC_PUBLIC, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Object.class)), null, null); constructor.visitParameter("listener", ACC_FINAL); constructor.visitCode(); constructor.visitVarInsn(ALOAD, 0); constructor.visitMethodInsn(INVOKESPECIAL, BytecodeEventListenerGeneration.objectType.getInternalName(), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE), false); constructor.visitVarInsn(ALOAD, 0); constructor.visitVarInsn(ALOAD, 1); constructor.visitTypeInsn(CHECKCAST, listenerType.getInternalName()); constructor.visitFieldInsn(PUTFIELD, internalImplName, "listener", listenerType.getDescriptor()); constructor.visitInsn(RETURN); constructor.visitMaxs(0, 0); constructor.visitEnd(); MethodVisitor name = visitor.visitMethod(ACC_PUBLIC, "name", Type.getMethodDescriptor(Type.getType(String.class)), null, null); name.visitLdcInsn(simpleName); name.visitInsn(ARETURN); name.visitMaxs(0, 0); name.visitEnd(); MethodVisitor priority = visitor.visitMethod(ACC_PUBLIC | ACC_FINAL, "priority", BytecodeEventListenerGeneration.priorityMethod.getDescriptor(), null, null); priority.visitCode(); priority.visitLdcInsn(eventListener.value()); priority.visitInsn(IRETURN); priority.visitMaxs(0, 0); priority.visitEnd(); MethodVisitor getListener = visitor.visitMethod(ACC_PUBLIC | ACC_FINAL, "listener", BytecodeEventListenerGeneration.listenerMethod.getDescriptor(), null, null); getListener.visitVarInsn(ALOAD, 0); getListener.visitFieldInsn(GETFIELD, internalImplName, "listener", listenerType.getDescriptor()); getListener.visitInsn(ARETURN); getListener.visitMaxs(0, 0); getListener.visitEnd(); MethodVisitor event = visitor.visitMethod(ACC_PUBLIC | ACC_FINAL, "mainEvent", BytecodeEventListenerGeneration.mainEventMethod.getDescriptor(), null, null); event.visitCode(); event.visitLdcInsn(eventType); event.visitInsn(ARETURN); event.visitMaxs(0, 0); event.visitEnd(); return internalImplName; }
From source file:com.gmail.socraticphoenix.occurence.wrappers.BytecodeEventListenerGeneration.java
License:Open Source License
public static void get(Get get, Parameter parameter, Class eventClass, int param, int event, MethodVisitor visitor) { try {/*from w w w . j av a 2 s .com*/ String name = EventListenerWrapper.name(get, parameter, eventClass).get(); Type eventType = Type.getType(eventClass); Method rMethod = eventClass.getMethod(name); Type method = Type.getType(rMethod); visitor.visitVarInsn(ALOAD, event); if (eventClass.isInterface()) { visitor.visitMethodInsn(INVOKEINTERFACE, eventType.getInternalName(), name, method.getDescriptor(), true); } else { visitor.visitMethodInsn(INVOKEVIRTUAL, eventType.getInternalName(), name, method.getDescriptor(), false); } if (get.nonnull() && method.getReturnType().getDescriptor().startsWith("L")) { Label continueLabel = new Label(); visitor.visitInsn(DUP); visitor.visitJumpInsn(IFNONNULL, continueLabel); visitor.visitInsn(RETURN); visitor.visitLabel(continueLabel); visitor.visitVarInsn(ASTORE, param); } else { if (!method.getReturnType().getDescriptor().startsWith("L")) { Type boxing = Type.getType(Reflections.boxingType(rMethod.getReturnType())); visitor.visitTypeInsn(NEW, boxing.getInternalName()); visitor.visitInsn(DUP_X1); visitor.visitInsn(SWAP); visitor.visitMethodInsn(INVOKESPECIAL, boxing.getInternalName(), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, method.getReturnType()), false); } visitor.visitVarInsn(ASTORE, param); } } catch (NoSuchMethodException e) { //Meh } }
From source file:com.google.devtools.build.android.desugar.Bug62060793TestDataGenerator.java
License:Open Source License
private static byte[] createClass() { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); MethodVisitor mv; cw.visit(V1_8, ACC_PUBLIC | ACC_SUPER, CLASS_NAME, null, "java/lang/Object", null); cw.visitInnerClass(INTERFACE_TYPE_NAME, CLASS_NAME, "Interface", ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_INTERFACE); cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup", ACC_PUBLIC | ACC_FINAL | ACC_STATIC); {// w ww . ja v a 2s.c o m mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); mv.visitInsn(RETURN); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PRIVATE | ACC_STATIC, "method", "(Ljava/lang/String;)Ljava/lang/String;", null, null); mv.visitParameter("str", 0); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ARETURN); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PRIVATE | ACC_STATIC, "method", "(ZCBFDJISLjava/lang/Object;[Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/String;", null, null); mv.visitParameter("bool", 0); mv.visitParameter("c", 0); mv.visitParameter("b", 0); mv.visitParameter("f", 0); mv.visitParameter("d", 0); mv.visitParameter("l", 0); mv.visitParameter("i", 0); mv.visitParameter("s", 0); mv.visitParameter("o", 0); mv.visitParameter("array", 0); mv.visitParameter("str", 0); mv.visitCode(); mv.visitVarInsn(ALOAD, 10); mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(Ljava/lang/Object;)Ljava/lang/String;", false); mv.visitVarInsn(ASTORE, 13); mv.visitVarInsn(ALOAD, 11); Label l0 = new Label(); mv.visitJumpInsn(IFNONNULL, l0); mv.visitInsn(ICONST_1); Label l1 = new Label(); mv.visitJumpInsn(GOTO, l1); mv.visitLabel(l0); mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { "java/lang/String" }, 0, null); mv.visitInsn(ICONST_0); mv.visitLabel(l1); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { Opcodes.INTEGER }); mv.visitVarInsn(ISTORE, 14); mv.visitIntInsn(BIPUSH, 91); mv.visitVarInsn(ALOAD, 12); mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(Ljava/lang/Object;)Ljava/lang/String;", false); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "length", "()I", false); mv.visitInsn(IADD); mv.visitVarInsn(ALOAD, 13); mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(Ljava/lang/Object;)Ljava/lang/String;", false); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "length", "()I", false); mv.visitInsn(IADD); mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); mv.visitInsn(DUP_X1); mv.visitInsn(SWAP); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(I)V", false); mv.visitVarInsn(ALOAD, 12); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); mv.visitVarInsn(ILOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Z)Ljava/lang/StringBuilder;", false); mv.visitVarInsn(ILOAD, 1); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(C)Ljava/lang/StringBuilder;", false); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;", false); mv.visitVarInsn(FLOAD, 3); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(F)Ljava/lang/StringBuilder;", false); mv.visitVarInsn(DLOAD, 4); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(D)Ljava/lang/StringBuilder;", false); mv.visitVarInsn(LLOAD, 6); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(J)Ljava/lang/StringBuilder;", false); mv.visitVarInsn(ILOAD, 8); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;", false); mv.visitVarInsn(ILOAD, 9); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;", false); mv.visitVarInsn(ALOAD, 13); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); mv.visitVarInsn(ILOAD, 14); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Z)Ljava/lang/StringBuilder;", false); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false); mv.visitInsn(ARETURN); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "lambdaWithConstantArguments", "()L" + INTERFACE_TYPE_NAME + ";", null, null); mv.visitCode(); mv.visitInsn(ICONST_0); mv.visitInsn(ICONST_1); mv.visitInsn(ICONST_2); mv.visitInsn(FCONST_0); mv.visitInsn(DCONST_0); mv.visitInsn(LCONST_0); mv.visitInsn(ICONST_4); mv.visitIntInsn(SIPUSH, 9); mv.visitInsn(ACONST_NULL); mv.visitInsn(ACONST_NULL); mv.visitInvokeDynamicInsn("call", "(ZCBFDJISLjava/lang/Object;[Ljava/lang/Object;)L" + INTERFACE_TYPE_NAME + ";", new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory", "(Ljava/lang/invoke/MethodHandles$Lookup;" + "Ljava/lang/String;Ljava/lang/invoke/MethodType;" + "Ljava/lang/invoke/MethodType;" + "Ljava/lang/invoke/MethodHandle;" + "Ljava/lang/invoke/MethodType;" + ")Ljava/lang/invoke/CallSite;", false), new Object[] { Type.getType("(Ljava/lang/String;)Ljava/lang/String;"), new Handle(Opcodes.H_INVOKESTATIC, CLASS_NAME, "method", "(ZCBFDJISLjava/lang/Object;[Ljava/lang/Object;Ljava/lang/String;" + ")Ljava/lang/String;", false), Type.getType("(Ljava/lang/String;)Ljava/lang/String;") }); mv.visitInsn(ARETURN); mv.visitEnd(); } cw.visitEnd(); return cw.toByteArray(); }
From source file:com.google.devtools.build.android.desugar.CoreLibrarySupport.java
License:Open Source License
private void makeDispatchHelperMethod(ClassVisitor helper, EmulatedMethod method, ImmutableList<Class<?>> typechecks) { checkArgument(method.owner().isInterface()); String owner = method.owner().getName().replace('.', '/'); Type methodType = Type.getMethodType(method.descriptor()); String companionDesc = InterfaceDesugaring.companionDefaultMethodDescriptor(owner, method.descriptor()); MethodVisitor dispatchMethod = helper.visitMethod(method.access() | Opcodes.ACC_STATIC, method.name(), companionDesc, /*signature=*/ null, // signature is invalid due to extra "receiver" argument method.exceptions().toArray(EMPTY_LIST)); dispatchMethod.visitCode();/*from w w w .j ava2 s .c o m*/ { // See if the receiver might come with its own implementation of the method, and call it. // We do this by testing for the interface type created by EmulatedInterfaceRewriter Label fallthrough = new Label(); String emulationInterface = renameCoreLibrary(owner); dispatchMethod.visitVarInsn(Opcodes.ALOAD, 0); // load "receiver" dispatchMethod.visitTypeInsn(Opcodes.INSTANCEOF, emulationInterface); dispatchMethod.visitJumpInsn(Opcodes.IFEQ, fallthrough); dispatchMethod.visitVarInsn(Opcodes.ALOAD, 0); // load "receiver" dispatchMethod.visitTypeInsn(Opcodes.CHECKCAST, emulationInterface); visitLoadArgs(dispatchMethod, methodType, 1 /* receiver already loaded above */); dispatchMethod.visitMethodInsn(Opcodes.INVOKEINTERFACE, emulationInterface, method.name(), method.descriptor(), /*itf=*/ true); dispatchMethod.visitInsn(methodType.getReturnType().getOpcode(Opcodes.IRETURN)); dispatchMethod.visitLabel(fallthrough); // Trivial frame for the branch target: same empty stack as before dispatchMethod.visitFrame(Opcodes.F_SAME, 0, EMPTY_FRAME, 0, EMPTY_FRAME); } // Next, check for subtypes with specialized implementations and call them for (Class<?> tested : typechecks) { Label fallthrough = new Label(); String testedName = tested.getName().replace('.', '/'); // In case of a class this must be a member move; for interfaces use the companion. String target = tested.isInterface() ? InterfaceDesugaring.getCompanionClassName(testedName) : checkNotNull(memberMoves.get(rewriter.unprefix(testedName) + '#' + method.name())); dispatchMethod.visitVarInsn(Opcodes.ALOAD, 0); // load "receiver" dispatchMethod.visitTypeInsn(Opcodes.INSTANCEOF, testedName); dispatchMethod.visitJumpInsn(Opcodes.IFEQ, fallthrough); dispatchMethod.visitVarInsn(Opcodes.ALOAD, 0); // load "receiver" dispatchMethod.visitTypeInsn(Opcodes.CHECKCAST, testedName); // make verifier happy visitLoadArgs(dispatchMethod, methodType, 1 /* receiver already loaded above */); dispatchMethod.visitMethodInsn(Opcodes.INVOKESTATIC, target, method.name(), InterfaceDesugaring.companionDefaultMethodDescriptor(testedName, method.descriptor()), /*itf=*/ false); dispatchMethod.visitInsn(methodType.getReturnType().getOpcode(Opcodes.IRETURN)); dispatchMethod.visitLabel(fallthrough); // Trivial frame for the branch target: same empty stack as before dispatchMethod.visitFrame(Opcodes.F_SAME, 0, EMPTY_FRAME, 0, EMPTY_FRAME); } // Call static type's default implementation in companion class dispatchMethod.visitVarInsn(Opcodes.ALOAD, 0); // load "receiver" visitLoadArgs(dispatchMethod, methodType, 1 /* receiver already loaded above */); dispatchMethod.visitMethodInsn(Opcodes.INVOKESTATIC, InterfaceDesugaring.getCompanionClassName(owner), method.name(), companionDesc, /*itf=*/ false); dispatchMethod.visitInsn(methodType.getReturnType().getOpcode(Opcodes.IRETURN)); dispatchMethod.visitMaxs(0, 0); dispatchMethod.visitEnd(); }
From source file:com.google.devtools.build.android.desugar.CorePackageRenamerTest.java
License:Open Source License
@Test public void testSymbolRewrite() throws Exception { MockClassVisitor out = new MockClassVisitor(); CorePackageRenamer renamer = new CorePackageRenamer(out, new CoreLibrarySupport(new CoreLibraryRewriter(""), null, ImmutableList.of("java/time/"), ImmutableList.of(), ImmutableList.of("java/util/A#m->java/time/B"), ImmutableList.of())); MethodVisitor mv = renamer.visitMethod(0, "test", "()V", null, null); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/time/Instant", "now", "()Ljava/time/Instant;", false); assertThat(out.mv.owner).isEqualTo("j$/time/Instant"); assertThat(out.mv.desc).isEqualTo("()Lj$/time/Instant;"); // Ignore moved methods but not their descriptors mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/util/A", "m", "()Ljava/time/Instant;", false); assertThat(out.mv.owner).isEqualTo("java/util/A"); assertThat(out.mv.desc).isEqualTo("()Lj$/time/Instant;"); // Ignore arbitrary other methods but not their descriptors mv.visitMethodInsn(Opcodes.INVOKESTATIC, "other/time/Instant", "now", "()Ljava/time/Instant;", false); assertThat(out.mv.owner).isEqualTo("other/time/Instant"); assertThat(out.mv.desc).isEqualTo("()Lj$/time/Instant;"); mv.visitFieldInsn(Opcodes.GETFIELD, "other/time/Instant", "now", "Ljava/time/Instant;"); assertThat(out.mv.owner).isEqualTo("other/time/Instant"); assertThat(out.mv.desc).isEqualTo("Lj$/time/Instant;"); }
From source file:com.google.devtools.build.android.desugar.LambdaClassFixer.java
License:Open Source License
@Override public void visitEnd() { checkState(!hasState || hasFactory, "Expected factory method for capturing lambda %s", getInternalName()); if (!hasState) { checkState(signature == null, "Didn't expect generic constructor signature %s %s", getInternalName(), signature);//from w w w. j a v a2 s . c om checkState(lambdaInfo.factoryMethodDesc().startsWith("()"), "Expected 0-arg factory method for %s but found %s", getInternalName(), lambdaInfo.factoryMethodDesc()); // Since this is a stateless class we populate and use a static singleton field "$instance". // Field is package-private so we can read it from the class that had the invokedynamic. String singletonFieldDesc = lambdaInfo.factoryMethodDesc().substring("()".length()); super.visitField(Opcodes.ACC_STATIC | Opcodes.ACC_FINAL, SINGLETON_FIELD_NAME, singletonFieldDesc, (String) null, (Object) null).visitEnd(); MethodVisitor codeBuilder = super.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", (String) null, new String[0]); codeBuilder.visitTypeInsn(Opcodes.NEW, getInternalName()); codeBuilder.visitInsn(Opcodes.DUP); codeBuilder.visitMethodInsn(Opcodes.INVOKESPECIAL, getInternalName(), "<init>", checkNotNull(desc, "didn't see a constructor for %s", getInternalName()), /*itf*/ false); codeBuilder.visitFieldInsn(Opcodes.PUTSTATIC, getInternalName(), SINGLETON_FIELD_NAME, singletonFieldDesc); codeBuilder.visitInsn(Opcodes.RETURN); codeBuilder.visitMaxs(2, 0); // two values are pushed onto the stack codeBuilder.visitEnd(); } copyRewrittenLambdaMethods(); if (!allowDefaultMethods) { copyBridgeMethods(interfaces); } super.visitEnd(); }
From source file:com.google.devtools.build.android.desugar.LambdaDesugaring.java
License:Open Source License
@Override public void visitEnd() { for (Map.Entry<Handle, MethodReferenceBridgeInfo> bridge : bridgeMethods.entrySet()) { Handle original = bridge.getKey(); Handle neededMethod = bridge.getValue().bridgeMethod(); checkState(/* w w w . j a va 2 s .c o m*/ neededMethod.getTag() == Opcodes.H_INVOKESTATIC || neededMethod.getTag() == Opcodes.H_INVOKEVIRTUAL, "Cannot generate bridge method %s to reach %s", neededMethod, original); checkState(bridge.getValue().referenced() != null, "Need referenced method %s to generate bridge %s", original, neededMethod); int access = Opcodes.ACC_BRIDGE | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_FINAL; if (neededMethod.getTag() == Opcodes.H_INVOKESTATIC) { access |= Opcodes.ACC_STATIC; } MethodVisitor bridgeMethod = super.visitMethod(access, neededMethod.getName(), neededMethod.getDesc(), (String) null, toInternalNames(bridge.getValue().referenced().getExceptionTypes())); // Bridge is a factory method calling a constructor if (original.getTag() == Opcodes.H_NEWINVOKESPECIAL) { bridgeMethod.visitTypeInsn(Opcodes.NEW, original.getOwner()); bridgeMethod.visitInsn(Opcodes.DUP); } int slot = 0; if (neededMethod.getTag() != Opcodes.H_INVOKESTATIC) { bridgeMethod.visitVarInsn(Opcodes.ALOAD, slot++); } Type neededType = Type.getMethodType(neededMethod.getDesc()); for (Type arg : neededType.getArgumentTypes()) { bridgeMethod.visitVarInsn(arg.getOpcode(Opcodes.ILOAD), slot); slot += arg.getSize(); } bridgeMethod.visitMethodInsn(invokeOpcode(original), original.getOwner(), original.getName(), original.getDesc(), original.isInterface()); bridgeMethod.visitInsn(neededType.getReturnType().getOpcode(Opcodes.IRETURN)); bridgeMethod.visitMaxs(0, 0); // rely on class writer to compute these bridgeMethod.visitEnd(); } super.visitEnd(); }
From source file:com.google.devtools.build.android.resources.RClassGenerator.java
License:Open Source License
private static void writeConstructor(ClassWriter classWriter) { MethodVisitor constructor = classWriter.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, /* signature */ null /* exceptions */); constructor.visitCode();/* w w w .j a va 2 s . co m*/ constructor.visitVarInsn(Opcodes.ALOAD, 0); constructor.visitMethodInsn(Opcodes.INVOKESPECIAL, SUPER_CLASS, "<init>", "()V", false); constructor.visitInsn(Opcodes.RETURN); constructor.visitMaxs(1, 1); constructor.visitEnd(); }
From source file:com.google.devtools.build.android.resources.RClassWriter.java
License:Open Source License
private static void writeConstructor(ClassWriter classWriter) { MethodVisitor constructor = classWriter.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); constructor.visitCode();/*from w w w . jav a2s . co m*/ constructor.visitVarInsn(Opcodes.ALOAD, 0); constructor.visitMethodInsn(Opcodes.INVOKESPECIAL, SUPER_CLASS, "<init>", "()V", false); constructor.visitInsn(Opcodes.RETURN); constructor.visitMaxs(1, 1); constructor.visitEnd(); }
From source file:com.google.gwt.dev.shell.rewrite.RewriteSingleJsoImplDispatches.java
License:Apache License
/** * For regular Java objects that implement a SingleJsoImpl interface, write * instance trampoline dispatchers for mangled method names to the * implementing method.//from w w w.ja v a 2s . co m */ private void writeTrampoline(String stubIntr) { /* * This is almost the same kind of trampoline as the ones generated in * WriteJsoImpl, however there are enough small differences between the * semantics of the dispatches that would make a common implementation far * more awkward than the duplication of code. */ for (String mangledName : toImplement(stubIntr)) { for (Method method : jsoData.getDeclarations(mangledName)) { Method toCall = new Method(method.getName(), method.getDescriptor()); // Must not be final MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, mangledName, method.getDescriptor(), null, null); if (mv != null) { mv.visitCode(); /* * It just so happens that the stack and local variable sizes are the * same, but they're kept distinct to aid in clarity should the * dispatch logic change. * * These start at 1 because we need to load "this" onto the stack */ int var = 1; int size = 1; // load this mv.visitVarInsn(Opcodes.ALOAD, 0); // then the rest of the arguments for (Type t : toCall.getArgumentTypes()) { size += t.getSize(); mv.visitVarInsn(t.getOpcode(Opcodes.ILOAD), var); var += t.getSize(); } // Make sure there's enough room for the return value size = Math.max(size, toCall.getReturnType().getSize()); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, currentTypeName, toCall.getName(), toCall.getDescriptor(), false); mv.visitInsn(toCall.getReturnType().getOpcode(Opcodes.IRETURN)); mv.visitMaxs(size, var); mv.visitEnd(); } } } }