diff --git a/CHANGELOG.md b/CHANGELOG.md index ad4cff20a..72c5b52c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file. - #1633 AS3 decompilation - return in for..in clause - AS3 p-code/AS hilighting when outside trait - AS3 p-code/AS hilighting after p-code save +- Decompilation - Goto handling ### Removed - #1631 ActiveX Flash component download in windows installer diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java index 3a6f92677..4d5ce5387 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java @@ -91,6 +91,7 @@ import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.Loop; import com.jpexs.decompiler.graph.ScopeStack; +import com.jpexs.decompiler.graph.StopPartKind; import com.jpexs.decompiler.graph.ThrowState; import com.jpexs.decompiler.graph.TranslateStack; import com.jpexs.decompiler.graph.model.AnyItem; @@ -911,7 +912,7 @@ public class AVM2Graph extends Graph { } } - private boolean checkTry(List currentRet, List foundGotos, Map> partCodes, Map partCodePos, Set visited, AVM2LocalData localData, GraphPart part, List stopPart, List loops, List throwStates, Set allParts, TranslateStack stack, int staticOperation, String path, int recursionLevel) throws InterruptedException { + private boolean checkTry(List currentRet, List foundGotos, Map> partCodes, Map partCodePos, Set visited, AVM2LocalData localData, GraphPart part, List stopPart, List stopPartKind, List loops, List throwStates, Set allParts, TranslateStack stack, int staticOperation, String path, int recursionLevel) throws InterruptedException { if (localData.parsedExceptions == null) { localData.parsedExceptions = new ArrayList<>(); } @@ -1003,7 +1004,9 @@ public class AVM2Graph extends Graph { if (finallyException == null) { List stopPart2 = new ArrayList<>(stopPart); stopPart2.add(afterPart); - tryCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, part, stopPart2, loops, throwStates, staticOperation, path); + List stopPartKind2 = new ArrayList<>(stopPartKind); + stopPartKind2.add(StopPartKind.OTHER); + tryCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, part, stopPart2, stopPartKind2, loops, throwStates, staticOperation, path); } boolean inlinedFinally = false; @@ -1076,12 +1079,15 @@ public class AVM2Graph extends Graph { } List tryStopPart = new ArrayList<>(stopPart); + List tryStopPartKind = new ArrayList<>(stopPartKind); if (finallyPart != null) { tryStopPart.add(finallyPart); + tryStopPartKind.add(StopPartKind.OTHER); } if (defaultPart != null) { tryStopPart.add(defaultPart); + tryStopPartKind.add(StopPartKind.OTHER); } //switchPart == null && inlinedFinally && if (afterPart == null) { @@ -1090,6 +1096,7 @@ public class AVM2Graph extends Graph { if (afterPart != null) { tryStopPart.add(afterPart); + tryStopPartKind.add(StopPartKind.OTHER); } if (switchPart != null) { @@ -1104,9 +1111,10 @@ public class AVM2Graph extends Graph { if (localData.pushDefaultPart.containsKey(finallyIndex)) { exAfterPart = localData.pushDefaultPart.get(finallyIndex); tryStopPart.add(exAfterPart); + tryStopPartKind.add(StopPartKind.OTHER); } - tryCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, part, tryStopPart, loops, throwStates, staticOperation, path); + tryCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, part, tryStopPart, tryStopPartKind, loops, throwStates, staticOperation, path); makeAllCommands(tryCommands, stack); processIfs(tryCommands); @@ -1118,11 +1126,13 @@ public class AVM2Graph extends Graph { } List finallyStopPart = new ArrayList<>(stopPart); + List finallyStopPartKind = new ArrayList<>(stopPartKind); if (switchPart != null) { finallyStopPart.add(switchPart); + finallyStopPartKind.add(StopPartKind.OTHER); } if (finallyPart != null) { - finallyCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, finallyPart, finallyStopPart, loops, throwStates, staticOperation, path); + finallyCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, finallyPart, finallyStopPart, finallyStopPartKind, loops, throwStates, staticOperation, path); } if (switchPart != null) { finallyCommands.addAll(translatePart(localData, switchPart, stack, staticOperation, path)); @@ -1147,12 +1157,14 @@ public class AVM2Graph extends Graph { localData2.scopeStack = new ScopeStack(); List stopPart2 = new ArrayList<>(stopPart); + List stopPartKind2 = new ArrayList<>(stopPartKind); stopPart2.add(exAfterPart); if (defaultPart != null) { stopPart2.add(defaultPart); + stopPartKind2.add(StopPartKind.OTHER); } - List currentCatchCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData2, st2, allParts, null, catchPart, stopPart2, loops, throwStates, staticOperation, path); + List currentCatchCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData2, st2, allParts, null, catchPart, stopPart2, stopPartKind2, loops, throwStates, staticOperation, path); /*if (!currentCatchCommands.isEmpty() && (currentCatchCommands.get(0) instanceof SetLocalAVM2Item)) { if (currentCatchCommands.get(0).value.getNotCoerced() instanceof ExceptionAVM2Item) { currentCatchCommands.remove(0); @@ -1317,7 +1329,7 @@ public class AVM2Graph extends Graph { if (finallyIndex > -1 && localData.finallyIndicesWithDoublePush.contains(finallyIndex)) { stack.push(new AnyItem()); } - printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, afterPart, stopPart, loops, throwStates, currentRet, staticOperation, path, recursionLevel); + printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, afterPart, stopPart, stopPartKind, loops, throwStates, currentRet, staticOperation, path, recursionLevel); } return true; } @@ -1378,13 +1390,13 @@ public class AVM2Graph extends Graph { } @Override - protected boolean checkPartOutput(List currentRet, List foundGotos, Map> partCodes, Map partCodePos, Set visited, GraphSource code, BaseLocalData localData, Set allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List loops, List throwStates, Loop currentLoop, int staticOperation, String path, int recursionLevel) throws InterruptedException { + protected boolean checkPartOutput(List currentRet, List foundGotos, Map> partCodes, Map partCodePos, Set visited, GraphSource code, BaseLocalData localData, Set allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List stopPartKind, List loops, List throwStates, Loop currentLoop, int staticOperation, String path, int recursionLevel) throws InterruptedException { AVM2LocalData aLocalData = (AVM2LocalData) localData; - return checkTry(currentRet, foundGotos, partCodes, partCodePos, visited, aLocalData, part, stopPart, loops, throwStates, allParts, stack, staticOperation, path, recursionLevel); + return checkTry(currentRet, foundGotos, partCodes, partCodePos, visited, aLocalData, part, stopPart, stopPartKind, loops, throwStates, allParts, stack, staticOperation, path, recursionLevel); } @Override - protected List check(List currentRet, List foundGotos, Map> partCodes, Map partCodePos, Set visited, GraphSource code, BaseLocalData localData, Set allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List loops, List throwStates, List output, Loop currentLoop, int staticOperation, String path) throws InterruptedException { + protected List check(List currentRet, List foundGotos, Map> partCodes, Map partCodePos, Set visited, GraphSource code, BaseLocalData localData, Set allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List stopPartKind, List loops, List throwStates, List output, Loop currentLoop, int staticOperation, String path) throws InterruptedException { List ret = null; /*if (ret != null) { @@ -1478,7 +1490,7 @@ public class AVM2Graph extends Graph { Reference nextRef = new Reference<>(null); Reference tiRef = new Reference<>(null); - SwitchItem sw = handleSwitch(switchedObject, switchStartItem, foundGotos, partCodes, partCodePos, visited, allParts, stack, stopPart, loops, throwStates, localData, staticOperation, path, caseValuesMap, defaultPart, caseBodyParts, nextRef, tiRef); + SwitchItem sw = handleSwitch(switchedObject, switchStartItem, foundGotos, partCodes, partCodePos, visited, allParts, stack, stopPart, stopPartKind, loops, throwStates, localData, staticOperation, path, caseValuesMap, defaultPart, caseBodyParts, nextRef, tiRef); ret = new ArrayList<>(); ret.addAll(output); checkSwitch(localData, sw, otherSide, ret.isEmpty() ? currentRet : ret /*hack :-(*/); @@ -1487,7 +1499,7 @@ public class AVM2Graph extends Graph { if (tiRef.getVal() != null) { ret.add(tiRef.getVal()); } else { - ret.addAll(printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, nextRef.getVal(), stopPart, loops, throwStates, staticOperation, path)); + ret.addAll(printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, nextRef.getVal(), stopPart, stopPartKind, loops, throwStates, staticOperation, path)); } } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionGraph.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionGraph.java index a52575955..d95bdb564 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionGraph.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionGraph.java @@ -48,6 +48,7 @@ import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphSourceItemContainer; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.Loop; +import com.jpexs.decompiler.graph.StopPartKind; import com.jpexs.decompiler.graph.ThrowState; import com.jpexs.decompiler.graph.TranslateStack; import com.jpexs.decompiler.graph.model.BreakItem; @@ -290,7 +291,7 @@ public class ActionGraph extends Graph { } @Override - protected List check(List currentRet, List foundGotos, Map> partCodes, Map partCodePos, Set visited, GraphSource code, BaseLocalData localData, Set allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List loops, List throwStates, List output, Loop currentLoop, int staticOperation, String path) throws InterruptedException { + protected List check(List currentRet, List foundGotos, Map> partCodes, Map partCodePos, Set visited, GraphSource code, BaseLocalData localData, Set allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List stopPartKind, List loops, List throwStates, List output, Loop currentLoop, int staticOperation, String path) throws InterruptedException { if (!output.isEmpty()) { if (output.get(output.size() - 1) instanceof StoreRegisterActionItem) { StoreRegisterActionItem str = (StoreRegisterActionItem) output.get(output.size() - 1); @@ -347,7 +348,7 @@ public class ActionGraph extends Graph { Reference nextRef = new Reference<>(null); Reference tiRef = new Reference<>(null); - SwitchItem sw = handleSwitch(switchedObject, switchStartItem, foundGotos, partCodes, partCodePos, visited, allParts, stack, stopPart, loops, throwStates, localData, staticOperation, path, caseValuesMap, defaultPart, caseBodyParts, nextRef, tiRef); + SwitchItem sw = handleSwitch(switchedObject, switchStartItem, foundGotos, partCodes, partCodePos, visited, allParts, stack, stopPart, stopPartKind, loops, throwStates, localData, staticOperation, path, caseValuesMap, defaultPart, caseBodyParts, nextRef, tiRef); ret = new ArrayList<>(); ret.addAll(output); ret.add(sw); @@ -355,7 +356,7 @@ public class ActionGraph extends Graph { if (tiRef.getVal() != null) { ret.add(tiRef.getVal()); } else { - ret.addAll(printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, nextRef.getVal(), stopPart, loops, throwStates, staticOperation, path)); + ret.addAll(printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, nextRef.getVal(), stopPart, stopPartKind, loops, throwStates, staticOperation, path)); } } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java index 0c3eaa672..965646c6b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java @@ -100,10 +100,6 @@ public class Graph { return new LinkedHashMap<>(); } - protected List filter(List list) { - return new ArrayList<>(list); - } - public Graph(GraphSource code, List exceptions) { this.code = code; this.exceptions = exceptions; @@ -539,7 +535,7 @@ public class Graph { System.err.println("");//*/ List gotos = new ArrayList<>(); - List ret = printGraph(gotos, new HashMap<>(), new HashMap<>(), new HashSet<>(), localData, stack, allParts, null, heads.get(0), null, loops, throwStates, staticOperation, path); + List ret = printGraph(gotos, new HashMap<>(), new HashMap<>(), new HashSet<>(), localData, stack, allParts, null, heads.get(0), null, null, loops, throwStates, staticOperation, path); processIfGotos(gotos, ret); @@ -832,6 +828,28 @@ public class Graph { } if (item instanceof IfItem) { IfItem ii = (IfItem) item; + if (!ii.onTrue.isEmpty() && ii.onFalse.isEmpty()) { + if (ii.onTrue.get(ii.onTrue.size() - 1) instanceof GotoItem) { + if (i + 1 < list.size()) { + if (list.get(i + 1) instanceof GotoItem) { + GotoItem g1 = (GotoItem) ii.onTrue.get(ii.onTrue.size() - 1); + GotoItem g2 = (GotoItem) list.get(i + 1); + if (g1.labelName.equals(g2.labelName)) { + ii.onTrue.remove(ii.onTrue.size() - 1); + } + } + } + } + } + if (!ii.onTrue.isEmpty() && !ii.onFalse.isEmpty()) { + if (ii.onTrue.get(ii.onTrue.size() - 1) instanceof GotoItem) { + if (ii.onFalse.get(ii.onFalse.size() - 1) instanceof GotoItem) { + for (int j = i + 1; j < list.size(); j++) { + list.remove(i + 1); + } + } + } + } if (!ii.onTrue.isEmpty() && !ii.onFalse.isEmpty()) { if (ii.onTrue.get(ii.onTrue.size() - 1) instanceof GotoItem) { if (ii.onFalse.get(ii.onFalse.size() - 1) instanceof GotoItem) { @@ -1062,7 +1080,7 @@ public class Graph { return false; } - protected List check(List currentRet, List foundGotos, Map> partCodes, Map partCodePos, Set visited, GraphSource code, BaseLocalData localData, Set allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List loops, List throwStates, List output, Loop currentLoop, int staticOperation, String path) throws InterruptedException { + protected List check(List currentRet, List foundGotos, Map> partCodes, Map partCodePos, Set visited, GraphSource code, BaseLocalData localData, Set allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List stopPartKind, List loops, List throwStates, List output, Loop currentLoop, int staticOperation, String path) throws InterruptedException { return null; } @@ -1142,8 +1160,8 @@ public class Graph { list.remove(list.size() - 1); } - protected List printGraph(List foundGotos, Map> partCodes, Map partCodePos, Set visited, BaseLocalData localData, TranslateStack stack, Set allParts, GraphPart parent, GraphPart part, List stopPart, List loops, List throwStates, int staticOperation, String path) throws InterruptedException { - return printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, parent, part, stopPart, loops, throwStates, null, staticOperation, path, 0); + protected List printGraph(List foundGotos, Map> partCodes, Map partCodePos, Set visited, BaseLocalData localData, TranslateStack stack, Set allParts, GraphPart parent, GraphPart part, List stopPart, List stopPartKind, List loops, List throwStates, int staticOperation, String path) throws InterruptedException { + return printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, parent, part, stopPart, stopPartKind, loops, throwStates, null, staticOperation, path, 0); } protected GraphTargetItem checkLoop(List output, LoopItem loopItem, BaseLocalData localData, List loops, List throwStates) { @@ -1590,7 +1608,7 @@ public class Graph { return part.nextParts; } - protected boolean checkPartOutput(List currentRet, List foundGotos, Map> partCodes, Map partCodePos, Set visited, GraphSource code, BaseLocalData localData, Set allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List loops, List throwStates, Loop currentLoop, int staticOperation, String path, int recursionLevel) throws InterruptedException { + protected boolean checkPartOutput(List currentRet, List foundGotos, Map> partCodes, Map partCodePos, Set visited, GraphSource code, BaseLocalData localData, Set allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List stopPartKind, List loops, List throwStates, Loop currentLoop, int staticOperation, String path, int recursionLevel) throws InterruptedException { return false; } @@ -1619,13 +1637,16 @@ public class Graph { return true; } - protected List printGraph(List foundGotos, Map> partCodes, Map partCodePos, Set visited, BaseLocalData localData, TranslateStack stack, Set allParts, GraphPart parent, GraphPart part, List stopPart, List loops, List throwStates, List ret, int staticOperation, String path, int recursionLevel) throws InterruptedException { + protected List printGraph(List foundGotos, Map> partCodes, Map partCodePos, Set visited, BaseLocalData localData, TranslateStack stack, Set allParts, GraphPart parent, GraphPart part, List stopPart, List stopPartKind, List loops, List throwStates, List ret, int staticOperation, String path, int recursionLevel) throws InterruptedException { if (Thread.currentThread().isInterrupted()) { throw new InterruptedException(); } if (stopPart == null) { stopPart = new ArrayList<>(); } + if (stopPartKind == null) { + stopPartKind = new ArrayList<>(); + } if (recursionLevel > allParts.size() + 1) { throw new TranslateException("printGraph max recursion level reached."); } @@ -1743,13 +1764,31 @@ public class Graph { } if (stopPart.contains(part)) { - if (currentLoop != null) { - currentLoop.phase = 0; + + boolean hasBlockClosesAfter = false; + loopi: + for (int i = 0; i < stopPartKind.size(); i++) { + if (stopPart.get(i) == part) { + for (int j = i + 1; j < stopPartKind.size(); j++) { + if (stopPart.get(j) != part) { + if (stopPartKind.get(j) == StopPartKind.BLOCK_CLOSE) { + hasBlockClosesAfter = true; + break loopi; + } + } + } + } } - if (debugPrintGraph) { - System.err.println("Stopped on part " + part); + + if (!hasBlockClosesAfter) { + if (currentLoop != null) { + currentLoop.phase = 0; + } + if (debugPrintGraph) { + System.err.println("Stopped on part " + part); + } + return ret; } - return ret; } if (code.size() <= part.start) { @@ -1805,7 +1844,7 @@ public class Graph { //****************************DECOMPILING PART************* List output = new ArrayList<>(); - if (checkPartOutput(currentRet, foundGotos, partCodes, partCodePos, visited, code, localData, allParts, stack, parent, part, stopPart, loops, throwStates, currentLoop, staticOperation, path, recursionLevel)) { + if (checkPartOutput(currentRet, foundGotos, partCodes, partCodePos, visited, code, localData, allParts, stack, parent, part, stopPart, stopPartKind, loops, throwStates, currentLoop, staticOperation, path, recursionLevel)) { parseNext = false; } else { output.addAll(code.translatePart(part, localData, stack, part.start, part.end, staticOperation, path)); @@ -1815,7 +1854,7 @@ public class Graph { } if (parseNext) { - List retCheck = check(currentRet, foundGotos, partCodes, partCodePos, visited, code, localData, allParts, stack, parent, part, stopPart, loops, throwStates, output, currentLoop, staticOperation, path); + List retCheck = check(currentRet, foundGotos, partCodes, partCodePos, visited, code, localData, allParts, stack, parent, part, stopPart, stopPartKind, loops, throwStates, output, currentLoop, staticOperation, path); if (retCheck != null) { if (!retCheck.isEmpty()) { currentRet.addAll(retCheck); @@ -1983,7 +2022,7 @@ public class Graph { } Reference nextRef = new Reference<>(null); Reference tiRef = new Reference<>(null); - SwitchItem sw = handleSwitch(switchedItem, originalSwitchedItem.getSrc(), foundGotos, partCodes, partCodePos, visited, allParts, stack, stopPart, loops, throwStates, localData, staticOperation, path, + SwitchItem sw = handleSwitch(switchedItem, originalSwitchedItem.getSrc(), foundGotos, partCodes, partCodePos, visited, allParts, stack, stopPart, stopPartKind, loops, throwStates, localData, staticOperation, path, caseValues, defaultPart, caseBodyParts, nextRef, tiRef); GraphPart next = nextRef.getVal(); checkSwitch(localData, sw, caseExpressionOtherSides.values(), currentRet); @@ -1992,7 +2031,7 @@ public class Graph { if (tiRef.getVal() != null) { ret.add(tiRef.getVal()); } else { - currentRet.addAll(printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, part, next, stopPart, loops, throwStates, null, staticOperation, path, recursionLevel + 1)); + printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, part, next, stopPart, stopPartKind, loops, throwStates, currentRet, staticOperation, path, recursionLevel + 1); } } pos++; @@ -2031,19 +2070,21 @@ public class Graph { boolean hasOnFalse = nps.get(0) != next; List stopPart2 = new ArrayList<>(stopPart); + List stopPartKind2 = new ArrayList<>(stopPartKind); if ((!isEmpty) && (next != null)) { stopPart2.add(next); + stopPartKind2.add(StopPartKind.BLOCK_CLOSE); } List onTrue = new ArrayList<>(); if (!isEmpty && hasOntrue) { - onTrue = printGraph(foundGotos, partCodes, partCodePos, visited, prepareBranchLocalData(localData), trueStack, allParts, part, nps.get(1), stopPart2, loops, throwStates, null, staticOperation, path, recursionLevel + 1); + onTrue = printGraph(foundGotos, partCodes, partCodePos, visited, prepareBranchLocalData(localData), trueStack, allParts, part, nps.get(1), stopPart2, stopPartKind2, loops, throwStates, null, staticOperation, path, recursionLevel + 1); } List onFalse = new ArrayList<>(); if (!isEmpty && hasOnFalse) { - onFalse = printGraph(foundGotos, partCodes, partCodePos, visited, prepareBranchLocalData(localData), falseStack, allParts, part, nps.get(0), stopPart2, loops, throwStates, null, staticOperation, path, recursionLevel + 1); + onFalse = printGraph(foundGotos, partCodes, partCodePos, visited, prepareBranchLocalData(localData), falseStack, allParts, part, nps.get(0), stopPart2, stopPartKind2, loops, throwStates, null, staticOperation, path, recursionLevel + 1); } //List out2 = new ArrayList<>(); //makeAllCommands(out2, stack); @@ -2062,8 +2103,8 @@ public class Graph { } } - List filteredOnTrue = filter(onTrue); - List filteredOnFalse = filter(onFalse); + List filteredOnTrue = onTrue; + List filteredOnFalse = onFalse; if (!isEmpty(filteredOnTrue) && !isEmpty(filteredOnFalse) && filteredOnTrue.size() == 1 && filteredOnFalse.size() == 1 && (filteredOnTrue.get(0) instanceof PushItem) && (filteredOnFalse.get(0) instanceof PushItem)) { stack.push(new TernarOpItem(null, localData.lineStartInstruction, expr.invert(null), ((PushItem) filteredOnTrue.get(0)).value, ((PushItem) filteredOnFalse.get(0)).value)); @@ -2148,7 +2189,7 @@ public class Graph { } //currentRet.addAll(out2); if (next != null) { - printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, part, next, stopPart, loops, throwStates, currentRet, staticOperation, path, recursionLevel + 1); + printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, part, next, stopPart, stopPartKind, loops, throwStates, currentRet, staticOperation, path, recursionLevel + 1); //currentRet.addAll(); } } @@ -2162,7 +2203,7 @@ public class Graph { } if (nextOnePart != null) { - printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, part, getNextParts(localData, part).get(0), stopPart, loops, throwStates, currentRet, staticOperation, path, recursionLevel + 1); + printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, part, getNextParts(localData, part).get(0), stopPart, stopPartKind, loops, throwStates, currentRet, staticOperation, path, recursionLevel + 1); } } @@ -2185,9 +2226,11 @@ public class Graph { if (currentLoop.loopPreContinue != null) { List stopContPart = new ArrayList<>(); stopContPart.add(currentLoop.loopContinue); + List stopContPartKind = new ArrayList<>(); + stopContPartKind.add(StopPartKind.OTHER); GraphPart precoBackup = currentLoop.loopPreContinue; currentLoop.loopPreContinue = null; - loopItem.commands.addAll(printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, precoBackup, stopContPart, loops, throwStates, null, staticOperation, path, recursionLevel + 1)); + printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, precoBackup, stopContPart, stopContPartKind, loops, throwStates, loopItem.commands, staticOperation, path, recursionLevel + 1); checkContinueAtTheEnd(loopItem.commands, currentLoop); } } @@ -2252,7 +2295,9 @@ public class Graph { currentLoop.loopPreContinue = null; List stopPart2 = new ArrayList<>(stopPart); stopPart2.add(currentLoop.loopContinue); - List precoCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData, new TranslateStack(path), allParts, null, backup, stopPart2, loops, throwStates, null, staticOperation, path, recursionLevel + 1); + List stopPartKind2 = new ArrayList<>(stopPartKind); + stopPartKind2.add(StopPartKind.OTHER); + List precoCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData, new TranslateStack(path), allParts, null, backup, stopPart2, stopPartKind2, loops, throwStates, null, staticOperation, path, recursionLevel + 1); currentLoop.loopPreContinue = backup; checkContinueAtTheEnd(precoCommands, currentLoop); @@ -2345,7 +2390,9 @@ public class Graph { currentLoop.loopPreContinue = null; List stopPart2 = new ArrayList<>(stopPart); stopPart2.add(currentLoop.loopContinue); - List finalComm = printGraph(foundGotos, partCodes, partCodePos, visited, localData, new TranslateStack(path), allParts, null, backup, stopPart2, loops, throwStates, null, staticOperation, path, recursionLevel + 1); + List stopPartKind2 = new ArrayList<>(stopPartKind); + stopPartKind2.add(StopPartKind.OTHER); + List finalComm = printGraph(foundGotos, partCodes, partCodePos, visited, localData, new TranslateStack(path), allParts, null, backup, stopPart2, stopPartKind2, loops, throwStates, null, staticOperation, path, recursionLevel + 1); currentLoop.loopPreContinue = backup; checkContinueAtTheEnd(finalComm, currentLoop); @@ -2395,7 +2442,7 @@ public class Graph { } if (currentLoop.loopBreak != null) { - ret.addAll(printGraph(foundGotos, partCodes, partCodePos, visited, localData, sPreLoop, allParts, part, currentLoop.loopBreak, stopPart, loops, throwStates, null, staticOperation, path, recursionLevel + 1)); + printGraph(foundGotos, partCodes, partCodePos, visited, localData, sPreLoop, allParts, part, currentLoop.loopBreak, stopPart, stopPartKind, loops, throwStates, ret, staticOperation, path, recursionLevel + 1); } } @@ -2682,7 +2729,7 @@ public class Graph { } protected SwitchItem handleSwitch(GraphTargetItem switchedObject, - GraphSourceItem switchStartItem, List foundGotos, Map> partCodes, Map partCodePos, Set visited, Set allParts, TranslateStack stack, List stopPart, List loops, List throwStates, BaseLocalData localData, int staticOperation, String path, + GraphSourceItem switchStartItem, List foundGotos, Map> partCodes, Map partCodePos, Set visited, Set allParts, TranslateStack stack, List stopPart, List stopPartKind, List loops, List throwStates, BaseLocalData localData, int staticOperation, String path, List caseValuesMap, GraphPart defaultPart, List caseBodyParts, Reference nextRef, Reference tiRef) throws InterruptedException { boolean hasDefault = false; /* @@ -2819,15 +2866,18 @@ public class Graph { } List stopPart2x = new ArrayList<>(stopPart); + List stopPartKind2x = new ArrayList<>(stopPartKind); for (GraphPart b : caseBodies) { if (b != caseBodies.get(i)) { stopPart2x.add(b); + stopPartKind2x.add(StopPartKind.OTHER); } } if (breakPart != null) { stopPart2x.add(breakPart); + stopPartKind2x.add(StopPartKind.OTHER); } - currentCaseCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, caseBodies.get(i), stopPart2x, loops, throwStates, staticOperation, path); + currentCaseCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, caseBodies.get(i), stopPart2x, stopPartKind2x, loops, throwStates, staticOperation, path); if (willHaveBreak) { if (!currentCaseCommands.isEmpty()) { GraphTargetItem last = currentCaseCommands.get(currentCaseCommands.size() - 1); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/StopPartKind.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/StopPartKind.java new file mode 100644 index 000000000..1af77276e --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/StopPartKind.java @@ -0,0 +1,10 @@ +package com.jpexs.decompiler.graph; + +/** + * + * @author JPEXS + */ +public enum StopPartKind { + BLOCK_CLOSE, + OTHER +}