use of jadx.core.dex.attributes.nodes.LoopInfo in project jadx by skylot.
the class RegionMaker method insertLoopBreak.
private boolean insertLoopBreak(RegionStack stack, LoopInfo loop, BlockNode loopExit, Edge exitEdge) {
BlockNode exit = exitEdge.getTarget();
Edge insertEdge = null;
boolean confirm = false;
// process special cases:
// 1. jump to outer loop
BlockNode exitEnd = BlockUtils.followEmptyPath(exit);
List<LoopInfo> loops = exitEnd.getAll(AType.LOOP);
for (LoopInfo loopAtEnd : loops) {
if (loopAtEnd != loop) {
insertEdge = exitEdge;
confirm = true;
break;
}
}
if (!confirm) {
BlockNode insertBlock = null;
while (exit != null) {
if (insertBlock != null && isPathExists(loopExit, exit)) {
// found cross
if (canInsertBreak(insertBlock)) {
insertEdge = new Edge(insertBlock, insertBlock.getSuccessors().get(0));
confirm = true;
break;
}
return false;
}
insertBlock = exit;
List<BlockNode> cs = exit.getCleanSuccessors();
exit = cs.size() == 1 ? cs.get(0) : null;
}
}
if (!confirm) {
return false;
}
InsnNode breakInsn = new InsnNode(InsnType.BREAK, 0);
breakInsn.addAttr(AType.LOOP, loop);
EdgeInsnAttr.addEdgeInsn(insertEdge, breakInsn);
stack.addExit(exit);
// add label to 'break' if needed
addBreakLabel(exitEdge, exit, breakInsn);
return true;
}
use of jadx.core.dex.attributes.nodes.LoopInfo in project jadx by skylot.
the class RegionMaker method makeLoopRegion.
/**
* Select loop exit and construct LoopRegion
*/
private LoopRegion makeLoopRegion(IRegion curRegion, LoopInfo loop, List<BlockNode> exitBlocks) {
for (BlockNode block : exitBlocks) {
if (block.contains(AType.EXC_HANDLER)) {
continue;
}
InsnNode lastInsn = BlockUtils.getLastInsn(block);
if (lastInsn == null || lastInsn.getType() != InsnType.IF) {
continue;
}
List<LoopInfo> loops = block.getAll(AType.LOOP);
if (!loops.isEmpty() && loops.get(0) != loop) {
// skip nested loop condition
continue;
}
LoopRegion loopRegion = new LoopRegion(curRegion, loop, block, block == loop.getEnd());
boolean found;
if (block == loop.getStart() || block == loop.getEnd() || BlockUtils.isEmptySimplePath(loop.getStart(), block)) {
found = true;
} else if (block.getPredecessors().contains(loop.getStart())) {
loopRegion.setPreCondition(loop.getStart());
// if we can't merge pre-condition this is not correct header
found = loopRegion.checkPreCondition();
} else {
found = false;
}
if (found) {
List<LoopInfo> list = mth.getAllLoopsForBlock(block);
if (list.size() >= 2) {
// bad condition if successors going out of all loops
boolean allOuter = true;
for (BlockNode outerBlock : block.getCleanSuccessors()) {
List<LoopInfo> outLoopList = mth.getAllLoopsForBlock(outerBlock);
outLoopList.remove(loop);
if (!outLoopList.isEmpty()) {
// goes to outer loop
allOuter = false;
break;
}
}
if (allOuter) {
found = false;
}
}
}
if (found && !checkLoopExits(loop, block)) {
found = false;
}
if (found) {
return loopRegion;
}
}
// no exit found => endless loop
return null;
}
Aggregations