boolean (Statement general, HashMap<Integer, Set<Integer>> mapExtPost) { if (general.type == StatementType.ROOT) { Statement stat = general.getFirst(); if (stat.type != StatementType.GENERAL) { return true; } else { boolean complete = processStatement(stat, mapExtPost); if (complete) { // replace general purpose statement with simple one general.replaceStatement(stat, stat.getFirst()); } return complete; } } boolean mapRefreshed = mapExtPost.isEmpty(); for (int mapstage = 0; mapstage < 2; mapstage++) { for (int reducibility = 0; reducibility < 5; reducibility++) { // FIXME: implement proper node splitting. For now up to 5 nodes in sequence are splitted. if (reducibility > 0) { // take care of irreducible control flow graphs if (IrreducibleCFGDeobfuscator.isStatementIrreducible(general)) { if (!IrreducibleCFGDeobfuscator.splitIrreducibleNode(general)) { DecompilerContext.getLogger().writeMessage("Irreducible statement cannot be decomposed!", IFernflowerLogger.Severity.ERROR); break; } } else { if (mapRefreshed) { // last chance lost DecompilerContext.getLogger().writeMessage("Statement cannot be decomposed although reducible!", IFernflowerLogger.Severity.ERROR); } break; } mapExtPost = new HashMap<>(); mapRefreshed = true; } for (int i = 0; i < 2; i++) { boolean forceall = i != 0; while (true) { if (findSimpleStatements(general, mapExtPost)) { reducibility = 0; } if (general.type == StatementType.PLACEHOLDER) { return true; } Statement stat = findGeneralStatement(general, forceall, mapExtPost); if (stat != null) { boolean complete = processStatement(stat, general.getFirst() == stat ? mapExtPost : new HashMap<>()); if (complete) { // replace general purpose statement with simple one general.replaceStatement(stat, stat.getFirst()); } else { return false; } mapExtPost = new HashMap<>(); mapRefreshed = true; reducibility = 0; } else { break; } } } } if (mapRefreshed) { break; } else { mapExtPost = new HashMap<>(); } } return false; }