Search in sources :

Example 16 with LocalVariableNode

use of org.objectweb.asm.tree.LocalVariableNode in project cassandra by apache.

the class MonitorMethodTransformer method loadParamsAndReturnInvokeCode.

// TODO (cleanup): this _should_ be possible to determine purely from the method signature
int loadParamsAndReturnInvokeCode() {
    if (isInstanceMethod)
        instructions.add(new IntInsnNode(Opcodes.ALOAD, 0));
    ListIterator<LocalVariableNode> it = localVariables.listIterator();
    while (it.hasNext()) {
        LocalVariableNode cur = it.next();
        if (cur.index < maxLocalParams) {
            if (!isInstanceMethod || cur.index > 0) {
                int opcode;
                switch(cur.desc.charAt(0)) {
                    case 'L':
                    case '[':
                        opcode = Opcodes.ALOAD;
                        break;
                    case 'J':
                        opcode = Opcodes.LLOAD;
                        break;
                    case 'D':
                        opcode = Opcodes.DLOAD;
                        break;
                    case 'F':
                        opcode = Opcodes.FLOAD;
                        break;
                    default:
                        opcode = Opcodes.ILOAD;
                        break;
                }
                instructions.add(new IntInsnNode(opcode, cur.index));
            }
        }
    }
    int invokeCode;
    if (isInstanceMethod && (access & Opcodes.ACC_PRIVATE) != 0)
        invokeCode = Opcodes.INVOKESPECIAL;
    else if (isInstanceMethod)
        invokeCode = Opcodes.INVOKEVIRTUAL;
    else
        invokeCode = Opcodes.INVOKESTATIC;
    return invokeCode;
}
Also used : IntInsnNode(org.objectweb.asm.tree.IntInsnNode) LocalVariableNode(org.objectweb.asm.tree.LocalVariableNode)

Example 17 with LocalVariableNode

use of org.objectweb.asm.tree.LocalVariableNode in project dex2jar by pxb1988.

the class InvocationWeaver method wrapper.

