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 b4a9f9f70..971d8262c 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 @@ -319,7 +319,7 @@ public class AVM2Graph extends Graph { localData.pushDefaultPart.put(e, prevFinallyEndPart); } else if (ins.definition instanceof JumpIns) { } else { - if(localData.pushDefaultPart.containsKey(e)){ + if (localData.pushDefaultPart.containsKey(e)) { localData.pushDefaultPart.remove(e); } defaultPushByte = null; @@ -862,7 +862,7 @@ public class AVM2Graph extends Graph { 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) { @@ -1054,7 +1054,7 @@ public class AVM2Graph extends Graph { if (afterPart == null) { afterPart = searchFirstPartOutSideTryCatch(localData, finallyException, loops, allParts); } - + if (afterPart != null) { tryStopPart.add(afterPart); } @@ -1066,11 +1066,11 @@ public class AVM2Graph extends Graph { afterPart = null; } } - - if (afterPart == null && localData.pushDefaultPart.containsKey(finallyIndex)){ + + if (afterPart == null && localData.pushDefaultPart.containsKey(finallyIndex)) { exAfterPart = localData.pushDefaultPart.get(finallyIndex); tryStopPart.add(exAfterPart); - } + } tryCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, part, tryStopPart, loops, throwStates, staticOperation, path); makeAllCommands(tryCommands, stack); @@ -1191,9 +1191,6 @@ public class AVM2Graph extends Graph { processIfs(cc); } - - - List> blocksToCheck = new ArrayList<>(); blocksToCheck.add(tryItem.tryCommands); blocksToCheck.addAll(tryItem.catchCommands); @@ -1808,15 +1805,31 @@ public class AVM2Graph extends Graph { @Override protected void finalProcessAfter(List list, int level, FinalProcessLocalData localData, String path) { super.finalProcessAfter(list, level, localData, path); - /*for (int i = 0; i < list.size(); i++) { - if (list.get(i) instanceof SetLocalAVM2Item) { - SetLocalAVM2Item ri = (SetLocalAVM2Item) list.get(i); - if (localData.temporaryRegisters.contains(ri.regIndex)) { - list.remove(i); - i--; + for (int i = 0; i < list.size(); i++) { + if (list.get(i) instanceof SetTypeAVM2Item) { + if (((SetTypeAVM2Item) list.get(i)).getValue().getThroughDuplicate() instanceof ExceptionAVM2Item) { + + boolean doRemove = false; + if (list.get(i) instanceof SetSlotAVM2Item) { + doRemove = true; + } + if (list.get(i) instanceof SetLocalAVM2Item) { + int setLocalIp = avm2code.adr2pos(list.get(i).getSrc().getAddress()); + Set usages = localData.getRegisterUsage(setLocalIp); + //Note: There's a hack in PushScopeIns to bypass usage of register to puscope for restoring scopestack + //for example in catch in catch + if (usages.isEmpty()) { + doRemove = true; + } + } + if (doRemove) { + list.remove(i); + i--; + continue; + } } } - }*/ + } } private boolean isIntegerOrPopInteger(GraphTargetItem item) { @@ -1938,27 +1951,6 @@ public class AVM2Graph extends Graph { List ret = list; for (int i = 0; i < list.size(); i++) { - if (list.get(i) instanceof SetTypeAVM2Item) { - if (((SetTypeAVM2Item) list.get(i)).getValue().getThroughDuplicate() instanceof ExceptionAVM2Item) { - - boolean doRemove = false; - if (list.get(i) instanceof SetSlotAVM2Item) { - doRemove = true; - } - if (list.get(i) instanceof SetLocalAVM2Item) { - int setLocalIp = avm2code.adr2pos(list.get(i).getSrc().getAddress()); - Set usages = localData.getRegisterUsage(setLocalIp); - if (usages.isEmpty()) { - doRemove = true; - } - } - if (doRemove) { - list.remove(i); - i--; - continue; - } - } - } if (list.get(i) instanceof IfItem) { IfItem ifi = (IfItem) list.get(i); if (((ifi.expression instanceof HasNextAVM2Item) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushScopeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushScopeIns.java index 666da55f8..e5d42eb40 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushScopeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushScopeIns.java @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.abc.avm2.instructions.stack; import com.jpexs.decompiler.flash.abc.ABC; @@ -21,6 +22,7 @@ import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; import com.jpexs.decompiler.flash.abc.avm2.LocalDataArea; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; import java.util.List; @@ -48,7 +50,22 @@ public class PushScopeIns extends InstructionDefinition { @Override public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List output, String path) { - localData.scopeStack.push(stack.pop()); + GraphTargetItem top = stack.pop(); + + //Hack for catch inside catch to not detect pushscope register as used + if (top instanceof LocalRegAVM2Item) { + LocalRegAVM2Item getLocal = (LocalRegAVM2Item)top;; + if(getLocal.getSrc() != null){ + int getLocalIp = localData.code.adr2pos(getLocal.getSrc().getAddress()); + for(int setLocalPos : localData.setLocalPosToGetLocalPos.keySet()){ + if (localData.setLocalPosToGetLocalPos.get(setLocalPos).contains(getLocalIp)){ + localData.setLocalPosToGetLocalPos.get(setLocalPos).remove(getLocalIp); + } + } + } + + } + localData.scopeStack.push(top); } @Override diff --git a/libsrc/ffdec_lib/testdata/as3_cross_compile/bin/as3_cross_compile.air.swf b/libsrc/ffdec_lib/testdata/as3_cross_compile/bin/as3_cross_compile.air.swf index 6d0bdbefd..6a755b405 100644 Binary files a/libsrc/ffdec_lib/testdata/as3_cross_compile/bin/as3_cross_compile.air.swf and b/libsrc/ffdec_lib/testdata/as3_cross_compile/bin/as3_cross_compile.air.swf differ diff --git a/libsrc/ffdec_lib/testdata/as3_cross_compile/bin/as3_cross_compile.flex.swf b/libsrc/ffdec_lib/testdata/as3_cross_compile/bin/as3_cross_compile.flex.swf index da0daa04d..30778553b 100644 Binary files a/libsrc/ffdec_lib/testdata/as3_cross_compile/bin/as3_cross_compile.flex.swf and b/libsrc/ffdec_lib/testdata/as3_cross_compile/bin/as3_cross_compile.flex.swf differ diff --git a/libsrc/ffdec_lib/testdata/as3_cross_compile/bin/as3_cross_compile.flex_apache.swf b/libsrc/ffdec_lib/testdata/as3_cross_compile/bin/as3_cross_compile.flex_apache.swf index 4a016eb05..d288e12f1 100644 Binary files a/libsrc/ffdec_lib/testdata/as3_cross_compile/bin/as3_cross_compile.flex_apache.swf and b/libsrc/ffdec_lib/testdata/as3_cross_compile/bin/as3_cross_compile.flex_apache.swf differ diff --git a/libsrc/ffdec_lib/testdata/as3_cross_compile/bin/as3_cross_compile.swftools.swf b/libsrc/ffdec_lib/testdata/as3_cross_compile/bin/as3_cross_compile.swftools.swf index e188afc72..809e9c2ef 100644 Binary files a/libsrc/ffdec_lib/testdata/as3_cross_compile/bin/as3_cross_compile.swftools.swf and b/libsrc/ffdec_lib/testdata/as3_cross_compile/bin/as3_cross_compile.swftools.swf differ diff --git a/libsrc/ffdec_lib/testdata/as3_cross_compile/src/Main.as b/libsrc/ffdec_lib/testdata/as3_cross_compile/src/Main.as index 67443d627..f1bdc684d 100644 --- a/libsrc/ffdec_lib/testdata/as3_cross_compile/src/Main.as +++ b/libsrc/ffdec_lib/testdata/as3_cross_compile/src/Main.as @@ -32,6 +32,7 @@ package TestTryFinallyReturnNested; TestTryFinallyReturnNested2; TestTryFinallyReturnVoid; + TestTryCatchTry; public function Main() { diff --git a/libsrc/ffdec_lib/testdata/as3_cross_compile/src/tests/TestTryCatchTry.as b/libsrc/ffdec_lib/testdata/as3_cross_compile/src/tests/TestTryCatchTry.as new file mode 100644 index 000000000..4f842024d --- /dev/null +++ b/libsrc/ffdec_lib/testdata/as3_cross_compile/src/tests/TestTryCatchTry.as @@ -0,0 +1,34 @@ +package tests +{ + /** + * ... + * @author JPEXS + */ + public class TestTryCatchTry + { + + public function run() : void + { + trace("before try"); + try + { + trace("in try"); + } + catch (e:Error) + { + trace("in catch"); + try + { + trace("in catch try"); + } + catch (e2:Error) + { + trace("in catch in catch"); + } + } + trace("after"); + } + + } + +} \ No newline at end of file