Search in sources :

Example 1 with Frame

use of org.jetbrains.org.objectweb.asm.tree.analysis.Frame in project intellij-community by JetBrains.

the class Analysis method createStartFrame.

final Frame<BasicValue> createStartFrame() {
    Frame<BasicValue> frame = new Frame<>(methodNode.maxLocals, methodNode.maxStack);
    Type returnType = Type.getReturnType(methodNode.desc);
    BasicValue returnValue = Type.VOID_TYPE.equals(returnType) ? null : new BasicValue(returnType);
    frame.setReturn(returnValue);
    Type[] args = Type.getArgumentTypes(methodNode.desc);
    int local = 0;
    if ((methodNode.access & Opcodes.ACC_STATIC) == 0) {
        frame.setLocal(local++, new AbstractValues.NotNullValue(Type.getObjectType(controlFlow.className)));
    }
    for (int i = 0; i < args.length; i++) {
        BasicValue value;
        if (direction instanceof InOut && ((InOut) direction).paramIndex == i || direction instanceof In && ((In) direction).paramIndex == i) {
            value = new AbstractValues.ParamValue(args[i]);
        } else {
            value = new BasicValue(args[i]);
        }
        frame.setLocal(local++, value);
        if (args[i].getSize() == 2) {
            frame.setLocal(local++, BasicValue.UNINITIALIZED_VALUE);
        }
    }
    while (local < methodNode.maxLocals) {
        frame.setLocal(local++, BasicValue.UNINITIALIZED_VALUE);
    }
    return frame;
}
Also used : Frame(org.jetbrains.org.objectweb.asm.tree.analysis.Frame) Type(org.jetbrains.org.objectweb.asm.Type) In(com.intellij.codeInspection.bytecodeAnalysis.Direction.In) InOut(com.intellij.codeInspection.bytecodeAnalysis.Direction.InOut) BasicValue(org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue)

Example 2 with Frame

use of org.jetbrains.org.objectweb.asm.tree.analysis.Frame in project intellij-community by JetBrains.

the class NegationInterpreter method proceedBranch.

private void proceedBranch(Frame<BasicValue> startFrame, int startIndex, boolean branchValue) throws NegationAnalysisFailure, AnalyzerException {
    Frame<BasicValue> frame = new Frame<>(startFrame);
    int insnIndex = startIndex;
    while (true) {
        AbstractInsnNode insnNode = methodNode.instructions.get(insnIndex);
        switch(insnNode.getType()) {
            case AbstractInsnNode.LABEL:
            case AbstractInsnNode.LINE:
            case AbstractInsnNode.FRAME:
                insnIndex = controlFlow.transitions[insnIndex][0];
                break;
            default:
                switch(insnNode.getOpcode()) {
                    case IRETURN:
                        BasicValue returnValue = frame.pop();
                        if (branchValue) {
                            trueBranchValue = returnValue;
                        } else {
                            falseBranchValue = returnValue;
                        }
                        return;
                    default:
                        checkAssertion(controlFlow.transitions[insnIndex].length == 1);
                        frame.execute(insnNode, interpreter);
                        insnIndex = controlFlow.transitions[insnIndex][0];
                }
        }
    }
}
Also used : Frame(org.jetbrains.org.objectweb.asm.tree.analysis.Frame) BasicValue(org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue)

Example 3 with Frame

use of org.jetbrains.org.objectweb.asm.tree.analysis.Frame in project intellij-community by JetBrains.

the class LiteAnalyzer method analyze.