public ClassVisitor wrapper(final ClassVisitor cv) {
    return new RemappingClassAdapter(cv, remapper) {

        Map<MtdInfo, MtdInfo> toCreate = new HashMap<MtdInfo, MtdInfo>();

        String clzName;

        private MtdInfo newMethodA(int opcode, MtdInfo t, MtdInfo mapTo) {
            MtdInfo n = toCreate.get(t);
            if (n != null) {
                return n;
            }
            n = new MtdInfo();
            n.owner = t.owner;
            n.name = buildMethodAName(t.name);
            boolean hasThis = opcode != INVOKESTATIC;
            if (hasThis) {
                Type[] args = Type.getArgumentTypes(t.desc);
                Type ret = Type.getReturnType(t.desc);
                List<Type> ts = new ArrayList<>(args.length + 1);
                ts.add(Type.getType(t.owner));
                ts.addAll(Arrays.asList(args));
                n.desc = Type.getMethodDescriptor(ret, ts.toArray(new Type[ts.size()]));
            } else {
                n.desc = t.desc;
            }
            toCreate.put(t, n);
            MethodVisitor mv = cv.visitMethod(ACC_SYNTHETIC | ACC_PRIVATE | ACC_STATIC, n.name, n.desc, null, null);
            mv.visitCode();
            genMethodACode(opcode, t, mapTo, mv, t);
            return n;
        }

        private void genMethodACode(int opcode, MtdInfo t, MtdInfo mapTo, MethodVisitor mv, MtdInfo src) {
            boolean hasThis = opcode != INVOKESTATIC;
            Type[] args = Type.getArgumentTypes(t.desc);
            Type ret = Type.getReturnType(t.desc);
            final int start;
            mv.visitTypeInsn(NEW, getCurrentInvocationName());
            mv.visitInsn(DUP);
            if (hasThis) {
                mv.visitVarInsn(ALOAD, 0);
                start = 1;
            } else {
                mv.visitInsn(ACONST_NULL);
                start = 0;
            }
            if (args.length == 0) {
                mv.visitInsn(ACONST_NULL);
            } else {
                mv.visitLdcInsn(args.length);
                mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
                for (int i = 0; i < args.length; i++) {
                    mv.visitInsn(DUP);
                    mv.visitLdcInsn(i);
                    mv.visitVarInsn(args[i].getOpcode(ILOAD), i + start);
                    box(args[i], mv);
                    mv.visitInsn(AASTORE);
                }
            }
            int nextIdx = callbacks.size();
            mv.visitLdcInsn(nextIdx);
            mv.visitMethodInsn(INVOKESPECIAL, getCurrentInvocationName(), "<init>", "(Ljava/lang/Object;[Ljava/lang/Object;I)V");
            mv.visitMethodInsn(INVOKESTATIC, toInternal(mapTo.owner), mapTo.name, mapTo.desc);
            unBox(ret, Type.getReturnType(mapTo.desc), mv);
            mv.visitInsn(ret.getOpcode(IRETURN));
            mv.visitMaxs(-1, -1);
            mv.visitEnd();
            Callback cb = new Callback();
            cb.idx = nextIdx;
            cb.callback = newMethodCallback(opcode, t);
            cb.target = src;
            cb.isSpecial = opcode == INVOKESPECIAL;
            cb.isStatic = opcode == INVOKESTATIC;
            callbacks.add(cb);
        }

        private MtdInfo newMethodCallback(int opcode, MtdInfo t) {
            MtdInfo n = new MtdInfo();
            n.owner = "L" + className + ";";
            n.name = buildCallbackMethodName(t.name);
            if (opcode == INVOKESPECIAL || opcode == INVOKESTATIC) {
                n.desc = "([Ljava/lang/Object;)Ljava/lang/Object;";
            } else {
                n.desc = "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;";
            }
            MethodVisitor mv = cv.visitMethod(opcode == INVOKESPECIAL ? ACC_PUBLIC : ACC_PUBLIC | ACC_STATIC, n.name, n.desc, null, null);
            mv.visitCode();
            int start;
            if (opcode != INVOKESTATIC) {
                mv.visitVarInsn(ALOAD, 0);
                if (opcode != INVOKESPECIAL) {
                    mv.visitTypeInsn(CHECKCAST, toInternal(t.owner));
                }
                start = 1;
            } else {
                start = 0;
            }
            Type[] args = Type.getArgumentTypes(t.desc);
            for (int i = 0; i < args.length; i++) {
                mv.visitVarInsn(ALOAD, start);
                mv.visitLdcInsn(i);
                mv.visitInsn(AALOAD);
                unBox(args[i], OBJECT_TYPE, mv);
            }
            mv.visitMethodInsn(opcode, toInternal(t.owner), t.name, t.desc);
            Type ret = Type.getReturnType(t.desc);
            box(ret, mv);
            mv.visitInsn(ARETURN);
            mv.visitMaxs(-1, -1);
            mv.visitEnd();
            return n;
        }

        @Override
        public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
            super.visit(version, access, name, signature, superName, interfaces);
            clzName = name;
        }

        public MethodVisitor visitMethod(int access, final String name, String desc, String signature, String[] exceptions) {
            final MethodVisitor superMv = superMethodVisitor(access, name, desc, signature, exceptions);
            final MtdInfo mapTo = findDefinedTargetMethod("L" + clzName + ";", name, desc);
            if (mapTo != null) {
                final MtdInfo t1 = new MtdInfo();
                t1.owner = "L" + clzName + ";";
                t1.name = buildMethodAName(name);
                t1.desc = desc;
                final MtdInfo t = t1;
                final MtdInfo src = new MtdInfo();
                src.owner = t.owner;
                src.name = name;
                src.desc = desc;
                return new MethodNode(Opcodes.ASM4, access, name, desc, signature, exceptions) {

                    @Override
                    public void visitEnd() {
                        InsnList instructions = this.instructions;
                        List<TryCatchBlockNode> tryCatchBlocks = this.tryCatchBlocks;
                        List<LocalVariableNode> localVariables = this.localVariables;
                        this.instructions = new InsnList();
                        this.tryCatchBlocks = new ArrayList<>();
                        this.localVariables = new ArrayList<>();
                        this.maxLocals = -1;
                        this.maxStack = -1;
                        accept(superMv);
                        int opcode;
                        if (Modifier.isStatic(access)) {
                            opcode = Opcodes.INVOKESTATIC;
                        } else {
                            opcode = Opcodes.INVOKEVIRTUAL;
                        }
                        genMethodACode(opcode, t, mapTo, superMv, src);
                        // make sure public
                        int newAccess = (access & ~(ACC_PRIVATE | ACC_PROTECTED)) | ACC_PUBLIC;
                        MethodVisitor rmv = wrap(superMethodVisitor(newAccess, t.name, desc, null, null));
                        if (rmv != null) {
                            rmv.visitCode();
                            int n, i;
                            n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size();
                            for (i = 0; i < n; ++i) {
                                tryCatchBlocks.get(i).accept(rmv);
                            }
                            instructions.accept(rmv);
                            n = localVariables == null ? 0 : localVariables.size();
                            for (i = 0; i < n; ++i) {
                                localVariables.get(i).accept(rmv);
                            }
                            rmv.visitMaxs(-1, -1);
                            rmv.visitEnd();
                        }
                    }
                };
            } else {
                return wrap(superMv);
            }
        }

        private MethodVisitor superMethodVisitor(int access, String name, String desc, String signature, String[] exceptions) {
            return super.visitMethod(access, name, desc, signature, exceptions);
        }

        MethodVisitor wrap(MethodVisitor mv) {
            return mv == null ? null : new ReplaceMethodVisitor(mv);
        }

        class ReplaceMethodVisitor extends MethodVisitor {

            public ReplaceMethodVisitor(MethodVisitor mv) {
                super(Opcodes.ASM4, mv);
            }

            @Override
            public void visitMethodInsn(int opcode, String owner, String name, String desc) {
                MtdInfo mapTo = findTargetMethod("L" + owner + ";", name, desc);
                if (mapTo != null) {
                    boolean isStatic = opcode == INVOKESTATIC;
                    Type orgRet = Type.getReturnType(desc);
                    Type[] orgArgs = Type.getArgumentTypes(desc);
                    Type nRet = Type.getReturnType(mapTo.desc);
                    Type[] nArgs = Type.getArgumentTypes(mapTo.desc);
                    if (orgRet.getSort() != Type.VOID && nRet.getSort() == Type.VOID) {
                        throw new RuntimeException("can't cast " + nRet + " to " + orgRet);
                    }
                    if (nArgs.length == 1 && nArgs[0].getDescriptor().equals(invocationInterfaceDesc)) {
                        MtdInfo t = new MtdInfo();
                        t.owner = "L" + owner + ";";
                        t.name = name;
                        t.desc = desc;
                        MtdInfo n = newMethodA(opcode, t, mapTo);
                        super.visitMethodInsn(INVOKESTATIC, clzName, n.name, n.desc);
                    } else {
                        // checking for invalid replace
                        if (isStatic) {
                            if (!Arrays.deepEquals(orgArgs, nArgs)) {
                                throw new RuntimeException("arguments not equal: " + owner + "." + name + desc + " <> " + mapTo.owner + "." + mapTo.name + mapTo.desc);
                            }
                        } else {
                            if (nArgs.length != orgArgs.length + 1) {
                                throw new RuntimeException("arguments not equal: " + owner + "." + name + desc + " <> " + mapTo.owner + "." + mapTo.name + mapTo.desc);
                            }
                            if (orgArgs.length > 0) {
                                for (int i = 0; i < orgArgs.length; i++) {
                                    if (!orgArgs[i].equals(nArgs[i + 1])) {
                                        throw new RuntimeException("arguments not equal: " + owner + "." + name + desc + " <> " + mapTo.owner + "." + mapTo.name + mapTo.desc);
                                    }
                                }
                            }
                        }
                        // replace it!
                        super.visitMethodInsn(INVOKESTATIC, toInternal(mapTo.owner), mapTo.name, mapTo.desc);
                        unBox(orgRet, nRet, this.mv);
                    }
                } else {
                    super.visitMethodInsn(opcode, owner, name, desc);
                }
            }
        }
    };
}
Also used : TryCatchBlockNode(org.objectweb.asm.tree.TryCatchBlockNode) InsnList(org.objectweb.asm.tree.InsnList) LocalVariableNode(org.objectweb.asm.tree.LocalVariableNode) MethodNode(org.objectweb.asm.tree.MethodNode) RemappingClassAdapter(org.objectweb.asm.commons.RemappingClassAdapter)

