BasicBlock (ControlFlowGraph graph, Set<BasicBlock[]> setNext) { // precondition: there is at most one true exit path in the `finally` statement BasicBlock next = null; boolean multiple = false; for (BasicBlock[] arr : setNext) { if (arr[2] != null) { next = arr[1]; multiple = false; break; } else { if (next == null) { next = arr[1]; } else if (next != arr[1]) { multiple = true; } if (arr[1].getPredecessors().size() == 1) { next = arr[1]; } } } if (multiple) { // TODO: generic solution for (BasicBlock[] arr : setNext) { BasicBlock block = arr[1]; if (block != next) { if (InterpreterUtil.equalSets(next.getSuccessors(), block.getSuccessors())) { InstructionSequence seqNext = next.getSeq(); InstructionSequence seqBlock = block.getSeq(); if (seqNext.length() == seqBlock.length()) { for (int i = 0; i < seqNext.length(); i++) { Instruction instrNext = seqNext.getInstr(i); Instruction instrBlock = seqBlock.getInstr(i); if (!Instruction.equals(instrNext, instrBlock)) { return null; } for (int j = 0; j < instrNext.operandsCount(); j++) { if (instrNext.operand(j) != instrBlock.operand(j)) { return null; } } } } else { return null; } } else { return null; } } } for (BasicBlock[] arr : setNext) { if (arr[1] != next) { // FIXME: exception edge possible? arr[0].removeSuccessor(arr[1]); arr[0].addSuccessor(next); } } DeadCodeHelper.removeDeadBlocks(graph); } return next; }