Search in sources :

Example 6 with SplitterBlockAttr

use of jadx.core.dex.trycatch.SplitterBlockAttr in project jadx by skylot.

the class BlockSplitter method splitBasicBlocks.

private static void splitBasicBlocks(MethodNode mth) {
    InsnNode prevInsn = null;
    Map<Integer, BlockNode> blocksMap = new HashMap<Integer, BlockNode>();
    BlockNode curBlock = startNewBlock(mth, 0);
    mth.setEnterBlock(curBlock);
    // split into blocks
    for (InsnNode insn : mth.getInstructions()) {
        if (insn == null) {
            continue;
        }
        boolean startNew = false;
        if (prevInsn != null) {
            InsnType type = prevInsn.getType();
            if (type == InsnType.GOTO || type == InsnType.THROW || SEPARATE_INSNS.contains(type)) {
                if (type == InsnType.RETURN || type == InsnType.THROW) {
                    mth.addExitBlock(curBlock);
                }
                BlockNode block = startNewBlock(mth, insn.getOffset());
                if (type == InsnType.MONITOR_ENTER || type == InsnType.MONITOR_EXIT) {
                    connect(curBlock, block);
                }
                curBlock = block;
                startNew = true;
            } else {
                startNew = isSplitByJump(prevInsn, insn) || SEPARATE_INSNS.contains(insn.getType()) || isDoWhile(blocksMap, curBlock, insn) || prevInsn.contains(AFlag.TRY_LEAVE) || prevInsn.getType() == InsnType.MOVE_EXCEPTION;
                if (startNew) {
                    BlockNode block = startNewBlock(mth, insn.getOffset());
                    connect(curBlock, block);
                    curBlock = block;
                }
            }
        }
        // for try/catch make empty block for connect handlers
        if (insn.contains(AFlag.TRY_ENTER)) {
            BlockNode block;
            if (insn.getOffset() != 0 && !startNew) {
                block = startNewBlock(mth, insn.getOffset());
                connect(curBlock, block);
                curBlock = block;
            }
            blocksMap.put(insn.getOffset(), curBlock);
            // add this insn in new block
            block = startNewBlock(mth, -1);
            curBlock.add(AFlag.SYNTHETIC);
            SplitterBlockAttr splitter = new SplitterBlockAttr(curBlock);
            block.addAttr(splitter);
            curBlock.addAttr(splitter);
            connect(curBlock, block);
            curBlock = block;
        } else {
            blocksMap.put(insn.getOffset(), curBlock);
        }
        curBlock.getInstructions().add(insn);
        prevInsn = insn;
    }
    // setup missing connections
    setupConnections(mth, blocksMap);
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) InsnNode(jadx.core.dex.nodes.InsnNode) SplitterBlockAttr(jadx.core.dex.trycatch.SplitterBlockAttr) HashMap(java.util.HashMap) InsnType(jadx.core.dex.instructions.InsnType)

Aggregations

BlockNode (jadx.core.dex.nodes.BlockNode)6 SplitterBlockAttr (jadx.core.dex.trycatch.SplitterBlockAttr)6 ExceptionHandler (jadx.core.dex.trycatch.ExceptionHandler)3 BitSet (java.util.BitSet)3 InsnNode (jadx.core.dex.nodes.InsnNode)2 CatchAttr (jadx.core.dex.trycatch.CatchAttr)2 ExcHandlerAttr (jadx.core.dex.trycatch.ExcHandlerAttr)2 TryCatchBlock (jadx.core.dex.trycatch.TryCatchBlock)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 InsnType (jadx.core.dex.instructions.InsnType)1 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)1 BlocksRemoveInfo (jadx.core.dex.visitors.blocksmaker.helpers.BlocksRemoveInfo)1 LiveVarAnalysis (jadx.core.dex.visitors.ssa.LiveVarAnalysis)1 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)1 ArrayList (java.util.ArrayList)1 LinkedList (java.util.LinkedList)1 Map (java.util.Map)1