Example 18 with LocalVariableNode

use of org.objectweb.asm.tree.LocalVariableNode in project spring-loaded by spring-projects.

the class SpringLoadedTests method checkLocalVariables.

@SuppressWarnings("unchecked")
protected void checkLocalVariables(byte[] bytes, String methodNameAndDescriptor, String... expected) {
    ClassNode cn = new ClassNode();
    ClassReader cr = new ClassReader(bytes);
    cr.accept(cn, 0);
    boolean checked = false;
    List<MethodNode> methods = cn.methods;
    for (MethodNode mn : methods) {
        if (methodNameAndDescriptor.equals(mn.name + mn.desc)) {
            List<LocalVariableNode> localVariables = mn.localVariables;
            Assert.assertEquals(expected.length, localVariables.size());
            for (int i = 0; i < expected.length; i++) {
                StringTokenizer tokenizer = new StringTokenizer(expected[i], ":");
                String expectedName = tokenizer.nextToken();
                String expectedDesc = tokenizer.nextToken();
                LocalVariableNode localVariable = localVariables.get(i);
                Assert.assertEquals(i, localVariable.index);
                Assert.assertEquals(expectedName, localVariable.name);
                Assert.assertEquals(expectedDesc, localVariable.desc);
            }
            checked = true;
        }
    }
    if (!checked) {
        for (MethodNode mn : methods) {
            System.out.println(mn.name + mn.desc);
        }
        Assert.fail("Unable to find method " + methodNameAndDescriptor);
    }
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) StringTokenizer(java.util.StringTokenizer) MethodNode(org.objectweb.asm.tree.MethodNode) ClassReader(org.objectweb.asm.ClassReader) LocalVariableNode(org.objectweb.asm.tree.LocalVariableNode)

