boolean (ControlFlowGraph graph, CatchAllStatement fstat, Record information) { Set<BasicBlock> tryBlocks = getAllBasicBlocks(fstat.getFirst()); Set<BasicBlock> catchBlocks = getAllBasicBlocks(fstat.getHandler()); int finallyType = information.firstCode; Map<BasicBlock, Boolean> mapLast = information.mapLast; BasicBlock first = fstat.getHandler().getBasichead().getBlock(); boolean skippedFirst = false; if (finallyType == 3) { // empty finally removeExceptionInstructionsEx(first, 3, finallyType); if (mapLast.containsKey(first)) { graph.getFinallyExits().add(first); } return true; } else { if (first.getSeq().length() == 1 && finallyType > 0) { BasicBlock firstSuccessor = first.getSuccessors().get(0); if (catchBlocks.contains(firstSuccessor)) { first = firstSuccessor; skippedFirst = true; } } } // identify start blocks Set<BasicBlock> startBlocks = new HashSet<>(); for (BasicBlock block : tryBlocks) { startBlocks.addAll(block.getSuccessors()); } // `throw` in the `try` body will point directly to the dummy exit, so remove it startBlocks.remove(graph.getLast()); startBlocks.removeAll(tryBlocks); List<Area> areas = new ArrayList<>(); for (BasicBlock start : startBlocks) { Area arr = compareSubGraphsEx(graph, start, catchBlocks, first, finallyType, mapLast, skippedFirst); if (arr == null) { return false; } areas.add(arr); } // delete areas for (Area area : areas) { deleteArea(graph, area); } // INFO: Empty basic blocks may remain in the graph! for (Entry<BasicBlock, Boolean> entry : mapLast.entrySet()) { BasicBlock last = entry.getKey(); if (entry.getValue()) { removeExceptionInstructionsEx(last, 2, finallyType); graph.getFinallyExits().add(last); } } removeExceptionInstructionsEx(fstat.getHandler().getBasichead().getBlock(), 1, finallyType); return true; }