From 5c95ca24b8d1bd04b0d22a9f771d6466fce88903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sat, 20 Feb 2021 20:12:33 +0100 Subject: [PATCH] Fixed: AS3 direct editation - using finally clause for continue and break --- CHANGELOG.md | 1 + .../flash/SourceGeneratorLocalData.java | 7 ++- .../parser/script/AVM2SourceGenerator.java | 55 ++++++++++++++++++- 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc3e88ec2..f0c5c2adb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ All notable changes to this project will be documented in this file. - #1606 Run/Debug SWF that is embedded (has no file associated) - AS3 direct editation - coerce in setproperty - AS3 direct editation - unary minus (negate) compiled as 0 - value +- AS3 direct editation - using finally clause for continue and break - #1159, #1608 Regexp syntax hilight when not a regexp (only division) again - Graphviz Graph not showing AS3 exception end - #1609 First frame missing in frame to PDF export diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java index 0b8ba36db..a6239d157 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.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; import com.jpexs.decompiler.flash.abc.types.ABCException; @@ -45,6 +46,8 @@ public class SourceGeneratorLocalData implements Serializable { public List finallyCatches = new ArrayList<>(); + public List> finallyOpenedLoops = new ArrayList<>(); + public Map finallyCounter = new HashMap<>(); public int finallyRegister = -1; @@ -77,6 +80,8 @@ public class SourceGeneratorLocalData implements Serializable { public boolean isStatic = false; + public List openedLoops = new ArrayList<>(); + public String getFullClass() { return pkg == null ? currentClass : pkg.addWithSuffix(currentClass).toRawString(); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java index 606468f03..f7702465f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java @@ -396,6 +396,7 @@ public class AVM2SourceGenerator implements SourceGenerator { @Override public List generate(SourceGeneratorLocalData localData, WhileItem item) throws CompilationException { + localData.openedLoops.add(item.loop.id); List ret = new ArrayList<>(); List whileExpr = new ArrayList<>(); @@ -434,6 +435,7 @@ public class AVM2SourceGenerator implements SourceGenerator { } public List generateForIn(SourceGeneratorLocalData localData, Loop loop, GraphTargetItem collection, AssignableAVM2Item assignable, List commands, final boolean each) throws CompilationException { + localData.openedLoops.add(loop.id); List ret = new ArrayList<>(); final Reference counterReg = new Reference<>(0); final Reference collectionReg = new Reference<>(0); @@ -505,6 +507,7 @@ public class AVM2SourceGenerator implements SourceGenerator { @Override public List generate(SourceGeneratorLocalData localData, DoWhileItem item) throws CompilationException { + localData.openedLoops.add(item.loop.id); List ret = new ArrayList<>(); List whileExpr = new ArrayList<>(); @@ -554,6 +557,7 @@ public class AVM2SourceGenerator implements SourceGenerator { @Override public List generate(SourceGeneratorLocalData localData, ForItem item) throws CompilationException { + localData.openedLoops.add(item.loop.id); List ret = new ArrayList<>(); List forExpr = new ArrayList<>(); @@ -603,6 +607,7 @@ public class AVM2SourceGenerator implements SourceGenerator { @Override public List generate(SourceGeneratorLocalData localData, SwitchItem item) throws CompilationException { + localData.openedLoops.add(item.loop.id); List ret = new ArrayList<>(); Reference switchedReg = new Reference<>(0); AVM2Instruction forwardJump = ins(AVM2Instructions.Jump, 0); @@ -695,8 +700,29 @@ public class AVM2SourceGenerator implements SourceGenerator { } @Override - public List generate(SourceGeneratorLocalData localData, BreakItem item) { + public List generate(SourceGeneratorLocalData localData, BreakItem item) throws CompilationException { List ret = new ArrayList<>(); + if (!localData.finallyCatches.isEmpty()) { + for (int i = localData.finallyCatches.size() - 1; i >= 0; i--) { + if (localData.finallyOpenedLoops.get(i).contains(item.loopId)) { + if (i < localData.finallyCatches.size() - 1) { + ret.add(ins(AVM2Instructions.Label)); + } + int clauseId = localData.finallyCatches.get(i); + Integer cnt = localData.finallyCounter.get(clauseId); + if (cnt == null) { + cnt = -1; + } + cnt++; + localData.finallyCounter.put(clauseId, cnt); + ret.addAll(new IntegerValueAVM2Item(null, null, (long) cnt).toSource(localData, this)); + ret.add(ins(new FinallyJumpIns(clauseId), 0)); + ret.add(ins(AVM2Instructions.Label)); + ret.add(ins(AVM2Instructions.Pop)); + } + } + ret.add(ins(AVM2Instructions.Label)); + } AVM2Instruction abreak = ins(new BreakJumpIns(item.loopId), 0); ret.add(abreak); return ret; @@ -767,6 +793,7 @@ public class AVM2SourceGenerator implements SourceGenerator { if (finallyEx > -1) { localData.finallyCatches.add(finId); + localData.finallyOpenedLoops.add(new ArrayList<>(localData.openedLoops)); } List tryCmds = generateToInsList(localData, item.tryCommands); @@ -962,6 +989,7 @@ public class AVM2SourceGenerator implements SourceGenerator { if (finallyEx > -1) { localData.finallyCatches.remove(localData.finallyCatches.size() - 1); + localData.finallyOpenedLoops.remove(localData.finallyOpenedLoops.size() - 1); } if (newFinallyReg) { localData.finallyRegister = -1; @@ -1037,8 +1065,31 @@ public class AVM2SourceGenerator implements SourceGenerator { } @Override - public List generate(SourceGeneratorLocalData localData, ContinueItem item) { + public List generate(SourceGeneratorLocalData localData, ContinueItem item) throws CompilationException { List ret = new ArrayList<>(); + + if (!localData.finallyCatches.isEmpty()) { + for (int i = localData.finallyCatches.size() - 1; i >= 0; i--) { + if (localData.finallyOpenedLoops.get(i).contains(item.loopId)) { + if (i < localData.finallyCatches.size() - 1) { + ret.add(ins(AVM2Instructions.Label)); + } + int clauseId = localData.finallyCatches.get(i); + Integer cnt = localData.finallyCounter.get(clauseId); + if (cnt == null) { + cnt = -1; + } + cnt++; + localData.finallyCounter.put(clauseId, cnt); + ret.addAll(new IntegerValueAVM2Item(null, null, (long) cnt).toSource(localData, this)); + ret.add(ins(new FinallyJumpIns(clauseId), 0)); + ret.add(ins(AVM2Instructions.Label)); + ret.add(ins(AVM2Instructions.Pop)); + } + } + ret.add(ins(AVM2Instructions.Label)); + } + AVM2Instruction acontinue = ins(new ContinueJumpIns(item.loopId), 0); ret.add(acontinue); return ret;