Search in sources :

Example 1 with IfRegion

use of jadx.core.dex.regions.conditions.IfRegion in project jadx by skylot.

the class RegionMaker method processIf.

private BlockNode processIf(IRegion currentRegion, BlockNode block, IfNode ifnode, RegionStack stack) {
    if (block.contains(AFlag.ADDED_TO_REGION)) {
        // block already included in other 'if' region
        return ifnode.getThenBlock();
    }
    IfInfo currentIf = makeIfInfo(mth, block);
    if (currentIf == null) {
        return null;
    }
    IfInfo mergedIf = mergeNestedIfNodes(currentIf);
    if (mergedIf != null) {
        currentIf = mergedIf;
    } else {
        // invert simple condition (compiler often do it)
        currentIf = IfInfo.invert(currentIf);
    }
    IfInfo modifiedIf = IfMakerHelper.restructureIf(mth, block, currentIf);
    if (modifiedIf != null) {
        currentIf = modifiedIf;
    } else {
        if (currentIf.getMergedBlocks().size() <= 1) {
            return null;
        }
        currentIf = makeIfInfo(mth, block);
        currentIf = IfMakerHelper.restructureIf(mth, block, currentIf);
        if (currentIf == null) {
            // all attempts failed
            return null;
        }
    }
    confirmMerge(currentIf);
    IfRegion ifRegion = new IfRegion(currentRegion);
    ifRegion.updateCondition(currentIf);
    currentRegion.getSubBlocks().add(ifRegion);
    BlockNode outBlock = currentIf.getOutBlock();
    stack.push(ifRegion);
    stack.addExit(outBlock);
    ifRegion.setThenRegion(makeRegion(currentIf.getThenBlock(), stack));
    BlockNode elseBlock = currentIf.getElseBlock();
    if (elseBlock == null || stack.containsExit(elseBlock)) {
        ifRegion.setElseRegion(null);
    } else {
        ifRegion.setElseRegion(makeRegion(elseBlock, stack));
    }
    // TODO: make more common algorithm
    if (ifRegion.getElseRegion() == null && outBlock != null) {
        List<EdgeInsnAttr> edgeInsnAttrs = outBlock.getAll(AType.EDGE_INSN);
        if (!edgeInsnAttrs.isEmpty()) {
            Region elseRegion = new Region(ifRegion);
            for (EdgeInsnAttr edgeInsnAttr : edgeInsnAttrs) {
                if (edgeInsnAttr.getEnd().equals(outBlock)) {
                    addEdgeInsn(currentIf, elseRegion, edgeInsnAttr);
                }
            }
            ifRegion.setElseRegion(elseRegion);
        }
    }
    stack.pop();
    return outBlock;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) Region(jadx.core.dex.regions.Region) IRegion(jadx.core.dex.nodes.IRegion) SwitchRegion(jadx.core.dex.regions.SwitchRegion) SynchronizedRegion(jadx.core.dex.regions.SynchronizedRegion) LoopRegion(jadx.core.dex.regions.loops.LoopRegion) IfRegion(jadx.core.dex.regions.conditions.IfRegion) IfMakerHelper.makeIfInfo(jadx.core.dex.visitors.regions.IfMakerHelper.makeIfInfo) IfInfo(jadx.core.dex.regions.conditions.IfInfo) IfRegion(jadx.core.dex.regions.conditions.IfRegion) EdgeInsnAttr(jadx.core.dex.attributes.nodes.EdgeInsnAttr)

Example 2 with IfRegion

use of jadx.core.dex.regions.conditions.IfRegion in project jadx by skylot.

the class IfRegionVisitor method removeRedundantElseBlock.

