List of usage examples for org.objectweb.asm MethodVisitor visitVarInsn
public void visitVarInsn(final int opcode, final int var)
From source file:com.google.code.jconts.instrument.gen.ComputationClassGenerator.java
License:Apache License
private void generateConstructor(ClassVisitor cv) { final String name = info.computationClassName; final Type outerType = Type.getObjectType(info.owner); // Constructor have form either <init>(OuterClass this$0, State state) // or <init>(State state) String ctorDesc;/*from w w w . j a v a 2 s . co m*/ if (info.isStatic()) { ctorDesc = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { info.stateType }); } else { cv.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, "this$0", 'L' + info.owner + ';', null, null); ctorDesc = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { outerType, info.stateType }); } // Generate constructor MethodVisitor mv = cv.visitMethod(0, CTOR_NAME, ctorDesc, null, null); mv.visitCode(); Label start = new Label(); Label end = new Label(); mv.visitLabel(start); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, OBJECT_NAME, CTOR_NAME, DEFAULT_CTOR_DESC); // Save state field mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 1 + info.thisOffset); mv.visitFieldInsn(Opcodes.PUTFIELD, name, "state", stateDesc); // Save outer this if (!info.isStatic()) { mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitFieldInsn(Opcodes.PUTFIELD, name, "this$0", outerType.getDescriptor()); } mv.visitInsn(Opcodes.RETURN); mv.visitLabel(end); mv.visitLocalVariable("this", 'L' + name + ';', signature, start, end, 0); if (!info.isStatic()) { mv.visitLocalVariable("this$0", outerType.getDescriptor(), null, start, end, 1); } mv.visitLocalVariable("state", stateDesc, null, start, end, 1 + info.thisOffset); mv.visitMaxs(2, 2 + info.thisOffset); mv.visitEnd(); }
From source file:com.google.code.jconts.instrument.gen.ComputationClassGenerator.java
License:Apache License
private void generateExecute(ClassVisitor cv) { final String name = info.computationClassName; final Type outerType = Type.getObjectType(info.owner); // Generate execute(Continuation<T> cont); MethodVisitor mv = cv.visitMethod(Opcodes.ACC_FINAL | Opcodes.ACC_PUBLIC, COMPUTATION_EXECUTE_NAME, COMPUTATION_EXECUTE_DESC, executeSignature(), null); mv.visitCode();/*from w ww . j av a 2 s . com*/ Label start = new Label(); Label end = new Label(); mv.visitLabel(start); // Load outer this if (!info.isStatic()) { mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, name, "this$0", outerType.getDescriptor()); } // Load state field mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, name, "state", stateDesc); // state.continuation = continuation mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, name, "state", stateDesc); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitFieldInsn(Opcodes.PUTFIELD, info.stateClassName, CONTINUATION_FIELD, CONTINUATION_DESC); // Initial state (0) mv.visitIntInsn(Opcodes.BIPUSH, 0); mv.visitMethodInsn(info.isStatic() ? Opcodes.INVOKESTATIC : Opcodes.INVOKEVIRTUAL, info.owner, info.name + "$async", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { info.stateType, Type.INT_TYPE })); mv.visitInsn(Opcodes.RETURN); mv.visitLabel(end); mv.visitLocalVariable("this", 'L' + name + ';', signature, start, end, 0); if (!info.isStatic()) { mv.visitLocalVariable("this$0", outerType.getDescriptor(), null, start, end, 1); } SignatureWriter sign = new SignatureWriter(); contSignature(sign); mv.visitLocalVariable("continuation", CONTINUATION_DESC, sign.toString(), start, end, 1 + info.thisOffset); mv.visitMaxs(3 + info.thisOffset, 2 + info.thisOffset); mv.visitEnd(); }
From source file:com.google.code.jconts.instrument.gen.ContinuationClassGenerator.java
License:Apache License
private void generateConstructor(ClassVisitor cv) { final String name = info.continuationClassName; final Type outerType = Type.getObjectType(info.owner); // Constructor have form either <init>(OuterClass this$0, State state, // int index) // or <init>(State state, int index) String ctorDesc;/*from w w w . ja v a2 s .c o m*/ if (info.isStatic()) { ctorDesc = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { info.stateType, Type.INT_TYPE }); } else { cv.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, "this$0", 'L' + info.owner + ';', null, null); ctorDesc = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { outerType, info.stateType, Type.INT_TYPE }); } // Generate constructor MethodVisitor mv = cv.visitMethod(0, CTOR_NAME, ctorDesc, null, null); mv.visitCode(); Label start = new Label(); Label end = new Label(); mv.visitLabel(start); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, OBJECT_NAME, CTOR_NAME, DEFAULT_CTOR_DESC); // Save state field mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 1 + info.thisOffset); mv.visitFieldInsn(Opcodes.PUTFIELD, name, "state", stateDesc); // Save index field mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ILOAD, 2 + info.thisOffset); mv.visitFieldInsn(Opcodes.PUTFIELD, name, "index", "I"); // Save outer this if (!info.isStatic()) { mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitFieldInsn(Opcodes.PUTFIELD, name, "this$0", outerType.getDescriptor()); } mv.visitInsn(Opcodes.RETURN); mv.visitLabel(end); mv.visitLocalVariable("this", 'L' + name + ';', signature, start, end, 0); if (!info.isStatic()) { mv.visitLocalVariable("this$0", outerType.getDescriptor(), null, start, end, 1); } mv.visitLocalVariable("state", stateDesc, null, start, end, 1 + info.thisOffset); mv.visitLocalVariable("index", "I", null, start, end, 2 + info.thisOffset); mv.visitMaxs(2, 3 + info.thisOffset); mv.visitEnd(); }
From source file:com.google.code.jconts.instrument.gen.ContinuationClassGenerator.java
License:Apache License
private void generateExecute(ClassVisitor cv, boolean execute) { final String name = info.continuationClassName; final Type outerType = Type.getObjectType(info.owner); // Generate invoke(T result); String signature = null;//from w ww. ja va 2 s. com if (execute) { SignatureWriter sign = new SignatureWriter(); sign.visitParameterType().visitTypeVariable("T"); sign.visitReturnType().visitBaseType('V'); // void signature = sign.toString(); } MethodVisitor mv = cv.visitMethod(Opcodes.ACC_FINAL | Opcodes.ACC_PUBLIC, execute ? CONTINUATION_INVOKE_NAME : CONTINUATION_SET_EXCEPTION_NAME, execute ? CONTINUATION_INVOKE_DESC : CONTINUATION_SET_EXCEPTION_DESC, signature, null); mv.visitCode(); Label start = new Label(); Label end = new Label(); mv.visitLabel(start); // Load outer this if (!info.isStatic()) { mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, name, "this$0", outerType.getDescriptor()); } // state.result = result or state.exception = throwable mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, name, "state", stateDesc); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitFieldInsn(Opcodes.PUTFIELD, info.stateClassName, execute ? "result" : "exception", execute ? OBJECT_DESC : THROWABLE_DESC); // Load state field mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, name, "state", stateDesc); // Continue from this index or index+1 (for exception) mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitFieldInsn(Opcodes.GETFIELD, name, "index", "I"); if (!execute) { mv.visitInsn(Opcodes.ICONST_1); mv.visitInsn(Opcodes.IADD); } mv.visitMethodInsn(info.isStatic() ? Opcodes.INVOKESTATIC : Opcodes.INVOKEVIRTUAL, info.owner, info.name + "$async", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { info.stateType, Type.INT_TYPE })); mv.visitInsn(Opcodes.RETURN); mv.visitLabel(end); mv.visitLocalVariable("this", 'L' + name + ';', signature, start, end, 0); if (!info.isStatic()) { mv.visitLocalVariable("this$0", outerType.getDescriptor(), null, start, end, 1); } mv.visitLocalVariable("result", OBJECT_DESC, "TT;", start, end, 1 + info.thisOffset); mv.visitMaxs(3 + info.thisOffset + (execute ? 0 : 1), 2 + info.thisOffset); mv.visitEnd(); }
From source file:com.google.code.jconts.instrument.gen.StateClassGenerator.java
License:Apache License
public void accept(TransformationContext context) { ClassVisitor cv = context.writer();/*from ww w .ja v a2 s .c o m*/ final String name = info.stateClassName; cv.visit(Opcodes.V1_6, Opcodes.ACC_FINAL /*| Opcodes.ACC_SYNTHETIC*/, name, null, OBJECT_NAME, null); cv.visitSource(info.ownerSource, null); cv.visitOuterClass(info.owner, null, null); cv.visitField(0/*Opcodes.ACC_SYNTHETIC*/, CONTINUATION_FIELD, CONTINUATION_DESC, 'L' + CONTINUATION_NAME + '<' + info.valueSignature + ">;", null); // Local variables state List<String> names = info.tracker.getFieldNames(); List<Type> types = info.tracker.getFieldTypes(); for (int i = 0; i < names.size(); ++i) { cv.visitField(0/*Opcodes.ACC_SYNTHETIC*/, names.get(i), types.get(i).getDescriptor(), null, null); } // Return value variable cv.visitField(0/*Opcodes.ACC_SYNTHETIC*/, "result", OBJECT_DESC, null, null); cv.visitField(0/*Opcodes.ACC_SYNTHETIC*/, "exception", THROWABLE_DESC, null, null); // Generate constructor MethodVisitor mv = cv.visitMethod(0, CTOR_NAME, DEFAULT_CTOR_DESC, null, null); mv.visitCode(); Label start = new Label(); Label end = new Label(); mv.visitLabel(start); mv.visitLineNumber(0, start); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, OBJECT_NAME, CTOR_NAME, DEFAULT_CTOR_DESC); mv.visitInsn(Opcodes.RETURN); mv.visitLabel(end); mv.visitLocalVariable("this", 'L' + name + ';', null, start, end, 0); mv.visitMaxs(1, 1); mv.visitEnd(); cv.visitEnd(); }
From source file:com.google.code.jconts.instrument.gen.TramplineMethodGenerator.java
License:Apache License
public void accept(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(info.access, info.name, info.desc, info.signature, info.exceptions); mv.visitCode();/* w ww .j a va 2 s . co m*/ mv.visitTypeInsn(Opcodes.NEW, info.computationClassName); mv.visitInsn(Opcodes.DUP); // "this' for new Computation(this, state) if (!info.isStatic()) { mv.visitVarInsn(Opcodes.ALOAD, 0); } // new State() mv.visitTypeInsn(Opcodes.NEW, info.stateClassName); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, info.stateClassName, CTOR_NAME, DEFAULT_CTOR_DESC); // state.varX = argX String[] names = info.entryLocalsVars; for (int i = 0; i < info.entryLocals.length; ++i) { mv.visitInsn(Opcodes.DUP); mv.visitVarInsn(info.entryLocals[i].getOpcode(Opcodes.ILOAD), i + info.thisOffset); mv.visitFieldInsn(Opcodes.PUTFIELD, info.stateClassName, names[i], info.entryLocals[i].getDescriptor()); } // new Computation(this, state); String ctorDesc; if (info.isStatic()) { ctorDesc = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { info.stateType }); } else { ctorDesc = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getObjectType(info.owner), info.stateType }); } mv.visitMethodInsn(Opcodes.INVOKESPECIAL, info.computationClassName, CTOR_NAME, ctorDesc); mv.visitInsn(Opcodes.ARETURN); mv.visitMaxs(info.isStatic() ? 5 : 6, info.isStatic() ? info.entryLocals.length : info.entryLocals.length + 1); mv.visitEnd(); }
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); {/*from www . j ava 2 s . c om*/ 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 ww w. j a v a2 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.CoreLibrarySupport.java
License:Open Source License
/** * Emits instructions to load a method's parameters as arguments of a method call assumed to have * compatible descriptor, starting at the given local variable slot. *//* w ww. j av a 2 s . c o m*/ private static void visitLoadArgs(MethodVisitor dispatchMethod, Type neededType, int slot) { for (Type arg : neededType.getArgumentTypes()) { dispatchMethod.visitVarInsn(arg.getOpcode(Opcodes.ILOAD), slot); slot += arg.getSize(); } }
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(//from w ww . j a v a 2s .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(); }