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 087229e50..8df9a4524 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 @@ -145,12 +145,58 @@ public class AVM2Graph extends Graph { @Override protected void beforePrintGraph(BaseLocalData localData, String path, Set allParts, List loops) { - Map> setLocalPosToGetLocalPos = calculateLocalRegsUsage(path, allParts); + Map ignoredSwitches = getIgnoredSwitches(allParts); + Map> setLocalPosToGetLocalPos = calculateLocalRegsUsage(new HashSet(ignoredSwitches.values()), path, allParts); AVM2LocalData avm2LocalData = ((AVM2LocalData) localData); avm2LocalData.setLocalPosToGetLocalPos = setLocalPosToGetLocalPos; + } - public Map> calculateLocalRegsUsage(String path, Set allParts) { + private Map getIgnoredSwitches(Set allParts) { + Map ignoredSwitches = new HashMap<>(); + int finStart; + for (int e = 0; e < body.exceptions.length; e++) { + if (body.exceptions[e].isFinally()) { + { + { + AVM2Instruction jmpIns = avm2code.code.get(code.adr2pos(avm2code.fixAddrAfterDebugLine(body.exceptions[e].end))); + + if (jmpIns.definition instanceof JumpIns) { + finStart = code.adr2pos(avm2code.fixAddrAfterDebugLine(body.exceptions[e].end) + jmpIns.getBytesLength() + jmpIns.operands[0]); + + GraphPart fpart = null; + for (GraphPart p : allParts) { + if (p.start == finStart) { + fpart = p; + break; + } + } + int swPos = -1; + for (int f = finStart; f < avm2code.code.size(); f++) { + if (avm2code.code.get(f).definition instanceof LookupSwitchIns) { + AVM2Instruction swins = avm2code.code.get(f); + if (swins.operands.length >= 3) { + if (swins.operands[0] == swins.getBytesLength()) { + if (code.adr2pos(code.pos2adr(f) + swins.operands[2]) < finStart) { + swPos = f; + + break; + } + } + } + } + } + ignoredSwitches.put(e, swPos); + break; + } + } + } + } + } + return ignoredSwitches; + } + + public Map> calculateLocalRegsUsage(Set ignoredSwitches, String path, Set allParts) { logger.fine("--- " + path + " ---"); Map> setLocalPosToGetLocalPos = new TreeMap<>(); Map>> partUnresolvedRegisterToGetLocalPos = new HashMap<>(); @@ -213,7 +259,7 @@ public class AVM2Graph extends Graph { Set visited = new HashSet<>(); visited.add(p); for (GraphPart q : p.refs) { - calculateLocalRegsUsageWalk(q, unresolvedRegisterToGetLocalPos, visited, partRegisterToLastSetLocalPos, setLocalPosToGetLocalPos); + calculateLocalRegsUsageWalk(ignoredSwitches, q, unresolvedRegisterToGetLocalPos, visited, partRegisterToLastSetLocalPos, setLocalPosToGetLocalPos, p); } } @@ -229,14 +275,19 @@ public class AVM2Graph extends Graph { return setLocalPosToGetLocalPos; } - public void calculateLocalRegsUsageWalk(GraphPart q, + public void calculateLocalRegsUsageWalk(Set ignoredSwitches, GraphPart q, Map> unresolvedRegisterToGetLocalPos, Set visited, Map> partRegisterToLastSetLocalPos, - Map> setLocalPosToGetLocalPos) { + Map> setLocalPosToGetLocalPos, GraphPart next) { if (visited.contains(q)) { return; } + if (ignoredSwitches.contains(q.end)) { + if (!next.equals(q.nextParts.get(0))) { //first is after finally + return; + } + } Set regIds = new HashSet<>(unresolvedRegisterToGetLocalPos.keySet()); for (int regId : regIds) { if (partRegisterToLastSetLocalPos.containsKey(q)) { @@ -255,7 +306,7 @@ public class AVM2Graph extends Graph { visited.add(q); for (GraphPart r : q.refs) { - calculateLocalRegsUsageWalk(r, unresolvedRegisterToGetLocalPos, visited, partRegisterToLastSetLocalPos, setLocalPosToGetLocalPos); + calculateLocalRegsUsageWalk(ignoredSwitches, r, unresolvedRegisterToGetLocalPos, visited, partRegisterToLastSetLocalPos, setLocalPosToGetLocalPos, q); } }