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 ae3ec91f4..8e8a54263 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 @@ -169,7 +169,6 @@ public class AVM2Graph extends Graph { return true; } - @Override protected void beforeGetLoops(BaseLocalData localData, String path, Set allParts, List throwStates) throws InterruptedException { AVM2LocalData avm2LocalData = ((AVM2LocalData) localData); @@ -308,34 +307,35 @@ public class AVM2Graph extends Graph { } } - int finEndIp = avm2code.adr2pos(ex.end, true); - GraphPart finallyEndPart = searchPart(finEndIp, allParts); - List refs = getRealRefs(finallyEndPart); + int finEndIp = avm2code.adr2pos(ex.end, true) - 1; + GraphPart prevFinallyEndPart = searchPart(finEndIp, allParts); - if (refs.size() == 1) { - GraphPart prev = refs.get(0); - if (prev.getHeight() == 1) { - if (avm2code.code.get(prev.start).definition instanceof PushByteIns) { - defaultPushByte = avm2code.code.get(prev.start).operands[0]; - } + for (int j = prevFinallyEndPart.start; j <= prevFinallyEndPart.end; j++) { + AVM2Instruction ins = avm2code.code.get(j); + if (ins.definition instanceof NopIns) { + + } else if (ins.definition instanceof PushByteIns) { + defaultPushByte = ins.operands[0]; + } else if (ins.definition instanceof JumpIns) { + } else { + defaultPushByte = null; + break; } } - if (defaultPushByte == null) { - if (getRealRefs(finallyEndPart).size() == 0) { - if (avm2code.code.get(finallyEndPart.start - 1).definition instanceof JumpIns) { - GraphPart prevPart = searchPart(finallyEndPart.start - 1, allParts); - finallyEndPart = prevPart.nextParts.get(0); - if (finallyEndPart.nextParts.size() == 1 && finallyEndPart.nextParts.get(0).refs.size() > 1) { - for (int j = finallyEndPart.start; j <= finallyEndPart.end; j++) { - AVM2Instruction ins = avm2code.code.get(j); - if (ins.definition instanceof NopIns) { - } else if (ins.definition instanceof PushByteIns) { - defaultPushByte = ins.operands[0]; - break; - } else { - break; - } + if (defaultPushByte == null) { + if (avm2code.code.get(prevFinallyEndPart.end).definition instanceof JumpIns) { + prevFinallyEndPart = prevFinallyEndPart.nextParts.get(0); + if (prevFinallyEndPart.nextParts.size() == 1 && prevFinallyEndPart.nextParts.get(0).refs.size() > 1) { + for (int j = prevFinallyEndPart.start; j <= prevFinallyEndPart.end; j++) { + AVM2Instruction ins = avm2code.code.get(j); + if (ins.definition instanceof NopIns) { + + } else if (ins.definition instanceof PushByteIns) { + defaultPushByte = ins.operands[0]; + break; + } else { + break; } } } @@ -826,9 +826,6 @@ public class AVM2Graph extends Graph { } } - //GraphPart endPart = searchPart(endIp, allParts); - //finallyIndex.setVal(-1); - Collections.sort(finnalysIndicesToBe, new Comparator() { @Override public int compare(Integer o1, Integer o2) { @@ -856,12 +853,23 @@ public class AVM2Graph extends Graph { break; } if (outSideExceptionNonEmptyPart.nextParts.size() == 1 && outSideExceptionNonEmptyPart.nextParts.get(0) == outSideFinallyPart) { - if (outSideExceptionNonEmptyPart.getHeight() == 1) { - if (avm2code.code.get(outSideExceptionNonEmptyPart.start).definition instanceof PushByteIns) { - finallyIndex.setVal(e); - break; + boolean hashPushByteOnly = true; + for (int ip = outSideExceptionNonEmptyPart.start; ip <= outSideExceptionNonEmptyPart.end; ip++) { + AVM2Instruction ins = avm2code.code.get(outSideExceptionNonEmptyPart.start); + if (ins.definition instanceof PushByteIns) { + + } else if (ins.definition instanceof JumpIns) { + + } else if (ins.definition instanceof NopIns) { + + } else { + hashPushByteOnly = false; } } + if (hashPushByteOnly) { + finallyIndex.setVal(e); + break; + } } } } @@ -896,6 +904,7 @@ public class AVM2Graph extends Graph { if (finallyException != null) { catchedExceptions.add(finallyException); + catchedExceptionIds.add(finallyIndex); } int switchedReg = -1; @@ -918,6 +927,7 @@ public class AVM2Graph extends Graph { parsedExceptionIds.addAll(catchedExceptionIds); if (finallyException != null) { catchedExceptions.remove(finallyException); + catchedExceptionIds.remove((Integer) finallyIndex); } if (finallyIndex > -1) { parsedExceptionIds.add(finallyIndex); @@ -1163,6 +1173,70 @@ public class AVM2Graph extends Graph { } currentRet.add(tryItem); + /*processIfs(tryItem.tryCommands); + processIfs(tryItem.finallyCommands); + for (List cc : tryItem.catchCommands) { + processIfs(cc); + } + + + + + List> blocksToCheck = new ArrayList<>(); + blocksToCheck.add(tryItem.tryCommands); + blocksToCheck.addAll(tryItem.catchCommands); + + boolean allCntBreExit = true; + for (List block : blocksToCheck) { + if (block.isEmpty()) { + allCntBreExit = false; + break; + } + GraphTargetItem last = block.get(block.size() - 1); + if (!(last instanceof ExitItem) + && !(last instanceof ContinueItem) + && !(last instanceof BreakItem) + && !(last instanceof GotoItem)) { + allCntBreExit = false; + break; + } + } + + if (allCntBreExit) { + Map loopIdToCntCount = new HashMap<>(); + + ContinueItem maxCountCnt = null; + int maxCount = 0; + + for (List block : blocksToCheck) { + GraphTargetItem last = block.get(block.size() - 1); + if (last instanceof ContinueItem) { + ContinueItem cnt = (ContinueItem) last; + if (!loopIdToCntCount.containsKey(cnt.loopId)) { + loopIdToCntCount.put(cnt.loopId, 0); + } + int newCount = loopIdToCntCount.get(cnt.loopId) + 1; + if (newCount > maxCount) { + maxCount = newCount; + maxCountCnt = cnt; + } + loopIdToCntCount.put(cnt.loopId, newCount); + } + } + + if (maxCountCnt != null) { + for (List block : blocksToCheck) { + GraphTargetItem last = block.get(block.size() - 1); + if (last instanceof ContinueItem) { + ContinueItem cnt = (ContinueItem) last; + if (cnt.loopId == maxCountCnt.loopId) { + block.remove(block.size() - 1); + } + } + } + currentRet.add(maxCountCnt); + } + }*/ if (afterPart != null) { 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 647d71475..c22f6cc64 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java @@ -2388,7 +2388,7 @@ public class Graph { List alternateEntries = new ArrayList<>(); for (GraphException ex : exceptions) { alternateEntries.add(ex.start); - alternateEntries.add(ex.end); + //alternateEntries.add(ex.end); alternateEntries.add(ex.target); } HashMap> refs = code.visitCode(alternateEntries); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/precontinues/GraphPrecontinueDetector.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/precontinues/GraphPrecontinueDetector.java index 5a97d706f..45ad75200 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/precontinues/GraphPrecontinueDetector.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/precontinues/GraphPrecontinueDetector.java @@ -61,12 +61,6 @@ public class GraphPrecontinueDetector { for (GraphPart part : allParts) { Node node = partToNode.get(part); for (GraphPart prev : part.refs) { - /*if (prev.start < 0 && !partToNode.containsKey(prev)) { - Node minusNode = new Node(); - minusNode.graphPart = prev; - partToNode.put(prev, node); - continue; - }*/ if (prev.start < 0) { continue; } diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3CrossCompileSwfToolsDecompileTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3CrossCompileSwfToolsDecompileTest.java index 36510089d..b356c0b35 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3CrossCompileSwfToolsDecompileTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3CrossCompileSwfToolsDecompileTest.java @@ -152,7 +152,7 @@ public class ActionScript3CrossCompileSwfToolsDecompileTest extends ActionScript decompileMethod("swftools", "testTryCatchInWhile3", "var _loc1_:int = 0;\r\n" + "_loc1_ = 0;\r\n" + "trace(\"before loop\");\r\n" - + "for(; _loc1_ > 5; §§goto(addr15))\r\n" + + "while(_loc1_ > 5)\r\n" + "{\r\n" + "try\r\n" + "{\r\n" @@ -160,7 +160,6 @@ public class ActionScript3CrossCompileSwfToolsDecompileTest extends ActionScript + "}\r\n" + "catch(e:Error)\r\n" + "{\r\n" - + "addr15:\r\n" + "trace(\"in catch\");\r\n" + "_loc1_++;\r\n" + "continue;\r\n" @@ -174,7 +173,7 @@ public class ActionScript3CrossCompileSwfToolsDecompileTest extends ActionScript public void testTryCatchInWhile4() { decompileMethod("swftools", "testTryCatchInWhile4", "var _loc1_:int = 0;\r\n" + "_loc1_ = 0;\r\n" - + "for(; true; §§goto(addr23))\r\n" + + "while(true)\r\n" + "{\r\n" + "try\r\n" + "{\r\n" @@ -188,7 +187,6 @@ public class ActionScript3CrossCompileSwfToolsDecompileTest extends ActionScript + "}\r\n" + "catch(e:Error)\r\n" + "{\r\n" - + "addr23:\r\n" + "trace(\"in catch2\");\r\n" + "trace(\"a=\" + _loc1_);\r\n" + "continue;\r\n" @@ -255,7 +253,7 @@ public class ActionScript3CrossCompileSwfToolsDecompileTest extends ActionScript decompileMethod("swftools", "testTryCatchLoopBreak2", "var _loc1_:int = 0;\r\n" + "_loc1_ = 0;\r\n" + "trace(\"before loop\");\r\n" - + "for(; _loc1_ < 20; §§goto(addr17))\r\n" + + "while(_loc1_ < 20)\r\n" + "{\r\n" + "try\r\n" + "{\r\n" @@ -264,7 +262,6 @@ public class ActionScript3CrossCompileSwfToolsDecompileTest extends ActionScript + "}\r\n" + "catch(e:Error)\r\n" + "{\r\n" - + "addr17:\r\n" + "trace(\"in catch\");\r\n" + "trace(\"a=\" + _loc1_);\r\n" + "continue;\r\n"