Example 19 with LocalVariableNode

use of org.objectweb.asm.tree.LocalVariableNode in project enumerable by hraberg.

the class LambdaExpressionTrees method parseExpressionFromMethod.

public static Expression parseExpressionFromMethod(Method method, String... parameters) {
    try {
        MethodNode mn = findMethodNode(method);
        LocalVariableNode[] parameterLocals = new LocalVariableNode[parameters.length];
        Type[] argumentTypes = getArgumentTypes(mn.desc);
        int realIndex = 1;
        for (int i = 0; i < parameters.length; i++) {
            parameterLocals[i] = new LocalVariableNode(parameters[i], argumentTypes[i].getDescriptor(), null, null, null, realIndex);
            realIndex += argumentTypes[i].getSize();
        }
        final ExpressionInterpreter interpreter = new ExpressionInterpreter(mn, parameterLocals);
        Analyzer analyzer = new Analyzer(interpreter) {

            protected Frame newFrame(Frame src) {
                Frame frame = super.newFrame(src);
                interpreter.setCurrentFrame(frame);
                return frame;
            }

            protected void newControlFlowEdge(int insn, int successor) {
                interpreter.newControlFlowEdge(insn, successor);
            }
        };
        interpreter.analyzer = analyzer;
        analyzer.analyze(getInternalName(method.getDeclaringClass()), mn);
        return interpreter.expression;
    } catch (Exception e) {
        throw uncheck(e);
    }
}
Also used : Type(org.objectweb.asm.Type) Frame(org.objectweb.asm.tree.analysis.Frame) MethodNode(org.objectweb.asm.tree.MethodNode) Analyzer(org.objectweb.asm.tree.analysis.Analyzer) LocalVariableNode(org.objectweb.asm.tree.LocalVariableNode) IOException(java.io.IOException) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 20 with LocalVariableNode

