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); } }
private boolean insertBreak(RegionStack stack, BlockNode loopExit, Edge exitEdge) { BlockNode exit = exitEdge.getTarget(); BlockNode insertBlock = null; boolean confirm = false; // process special cases if (loopExit == exit) { // try/catch at loop end BlockNode source = exitEdge.getSource(); if (source.contains(AType.CATCH_BLOCK) && source.getSuccessors().size() == 2) { BlockNode other = BlockUtils.selectOther(loopExit, source.getSuccessors()); if (other != null) { other = BlockUtils.skipSyntheticSuccessor(other); if (other.contains(AType.EXC_HANDLER)) { insertBlock = source; confirm = true; } } } } if (!confirm) { while (exit != null) { if (insertBlock != null && isPathExists(loopExit, exit)) { // found cross if (canInsertBreak(insertBlock)) { 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); insertBlock.getInstructions().add(breakInsn); stack.addExit(exit); // add label to 'break' if needed addBreakLabel(exitEdge, exit, breakInsn); return true; }
private BlockNode makeEndlessLoop( IRegion curRegion, RegionStack stack, LoopInfo loop, BlockNode loopStart) { LoopRegion loopRegion = new LoopRegion(curRegion, loop, null, false); curRegion.getSubBlocks().add(loopRegion); loopStart.remove(AType.LOOP); stack.push(loopRegion); BlockNode loopExit = null; // insert 'break' for exits List<Edge> exitEdges = loop.getExitEdges(); for (Edge exitEdge : exitEdges) { BlockNode exit = exitEdge.getTarget(); if (insertBreak(stack, exit, exitEdge)) { BlockNode nextBlock = getNextBlock(exit); if (nextBlock != null) { stack.addExit(nextBlock); loopExit = nextBlock; } } } Region body = makeRegion(loopStart, stack); BlockNode loopEnd = loop.getEnd(); if (!RegionUtils.isRegionContainsBlock(body, loopEnd) && !loopEnd.contains(AType.EXC_HANDLER) && !inExceptionHandlerBlocks(loopEnd)) { body.getSubBlocks().add(loopEnd); } loopRegion.setBody(body); if (loopExit == null) { BlockNode next = getNextBlock(loopEnd); loopExit = RegionUtils.isRegionContainsBlock(body, next) ? null : next; } stack.pop(); loopStart.addAttr(AType.LOOP, loop); return loopExit; }