private static boolean removeRedundantElseBlock(MethodNode mth, IfRegion ifRegion) {
    if (ifRegion.getElseRegion() == null || ifRegion.contains(AFlag.ELSE_IF_CHAIN) || ifRegion.getElseRegion().contains(AFlag.ELSE_IF_CHAIN)) {
        return false;
    }
    if (!RegionUtils.hasExitBlock(ifRegion.getThenRegion())) {
        return false;
    }
    // see #jadx.tests.integration.conditions.TestConditions9
    if (mth.isVoidReturn() && insnsCount(ifRegion.getThenRegion()) == 2 && insnsCount(ifRegion.getElseRegion()) == 2) {
        return false;
    }
    IRegion parent = ifRegion.getParent();
    Region newRegion = new Region(parent);
    if (parent.replaceSubBlock(ifRegion, newRegion)) {
        newRegion.add(ifRegion);
        newRegion.add(ifRegion.getElseRegion());
        ifRegion.setElseRegion(null);
        return true;
    }
    return false;
}
Also used : IRegion(jadx.core.dex.nodes.IRegion) IfRegion(jadx.core.dex.regions.conditions.IfRegion) Region(jadx.core.dex.regions.Region) IRegion(jadx.core.dex.nodes.IRegion)

Example 3 with IfRegion

use of jadx.core.dex.regions.conditions.IfRegion in project jadx by skylot.

the class RegionGen method connectElseIf.

/**
 * Connect if-else-if block
 */
private boolean connectElseIf(ICodeWriter code, IContainer els) throws CodegenException {
    if (els.contains(AFlag.ELSE_IF_CHAIN) && els instanceof Region) {
        List<IContainer> subBlocks = ((Region) els).getSubBlocks();
        if (subBlocks.size() == 1) {
            IContainer elseBlock = subBlocks.get(0);
            if (elseBlock instanceof IfRegion) {
                declareVars(code, elseBlock);
                makeIf((IfRegion) elseBlock, code, false);
                return true;
            }
        }
    }
    return false;
}
Also used : TryCatchRegion(jadx.core.dex.regions.TryCatchRegion) SwitchRegion(jadx.core.dex.regions.SwitchRegion) SynchronizedRegion(jadx.core.dex.regions.SynchronizedRegion) LoopRegion(jadx.core.dex.regions.loops.LoopRegion) IfRegion(jadx.core.dex.regions.conditions.IfRegion) Region(jadx.core.dex.regions.Region) IContainer(jadx.core.dex.nodes.IContainer) IfRegion(jadx.core.dex.regions.conditions.IfRegion)

Example 4 with IfRegion

use of jadx.core.dex.regions.conditions.IfRegion in project jadx by skylot.

the class IfRegionVisitor method markElseIfChains.

/**
 * Mark if-else-if chains
 */
private static void markElseIfChains(IfRegion ifRegion) {
    if (hasSimpleReturnBlock(ifRegion.getThenRegion())) {
        return;
    }
    IContainer elsRegion = ifRegion.getElseRegion();
    if (elsRegion instanceof Region) {
        List<IContainer> subBlocks = ((Region) elsRegion).getSubBlocks();
        if (subBlocks.size() == 1 && subBlocks.get(0) instanceof IfRegion) {
            subBlocks.get(0).add(AFlag.ELSE_IF_CHAIN);
            elsRegion.add(AFlag.ELSE_IF_CHAIN);
        }
    }
}
Also used : IRegion(jadx.core.dex.nodes.IRegion) IfRegion(jadx.core.dex.regions.conditions.IfRegion) Region(jadx.core.dex.regions.Region) IContainer(jadx.core.dex.nodes.IContainer) IfRegion(jadx.core.dex.regions.conditions.IfRegion)

Aggregations

Region (jadx.core.dex.regions.Region)4 IfRegion (jadx.core.dex.regions.conditions.IfRegion)4 IRegion (jadx.core.dex.nodes.IRegion)3 IContainer (jadx.core.dex.nodes.IContainer)2 SwitchRegion (jadx.core.dex.regions.SwitchRegion)2 SynchronizedRegion (jadx.core.dex.regions.SynchronizedRegion)2 LoopRegion (jadx.core.dex.regions.loops.LoopRegion)2 EdgeInsnAttr (jadx.core.dex.attributes.nodes.EdgeInsnAttr)1 BlockNode (jadx.core.dex.nodes.BlockNode)1 TryCatchRegion (jadx.core.dex.regions.TryCatchRegion)1 IfInfo (jadx.core.dex.regions.conditions.IfInfo)1 IfMakerHelper.makeIfInfo (jadx.core.dex.visitors.regions.IfMakerHelper.makeIfInfo)1