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();
if (jump.getOpCode().isJumpToSubroutine() ||
targetHandlerNode == handlerNode ||
(handler != null &&
(handler.getTryBlock().contains(jump) ? handler.getTryBlock().contains(target)
: handler.getHandlerBlock().contains(target)))) {
//
// A jump within a handler is normal control flow.
//
createEdge(node, target, JumpType.Normal);
return;
}
if (handlerNode.getNodeType() == ControlFlowNodeType.CatchHandler) {
//
// First look for an immediately adjacent finally handler.
//
ControlFlowNode finallyHandlerNode = findInnermostFinallyHandlerNode(handler.getTryBlock().getLastInstruction().getOffset());
final ExceptionHandler finallyHandler = finallyHandlerNode.getExceptionHandler();
final ExceptionHandler outerFinallyHandler = outerFinally.getExceptionHandler();
if (finallyHandlerNode.getNodeType() != ControlFlowNodeType.FinallyHandler ||
(outerFinally.getNodeType() == ControlFlowNodeType.FinallyHandler &&
finallyHandler.getTryBlock().contains(outerFinallyHandler.getHandlerBlock()))) {
//
// We don't have an adjacent finally handler, or our containing finally handler is
// protected by the adjacent finally handler's try block. Use the containing finally.
//