use of org.objectweb.asm.tree.LocalVariableNode in project felix by apache.

the class InnerClassAdapter method generateMethodWrapper.

/**
 * Generate the method header of a POJO method.
 * This method header encapsulate the POJO method call to
 * signal entry exit and error to the container.
 *
 * The instance manager and flag are accessed using method calls.
 * @param access : access flag.
 * @param name : method name.
 * @param desc : method descriptor.
 * @param signature : method signature.
 * @param exceptions : declared exceptions.
 * @param localVariables : the local variable nodes.
 * @param annotations : the annotations to move to this method.
 * @param paramAnnotations : the parameter annotations to move to this method.
 */
private void generateMethodWrapper(int access, String name, String desc, String signature, String[] exceptions, List<LocalVariableNode> localVariables, List<ClassChecker.AnnotationDescriptor> annotations, Map<Integer, List<ClassChecker.AnnotationDescriptor>> paramAnnotations) {
    GeneratorAdapter mv = new GeneratorAdapter(cv.visitMethod(access, name, desc, signature, exceptions), access, name, desc);
    // If we have variables, we wraps the code within labels. The `lifetime` of the variables are bound to those
    // two variables.
    boolean hasArgumentLabels = localVariables != null && !localVariables.isEmpty();
    Label start = null;
    if (hasArgumentLabels) {
        start = new Label();
        mv.visitLabel(start);
    }
    mv.visitCode();
    Type returnType = Type.getReturnType(desc);
    // Compute result and exception stack location
    int result = -1;
    int exception;
    if (returnType.getSort() != Type.VOID) {
        // The method returns something
        result = mv.newLocal(returnType);
        exception = mv.newLocal(Type.getType(Throwable.class));
    } else {
        exception = mv.newLocal(Type.getType(Throwable.class));
    }
    Label l0 = new Label();
    Label l1 = new Label();
    Label l2 = new Label();
    mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Throwable");
    // Access the flag from the outer class
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, m_name, "this$0", "L" + m_outer + ";");
    mv.visitFieldInsn(GETFIELD, m_outer, getMethodFlagName(name, desc), "Z");
    mv.visitJumpInsn(IFNE, l0);
    mv.visitVarInsn(ALOAD, 0);
    mv.loadArgs();
    mv.visitMethodInsn(INVOKESPECIAL, m_name, ClassManipulator.PREFIX + name, desc, false);
    mv.visitInsn(returnType.getOpcode(IRETURN));
    // end of the non intercepted method invocation.
    mv.visitLabel(l0);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, m_name, "this$0", "L" + m_outer + ";");
    mv.visitFieldInsn(GETFIELD, m_outer, ClassManipulator.IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");
    mv.visitVarInsn(ALOAD, 0);
    mv.visitLdcInsn(getMethodId(name, desc));
    mv.loadArgArray();
    mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", ClassManipulator.ENTRY, "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V", false);
    mv.visitVarInsn(ALOAD, 0);
    // Do not allow argument modification : just reload arguments.
    mv.loadArgs();
    mv.visitMethodInsn(INVOKESPECIAL, m_name, ClassManipulator.PREFIX + name, desc, false);
    if (returnType.getSort() != Type.VOID) {
        mv.visitVarInsn(returnType.getOpcode(ISTORE), result);
    }
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, m_name, "this$0", "L" + m_outer + ";");
    mv.visitFieldInsn(GETFIELD, m_outer, ClassManipulator.IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");
    mv.visitVarInsn(ALOAD, 0);
    mv.visitLdcInsn(getMethodId(name, desc));
    if (returnType.getSort() != Type.VOID) {
        mv.visitVarInsn(returnType.getOpcode(ILOAD), result);
        mv.box(returnType);
    } else {
        mv.visitInsn(ACONST_NULL);
    }
    mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", ClassManipulator.EXIT, "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)V", false);
    mv.visitLabel(l1);
    Label l7 = new Label();
    mv.visitJumpInsn(GOTO, l7);
    mv.visitLabel(l2);
    mv.visitVarInsn(ASTORE, exception);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, m_name, "this$0", "L" + m_outer + ";");
    mv.visitFieldInsn(GETFIELD, m_outer, ClassManipulator.IM_FIELD, "Lorg/apache/felix/ipojo/InstanceManager;");
    mv.visitVarInsn(ALOAD, 0);
    mv.visitLdcInsn(getMethodId(name, desc));
    mv.visitVarInsn(ALOAD, exception);
    mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", ClassManipulator.ERROR, "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Throwable;)V", false);
    mv.visitVarInsn(ALOAD, exception);
    mv.visitInsn(ATHROW);
    mv.visitLabel(l7);
    if (returnType.getSort() != Type.VOID) {
        mv.visitVarInsn(returnType.getOpcode(ILOAD), result);
    }
    mv.visitInsn(returnType.getOpcode(IRETURN));
    // If we had arguments, we mark the end of the lifetime.
    Label end = null;
    if (hasArgumentLabels) {
        end = new Label();
        mv.visitLabel(end);
    }
    // Move annotations
    if (annotations != null) {
        for (ClassChecker.AnnotationDescriptor ad : annotations) {
            ad.visitAnnotation(mv);
        }
    }
    // Move parameter annotations
    if (paramAnnotations != null && !paramAnnotations.isEmpty()) {
        for (Integer id : paramAnnotations.keySet()) {
            List<ClassChecker.AnnotationDescriptor> ads = paramAnnotations.get(id);
            for (ClassChecker.AnnotationDescriptor ad : ads) {
                ad.visitParameterAnnotation(id, mv);
            }
        }
    }
    // Write the arguments name.
    if (hasArgumentLabels) {
        for (LocalVariableNode var : localVariables) {
            mv.visitLocalVariable(var.name, var.desc, var.signature, start, end, var.index);
        }
    }
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}
Also used : GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) LocalVariableNode(org.objectweb.asm.tree.LocalVariableNode)

