Search in sources :

Example 6 with InsnType

use of jadx.core.dex.instructions.InsnType 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

InsnType (jadx.core.dex.instructions.InsnType)6 InsnNode (jadx.core.dex.nodes.InsnNode)5 InsnWrapArg (jadx.core.dex.instructions.args.InsnWrapArg)3 ArithNode (jadx.core.dex.instructions.ArithNode)2 FieldInfo (jadx.core.dex.info.FieldInfo)1 IfNode (jadx.core.dex.instructions.IfNode)1 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)1 FieldArg (jadx.core.dex.instructions.args.FieldArg)1 InsnArg (jadx.core.dex.instructions.args.InsnArg)1 LiteralArg (jadx.core.dex.instructions.args.LiteralArg)1 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)1 BlockNode (jadx.core.dex.nodes.BlockNode)1 IBlock (jadx.core.dex.nodes.IBlock)1 IBranchRegion (jadx.core.dex.nodes.IBranchRegion)1 IContainer (jadx.core.dex.nodes.IContainer)1 IRegion (jadx.core.dex.nodes.IRegion)1 SplitterBlockAttr (jadx.core.dex.trycatch.SplitterBlockAttr)1 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)1 HashMap (java.util.HashMap)1