Search in sources :

Example 71 with BlockNode

use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.

the class TypeInferenceVisitor method insertSoftUseCast.

private boolean insertSoftUseCast(MethodNode mth, RegisterArg useArg) {
    InsnNode useInsn = useArg.getParentInsn();
    if (useInsn == null || useInsn.getType() == InsnType.PHI) {
        return false;
    }
    if (useInsn.getType() == InsnType.IF && useInsn.getArg(1).isZeroLiteral()) {
        // cast not needed if compare with null
        return false;
    }
    BlockNode useBlock = BlockUtils.getBlockByInsn(mth, useInsn);
    if (useBlock == null) {
        return false;
    }
    RegisterArg newUseArg = useArg.duplicateWithNewSSAVar(mth);
    useInsn.replaceArg(useArg, newUseArg);
    IndexInsnNode castInsn = makeSoftCastInsn(newUseArg, useArg, useArg.getInitType());
    return BlockUtils.insertBeforeInsn(useBlock, useInsn, castInsn);
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode)

Example 72 with BlockNode

use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.

the class BlockUtils method calcImmediatePostDominator.

@Nullable
public static BlockNode calcImmediatePostDominator(MethodNode mth, BlockNode block, Map<BlockNode, BitSet> postDomsMap) {
    BlockNode oneSuccessor = Utils.getOne(block.getSuccessors());
    if (oneSuccessor != null) {
        return oneSuccessor;
    }
    List<BlockNode> basicBlocks = mth.getBasicBlocks();
    BitSet postDoms = postDomsMap.get(block);
    BitSet bs = copyBlocksBitSet(mth, postDoms);
    for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) {
        BlockNode pdomBlock = basicBlocks.get(i);
        BitSet pdoms = postDomsMap.get(pdomBlock);
        if (pdoms != null) {
            bs.andNot(pdoms);
        }
    }
    return bitSetToOneBlock(mth, bs);
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) BitSet(java.util.BitSet) Nullable(org.jetbrains.annotations.Nullable)

Example 73 with BlockNode

use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.

the class LoopInfo method getExitNodes.

/**
 * Return source blocks of exit edges. <br>
 * Exit nodes belongs to loop (contains in {@code loopBlocks})
 */
public Set<BlockNode> getExitNodes() {
    Set<BlockNode> nodes = new HashSet<>();
    Set<BlockNode> blocks = getLoopBlocks();
    for (BlockNode block : blocks) {
        // exit: successor node not from this loop, (don't change to getCleanSuccessors)
        for (BlockNode s : block.getSuccessors()) {
            if (!blocks.contains(s) && !s.contains(AType.EXC_HANDLER)) {
                nodes.add(block);
            }
        }
    }
    return nodes;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) HashSet(java.util.HashSet)

Example 74 with BlockNode

use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.

the class LoopRegionVisitor method checkIterableForEach.

