public static ControlFlowGraph build(final List<Instruction> instructions, final List<ExceptionHandler> exceptionHandlers) { final ControlFlowGraphBuilder builder = new ControlFlowGraphBuilder( VerifyArgument.notNull(instructions, "instructions"), VerifyArgument.notNull(exceptionHandlers, "exceptionHandlers") ); return builder.build(); }
public final ControlFlowGraph build() { calculateIncomingJumps(); createNodes(); createRegularControlFlow(); createExceptionalControlFlow(); if (copyFinallyBlocks) { copyFinallyBlocksIntoLeaveEdges(); } else { transformLeaveEdges(); } return new ControlFlowGraph(_nodes.toArray(new ControlFlowNode[_nodes.size()])); }
private ControlFlowGraphBuilder(final List<Instruction> instructions, final List<ExceptionHandler> exceptionHandlers) { _instructions = VerifyArgument.notNull(instructions, "instructions"); _exceptionHandlers = coalesceExceptionHandlers(VerifyArgument.notNull(exceptionHandlers, "exceptionHandlers")); _offsets = new int[instructions.size()]; _hasIncomingJumps = new boolean[_offsets.length]; for (int i = 0; i < instructions.size(); i++) { _offsets[i] = instructions.get(i).getOffset(); } _entryPoint = new ControlFlowNode(_nextBlockId++, 0, ControlFlowNodeType.EntryPoint); _regularExit = new ControlFlowNode(_nextBlockId++, -1, ControlFlowNodeType.RegularExit); _exceptionalExit = new ControlFlowNode(_nextBlockId++, -1, ControlFlowNodeType.ExceptionalExit); _nodes.add(_entryPoint); _nodes.add(_regularExit); _nodes.add(_exceptionalExit); }
private void createBranchControlFlow(final ControlFlowNode node, final Instruction jump, final Instruction target) { final ControlFlowNode handlerNode = findInnermostHandlerBlock(jump.getOffset()); final ControlFlowNode outerFinally = findInnermostHandlerBlock(jump.getOffset(), true); final ControlFlowNode targetHandlerNode = findInnermostHandlerBlock(target.getOffset()); final ExceptionHandler handler = handlerNode.getExceptionHandler(); createEdge(node, target, JumpType.Normal); return; ControlFlowNode finallyHandlerNode = findInnermostFinallyHandlerNode(handler.getTryBlock().getLastInstruction().getOffset()); createEdge(node, target, JumpType.LeaveTry); createEdge(node, target, JumpType.Normal); createEdge(node, target, JumpType.LeaveTry); ControlFlowNode parentHandler = findParentExceptionHandlerNode(handlerNode); parentHandler = findParentExceptionHandlerNode(parentHandler); !parentHandler.getExceptionHandler().getTryBlock().contains(target)) { createEdge(node, target, JumpType.LeaveTry); createEdge(node, handlerNode.getEndFinallyNode(), JumpType.Normal); createEdge(handlerNode.getEndFinallyNode(), target, JumpType.Normal); createEdge(node, target, JumpType.Normal);
createEdge(_entryPoint, instructions.get(0), JumpType.Normal); createEdge(node, next, JumpType.Normal); opCode.getOperandType() == OperandType.BranchTargetWide) { createBranchControlFlow(node, instruction, instruction.<Instruction>getOperand(0)); createEdge(node, switchInfo.getDefaultTarget(), JumpType.Normal); createEdge(node, target, JumpType.Normal); final ControlFlowNode handlerBlock = findInnermostFinallyBlock(end.getOffset()); createEdge(node, handlerBlock.getEndFinallyNode(), JumpType.Normal); ControlFlowNode handlerBlock = findInnermostHandlerBlock(end.getOffset()); handlerBlock = findInnermostFinallyHandlerNode( handlerBlock.getExceptionHandler().getTryBlock().getLastInstruction().getOffset() ); createEdge(node, handlerBlock.getEndFinallyNode(), JumpType.LeaveTry); createReturnControlFlow(node, end);
private void copyFinallyBlocksIntoLeaveEdges() { // // Step 5b: Copy finally blocks into the LeaveTry edges. // for (int n = _nodes.size(), i = n - 1; i >= 0; i--) { final ControlFlowNode node = _nodes.get(i); final Instruction end = node.getEnd(); if (end != null && node.getOutgoing().size() == 1 && node.getOutgoing().get(0).getType() == JumpType.LeaveTry) { assert end.getOpCode() == OpCode.GOTO || end.getOpCode() == OpCode.GOTO_W; final ControlFlowEdge edge = node.getOutgoing().get(0); final ControlFlowNode target = edge.getTarget(); target.getIncoming().remove(edge); node.getOutgoing().clear(); final ControlFlowNode handler = findInnermostExceptionHandlerNode(end.getEndOffset()); assert handler.getNodeType() == ControlFlowNodeType.FinallyHandler; final ControlFlowNode copy = copyFinallySubGraph(handler, handler.getEndFinallyNode(), target); createEdge(node, copy, JumpType.Normal); } } }
_cfg = ControlFlowGraphBuilder.build(instructions, handlers); _cfg.computeDominance(); _cfg.computeDominanceFrontier();
@SuppressWarnings("UnusedParameters") private void createReturnControlFlow(final ControlFlowNode node, final Instruction end) { // final ControlFlowNode handlerNode = findInnermostHandlerBlock(end.getOffset()); // final ControlFlowNode finallyNode; // // if (handlerNode.getNodeType() == ControlFlowNodeType.CatchHandler) { // finallyNode = findInnermostFinallyHandlerNode( // handlerNode.getExceptionHandler().getTryBlock().getLastInstruction().getOffset() // ); // } // else if (handlerNode.getNodeType() == ControlFlowNodeType.FinallyHandler) { // finallyNode = handlerNode; // } // else { // finallyNode = _exceptionalExit; // } // // if (finallyNode.getNodeType() == ControlFlowNodeType.FinallyHandler) { // createEdge(node, _regularExit, JumpType.LeaveTry); // } // else { createEdge(node, _regularExit, JumpType.Normal); // } }
private void createBranchControlFlow(final ControlFlowNode node, final Instruction jump, final Instruction target) { final ControlFlowNode handlerNode = findInnermostHandlerBlock(jump.getOffset()); final ControlFlowNode outerFinally = findInnermostHandlerBlock(jump.getOffset(), true); final ControlFlowNode targetHandlerNode = findInnermostHandlerBlock(target.getOffset()); final ExceptionHandler handler = handlerNode.getExceptionHandler(); createEdge(node, target, JumpType.Normal); return; ControlFlowNode finallyHandlerNode = findInnermostFinallyHandlerNode(handler.getTryBlock().getLastInstruction().getOffset()); createEdge(node, target, JumpType.LeaveTry); createEdge(node, target, JumpType.Normal); createEdge(node, target, JumpType.LeaveTry); ControlFlowNode parentHandler = findParentExceptionHandlerNode(handlerNode); parentHandler = findParentExceptionHandlerNode(parentHandler); !parentHandler.getExceptionHandler().getTryBlock().contains(target)) { createEdge(node, target, JumpType.LeaveTry); createEdge(node, handlerNode.getEndFinallyNode(), JumpType.Normal); createEdge(handlerNode.getEndFinallyNode(), target, JumpType.Normal); createEdge(node, target, JumpType.Normal);
createEdge(_entryPoint, instructions.get(0), JumpType.Normal); createEdge(node, next, JumpType.Normal); opCode.getOperandType() == OperandType.BranchTargetWide) { createBranchControlFlow(node, instruction, instruction.<Instruction>getOperand(0)); createEdge(node, switchInfo.getDefaultTarget(), JumpType.Normal); createEdge(node, target, JumpType.Normal); final ControlFlowNode handlerBlock = findInnermostFinallyBlock(end.getOffset()); createEdge(node, handlerBlock.getEndFinallyNode(), JumpType.Normal); ControlFlowNode handlerBlock = findInnermostHandlerBlock(end.getOffset()); handlerBlock = findInnermostFinallyHandlerNode( handlerBlock.getExceptionHandler().getTryBlock().getLastInstruction().getOffset() ); createEdge(node, handlerBlock.getEndFinallyNode(), JumpType.LeaveTry); createReturnControlFlow(node, end);
private void copyFinallyBlocksIntoLeaveEdges() { // // Step 5b: Copy finally blocks into the LeaveTry edges. // for (int n = _nodes.size(), i = n - 1; i >= 0; i--) { final ControlFlowNode node = _nodes.get(i); final Instruction end = node.getEnd(); if (end != null && node.getOutgoing().size() == 1 && node.getOutgoing().get(0).getType() == JumpType.LeaveTry) { assert end.getOpCode() == OpCode.GOTO || end.getOpCode() == OpCode.GOTO_W; final ControlFlowEdge edge = node.getOutgoing().get(0); final ControlFlowNode target = edge.getTarget(); target.getIncoming().remove(edge); node.getOutgoing().clear(); final ControlFlowNode handler = findInnermostExceptionHandlerNode(end.getEndOffset()); assert handler.getNodeType() == ControlFlowNodeType.FinallyHandler; final ControlFlowNode copy = copyFinallySubGraph(handler, handler.getEndFinallyNode(), target); createEdge(node, copy, JumpType.Normal); } } }
_cfg = ControlFlowGraphBuilder.build(instructions, handlers); _cfg.computeDominance(); _cfg.computeDominanceFrontier();
@SuppressWarnings("UnusedParameters") private void createReturnControlFlow(final ControlFlowNode node, final Instruction end) { // final ControlFlowNode handlerNode = findInnermostHandlerBlock(end.getOffset()); // final ControlFlowNode finallyNode; // // if (handlerNode.getNodeType() == ControlFlowNodeType.CatchHandler) { // finallyNode = findInnermostFinallyHandlerNode( // handlerNode.getExceptionHandler().getTryBlock().getLastInstruction().getOffset() // ); // } // else if (handlerNode.getNodeType() == ControlFlowNodeType.FinallyHandler) { // finallyNode = handlerNode; // } // else { // finallyNode = _exceptionalExit; // } // // if (finallyNode.getNodeType() == ControlFlowNodeType.FinallyHandler) { // createEdge(node, _regularExit, JumpType.LeaveTry); // } // else { createEdge(node, _regularExit, JumpType.Normal); // } }
private void createBranchControlFlow(final ControlFlowNode node, final Instruction jump, final Instruction target) { final ControlFlowNode handlerNode = findInnermostHandlerBlock(jump.getOffset()); final ControlFlowNode outerFinally = findInnermostHandlerBlock(jump.getOffset(), true); final ControlFlowNode targetHandlerNode = findInnermostHandlerBlock(target.getOffset()); final ExceptionHandler handler = handlerNode.getExceptionHandler(); createEdge(node, target, JumpType.Normal); return; ControlFlowNode finallyHandlerNode = findInnermostFinallyHandlerNode(handler.getTryBlock().getLastInstruction().getOffset()); createEdge(node, target, JumpType.LeaveTry); createEdge(node, target, JumpType.Normal); createEdge(node, target, JumpType.LeaveTry); ControlFlowNode parentHandler = findParentExceptionHandlerNode(handlerNode); parentHandler = findParentExceptionHandlerNode(parentHandler); !parentHandler.getExceptionHandler().getTryBlock().contains(target)) { createEdge(node, target, JumpType.LeaveTry); createEdge(node, handlerNode.getEndFinallyNode(), JumpType.Normal); createEdge(handlerNode.getEndFinallyNode(), target, JumpType.Normal); createEdge(node, target, JumpType.Normal);
public final ControlFlowGraph build() { calculateIncomingJumps(); createNodes(); createRegularControlFlow(); createExceptionalControlFlow(); if (copyFinallyBlocks) { copyFinallyBlocksIntoLeaveEdges(); } else { transformLeaveEdges(); } return new ControlFlowGraph(_nodes.toArray(new ControlFlowNode[_nodes.size()])); }
createEdge(_entryPoint, instructions.get(0), JumpType.Normal); createEdge(node, next, JumpType.Normal); opCode.getOperandType() == OperandType.BranchTargetWide) { createBranchControlFlow(node, instruction, instruction.<Instruction>getOperand(0)); createEdge(node, switchInfo.getDefaultTarget(), JumpType.Normal); createEdge(node, target, JumpType.Normal); final ControlFlowNode handlerBlock = findInnermostFinallyBlock(end.getOffset()); createEdge(node, handlerBlock.getEndFinallyNode(), JumpType.Normal); ControlFlowNode handlerBlock = findInnermostHandlerBlock(end.getOffset()); handlerBlock = findInnermostFinallyHandlerNode( handlerBlock.getExceptionHandler().getTryBlock().getLastInstruction().getOffset() ); createEdge(node, handlerBlock.getEndFinallyNode(), JumpType.LeaveTry); createReturnControlFlow(node, end);
private void copyFinallyBlocksIntoLeaveEdges() { // // Step 5b: Copy finally blocks into the LeaveTry edges. // for (int n = _nodes.size(), i = n - 1; i >= 0; i--) { final ControlFlowNode node = _nodes.get(i); final Instruction end = node.getEnd(); if (end != null && node.getOutgoing().size() == 1 && node.getOutgoing().get(0).getType() == JumpType.LeaveTry) { assert end.getOpCode() == OpCode.GOTO || end.getOpCode() == OpCode.GOTO_W; final ControlFlowEdge edge = node.getOutgoing().get(0); final ControlFlowNode target = edge.getTarget(); target.getIncoming().remove(edge); node.getOutgoing().clear(); final ControlFlowNode handler = findInnermostExceptionHandlerNode(end.getEndOffset()); assert handler.getNodeType() == ControlFlowNodeType.FinallyHandler; final ControlFlowNode copy = copyFinallySubGraph(handler, handler.getEndFinallyNode(), target); createEdge(node, copy, JumpType.Normal); } } }
public static ControlFlowGraph build(final List<Instruction> instructions, final List<ExceptionHandler> exceptionHandlers) { final ControlFlowGraphBuilder builder = new ControlFlowGraphBuilder( VerifyArgument.notNull(instructions, "instructions"), VerifyArgument.notNull(exceptionHandlers, "exceptionHandlers") ); return builder.build(); }
_cfg = ControlFlowGraphBuilder.build(instructions, handlers); _cfg.computeDominance(); _cfg.computeDominanceFrontier();
@SuppressWarnings("UnusedParameters") private void createReturnControlFlow(final ControlFlowNode node, final Instruction end) { // final ControlFlowNode handlerNode = findInnermostHandlerBlock(end.getOffset()); // final ControlFlowNode finallyNode; // // if (handlerNode.getNodeType() == ControlFlowNodeType.CatchHandler) { // finallyNode = findInnermostFinallyHandlerNode( // handlerNode.getExceptionHandler().getTryBlock().getLastInstruction().getOffset() // ); // } // else if (handlerNode.getNodeType() == ControlFlowNodeType.FinallyHandler) { // finallyNode = handlerNode; // } // else { // finallyNode = _exceptionalExit; // } // // if (finallyNode.getNodeType() == ControlFlowNodeType.FinallyHandler) { // createEdge(node, _regularExit, JumpType.LeaveTry); // } // else { createEdge(node, _regularExit, JumpType.Normal); // } }