Aggregations

LocalVariableNode (org.objectweb.asm.tree.LocalVariableNode)41 Label (org.objectweb.asm.Label)11 MethodNode (org.objectweb.asm.tree.MethodNode)9 Type (org.objectweb.asm.Type)8 LabelNode (org.objectweb.asm.tree.LabelNode)8 VarInsnNode (org.objectweb.asm.tree.VarInsnNode)8 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)6 IincInsnNode (org.objectweb.asm.tree.IincInsnNode)6 GeneratorAdapter (org.objectweb.asm.commons.GeneratorAdapter)5 AbstractInsnNode (org.objectweb.asm.tree.AbstractInsnNode)5 InsnList (org.objectweb.asm.tree.InsnList)5 MethodInsnNode (org.objectweb.asm.tree.MethodInsnNode)5 ClassNode (org.objectweb.asm.tree.ClassNode)4 HashMap (java.util.HashMap)3 Iterator (java.util.Iterator)3 FieldNode (org.objectweb.asm.tree.FieldNode)3 FrameNode (org.objectweb.asm.tree.FrameNode)3 TryCatchBlockNode (org.objectweb.asm.tree.TryCatchBlockNode)3 NeverNullArgAnalyzerAdapter (edu.columbia.cs.psl.phosphor.instrumenter.analyzer.NeverNullArgAnalyzerAdapter)2 ControlTaintTagStack (edu.columbia.cs.psl.phosphor.struct.ControlTaintTagStack)2