private static boolean checkIterableForEach(MethodNode mth, LoopRegion loopRegion, IfCondition condition) {
    List<RegisterArg> condArgs = condition.getRegisterArgs();
    if (condArgs.size() != 1) {
        return false;
    }
    RegisterArg iteratorArg = condArgs.get(0);
    SSAVar sVar = iteratorArg.getSVar();
    if (sVar == null || sVar.isUsedInPhi()) {
        return false;
    }
    List<RegisterArg> itUseList = sVar.getUseList();
    InsnNode assignInsn = iteratorArg.getAssignInsn();
    if (itUseList.size() != 2) {
        return false;
    }
    if (!checkInvoke(assignInsn, null, "iterator()Ljava/util/Iterator;")) {
        return false;
    }
    InsnArg iterableArg = assignInsn.getArg(0);
    InsnNode hasNextCall = itUseList.get(0).getParentInsn();
    InsnNode nextCall = itUseList.get(1).getParentInsn();
    if (!checkInvoke(hasNextCall, "java.util.Iterator", "hasNext()Z") || !checkInvoke(nextCall, "java.util.Iterator", "next()Ljava/lang/Object;")) {
        return false;
    }
    List<InsnNode> toSkip = new LinkedList<>();
    RegisterArg iterVar;
    if (nextCall.contains(AFlag.WRAPPED)) {
        InsnArg wrapArg = BlockUtils.searchWrappedInsnParent(mth, nextCall);
        if (wrapArg != null && wrapArg.getParentInsn() != null) {
            InsnNode parentInsn = wrapArg.getParentInsn();
            BlockNode block = BlockUtils.getBlockByInsn(mth, parentInsn);
            if (block == null) {
                return false;
            }
            if (!RegionUtils.isRegionContainsBlock(loopRegion, block)) {
                return false;
            }
            if (parentInsn.getType() == InsnType.CHECK_CAST) {
                iterVar = parentInsn.getResult();
                if (iterVar == null || !fixIterableType(mth, iterableArg, iterVar)) {
                    return false;
                }
                InsnArg castArg = BlockUtils.searchWrappedInsnParent(mth, parentInsn);
                if (castArg != null && castArg.getParentInsn() != null) {
                    castArg.getParentInsn().replaceArg(castArg, iterVar);
                } else {
                    // cast not inlined
                    toSkip.add(parentInsn);
                }
            } else {
                iterVar = nextCall.getResult();
                if (iterVar == null) {
                    return false;
                }
                // restore variable from inlined insn
                iterVar.remove(AFlag.REMOVE);
                nextCall.add(AFlag.DONT_GENERATE);
                if (!fixIterableType(mth, iterableArg, iterVar)) {
                    return false;
                }
                parentInsn.replaceArg(wrapArg, iterVar);
            }
        } else {
            LOG.warn(" checkIterableForEach: Wrapped insn not found: {}, mth: {}", nextCall, mth);
            return false;
        }
    } else {
        iterVar = nextCall.getResult();
        if (iterVar == null) {
            return false;
        }
        if (!usedOnlyInLoop(mth, loopRegion, iterVar)) {
            return false;
        }
        if (!assignOnlyInLoop(mth, loopRegion, iterVar)) {
            return false;
        }
        toSkip.add(nextCall);
    }
    assignInsn.add(AFlag.DONT_GENERATE);
    assignInsn.getResult().add(AFlag.DONT_GENERATE);
    for (InsnNode insnNode : toSkip) {
        insnNode.add(AFlag.DONT_GENERATE);
    }
    for (RegisterArg itArg : itUseList) {
        itArg.add(AFlag.DONT_GENERATE);
    }
    ForEachLoop forEachLoop = new ForEachLoop(iterVar, iterableArg);
    forEachLoop.injectFakeInsns(loopRegion);
    loopRegion.setType(forEachLoop);
    return true;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) SSAVar(jadx.core.dex.instructions.args.SSAVar) InsnArg(jadx.core.dex.instructions.args.InsnArg) ForEachLoop(jadx.core.dex.regions.loops.ForEachLoop) LinkedList(java.util.LinkedList)

Example 75 with BlockNode

use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.

the class RegionMaker method addBreakLabel.

private void addBreakLabel(Edge exitEdge, BlockNode exit, InsnNode breakInsn) {
    BlockNode outBlock = BlockUtils.getNextBlock(exitEdge.getTarget());
    if (outBlock == null) {
        return;
    }
    List<LoopInfo> exitLoop = mth.getAllLoopsForBlock(outBlock);
    if (!exitLoop.isEmpty()) {
        return;
    }
    List<LoopInfo> inLoops = mth.getAllLoopsForBlock(exitEdge.getSource());
    if (inLoops.size() < 2) {
        return;
    }
    // search for parent loop
    LoopInfo parentLoop = null;
    for (LoopInfo loop : inLoops) {
        if (loop.getParentLoop() == null) {
            parentLoop = loop;
            break;
        }
    }
    if (parentLoop == null) {
        return;
    }
    if (parentLoop.getEnd() != exit && !parentLoop.getExitNodes().contains(exit)) {
        LoopLabelAttr labelAttr = new LoopLabelAttr(parentLoop);
        breakInsn.addAttr(labelAttr);
        parentLoop.getStart().addAttr(labelAttr);
    }
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) LoopInfo(jadx.core.dex.attributes.nodes.LoopInfo) LoopLabelAttr(jadx.core.dex.attributes.nodes.LoopLabelAttr)

Aggregations

BlockNode (jadx.core.dex.nodes.BlockNode)220 InsnNode (jadx.core.dex.nodes.InsnNode)91 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)43 ArrayList (java.util.ArrayList)41 BitSet (java.util.BitSet)31 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)29 InsnArg (jadx.core.dex.instructions.args.InsnArg)25 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)21 ExceptionHandler (jadx.core.dex.trycatch.ExceptionHandler)19 PhiInsn (jadx.core.dex.instructions.PhiInsn)14 SSAVar (jadx.core.dex.instructions.args.SSAVar)14 Nullable (org.jetbrains.annotations.Nullable)14 LoopInfo (jadx.core.dex.attributes.nodes.LoopInfo)13 IRegion (jadx.core.dex.nodes.IRegion)13 HashSet (java.util.HashSet)13 MethodNode (jadx.core.dex.nodes.MethodNode)12 Region (jadx.core.dex.regions.Region)12 LoopRegion (jadx.core.dex.regions.loops.LoopRegion)12 InsnType (jadx.core.dex.instructions.InsnType)11 SynchronizedRegion (jadx.core.dex.regions.SynchronizedRegion)11