Search in sources :

Example 1 with BasicInterpreter

use of org.jetbrains.org.objectweb.asm.tree.analysis.BasicInterpreter 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)

Aggregations

NonNull (com.android.annotations.NonNull)1 AbstractInsnNode (org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode)1 InsnList (org.jetbrains.org.objectweb.asm.tree.InsnList)1 TryCatchBlockNode (org.jetbrains.org.objectweb.asm.tree.TryCatchBlockNode)1 Analyzer (org.jetbrains.org.objectweb.asm.tree.analysis.Analyzer)1 BasicInterpreter (org.jetbrains.org.objectweb.asm.tree.analysis.BasicInterpreter)1