Search in sources :

Example 1 with TryCatchBlockNode

use of org.jetbrains.org.objectweb.asm.tree.TryCatchBlockNode in project kotlin by JetBrains.

the class ControlFlowGraph method create.

/**
     * Creates a new {@link ControlFlowGraph} and populates it with the flow
     * control for the given method. If the optional {@code initial} parameter is
     * provided with an existing graph, then the graph is simply populated, not
     * created. This allows subclassing of the graph instance, if necessary.
     *
     * @param initial usually null, but can point to an existing instance of a
     *            {@link ControlFlowGraph} in which that graph is reused (but
     *            populated with new edges)
     * @param classNode the class containing the method to be analyzed
     * @param method the method to be analyzed
     * @return a {@link ControlFlowGraph} with nodes for the control flow in the
     *         given method
     * @throws AnalyzerException if the underlying bytecode library is unable to
     *             analyze the method bytecode
     */
@NonNull
public static ControlFlowGraph create(@Nullable ControlFlowGraph initial, @NonNull ClassNode classNode, @NonNull MethodNode method) throws AnalyzerException {
    final ControlFlowGraph graph = initial != null ? initial : new ControlFlowGraph();
    final InsnList instructions = method.instructions;
    graph.mNodeMap = Maps.newHashMapWithExpectedSize(instructions.size());
    graph.mMethod = method;
    // Create a flow control graph using ASM5's analyzer. According to the ASM 4 guide
    // (download.forge.objectweb.org/asm/asm4-guide.pdf) there are faster ways to construct
    // it, but those require a lot more code.
    Analyzer analyzer = new Analyzer(new BasicInterpreter()) {

        @Override
        protected void newControlFlowEdge(int insn, int successor) {
            // Update the information as of whether the this object has been
            // initialized at the given instruction.
            AbstractInsnNode from = instructions.get(insn);
            AbstractInsnNode to = instructions.get(successor);
            graph.add(from, to);
        }

        @Override
        protected boolean newControlFlowExceptionEdge(int insn, TryCatchBlockNode tcb) {
            AbstractInsnNode from = instructions.get(insn);
            graph.exception(from, tcb);
            return super.newControlFlowExceptionEdge(insn, tcb);
        }

        @Override
        protected boolean newControlFlowExceptionEdge(int insn, int successor) {
            AbstractInsnNode from = instructions.get(insn);
            AbstractInsnNode to = instructions.get(successor);
            graph.exception(from, to);
            return super.newControlFlowExceptionEdge(insn, successor);
        }
    };
    analyzer.analyze(classNode.name, method);
    return graph;
}
Also used : TryCatchBlockNode(org.jetbrains.org.objectweb.asm.tree.TryCatchBlockNode) BasicInterpreter(org.jetbrains.org.objectweb.asm.tree.analysis.BasicInterpreter) InsnList(org.jetbrains.org.objectweb.asm.tree.InsnList) Analyzer(org.jetbrains.org.objectweb.asm.tree.analysis.Analyzer) AbstractInsnNode(org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode) NonNull(com.android.annotations.NonNull)

Example 2 with TryCatchBlockNode

use of org.jetbrains.org.objectweb.asm.tree.TryCatchBlockNode in project kotlin by JetBrains.

the class ControlFlowGraph method exception.

/** Adds an exception try block node to this graph */
protected void exception(@NonNull AbstractInsnNode from, @NonNull TryCatchBlockNode tcb) {
    // Add tcb's to all instructions in the range
    LabelNode start = tcb.start;
    // exclusive
    LabelNode end = tcb.end;
    // Add exception edges for all method calls in the range
    AbstractInsnNode curr = start;
    Node handlerNode = getNode(tcb.handler);
    while (curr != end && curr != null) {
        // A method can throw can exception, or a throw instruction directly
        if (curr.getType() == AbstractInsnNode.METHOD_INSN || (curr.getType() == AbstractInsnNode.INSN && curr.getOpcode() == Opcodes.ATHROW)) {
            // Method call; add exception edge to handler
            if (tcb.type == null) {
                // finally block: not an exception path
                getNode(curr).addSuccessor(handlerNode);
            }
            getNode(curr).addExceptionPath(handlerNode);
        }
        curr = curr.getNext();
    }
}
Also used : LabelNode(org.jetbrains.org.objectweb.asm.tree.LabelNode) FieldInsnNode(org.jetbrains.org.objectweb.asm.tree.FieldInsnNode) FrameNode(org.jetbrains.org.objectweb.asm.tree.FrameNode) JumpInsnNode(org.jetbrains.org.objectweb.asm.tree.JumpInsnNode) MethodInsnNode(org.jetbrains.org.objectweb.asm.tree.MethodInsnNode) TryCatchBlockNode(org.jetbrains.org.objectweb.asm.tree.TryCatchBlockNode) AbstractInsnNode(org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode) LineNumberNode(org.jetbrains.org.objectweb.asm.tree.LineNumberNode) TypeInsnNode(org.jetbrains.org.objectweb.asm.tree.TypeInsnNode) ClassNode(org.jetbrains.org.objectweb.asm.tree.ClassNode) IntInsnNode(org.jetbrains.org.objectweb.asm.tree.IntInsnNode) LabelNode(org.jetbrains.org.objectweb.asm.tree.LabelNode) LdcInsnNode(org.jetbrains.org.objectweb.asm.tree.LdcInsnNode) MethodNode(org.jetbrains.org.objectweb.asm.tree.MethodNode) AbstractInsnNode(org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode)

Aggregations

AbstractInsnNode (org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode)2 TryCatchBlockNode (org.jetbrains.org.objectweb.asm.tree.TryCatchBlockNode)2 NonNull (com.android.annotations.NonNull)1 ClassNode (org.jetbrains.org.objectweb.asm.tree.ClassNode)1 FieldInsnNode (org.jetbrains.org.objectweb.asm.tree.FieldInsnNode)1 FrameNode (org.jetbrains.org.objectweb.asm.tree.FrameNode)1 InsnList (org.jetbrains.org.objectweb.asm.tree.InsnList)1 IntInsnNode (org.jetbrains.org.objectweb.asm.tree.IntInsnNode)1 JumpInsnNode (org.jetbrains.org.objectweb.asm.tree.JumpInsnNode)1 LabelNode (org.jetbrains.org.objectweb.asm.tree.LabelNode)1 LdcInsnNode (org.jetbrains.org.objectweb.asm.tree.LdcInsnNode)1 LineNumberNode (org.jetbrains.org.objectweb.asm.tree.LineNumberNode)1 MethodInsnNode (org.jetbrains.org.objectweb.asm.tree.MethodInsnNode)1 MethodNode (org.jetbrains.org.objectweb.asm.tree.MethodNode)1 TypeInsnNode (org.jetbrains.org.objectweb.asm.tree.TypeInsnNode)1 Analyzer (org.jetbrains.org.objectweb.asm.tree.analysis.Analyzer)1 BasicInterpreter (org.jetbrains.org.objectweb.asm.tree.analysis.BasicInterpreter)1