public Frame<V>[] analyze(final String owner, final MethodNode m) throws AnalyzerException {
    if ((m.access & (ACC_ABSTRACT | ACC_NATIVE)) != 0 || m.instructions.size() == 0) {
        frames = (Frame<V>[]) new Frame<?>[0];
        return frames;
    }
    int n = m.instructions.size();
    InsnList insns = m.instructions;
    List<TryCatchBlockNode>[] handlers = (List<TryCatchBlockNode>[]) new List<?>[n];
    frames = (Frame<V>[]) new Frame<?>[n];
    queued = new boolean[n];
    queue = new int[n];
    top = 0;
    // computes exception handlers for each instruction
    for (int i = 0; i < m.tryCatchBlocks.size(); ++i) {
        TryCatchBlockNode tcb = m.tryCatchBlocks.get(i);
        int begin = insns.indexOf(tcb.start);
        int end = insns.indexOf(tcb.end);
        for (int j = begin; j < end; ++j) {
            List<TryCatchBlockNode> insnHandlers = handlers[j];
            if (insnHandlers == null) {
                insnHandlers = new ArrayList<>();
                handlers[j] = insnHandlers;
            }
            insnHandlers.add(tcb);
        }
    }
    // initializes the data structures for the control flow analysis
    Frame<V> current = new Frame<>(m.maxLocals, m.maxStack);
    Frame<V> handler = new Frame<>(m.maxLocals, m.maxStack);
    current.setReturn(interpreter.newValue(Type.getReturnType(m.desc)));
    Type[] args = Type.getArgumentTypes(m.desc);
    int local = 0;
    if ((m.access & ACC_STATIC) == 0) {
        Type ctype = Type.getObjectType(owner);
        current.setLocal(local++, interpreter.newValue(ctype));
    }
    for (int i = 0; i < args.length; ++i) {
        current.setLocal(local++, interpreter.newValue(args[i]));
        if (args[i].getSize() == 2) {
            current.setLocal(local++, interpreter.newValue(null));
        }
    }
    while (local < m.maxLocals) {
        current.setLocal(local++, interpreter.newValue(null));
    }
    merge(0, current);
    // control flow analysis
    while (top > 0) {
        int insn = queue[--top];
        Frame<V> f = frames[insn];
        queued[insn] = false;
        AbstractInsnNode insnNode = null;
        try {
            insnNode = m.instructions.get(insn);
            int insnOpcode = insnNode.getOpcode();
            int insnType = insnNode.getType();
            if (insnType == AbstractInsnNode.LABEL || insnType == AbstractInsnNode.LINE || insnType == AbstractInsnNode.FRAME) {
                merge(insn + 1, f);
            } else {
                current.init(f).execute(insnNode, interpreter);
                if (insnNode instanceof JumpInsnNode) {
                    JumpInsnNode j = (JumpInsnNode) insnNode;
                    if (insnOpcode != GOTO && insnOpcode != JSR) {
                        merge(insn + 1, current);
                    }
                    int jump = insns.indexOf(j.label);
                    merge(jump, current);
                } else if (insnNode instanceof LookupSwitchInsnNode) {
                    LookupSwitchInsnNode lsi = (LookupSwitchInsnNode) insnNode;
                    int jump = insns.indexOf(lsi.dflt);
                    merge(jump, current);
                    for (int j = 0; j < lsi.labels.size(); ++j) {
                        LabelNode label = lsi.labels.get(j);
                        jump = insns.indexOf(label);
                        merge(jump, current);
                    }
                } else if (insnNode instanceof TableSwitchInsnNode) {
                    TableSwitchInsnNode tsi = (TableSwitchInsnNode) insnNode;
                    int jump = insns.indexOf(tsi.dflt);
                    merge(jump, current);
                    for (int j = 0; j < tsi.labels.size(); ++j) {
                        LabelNode label = tsi.labels.get(j);
                        jump = insns.indexOf(label);
                        merge(jump, current);
                    }
                } else if (insnOpcode != ATHROW && (insnOpcode < IRETURN || insnOpcode > RETURN)) {
                    merge(insn + 1, current);
                }
            }
            List<TryCatchBlockNode> insnHandlers = handlers[insn];
            if (insnHandlers != null) {
                for (int i = 0; i < insnHandlers.size(); ++i) {
                    TryCatchBlockNode tcb = insnHandlers.get(i);
                    int jump = insns.indexOf(tcb.handler);
                    handler.init(f);
                    handler.clearStack();
                    handler.push(interpreter.newValue(ASMUtils.THROWABLE_TYPE));
                    merge(jump, handler);
                }
            }
        } catch (AnalyzerException e) {
            throw new AnalyzerException(e.node, "Error at instruction " + insn + ": " + e.getMessage(), e);
        } catch (Exception e) {
            throw new AnalyzerException(insnNode, "Error at instruction " + insn + ": " + e.getMessage(), e);
        }
    }
    return frames;
}
Also used : Frame(org.jetbrains.org.objectweb.asm.tree.analysis.Frame) AnalyzerException(org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException) AnalyzerException(org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException) Type(org.jetbrains.org.objectweb.asm.Type) List(java.util.List) ArrayList(java.util.ArrayList)

