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 b7f75d13c..29924ad11 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 @@ -77,8 +77,10 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; /** * @@ -136,7 +138,7 @@ public class AVM2Graph extends Graph { localData.refs = refs; localData.code = code; g.init(localData); - List allParts = new ArrayList<>(); + Set allParts = new HashSet<>(); for (GraphPart head : g.heads) { populateParts(head, allParts); } @@ -166,7 +168,7 @@ public class AVM2Graph extends Graph { } @Override - protected List check(Map> partCodes, Map partCodePos, GraphSource code, BaseLocalData localData, List allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List loops, List output, Loop currentLoop, int staticOperation, String path) throws InterruptedException { + protected List check(Map> partCodes, Map partCodePos, GraphSource code, BaseLocalData localData, Set allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List loops, List output, Loop currentLoop, int staticOperation, String path) throws InterruptedException { List ret = null; AVM2LocalData aLocalData = (AVM2LocalData) localData; @@ -649,7 +651,7 @@ public class AVM2Graph extends Graph { } @Override - protected GraphPart checkPart(TranslateStack stack, BaseLocalData localData, GraphPart next, List allParts) { + protected GraphPart checkPart(TranslateStack stack, BaseLocalData localData, GraphPart next, Set allParts) { AVM2LocalData aLocalData = (AVM2LocalData) localData; Map> finallyJumps = aLocalData.finallyJumps; Map ignoredSwitches = aLocalData.ignoredSwitches; 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 2292f5ed1..41e542faf 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 @@ -53,6 +53,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; /** * @@ -248,7 +249,7 @@ public class ActionGraph extends Graph { } @Override - protected List check(Map> partCodes, Map partCodePos, GraphSource code, BaseLocalData localData, List allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List loops, List output, Loop currentLoop, int staticOperation, String path) throws InterruptedException { + protected List check(Map> partCodes, Map partCodePos, GraphSource code, BaseLocalData localData, Set allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List loops, 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); 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 60af2072e..de430e94e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java @@ -75,13 +75,13 @@ public class Graph { * Identify loop exits * * @param localData - * @param N All nodes + * @param allParts All nodes * @return */ - public Map> identifyLoopBreaks(BaseLocalData localData, List N) { + public Map> identifyLoopBreaks(BaseLocalData localData, Set allParts) { Map> lb = new HashMap<>(); - for (GraphPart b0 : N) { + for (GraphPart b0 : allParts) { List np = new ArrayList<>(b0.nextParts); np.addAll(b0.throwParts); for (GraphPart b : np) { @@ -107,10 +107,10 @@ public class Graph { * @param localData * @param loopContinues Result - list of loop headers * @param heads Entries - * @param N All Nodes + * @param appParts All Nodes */ - public void identifyLoops(BaseLocalData localData, List loopContinues, List heads, List N) { - for (GraphPart b : N) { + public void identifyLoops(BaseLocalData localData, List loopContinues, List heads, Set appParts) { + for (GraphPart b : appParts) { b.traversed = false; b.DFSP_pos = 0; b.irreducible = false; @@ -169,7 +169,7 @@ public class Graph { folParts.addAll(b0.throwParts); b0.traversed = true; - b0.DFSP_pos = DFSP_pos; //Mark b0’s position in DFSP + b0.DFSP_pos = DFSP_pos; //Mark b0’s position in DFSP for (GraphPart b : folParts) { b = checkPart(null, localData, b, null); if (b == null) { @@ -180,7 +180,7 @@ public class Graph { GraphPart nh = trav_loops_DFS(localData, loopHeaders, b, DFSP_pos + 1); tag_lhead(b0, nh); } else { - if (b.DFSP_pos > 0) { // b in DFSP(b0) + if (b.DFSP_pos > 0) { // b in DFSP(b0) //case (B) if (b.type != GraphPart.TYPE_LOOP_HEADER) { b.type = GraphPart.TYPE_LOOP_HEADER; @@ -194,7 +194,7 @@ public class Graph { if (h.DFSP_pos > 0) { // h in DFSP(b0) //case (D) tag_lhead(b0, h); - } else { // h not in DFSP(b0) + } else { // h not in DFSP(b0) //case (E), reentry b.type = GraphPart.TYPE_REENTRY; //TODO:and b0,b ? h.irreducible = true; @@ -233,7 +233,7 @@ public class Graph { } } - protected static void populateParts(GraphPart part, List allParts) { + protected static void populateParts(GraphPart part, Set allParts) { if (allParts.contains(part)) { return; } @@ -243,40 +243,43 @@ public class Graph { } } - public GraphPart deepCopy(GraphPart part, List visited, List copies) { - if (visited == null) { - visited = new ArrayList<>(); + public GraphPart deepCopy(GraphPart part) { + return deepCopy(part, new HashMap<>()); + } + + private GraphPart deepCopy(GraphPart part, Map copies) { + GraphPart copy = copies.get(part); + if (copy != null) { + return copy; } - if (copies == null) { - copies = new ArrayList<>(); - } - if (visited.contains(part)) { - return copies.get(visited.indexOf(part)); - } - visited.add(part); - GraphPart copy = new GraphPart(part.start, part.end); + + copy = new GraphPart(part.start, part.end); copy.path = part.path; - copies.add(copy); + copies.put(part, copy); copy.nextParts = new ArrayList<>(); for (int i = 0; i < part.nextParts.size(); i++) { - copy.nextParts.add(deepCopy(part.nextParts.get(i), visited, copies)); + copy.nextParts.add(deepCopy(part.nextParts.get(i), copies)); } + for (int i = 0; i < part.refs.size(); i++) { - copy.refs.add(deepCopy(part.refs.get(i), visited, copies)); + copy.refs.add(deepCopy(part.refs.get(i), copies)); } + return copy; } - public void resetGraph(GraphPart part, List visited) { + public void resetGraph(GraphPart part, Set visited) { if (visited.contains(part)) { return; } + visited.add(part); int pos = 0; for (GraphPart p : part.nextParts) { if (!visited.contains(p)) { p.path = part.path.sub(pos, p.end); } + resetGraph(p, visited); pos++; } @@ -567,7 +570,7 @@ public class Graph { } public List translate(BaseLocalData localData, int staticOperation, String path) throws InterruptedException { - List allParts = new ArrayList<>(); + Set allParts = new HashSet<>(); for (GraphPart head : heads) { populateParts(head, allParts); } @@ -919,11 +922,11 @@ public class Graph { return false; } - protected List check(Map> partCodes, Map partCodePos, GraphSource code, BaseLocalData localData, List allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List loops, List output, Loop currentLoop, int staticOperation, String path) throws InterruptedException { + protected List check(Map> partCodes, Map partCodePos, GraphSource code, BaseLocalData localData, Set allParts, TranslateStack stack, GraphPart parent, GraphPart part, List stopPart, List loops, List output, Loop currentLoop, int staticOperation, String path) throws InterruptedException { return null; } - protected GraphPart checkPart(TranslateStack stack, BaseLocalData localData, GraphPart part, List allParts) { + protected GraphPart checkPart(TranslateStack stack, BaseLocalData localData, GraphPart part, Set allParts) { return part; } @@ -995,9 +998,8 @@ public class Graph { list.remove(list.size() - 1); } - protected List printGraph(Map> partCodes, Map partCodePos, BaseLocalData localData, TranslateStack stack, List allParts, GraphPart parent, GraphPart part, List stopPart, List loops, int staticOperation, String path) throws InterruptedException { - List visited = new ArrayList<>(); - return printGraph(partCodes, partCodePos, visited, localData, stack, allParts, parent, part, stopPart, loops, null, staticOperation, path, 0); + protected List printGraph(Map> partCodes, Map partCodePos, BaseLocalData localData, TranslateStack stack, Set allParts, GraphPart parent, GraphPart part, List stopPart, List loops, int staticOperation, String path) throws InterruptedException { + return printGraph(partCodes, partCodePos, new HashSet<>(), localData, stack, allParts, parent, part, stopPart, loops, null, staticOperation, path, 0); } protected GraphTargetItem checkLoop(LoopItem loopItem, BaseLocalData localData, List loops) { @@ -1005,7 +1007,7 @@ public class Graph { } //TODO: Make this faster!!! - private void getPrecontinues(String path, BaseLocalData localData, GraphPart parent, GraphPart part, List allParts, List loops, List stopPart) throws InterruptedException { + private void getPrecontinues(String path, BaseLocalData localData, GraphPart parent, GraphPart part, Set allParts, List loops, List stopPart) throws InterruptedException { try { markLevels(path, localData, part, allParts, loops); } catch (ThreadDeath | InterruptedException iex) { @@ -1063,13 +1065,13 @@ public class Graph { clearLoops(loops);*/ } - private void markLevels(String path, BaseLocalData localData, GraphPart part, List allParts, List loops) throws InterruptedException { + private void markLevels(String path, BaseLocalData localData, GraphPart part, Set allParts, List loops) throws InterruptedException { clearLoops(loops); - markLevels(path, localData, part, allParts, loops, new ArrayList<>(), 1, new ArrayList<>(), 0); + markLevels(path, localData, part, allParts, loops, new ArrayList<>(), 1, new HashSet<>(), 0); clearLoops(loops); } - private void markLevels(String path, BaseLocalData localData, GraphPart part, List allParts, List loops, List stopPart, int level, List visited, int recursionLevel) throws InterruptedException { + private void markLevels(String path, BaseLocalData localData, GraphPart part, Set allParts, List loops, List stopPart, int level, Set visited, int recursionLevel) throws InterruptedException { boolean debugMode = false; if (stopPart == null) { stopPart = new ArrayList<>(); @@ -1499,7 +1501,7 @@ public class Graph { } } - protected List printGraph(Map> partCodes, Map partCodePos, List visited, BaseLocalData localData, TranslateStack stack, List allParts, GraphPart parent, GraphPart part, List stopPart, List loops, List ret, int staticOperation, String path, int recursionLevel) throws InterruptedException { + protected List printGraph(Map> partCodes, Map partCodePos, Set visited, BaseLocalData localData, TranslateStack stack, Set allParts, GraphPart parent, GraphPart part, List stopPart, List loops, List ret, int staticOperation, String path, int recursionLevel) throws InterruptedException { if (Thread.currentThread().isInterrupted()) { throw new InterruptedException(); }