Example 4 with Frame

use of org.jetbrains.org.objectweb.asm.tree.analysis.Frame in project intellij-community by JetBrains.

the class InOutInterpreter method generalize.

private Conf generalize(Conf conf) {
    Frame<BasicValue> frame = new Frame<>(conf.frame);
    for (int i = generalizeShift; i < frame.getLocals(); i++) {
        BasicValue value = frame.getLocal(i);
        Class<?> valueClass = value.getClass();
        if (valueClass != BasicValue.class && valueClass != ParamValue.class) {
            frame.setLocal(i, new BasicValue(value.getType()));
        }
    }
    BasicValue[] stack = new BasicValue[frame.getStackSize()];
    for (int i = 0; i < frame.getStackSize(); i++) {
        stack[i] = frame.getStack(i);
    }
    frame.clearStack();
    for (BasicValue value : stack) {
        Class<?> valueClass = value.getClass();
        if (valueClass != BasicValue.class && valueClass != ParamValue.class) {
            frame.push(new BasicValue(value.getType()));
        } else {
            frame.push(value);
        }
    }
    return new Conf(conf.insnIndex, frame);
}
Also used : Frame(org.jetbrains.org.objectweb.asm.tree.analysis.Frame) BasicValue(org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue)

Example 5 with Frame

use of org.jetbrains.org.objectweb.asm.tree.analysis.Frame in project intellij-community by JetBrains.

the class NegationInterpreter method createStartFrame.

final Frame<BasicValue> createStartFrame() {
    Frame<BasicValue> frame = new Frame<>(methodNode.maxLocals, methodNode.maxStack);
    Type returnType = Type.getReturnType(methodNode.desc);
    BasicValue returnValue = Type.VOID_TYPE.equals(returnType) ? null : new BasicValue(returnType);
    frame.setReturn(returnValue);
    Type[] args = Type.getArgumentTypes(methodNode.desc);
    int local = 0;
    if ((methodNode.access & ACC_STATIC) == 0) {
        frame.setLocal(local++, ThisValue);
    }
    for (int i = 0; i < args.length; i++) {
        BasicValue value = new NthParamValue(args[i], i);
        frame.setLocal(local++, value);
        if (args[i].getSize() == 2) {
            frame.setLocal(local++, BasicValue.UNINITIALIZED_VALUE);
        }
    }
    while (local < methodNode.maxLocals) {
        frame.setLocal(local++, BasicValue.UNINITIALIZED_VALUE);
    }
    return frame;
}
Also used : Frame(org.jetbrains.org.objectweb.asm.tree.analysis.Frame) Type(org.jetbrains.org.objectweb.asm.Type) BasicValue(org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue)

Aggregations

Frame (org.jetbrains.org.objectweb.asm.tree.analysis.Frame)6 BasicValue (org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue)5 Type (org.jetbrains.org.objectweb.asm.Type)3 In (com.intellij.codeInspection.bytecodeAnalysis.Direction.In)1 InOut (com.intellij.codeInspection.bytecodeAnalysis.Direction.InOut)1 AnalyzerExt (com.intellij.codeInspection.bytecodeAnalysis.asm.AnalyzerExt)1 LiteAnalyzerExt (com.intellij.codeInspection.bytecodeAnalysis.asm.LiteAnalyzerExt)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 List (java.util.List)1 AnalyzerException (org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException)1