From 98c2b1eba97e6f8e4ec8144ea2666b7791a290ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Tue, 26 Jan 2021 21:12:34 +0100 Subject: [PATCH] AS3 p-code more RAbcDasm like - get/setlocal_x renamed to get/setlocalx - QName casing changed from Qname Better increment/decrement detection, chained assignments. --- CHANGELOG.md | 9 +- .../instructions/InstructionDefinition.java | 20 -- .../avm2/instructions/executing/CallIns.java | 21 +- .../instructions/localregs/GetLocal0Ins.java | 5 +- .../instructions/localregs/GetLocal1Ins.java | 5 +- .../instructions/localregs/GetLocal2Ins.java | 5 +- .../instructions/localregs/GetLocal3Ins.java | 5 +- .../localregs/GetLocalTypeIns.java | 26 ++- .../instructions/localregs/SetLocal0Ins.java | 5 +- .../instructions/localregs/SetLocal1Ins.java | 5 +- .../instructions/localregs/SetLocal2Ins.java | 5 +- .../instructions/localregs/SetLocal3Ins.java | 5 +- .../localregs/SetLocalTypeIns.java | 26 +++ .../instructions/other/SetPropertyIns.java | 203 ++++++++++++------ .../flash/abc/avm2/model/AVM2Item.java | 32 ++- .../flash/abc/avm2/model/GetLexAVM2Item.java | 11 +- .../flash/abc/types/MethodBody.java | 3 +- .../decompiler/flash/abc/types/Multiname.java | 2 +- .../flash/locales/docs/pcode/AS3.properties | 80 +++---- .../locales/docs/pcode/AS3_ca.properties | 80 +++---- .../locales/docs/pcode/AS3_tr.properties | 80 +++---- .../locales/docs/pcode/AS3_zh.properties | 80 +++---- .../decompiler/graph/GraphTargetItem.java | 4 + .../flash/ActionScript3AssemblerTest.java | 15 +- .../flash/ActionScript3DeobfuscatorTest.java | 4 +- .../decompiler/flash/ActionScript3Test.java | 186 +++++++++------- .../flash/generators/AS3Generator.java | 25 ++- .../testdata/custom/abc/custom-0.abc | Bin 0 -> 881 bytes .../custom/abc/custom-0/Main.class.asasm | 87 ++++++++ .../custom/abc/custom-0/Main.script.asasm | 49 +++++ .../custom/abc/custom-0/custom-0.main.abc | Bin 0 -> 1058 bytes .../custom/abc/custom-0/custom-0.main.asasm | 10 + .../tests/TestDupAssignment.class.asasm | 77 +++++++ .../tests/TestDupAssignment.script.asasm | 29 +++ .../custom-0/tests/TestIncrement.class.asasm | 71 ++++++ .../custom-0/tests/TestIncrement.script.asasm | 29 +++ .../ffdec_lib/testdata/custom/bin/custom.swf | Bin 0 -> 995 bytes .../testdata/custom/bin/expressInstall.swf | Bin 0 -> 773 bytes .../ffdec_lib/testdata/custom/bin/index.html | 40 ++++ .../testdata/custom/bin/js/swfobject.js | 4 + .../ffdec_lib/testdata/custom/custom.as3proj | 93 ++++++++ .../testdata/custom/obj/customConfig.old | 50 +++++ .../testdata/custom/obj/customConfig.xml | 50 +++++ .../testdata/custom/run_abcexport.bat | 13 ++ .../ffdec_lib/testdata/custom/run_rabcasm.bat | 5 + libsrc/ffdec_lib/testdata/custom/src/Main.as | 29 +++ .../custom/src/tests/TestDupAssignment.as | 13 ++ .../flashdevelop/bin/flashdevelop.swf | Bin 20049 -> 20163 bytes .../flashdevelop/obj/flashdevelopConfig.old | 2 +- .../flashdevelop/obj/flashdevelopConfig.xml | 2 +- .../testdata/flashdevelop/src/Main.as | 1 + .../flashdevelop/src/tests/TestDup.as | 18 ++ .../flashdevelop/src/tests/TestHello.as | 2 +- 53 files changed, 1245 insertions(+), 376 deletions(-) create mode 100644 libsrc/ffdec_lib/testdata/custom/abc/custom-0.abc create mode 100644 libsrc/ffdec_lib/testdata/custom/abc/custom-0/Main.class.asasm create mode 100644 libsrc/ffdec_lib/testdata/custom/abc/custom-0/Main.script.asasm create mode 100644 libsrc/ffdec_lib/testdata/custom/abc/custom-0/custom-0.main.abc create mode 100644 libsrc/ffdec_lib/testdata/custom/abc/custom-0/custom-0.main.asasm create mode 100644 libsrc/ffdec_lib/testdata/custom/abc/custom-0/tests/TestDupAssignment.class.asasm create mode 100644 libsrc/ffdec_lib/testdata/custom/abc/custom-0/tests/TestDupAssignment.script.asasm create mode 100644 libsrc/ffdec_lib/testdata/custom/abc/custom-0/tests/TestIncrement.class.asasm create mode 100644 libsrc/ffdec_lib/testdata/custom/abc/custom-0/tests/TestIncrement.script.asasm create mode 100644 libsrc/ffdec_lib/testdata/custom/bin/custom.swf create mode 100644 libsrc/ffdec_lib/testdata/custom/bin/expressInstall.swf create mode 100644 libsrc/ffdec_lib/testdata/custom/bin/index.html create mode 100644 libsrc/ffdec_lib/testdata/custom/bin/js/swfobject.js create mode 100644 libsrc/ffdec_lib/testdata/custom/custom.as3proj create mode 100644 libsrc/ffdec_lib/testdata/custom/obj/customConfig.old create mode 100644 libsrc/ffdec_lib/testdata/custom/obj/customConfig.xml create mode 100644 libsrc/ffdec_lib/testdata/custom/run_abcexport.bat create mode 100644 libsrc/ffdec_lib/testdata/custom/run_rabcasm.bat create mode 100644 libsrc/ffdec_lib/testdata/custom/src/Main.as create mode 100644 libsrc/ffdec_lib/testdata/custom/src/tests/TestDupAssignment.as create mode 100644 libsrc/ffdec_lib/testdata/flashdevelop/src/tests/TestDup.as diff --git a/CHANGELOG.md b/CHANGELOG.md index 62ffb843b..b3fd8ff67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,9 +24,12 @@ All notable changes to this project will be documented in this file. ### Changed - AS3 test methods separated to classes -- AS3 p-code more RAbcDasm like: parenthesis after True/False/Undefined/Null trait kinds -- AS3 p-code more RAbcDasm like: commas in parameters list (WARNING: Breaks backward compatibility) -- AS3 p-code more RAbcDasm like: lookupswitch caseoffsets in brackets +- AS3 p-code more RAbcDasm like (WARNING: Breaks backward compatibility): +- parenthesis after True/False/Undefined/Null trait kinds +- commas in parameters list +- lookupswitch caseoffsets in brackets +- get/setlocal_x renamed to get/setlocalx +- QName casing changed from Qname ### Removed - Code structure detection in Graphviz graphs as it was usually wrong diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/InstructionDefinition.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/InstructionDefinition.java index 49d79b4b8..b3bff26ae 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/InstructionDefinition.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/InstructionDefinition.java @@ -320,24 +320,4 @@ public abstract class InstructionDefinition implements Serializable { } return localData.code.adr2pos(src.getAddress()); } - - public void cleanTempRegisters(AVM2LocalData localData, List output, List usedLocalRegs) { - for (LocalRegAVM2Item reg : usedLocalRegs) { - for (int i = output.size() - 1; i >= 0; i--) { - if (output.get(i) instanceof SetLocalAVM2Item) { - SetLocalAVM2Item setLocal = (SetLocalAVM2Item) output.get(i); - if (setLocal.regIndex == reg.regIndex) { - int setLocalIp = getItemIp(localData, setLocal); - Set usages = localData.getSetLocalUsages(setLocalIp); - int usageIp = getItemIp(localData, reg); - if (usages.size() == 1 && usages.iterator().next().equals(usageIp)) { - output.remove(i); - } - } - } else { - break; - } - } - } - } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallIns.java index c42ac645f..1be0ac319 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallIns.java @@ -24,7 +24,9 @@ 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.CallAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item; import com.jpexs.decompiler.flash.ecma.NotCompileTime; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; @@ -74,12 +76,21 @@ public class CallIns extends InstructionDefinition { args.add(0, stack.pop()); } GraphTargetItem receiver = stack.pop(); - if (receiver instanceof LocalRegAVM2Item) { - List localRegs = new ArrayList<>(); - localRegs.add((LocalRegAVM2Item) receiver); - cleanTempRegisters(localData, output, localRegs); - } GraphTargetItem function = stack.pop(); + + if (function instanceof GetPropertyAVM2Item) { + GetPropertyAVM2Item getProperty = (GetPropertyAVM2Item) function; + if (getProperty.object instanceof SetLocalAVM2Item) { + SetLocalAVM2Item setLocal = (SetLocalAVM2Item) getProperty.object; + if (receiver instanceof LocalRegAVM2Item) { + LocalRegAVM2Item getLocal = (LocalRegAVM2Item) receiver; + if (getLocal.regIndex == setLocal.regIndex) { + getProperty.object = getProperty.object.value; + receiver = getProperty.object; + } + } + } + } stack.push(new CallAVM2Item(ins, localData.lineStartInstruction, receiver, function, args)); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal0Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal0Ins.java index 8a37c4a7e..8feb46381 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal0Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal0Ins.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.localregs; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; @@ -24,7 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; public class GetLocal0Ins extends GetLocalTypeIns { public GetLocal0Ins() { - super(0xd0, "getlocal_0", new int[]{}, false); + super(0xd0, "getlocal0", new int[]{}, false); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal1Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal1Ins.java index f94a79a87..43f9eb141 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal1Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal1Ins.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.localregs; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; @@ -24,7 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; public class GetLocal1Ins extends GetLocalTypeIns { public GetLocal1Ins() { - super(0xd1, "getlocal_1", new int[]{}, false); + super(0xd1, "getlocal1", new int[]{}, false); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal2Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal2Ins.java index 62dec1f91..54a09df0f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal2Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal2Ins.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.localregs; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; @@ -24,7 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; public class GetLocal2Ins extends GetLocalTypeIns { public GetLocal2Ins() { - super(0xd2, "getlocal_2", new int[]{}, false); + super(0xd2, "getlocal2", new int[]{}, false); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal3Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal3Ins.java index 3c4f82272..9a982c0b6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal3Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocal3Ins.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.localregs; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; @@ -24,7 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; public class GetLocal3Ins extends GetLocalTypeIns { public GetLocal3Ins() { - super(0xd3, "getlocal_3", new int[]{}, false); + super(0xd3, "getlocal3", new int[]{}, false); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalTypeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalTypeIns.java index 7cba66b9f..45f1a55b3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalTypeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalTypeIns.java @@ -23,6 +23,8 @@ 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.ClassAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.CoerceAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ConvertAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.ScriptAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item; @@ -86,7 +88,27 @@ public abstract class GetLocalTypeIns extends InstructionDefinition { //computedValue = new NotCompileTimeItem(ins, localData.lineStartInstruction, computedValue); } - if (output.size() >= 2) { + //chained assignments + if (!output.isEmpty()) { + if ((output.get(output.size() - 1) instanceof SetTypeAVM2Item)) { + GraphTargetItem setItem = output.get(output.size() - 1); + if (setItem.value.getNotCoerced() instanceof SetLocalAVM2Item) { + SetLocalAVM2Item setLocal = (SetLocalAVM2Item) setItem.value.getNotCoerced(); + if (setLocal.regIndex == regId) { + if ((setItem.value instanceof CoerceAVM2Item) || (setItem.value instanceof ConvertAVM2Item)) { + setItem.value.value = setLocal.value; + } else { + setItem.value = setLocal.value; + } + + output.remove(output.size() - 1); + stack.add(setItem); + return; + } + } + } + } + /*if (output.size() >= 2) { if ((output.get(output.size() - 1) instanceof SetTypeAVM2Item) && (output.get(output.size() - 2) instanceof SetLocalAVM2Item)) { SetLocalAVM2Item setLocal = (SetLocalAVM2Item) output.get(output.size() - 2); GraphTargetItem setItem = output.get(output.size() - 1); @@ -105,7 +127,7 @@ public abstract class GetLocalTypeIns extends InstructionDefinition { } } } - } + }*/ stack.push(new LocalRegAVM2Item(ins, localData.lineStartInstruction, regId, computedValue)); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal0Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal0Ins.java index cdcaed0a5..7aaacc0fc 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal0Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal0Ins.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.localregs; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; @@ -24,7 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; public class SetLocal0Ins extends SetLocalTypeIns { public SetLocal0Ins() { - super(0xd4, "setlocal_0", new int[]{}, false); + super(0xd4, "setlocal0", new int[]{}, false); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal1Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal1Ins.java index 1dc9378d9..89f617518 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal1Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal1Ins.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.localregs; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; @@ -24,7 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; public class SetLocal1Ins extends SetLocalTypeIns { public SetLocal1Ins() { - super(0xd5, "setlocal_1", new int[]{}, false); + super(0xd5, "setlocal1", new int[]{}, false); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal2Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal2Ins.java index 397edd21d..95b148193 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal2Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal2Ins.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.localregs; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; @@ -24,7 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; public class SetLocal2Ins extends SetLocalTypeIns { public SetLocal2Ins() { - super(0xd6, "setlocal_2", new int[]{}, false); + super(0xd6, "setlocal2", new int[]{}, false); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal3Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal3Ins.java index ccd8cb76e..db2e99c13 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal3Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocal3Ins.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.localregs; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; @@ -24,7 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; public class SetLocal3Ins extends SetLocalTypeIns { public SetLocal3Ins() { - super(0xd7, "setlocal_3", new int[]{}, false); + super(0xd7, "setlocal3", new int[]{}, false); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalTypeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalTypeIns.java index 78ddfe132..1dfaafc80 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalTypeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/SetLocalTypeIns.java @@ -21,8 +21,11 @@ import com.jpexs.decompiler.flash.abc.AVM2LocalData; import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import static com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition.getItemIp; import com.jpexs.decompiler.flash.abc.avm2.instructions.SetTypeIns; import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.CoerceAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ConvertAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.DecrementAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.FindPropertyAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item; @@ -31,6 +34,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.NewActivationAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.PostIncrementAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.SetTypeAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreDecrementAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreIncrementAVM2Item; import com.jpexs.decompiler.flash.abc.types.MethodBody; @@ -41,6 +45,7 @@ import com.jpexs.decompiler.graph.model.DuplicateItem; import com.jpexs.decompiler.graph.model.PopItem; import java.util.HashMap; import java.util.List; +import java.util.Set; import java.util.Stack; /** @@ -132,6 +137,27 @@ public abstract class SetLocalTypeIns extends InstructionDefinition implements S if (localData.getSetLocalUsages(localData.code.adr2pos(ins.getAddress())).isEmpty() && (value instanceof DuplicateItem)) { return; } + + GraphTargetItem notCoercedValue = value; + if ((value instanceof CoerceAVM2Item) || (value instanceof ConvertAVM2Item)) { + notCoercedValue = value.value; + } + + if (notCoercedValue instanceof DuplicateItem) { + GraphTargetItem insideDup = notCoercedValue.value; + if (!stack.isEmpty() && stack.peek() == insideDup) { + stack.pop(); + if ((value instanceof CoerceAVM2Item) || (value instanceof ConvertAVM2Item)) { + value.value = insideDup; + } else { + value = insideDup; + } + + GraphTargetItem result = new SetLocalAVM2Item(ins, localData.lineStartInstruction, regId, value); + stack.push(result); + return; + } + } GraphTargetItem result = new SetLocalAVM2Item(ins, localData.lineStartInstruction, regId, value); output.add(result); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetPropertyIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetPropertyIns.java index f71efa8e8..2db1f4396 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetPropertyIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetPropertyIns.java @@ -27,12 +27,14 @@ import com.jpexs.decompiler.flash.abc.avm2.model.ApplyTypeAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.ConstructAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.DecrementAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.GetLexAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.InitVectorAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.PostIncrementAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.SetPropertyAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreDecrementAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreIncrementAVM2Item; @@ -40,6 +42,7 @@ import com.jpexs.decompiler.flash.abc.types.MethodBody; import com.jpexs.decompiler.graph.DottedChain; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.model.DuplicateItem; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -55,98 +58,156 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns super(0x61, "setproperty", new int[]{AVM2Code.DAT_MULTINAME_INDEX}, true); } + private GraphTargetItem checkIncDec(boolean standalone, int multinameIndex, AVM2Instruction ins, AVM2LocalData localData, GraphTargetItem item, + LocalRegAVM2Item valueLocalReg, LocalRegAVM2Item nameLocalReg, LocalRegAVM2Item objLocalReg) { + if (item instanceof SetLocalAVM2Item) { + SetLocalAVM2Item valueSetLocalReg = (SetLocalAVM2Item) item; + if ((valueSetLocalReg.value instanceof IncrementAVM2Item) || (valueSetLocalReg.value instanceof DecrementAVM2Item)) { + boolean isIncrement = (valueSetLocalReg.value instanceof IncrementAVM2Item); + if (valueSetLocalReg.value.value instanceof GetPropertyAVM2Item) { + GetPropertyAVM2Item getProperty = (GetPropertyAVM2Item) valueSetLocalReg.value.value; + FullMultinameAVM2Item propertyName = ((FullMultinameAVM2Item) getProperty.propertyName); + SetLocalAVM2Item nameSetLocalReg = null; + if (propertyName.name instanceof SetLocalAVM2Item) { + nameSetLocalReg = (SetLocalAVM2Item) propertyName.name; + } + if (getProperty.object instanceof SetLocalAVM2Item) { + SetLocalAVM2Item objSetLocalReg = (SetLocalAVM2Item) getProperty.object; + + if ((valueLocalReg.regIndex == valueSetLocalReg.regIndex) + && (propertyName.multinameIndex == multinameIndex) + && ((nameLocalReg == null && nameSetLocalReg == null) || (nameLocalReg.regIndex == nameSetLocalReg.regIndex)) + && (objLocalReg.regIndex == objSetLocalReg.regIndex)) { + if (nameSetLocalReg != null) { + propertyName.name = nameSetLocalReg.value; + } + getProperty.object = objSetLocalReg.value; + + if (standalone) { + if (isIncrement) { + return new PostIncrementAVM2Item(ins, localData.lineStartInstruction, getProperty); + } else { + return new PostDecrementAVM2Item(ins, localData.lineStartInstruction, getProperty); + } + } else { + if (isIncrement) { + return new PreIncrementAVM2Item(ins, localData.lineStartInstruction, getProperty); + } else { + return new PreDecrementAVM2Item(ins, localData.lineStartInstruction, getProperty); + } + } + } + } + } + } + } + return null; + } + @Override public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List output, String path) { int multinameIndex = ins.operands[0]; GraphTargetItem value = stack.pop(); FullMultinameAVM2Item multiname = resolveMultiname(localData, true, stack, localData.getConstants(), multinameIndex, ins); GraphTargetItem obj = stack.pop(); - if (value.getThroughDuplicate().getThroughRegister().getThroughDuplicate() instanceof IncrementAVM2Item) { - List localRegs = new ArrayList<>(); - if (value.getThroughDuplicate() instanceof LocalRegAVM2Item) { - localRegs.add((LocalRegAVM2Item) value.getThroughDuplicate()); - } - GraphTargetItem inside = ((IncrementAVM2Item) value.getThroughDuplicate().getThroughRegister().getThroughDuplicate()).value.getThroughRegister().getNotCoerced().getThroughDuplicate(); - if (inside instanceof GetPropertyAVM2Item) { - GetPropertyAVM2Item insideProp = ((GetPropertyAVM2Item) inside); - if (((FullMultinameAVM2Item) insideProp.propertyName).compareSame(multiname)) { - GraphTargetItem insideObj = obj.getThroughDuplicate(); - if (insideObj instanceof LocalRegAVM2Item) { - localRegs.add((LocalRegAVM2Item) insideObj); - if (((LocalRegAVM2Item) insideObj).computedValue != null) { - insideObj = ((LocalRegAVM2Item) insideObj).computedValue.getThroughNotCompilable().getThroughDuplicate(); - } - } - if (multiname.name instanceof LocalRegAVM2Item) { - localRegs.add((LocalRegAVM2Item) multiname.name); - } - if (multiname.namespace instanceof LocalRegAVM2Item) { - localRegs.add((LocalRegAVM2Item) multiname.namespace); - } - if (insideProp.object.getThroughDuplicate() == insideObj) { - cleanTempRegisters(localData, output, localRegs); - if (stack.size() > 0) { - GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); - if (top == insideProp) { + + if ((value instanceof IncrementAVM2Item) || (value instanceof DecrementAVM2Item)) { + boolean isIncrement = (value instanceof IncrementAVM2Item); + if (value.value instanceof DuplicateItem) { + GraphTargetItem duplicated = value.value.value; + if (!stack.isEmpty()) { + if (stack.peek() == duplicated) { + GraphTargetItem notCoerced = duplicated.getNotCoerced(); + if (notCoerced instanceof GetLexAVM2Item) { + GetLexAVM2Item getLex = (GetLexAVM2Item) notCoerced; + if (localData.abc.constants.getMultiname(multinameIndex).equals(getLex.propertyName)) { stack.pop(); - stack.push(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, insideProp)); - } else if ((top instanceof IncrementAVM2Item) && (((IncrementAVM2Item) top).value == inside)) { - stack.pop(); - stack.push(new PreIncrementAVM2Item(ins, localData.lineStartInstruction, insideProp)); - } else { - output.add(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, insideProp)); + if (isIncrement) { + stack.push(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, getLex)); + } else { + stack.push(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, getLex)); + } + return; } - } else { - output.add(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, insideProp)); } - return; + } } } + } - if (value.getThroughDuplicate().getThroughRegister().getThroughDuplicate() instanceof DecrementAVM2Item) { - List localRegs = new ArrayList<>(); - if (value.getThroughDuplicate() instanceof LocalRegAVM2Item) { - localRegs.add((LocalRegAVM2Item) value.getThroughDuplicate()); + if (value instanceof LocalRegAVM2Item) { + LocalRegAVM2Item valueLocalReg = (LocalRegAVM2Item) value; + LocalRegAVM2Item nameLocalReg = null; + if (multiname.name instanceof LocalRegAVM2Item) { + nameLocalReg = (LocalRegAVM2Item) multiname.name;; } + if (obj instanceof LocalRegAVM2Item) { + LocalRegAVM2Item objLocalReg = (LocalRegAVM2Item) obj; - GraphTargetItem inside = ((DecrementAVM2Item) value.getThroughDuplicate().getThroughRegister().getThroughDuplicate()).value.getThroughRegister().getNotCoerced().getThroughDuplicate(); - if (inside instanceof GetPropertyAVM2Item) { - GetPropertyAVM2Item insideProp = ((GetPropertyAVM2Item) inside); - if (((FullMultinameAVM2Item) insideProp.propertyName).compareSame(multiname)) { - GraphTargetItem insideObj = obj.getThroughDuplicate(); - if (insideObj instanceof LocalRegAVM2Item) { - localRegs.add((LocalRegAVM2Item) insideObj); - if (((LocalRegAVM2Item) insideObj).computedValue != null) { - insideObj = ((LocalRegAVM2Item) insideObj).computedValue.getThroughNotCompilable().getThroughDuplicate(); - } - } - if (multiname.name instanceof LocalRegAVM2Item) { - localRegs.add((LocalRegAVM2Item) multiname.name); - } - if (multiname.namespace instanceof LocalRegAVM2Item) { - localRegs.add((LocalRegAVM2Item) multiname.namespace); - } - if (insideProp.object.getThroughDuplicate() == insideObj) { - cleanTempRegisters(localData, output, localRegs); - if (stack.size() > 0) { - GraphTargetItem top = stack.peek().getNotCoerced().getThroughDuplicate(); - if (top == insideProp) { - stack.pop(); - stack.push(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, insideProp)); - } else if ((top instanceof DecrementAVM2Item) && (((DecrementAVM2Item) top).value == inside)) { - stack.pop(); - stack.push(new PreDecrementAVM2Item(ins, localData.lineStartInstruction, insideProp)); - } else { - output.add(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, insideProp)); + if (!output.isEmpty() && !stack.isEmpty()) { + if (output.get(output.size() - 1) instanceof SetLocalAVM2Item) { + SetLocalAVM2Item valueSetLocalReg = (SetLocalAVM2Item) output.get(output.size() - 1); + if ((valueSetLocalReg.value instanceof IncrementAVM2Item) + || (valueSetLocalReg.value instanceof DecrementAVM2Item)) { + boolean isIncrement = (valueSetLocalReg.value instanceof IncrementAVM2Item); + if (valueSetLocalReg.value.value instanceof DuplicateItem) { + GraphTargetItem duplicated = valueSetLocalReg.value.value.value; + if (stack.peek() == duplicated) { + GraphTargetItem notCoerced = duplicated.getNotCoerced(); + if (notCoerced instanceof GetPropertyAVM2Item) { + GetPropertyAVM2Item getProperty = (GetPropertyAVM2Item) notCoerced; + FullMultinameAVM2Item propertyName = ((FullMultinameAVM2Item) getProperty.propertyName); + SetLocalAVM2Item nameSetLocalReg = null; + if (propertyName.name instanceof SetLocalAVM2Item) { + nameSetLocalReg = (SetLocalAVM2Item) propertyName.name; + } + if (getProperty.object instanceof SetLocalAVM2Item) { + SetLocalAVM2Item objSetLocalReg = (SetLocalAVM2Item) getProperty.object; + + if ((valueLocalReg.regIndex == valueSetLocalReg.regIndex) + && (propertyName.multinameIndex == multinameIndex) + && ((nameLocalReg == null && nameSetLocalReg == null) || (nameLocalReg.regIndex == nameSetLocalReg.regIndex)) + && (objLocalReg.regIndex == objSetLocalReg.regIndex)) { + if (nameSetLocalReg != null) { + propertyName.name = nameSetLocalReg.value; + } + getProperty.object = objSetLocalReg.value; + output.remove(output.size() - 1); + stack.pop(); + if (isIncrement) { + stack.push(new PostIncrementAVM2Item(ins, localData.lineStartInstruction, getProperty)); + } else { + stack.push(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, getProperty)); + } + return; + } + } + } + } } - } else { - output.add(new PostDecrementAVM2Item(ins, localData.lineStartInstruction, insideProp)); } + } + } + + if (!stack.isEmpty()) { + GraphTargetItem checked = checkIncDec(false, multinameIndex, ins, localData, stack.peek(), valueLocalReg, nameLocalReg, objLocalReg); + if (checked != null) { + stack.pop(); + stack.push(checked); return; } } + if (!output.isEmpty()) { + GraphTargetItem checked = checkIncDec(true, multinameIndex, ins, localData, output.get(output.size() - 1), valueLocalReg, nameLocalReg, objLocalReg); + if (checked != null) { + output.remove(output.size() - 1); + output.add(checked); + return; + } + } + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/AVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/AVM2Item.java index 68e16f513..893b5d42b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/AVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/AVM2Item.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.model; import com.jpexs.decompiler.flash.IdentifiersDeobfuscation; @@ -172,4 +173,33 @@ public abstract class AVM2Item extends GraphTargetItem { AVM2SourceGenerator g = (AVM2SourceGenerator) generator; g.killRegister(localData, regNumber); } + + @Override + public boolean isIdentical(GraphTargetItem other) { + GraphTargetItem tiName = this; + while (tiName instanceof LocalRegAVM2Item) { + if (((LocalRegAVM2Item) tiName).computedValue != null) { + tiName = ((LocalRegAVM2Item) tiName).computedValue.getThroughNotCompilable().getThroughDuplicate(); + } else { + break; + } + } + + GraphTargetItem tiName2 = other; + if (tiName2 != null) { + tiName2 = tiName2.getThroughDuplicate(); + } + while (tiName2 instanceof LocalRegAVM2Item) { + if (((LocalRegAVM2Item) tiName2).computedValue != null) { + tiName2 = ((LocalRegAVM2Item) tiName2).computedValue.getThroughNotCompilable().getThroughDuplicate(); + } else { + break; + } + } + if (tiName != tiName2) { + return false; + } + return true; + } + } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/GetLexAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/GetLexAVM2Item.java index 469b63b62..350dc5ab6 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/GetLexAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/GetLexAVM2Item.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.model; import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; @@ -21,6 +22,7 @@ import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.DottedChain; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.SimpleValue; import com.jpexs.decompiler.graph.TypeItem; import com.jpexs.decompiler.graph.model.LocalData; @@ -28,7 +30,7 @@ import com.jpexs.decompiler.graph.model.LocalData; * * @author JPEXS */ -public class GetLexAVM2Item extends AVM2Item { +public class GetLexAVM2Item extends AVM2Item implements SimpleValue { public Multiname propertyName; @@ -60,4 +62,9 @@ public class GetLexAVM2Item extends AVM2Item { public boolean hasReturnValue() { return true; } + + @Override + public boolean isSimpleValue() { + return true; + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java index bc58a448e..424354899 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java @@ -319,7 +319,7 @@ public final class MethodBody implements Cloneable { } catch (InterruptedException ex) { throw ex; } catch (Exception | OutOfMemoryError | StackOverflowError ex) { - + ex.printStackTrace(); convertException = ex; Throwable cause = ex.getCause(); if (ex instanceof ExecutionException && cause instanceof Exception) { @@ -384,6 +384,7 @@ public final class MethodBody implements Cloneable { } catch (ThreadDeath | InterruptedException ex) { throw ex; } catch (Throwable ex) { + ex.printStackTrace(); //ignore logger.log(Level.SEVERE, "Deobfuscation failed in: " + path, ex); body = clone(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/Multiname.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/Multiname.java index 80e27fcb6..899895723 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/Multiname.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/Multiname.java @@ -56,7 +56,7 @@ public class Multiname { private static final int[] multinameKinds = new int[]{QNAME, QNAMEA, MULTINAME, MULTINAMEA, RTQNAME, RTQNAMEA, MULTINAMEL, RTQNAMEL, RTQNAMELA, MULTINAMELA, TYPENAME}; - private static final String[] multinameKindNames = new String[]{"Qname", "QnameA", "Multiname", "MultinameA", "RTQname", "RTQnameA", "MultinameL", "RTQnameL", "RTQnameLA", "MultinameLA", "TypeName"}; + private static final String[] multinameKindNames = new String[]{"QName", "QNameA", "Multiname", "MultinameA", "RTQName", "RTQNameA", "MultinameL", "RTQNameL", "RTQNameLA", "MultinameLA", "TypeName"}; public int kind; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/docs/pcode/AS3.properties b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/docs/pcode/AS3.properties index 8ff27e646..dc8c31ef3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/docs/pcode/AS3.properties +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/docs/pcode/AS3.properties @@ -1278,53 +1278,53 @@ instruction.multiply_i.stackBefore = value1, value2 instruction.multiply_i.stackAfter = value3 instruction.multiply_i.operands = -instruction.getlocal_0.shortDescription = Get local register 0 -instruction.getlocal_0.description = -instruction.getlocal_0.stackBefore = -instruction.getlocal_0.stackAfter = value -instruction.getlocal_0.operands = +instruction.getlocal0.shortDescription = Get local register 0 +instruction.getlocal0.description = +instruction.getlocal0.stackBefore = +instruction.getlocal0.stackAfter = value +instruction.getlocal0.operands = -instruction.getlocal_1.shortDescription = Get local register 1 -instruction.getlocal_1.description = -instruction.getlocal_1.stackBefore = -instruction.getlocal_1.stackAfter = value -instruction.getlocal_1.operands = +instruction.getlocal1.shortDescription = Get local register 1 +instruction.getlocal1.description = +instruction.getlocal1.stackBefore = +instruction.getlocal1.stackAfter = value +instruction.getlocal1.operands = -instruction.getlocal_2.shortDescription = Get local register 2 -instruction.getlocal_2.description = -instruction.getlocal_2.stackBefore = -instruction.getlocal_2.stackAfter = value -instruction.getlocal_2.operands = +instruction.getlocal2.shortDescription = Get local register 2 +instruction.getlocal2.description = +instruction.getlocal2.stackBefore = +instruction.getlocal2.stackAfter = value +instruction.getlocal2.operands = -instruction.getlocal_3.shortDescription = Get local register 3 -instruction.getlocal_3.description = -instruction.getlocal_3.stackBefore = -instruction.getlocal_3.stackAfter = value -instruction.getlocal_3.operands = +instruction.getlocal3.shortDescription = Get local register 3 +instruction.getlocal3.description = +instruction.getlocal3.stackBefore = +instruction.getlocal3.stackAfter = value +instruction.getlocal3.operands = -instruction.setlocal_0.shortDescription = Set local register 0 -instruction.setlocal_0.description = -instruction.setlocal_0.stackBefore = value -instruction.setlocal_0.stackAfter = -instruction.setlocal_0.operands = +instruction.setlocal0.shortDescription = Set local register 0 +instruction.setlocal0.description = +instruction.setlocal0.stackBefore = value +instruction.setlocal0.stackAfter = +instruction.setlocal0.operands = -instruction.setlocal_1.shortDescription = Set local register 1 -instruction.setlocal_1.description = -instruction.setlocal_1.stackBefore = value -instruction.setlocal_1.stackAfter = -instruction.setlocal_1.operands = +instruction.setlocal1.shortDescription = Set local register 1 +instruction.setlocal1.description = +instruction.setlocal1.stackBefore = value +instruction.setlocal1.stackAfter = +instruction.setlocal1.operands = -instruction.setlocal_2.shortDescription = Set local register 2 -instruction.setlocal_2.description = -instruction.setlocal_2.stackBefore = value -instruction.setlocal_2.stackAfter = -instruction.setlocal_2.operands = +instruction.setlocal2.shortDescription = Set local register 2 +instruction.setlocal2.description = +instruction.setlocal2.stackBefore = value +instruction.setlocal2.stackAfter = +instruction.setlocal2.operands = -instruction.setlocal_3.shortDescription = Set local register 3 -instruction.setlocal_3.description = -instruction.setlocal_3.stackBefore = value -instruction.setlocal_3.stackAfter = -instruction.setlocal_3.operands = +instruction.setlocal3.shortDescription = Set local register 3 +instruction.setlocal3.description = +instruction.setlocal3.stackBefore = value +instruction.setlocal3.stackAfter = +instruction.setlocal3.operands = #Undocumented: instruction.invalid.shortDescription = Invalid diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/docs/pcode/AS3_ca.properties b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/docs/pcode/AS3_ca.properties index e1af4856d..436fbef30 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/docs/pcode/AS3_ca.properties +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/docs/pcode/AS3_ca.properties @@ -1278,53 +1278,53 @@ instruction.multiply_i.stackBefore = value1, value2 instruction.multiply_i.stackAfter = value3 instruction.multiply_i.operands = -instruction.getlocal_0.shortDescription = Obt\u00e9 el registre local 0 -instruction.getlocal_0.description = -instruction.getlocal_0.stackBefore = -instruction.getlocal_0.stackAfter = value -instruction.getlocal_0.operands = +instruction.getlocal0.shortDescription = Obt\u00e9 el registre local 0 +instruction.getlocal0.description = +instruction.getlocal0.stackBefore = +instruction.getlocal0.stackAfter = value +instruction.getlocal0.operands = -instruction.getlocal_1.shortDescription = Obt\u00e9 el registre local 1 -instruction.getlocal_1.description = -instruction.getlocal_1.stackBefore = -instruction.getlocal_1.stackAfter = value -instruction.getlocal_1.operands = +instruction.getlocal1.shortDescription = Obt\u00e9 el registre local 1 +instruction.getlocal1.description = +instruction.getlocal1.stackBefore = +instruction.getlocal1.stackAfter = value +instruction.getlocal1.operands = -instruction.getlocal_2.shortDescription = Obt\u00e9 el registre local 2 -instruction.getlocal_2.description = -instruction.getlocal_2.stackBefore = -instruction.getlocal_2.stackAfter = value -instruction.getlocal_2.operands = +instruction.getlocal2.shortDescription = Obt\u00e9 el registre local 2 +instruction.getlocal2.description = +instruction.getlocal2.stackBefore = +instruction.getlocal2.stackAfter = value +instruction.getlocal2.operands = -instruction.getlocal_3.shortDescription = Obt\u00e9 el registre local 3 -instruction.getlocal_3.description = -instruction.getlocal_3.stackBefore = -instruction.getlocal_3.stackAfter = value -instruction.getlocal_3.operands = +instruction.getlocal3.shortDescription = Obt\u00e9 el registre local 3 +instruction.getlocal3.description = +instruction.getlocal3.stackBefore = +instruction.getlocal3.stackAfter = value +instruction.getlocal3.operands = -instruction.setlocal_0.shortDescription = Estableix el registre local 0 -instruction.setlocal_0.description = -instruction.setlocal_0.stackBefore = value -instruction.setlocal_0.stackAfter = -instruction.setlocal_0.operands = +instruction.setlocal0.shortDescription = Estableix el registre local 0 +instruction.setlocal0.description = +instruction.setlocal0.stackBefore = value +instruction.setlocal0.stackAfter = +instruction.setlocal0.operands = -instruction.setlocal_1.shortDescription = Estableix el registre local 1 -instruction.setlocal_1.description = -instruction.setlocal_1.stackBefore = value -instruction.setlocal_1.stackAfter = -instruction.setlocal_1.operands = +instruction.setlocal1.shortDescription = Estableix el registre local 1 +instruction.setlocal1.description = +instruction.setlocal1.stackBefore = value +instruction.setlocal1.stackAfter = +instruction.setlocal1.operands = -instruction.setlocal_2.shortDescription = Estableix el registre local 2 -instruction.setlocal_2.description = -instruction.setlocal_2.stackBefore = value -instruction.setlocal_2.stackAfter = -instruction.setlocal_2.operands = +instruction.setlocal2.shortDescription = Estableix el registre local 2 +instruction.setlocal2.description = +instruction.setlocal2.stackBefore = value +instruction.setlocal2.stackAfter = +instruction.setlocal2.operands = -instruction.setlocal_3.shortDescription = Estableix el registre local 3 -instruction.setlocal_3.description = -instruction.setlocal_3.stackBefore = value -instruction.setlocal_3.stackAfter = -instruction.setlocal_3.operands = +instruction.setlocal3.shortDescription = Estableix el registre local 3 +instruction.setlocal3.description = +instruction.setlocal3.stackBefore = value +instruction.setlocal3.stackAfter = +instruction.setlocal3.operands = #Undocumented: instruction.invalid.shortDescription = Inv\u00e0lid diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/docs/pcode/AS3_tr.properties b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/docs/pcode/AS3_tr.properties index c10b5ef1d..0e6bb0233 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/docs/pcode/AS3_tr.properties +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/docs/pcode/AS3_tr.properties @@ -1698,67 +1698,67 @@ instruction.multiply_i.operands = -instruction.getlocal_0.shortDescription = Yerel kay\u0131t al 0 -instruction.getlocal_0.description = -instruction.getlocal_0.stackBefore = -instruction.getlocal_0.stackAfter = de\u011fer -instruction.getlocal_0.operands = +instruction.getlocal0.shortDescription = Yerel kay\u0131t al 0 +instruction.getlocal0.description = +instruction.getlocal0.stackBefore = +instruction.getlocal0.stackAfter = de\u011fer +instruction.getlocal0.operands = -instruction.getlocal_1.shortDescription = Yerel kay\u0131t al 1 -instruction.getlocal_1.description = -instruction.getlocal_1.stackBefore = -instruction.getlocal_1.stackAfter = de\u011fer -instruction.getlocal_1.operands = +instruction.getlocal1.shortDescription = Yerel kay\u0131t al 1 +instruction.getlocal1.description = +instruction.getlocal1.stackBefore = +instruction.getlocal1.stackAfter = de\u011fer +instruction.getlocal1.operands = -instruction.getlocal_2.shortDescription = Yerel kay\u0131t al 2 -instruction.getlocal_2.description = -instruction.getlocal_2.stackBefore = -instruction.getlocal_2.stackAfter = de\u011fer -instruction.getlocal_2.operands = +instruction.getlocal2.shortDescription = Yerel kay\u0131t al 2 +instruction.getlocal2.description = +instruction.getlocal2.stackBefore = +instruction.getlocal2.stackAfter = de\u011fer +instruction.getlocal2.operands = -instruction.getlocal_3.shortDescription = Yerel kay\u0131t al 3 -instruction.getlocal_3.description = -instruction.getlocal_3.stackBefore = -instruction.getlocal_3.stackAfter = de\u011fer -instruction.getlocal_3.operands = +instruction.getlocal3.shortDescription = Yerel kay\u0131t al 3 +instruction.getlocal3.description = +instruction.getlocal3.stackBefore = +instruction.getlocal3.stackAfter = de\u011fer +instruction.getlocal3.operands = -instruction.setlocal_0.shortDescription = Yerel kay\u0131t ayarla 0 -instruction.setlocal_0.description = -instruction.setlocal_0.stackBefore = de\u011fer -instruction.setlocal_0.stackAfter = -instruction.setlocal_0.operands = +instruction.setlocal0.shortDescription = Yerel kay\u0131t ayarla 0 +instruction.setlocal0.description = +instruction.setlocal0.stackBefore = de\u011fer +instruction.setlocal0.stackAfter = +instruction.setlocal0.operands = -instruction.setlocal_1.shortDescription = Yerel kay\u0131t ayarla 1 -instruction.setlocal_1.description = -instruction.setlocal_1.stackBefore = de\u011fer -instruction.setlocal_1.stackAfter = -instruction.setlocal_1.operands = +instruction.setlocal1.shortDescription = Yerel kay\u0131t ayarla 1 +instruction.setlocal1.description = +instruction.setlocal1.stackBefore = de\u011fer +instruction.setlocal1.stackAfter = +instruction.setlocal1.operands = -instruction.setlocal_2.shortDescription = Yerel kay\u0131t ayarla 2 -instruction.setlocal_2.description = -instruction.setlocal_2.stackBefore = de\u011fer -instruction.setlocal_2.stackAfter = -instruction.setlocal_2.operands = +instruction.setlocal2.shortDescription = Yerel kay\u0131t ayarla 2 +instruction.setlocal2.description = +instruction.setlocal2.stackBefore = de\u011fer +instruction.setlocal2.stackAfter = +instruction.setlocal2.operands = -instruction.setlocal_3.shortDescription = Yerel kay\u0131t ayarla 3 -instruction.setlocal_3.description = -instruction.setlocal_3.stackBefore = de\u011fer -instruction.setlocal_3.stackAfter = -instruction.setlocal_3.operands = +instruction.setlocal3.shortDescription = Yerel kay\u0131t ayarla 3 +instruction.setlocal3.description = +instruction.setlocal3.stackBefore = de\u011fer +instruction.setlocal3.stackAfter = +instruction.setlocal3.operands = #Undocumented: diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/docs/pcode/AS3_zh.properties b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/docs/pcode/AS3_zh.properties index 45b4dcc8b..219516319 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/docs/pcode/AS3_zh.properties +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/locales/docs/pcode/AS3_zh.properties @@ -1278,53 +1278,53 @@ instruction.multiply_i.stackBefore = value1, value2 instruction.multiply_i.stackAfter = value3 instruction.multiply_i.operands = -instruction.getlocal_0.shortDescription = Get local register 0 -instruction.getlocal_0.description = -instruction.getlocal_0.stackBefore = -instruction.getlocal_0.stackAfter = value -instruction.getlocal_0.operands = +instruction.getlocal0.shortDescription = Get local register 0 +instruction.getlocal0.description = +instruction.getlocal0.stackBefore = +instruction.getlocal0.stackAfter = value +instruction.getlocal0.operands = -instruction.getlocal_1.shortDescription = Get local register 1 -instruction.getlocal_1.description = -instruction.getlocal_1.stackBefore = -instruction.getlocal_1.stackAfter = value -instruction.getlocal_1.operands = +instruction.getlocal1.shortDescription = Get local register 1 +instruction.getlocal1.description = +instruction.getlocal1.stackBefore = +instruction.getlocal1.stackAfter = value +instruction.getlocal1.operands = -instruction.getlocal_2.shortDescription = Get local register 2 -instruction.getlocal_2.description = -instruction.getlocal_2.stackBefore = -instruction.getlocal_2.stackAfter = value -instruction.getlocal_2.operands = +instruction.getlocal2.shortDescription = Get local register 2 +instruction.getlocal2.description = +instruction.getlocal2.stackBefore = +instruction.getlocal2.stackAfter = value +instruction.getlocal2.operands = -instruction.getlocal_3.shortDescription = Get local register 3 -instruction.getlocal_3.description = -instruction.getlocal_3.stackBefore = -instruction.getlocal_3.stackAfter = value -instruction.getlocal_3.operands = +instruction.getlocal3.shortDescription = Get local register 3 +instruction.getlocal3.description = +instruction.getlocal3.stackBefore = +instruction.getlocal3.stackAfter = value +instruction.getlocal3.operands = -instruction.setlocal_0.shortDescription = Set local register 0 -instruction.setlocal_0.description = -instruction.setlocal_0.stackBefore = value -instruction.setlocal_0.stackAfter = -instruction.setlocal_0.operands = +instruction.setlocal0.shortDescription = Set local register 0 +instruction.setlocal0.description = +instruction.setlocal0.stackBefore = value +instruction.setlocal0.stackAfter = +instruction.setlocal0.operands = -instruction.setlocal_1.shortDescription = Set local register 1 -instruction.setlocal_1.description = -instruction.setlocal_1.stackBefore = value -instruction.setlocal_1.stackAfter = -instruction.setlocal_1.operands = +instruction.setlocal1.shortDescription = Set local register 1 +instruction.setlocal1.description = +instruction.setlocal1.stackBefore = value +instruction.setlocal1.stackAfter = +instruction.setlocal1.operands = -instruction.setlocal_2.shortDescription = Set local register 2 -instruction.setlocal_2.description = -instruction.setlocal_2.stackBefore = value -instruction.setlocal_2.stackAfter = -instruction.setlocal_2.operands = +instruction.setlocal2.shortDescription = Set local register 2 +instruction.setlocal2.description = +instruction.setlocal2.stackBefore = value +instruction.setlocal2.stackAfter = +instruction.setlocal2.operands = -instruction.setlocal_3.shortDescription = Set local register 3 -instruction.setlocal_3.description = -instruction.setlocal_3.stackBefore = value -instruction.setlocal_3.stackAfter = -instruction.setlocal_3.operands = +instruction.setlocal3.shortDescription = Set local register 3 +instruction.setlocal3.description = +instruction.setlocal3.stackBefore = value +instruction.setlocal3.stackAfter = +instruction.setlocal3.operands = #Undocumented: instruction.invalid.shortDescription = Invalid diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphTargetItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphTargetItem.java index 1befc7368..d9fc581af 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphTargetItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/GraphTargetItem.java @@ -601,4 +601,8 @@ public abstract class GraphTargetItem implements Serializable, Cloneable { return 0; } + + public boolean isIdentical(GraphTargetItem other) { + return this == other; + } } diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3AssemblerTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3AssemblerTest.java index f50b497d4..83804fe6f 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3AssemblerTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3AssemblerTest.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.ABC; @@ -56,7 +57,7 @@ public class ActionScript3AssemblerTest extends ActionScriptTestBase { } private int getBaseAddr() { - return 2; //getlocal_0 + pushscope + return 2; //getlocal0 + pushscope } private ABC getABC() { @@ -81,7 +82,7 @@ public class ActionScript3AssemblerTest extends ActionScriptTestBase { private MethodBody compilePCode(String str) throws IOException, AVM2ParseException, InterruptedException { str = "code\r\n" - + "getlocal_0\r\n" + + "getlocal0\r\n" + "pushscope\r\n" + str + "returnvoid\r\n"; @@ -101,7 +102,7 @@ public class ActionScript3AssemblerTest extends ActionScriptTestBase { @Test public void removeInstruction() throws Exception { MethodBody b = compilePCode("pushbyte 1\r\n" - + "setlocal_1\r\n" //remove this + + "setlocal1\r\n" //remove this + "jump label1\r\n" + "pushtrue\r\n" + "pop\r\n" @@ -112,7 +113,7 @@ public class ActionScript3AssemblerTest extends ActionScriptTestBase { @Test public void removeInstruction2() throws Exception { MethodBody b = compilePCode("pushbyte 1\r\n" - + "setlocal_1\r\n" + + "setlocal1\r\n" + "jump label1\r\n" + "pushtrue\r\n" + "pop\r\n" //remove this @@ -123,7 +124,7 @@ public class ActionScript3AssemblerTest extends ActionScriptTestBase { @Test public void replaceInstruction() throws Exception { MethodBody b = compilePCode("pushbyte 1\r\n" - + "setlocal_1\r\n" + + "setlocal1\r\n" + "jump label1\r\n" //remove this + "jump label1\r\n" + "pushtrue\r\n" @@ -135,7 +136,7 @@ public class ActionScript3AssemblerTest extends ActionScriptTestBase { @Test public void replaceInstruction2() throws Exception { MethodBody b = compilePCode("pushbyte 1\r\n" - + "setlocal_1\r\n" + + "setlocal1\r\n" + "jump label1\r\n" + "pushtrue\r\n" + "jump label1\r\n" //remove this diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3DeobfuscatorTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3DeobfuscatorTest.java index 22417447b..7744c7a2c 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3DeobfuscatorTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3DeobfuscatorTest.java @@ -64,7 +64,7 @@ public class ActionScript3DeobfuscatorTest extends ActionScriptTestBase { private String recompilePCode(String str) throws IOException, AVM2ParseException, InterruptedException { str = "code\r\n" - + "getlocal_0\r\n" + + "getlocal0\r\n" + "pushscope\r\n" + str + "returnvoid\r\n"; @@ -238,7 +238,7 @@ public class ActionScript3DeobfuscatorTest extends ActionScriptTestBase { + "a:jump c\r\n" + "c:pushbyte 4\r\n" + "b:pushbyte 3\r\n"); - Assert.assertEquals(res, "getlocal_0\r\n" + Assert.assertEquals(res, "getlocal0\r\n" + "pushscope\r\n" + "pushbyte 3\r\n" + "pushbyte 4\r\n" diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3Test.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3Test.java index 395cde4b4..ddf31d88f 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3Test.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3Test.java @@ -35,7 +35,9 @@ import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; @@ -49,13 +51,13 @@ import org.testng.annotations.Test; */ public class ActionScript3Test extends ActionScriptTestBase { - private SWF swf; + private Map swfMap = new HashMap<>(); @BeforeClass public void init() throws IOException, InterruptedException { //Main.initLogging(false); - swf = new SWF(new BufferedInputStream(new FileInputStream("testdata/flashdevelop/bin/flashdevelop.swf")), false); - + swfMap.put("standard", new SWF(new BufferedInputStream(new FileInputStream("testdata/flashdevelop/bin/flashdevelop.swf")), false)); + swfMap.put("assembled", new SWF(new BufferedInputStream(new FileInputStream("testdata/custom/bin/custom.swf")), false)); Configuration.autoDeobfuscate.set(false); Configuration.simplifyExpressions.set(false); @@ -64,13 +66,14 @@ public class ActionScript3Test extends ActionScriptTestBase { Configuration.showMethodBodyId.set(false); } - private void decompileMethod(String methodName, String expectedResult, boolean isStatic) { + private void decompileMethod(String swfIdentifier, String methodName, String expectedResult, boolean isStatic) { String className = methodName.substring(0, 1).toUpperCase() + methodName.substring(1); int clsIndex = -1; int scriptIndex = -1; ABC abc = null; + SWF swf = swfMap.get(swfIdentifier); List abcs = new ArrayList<>(); for (ABCContainerTag abcTag : swf.getAbcList()) { abcs.add(abcTag.getABC()); @@ -115,7 +118,7 @@ public class ActionScript3Test extends ActionScriptTestBase { DoABC2Tag tag = null; ABC abc = null; ScriptPack scriptPack = null; - for (Tag t : swf.getTags()) { + for (Tag t : swfMap.get("standard").getTags()) { if (t instanceof DoABC2Tag) { tag = (DoABC2Tag) t; abc = tag.getABC(); @@ -141,13 +144,13 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testArguments() { - decompileMethod("testArguments", "return arguments[0];\r\n", + decompileMethod("standard", "testArguments", "return arguments[0];\r\n", false); } @Test public void testCatchFinally() { - decompileMethod("testCatchFinally", "var a:* = 5;\r\n" + decompileMethod("standard", "testCatchFinally", "var a:* = 5;\r\n" + "try\r\n" + "{\r\n" + "a = 9;\r\n" @@ -166,7 +169,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testChain2() { - decompileMethod("testChain2", "var g:Array = null;\r\n" + decompileMethod("standard", "testChain2", "var g:Array = null;\r\n" + "var h:Boolean = false;\r\n" + "var extraLine:Boolean = false;\r\n" + "var r:int = 7;\r\n" @@ -186,7 +189,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testChainedAssignments() { - decompileMethod("testChainedAssignments", "var a:int = 0;\r\n" + decompileMethod("standard", "testChainedAssignments", "var a:int = 0;\r\n" + "var b:int = 0;\r\n" + "var c:int = 0;\r\n" + "var d:int = 0;\r\n" @@ -199,7 +202,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testComplexExpressions() { - decompileMethod("testComplexExpressions", "var i:int = 0;\r\n" + decompileMethod("standard", "testComplexExpressions", "var i:int = 0;\r\n" + "var j:int = 0;\r\n" + "j = i = i + (i = i + i++);\r\n", false); @@ -207,7 +210,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testContinueLevels() { - decompileMethod("testContinueLevels", "var b:* = undefined;\r\n" + decompileMethod("standard", "testContinueLevels", "var b:* = undefined;\r\n" + "var c:* = undefined;\r\n" + "var d:* = undefined;\r\n" + "var e:* = undefined;\r\n" @@ -273,7 +276,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testDecl2() { - decompileMethod("testDecl2", "var k:int = 0;\r\n" + decompileMethod("standard", "testDecl2", "var k:int = 0;\r\n" + "var i:int = 5;\r\n" + "i = i + 7;\r\n" + "if(i == 5)\r\n" @@ -289,7 +292,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testDeclarations() { - decompileMethod("testDeclarations", "var vall:* = undefined;\r\n" + decompileMethod("standard", "testDeclarations", "var vall:* = undefined;\r\n" + "var vstr:String = null;\r\n" + "var vint:int = 0;\r\n" + "var vuint:uint = 0;\r\n" @@ -309,7 +312,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testDefaultNotLastGrouped() { - decompileMethod("testDefaultNotLastGrouped", "var k:* = 10;\r\n" + decompileMethod("standard", "testDefaultNotLastGrouped", "var k:* = 10;\r\n" + "switch(k)\r\n" + "{\r\n" + "default:\r\n" @@ -327,7 +330,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testDoWhile() { - decompileMethod("testDoWhile", "var a:* = 8;\r\n" + decompileMethod("standard", "testDoWhile", "var a:* = 8;\r\n" + "do\r\n" + "{\r\n" + "trace(\"a=\" + a);\r\n" @@ -339,7 +342,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testDoWhile2() { - decompileMethod("testDoWhile2", "var k:int = 5;\r\n" + decompileMethod("standard", "testDoWhile2", "var k:int = 5;\r\n" + "do\r\n" + "{\r\n" + "k++;\r\n" @@ -358,9 +361,20 @@ public class ActionScript3Test extends ActionScriptTestBase { false); } + @Test + public void testDup() { + decompileMethod("standard", "testDup", "var a:Boolean = false;\r\n" + + "var b:Boolean = false;\r\n" + + "if(a = b)\r\n" + + "{\r\n" + + "trace(a);\r\n" + + "}\r\n", + false); + } + @Test public void testExpressions() { - decompileMethod("testExpressions", "var arr:Array = null;\r\n" + decompileMethod("standard", "testExpressions", "var arr:Array = null;\r\n" + "var i:int = 5;\r\n" + "var j:int = 5;\r\n" + "if((i = i = i / 2) == 1 || i == 2)\r\n" @@ -381,7 +395,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testFinallyZeroJump() { - decompileMethod("testFinallyZeroJump", "var str:String = param1;\r\n" + decompileMethod("standard", "testFinallyZeroJump", "var str:String = param1;\r\n" + "try\r\n" + "{\r\n" + "}\r\n" @@ -403,7 +417,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testFor() { - decompileMethod("testFor", "for(var a:* = 0; a < 10; a++)\r\n" + decompileMethod("standard", "testFor", "for(var a:* = 0; a < 10; a++)\r\n" + "{\r\n" + "trace(\"a=\" + a);\r\n" + "}\r\n", @@ -412,7 +426,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testForAnd() { - decompileMethod("testForAnd", "var x:Boolean = false;\r\n" + decompileMethod("standard", "testForAnd", "var x:Boolean = false;\r\n" + "var len:int = 5;\r\n" + "var a:int = 4;\r\n" + "var b:int = 7;\r\n" @@ -437,7 +451,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testForBreak() { - decompileMethod("testForBreak", "for(var a:* = 0; a < 10; a++)\r\n" + decompileMethod("standard", "testForBreak", "for(var a:* = 0; a < 10; a++)\r\n" + "{\r\n" + "if(a == 5)\r\n" + "{\r\n" @@ -450,7 +464,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testForContinue() { - decompileMethod("testForContinue", "for(var a:* = 0; a < 10; a = a + 1)\r\n" + decompileMethod("standard", "testForContinue", "for(var a:* = 0; a < 10; a = a + 1)\r\n" + "{\r\n" + "if(a == 9)\r\n" + "{\r\n" @@ -478,7 +492,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testForEach() { - decompileMethod("testForEach", "var list:Array = null;\r\n" + decompileMethod("standard", "testForEach", "var list:Array = null;\r\n" + "var item:* = undefined;\r\n" + "list = new Array();\r\n" + "list[0] = \"first\";\r\n" @@ -493,7 +507,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testForEachObjectArray() { - decompileMethod("testForEachObjectArray", "var list:Array = null;\r\n" + decompileMethod("standard", "testForEachObjectArray", "var list:Array = null;\r\n" + "var test:Array = null;\r\n" + "list = new Array();\r\n" + "list[0] = \"first\";\r\n" @@ -510,7 +524,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testForEachObjectAttribute() { - decompileMethod("testForEachObjectAttribute", "var list:Array = null;\r\n" + decompileMethod("standard", "testForEachObjectAttribute", "var list:Array = null;\r\n" + "list = new Array();\r\n" + "list[0] = \"first\";\r\n" + "list[1] = \"second\";\r\n" @@ -524,7 +538,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testForGoto() { - decompileMethod("testForGoto", "var c:int = 0;\r\n" + decompileMethod("standard", "testForGoto", "var c:int = 0;\r\n" + "var len:int = 5;\r\n" + "for(var i:uint = 0; i < len; i++)\r\n" + "{\r\n" @@ -549,7 +563,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testForIn() { - decompileMethod("testForIn", "var dic:Dictionary = null;\r\n" + decompileMethod("standard", "testForIn", "var dic:Dictionary = null;\r\n" + "var item:* = null;\r\n" + "for(item in dic)\r\n" + "{\r\n" @@ -564,7 +578,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testForXml() { - decompileMethod("testForXml", "var c:int = 0;\r\n" + decompileMethod("standard", "testForXml", "var c:int = 0;\r\n" + "var name:String = \"ahoj\";\r\n" + "var myXML:XML = \r\n" + "\r\n" @@ -597,7 +611,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testGotos() { - decompileMethod("testGotos", "var a:Boolean = true;\r\n" + decompileMethod("standard", "testGotos", "var a:Boolean = true;\r\n" + "var b:Boolean = false;\r\n" + "if(a)\r\n" + "{\r\n" @@ -629,7 +643,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testGotos2() { - decompileMethod("testGotos2", "var a:Boolean = true;\r\n" + decompileMethod("standard", "testGotos2", "var a:Boolean = true;\r\n" + "var b:Boolean = false;\r\n" + "var c:Boolean = true;\r\n" + "if(a)\r\n" @@ -653,7 +667,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testGotos3() { - decompileMethod("testGotos3", "var i:int = 0;\r\n" + decompileMethod("standard", "testGotos3", "var i:int = 0;\r\n" + "var a:int = 5;\r\n" + "if(a > 5)\r\n" + "{\r\n" @@ -680,7 +694,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testGotos4() { - decompileMethod("testGotos4", "var a:int = 5;\r\n" + decompileMethod("standard", "testGotos4", "var a:int = 5;\r\n" + "if(a > 3)\r\n" + "{\r\n" + "if(a < 7)\r\n" @@ -701,7 +715,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testGotos5() { - decompileMethod("testGotos5", "var j:int = 0;\r\n" + decompileMethod("standard", "testGotos5", "var j:int = 0;\r\n" + "var s:String = \"A\";\r\n" + "for(var i:int = 0; i < 10; i++)\r\n" + "{\r\n" @@ -725,7 +739,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testGotos6() { - decompileMethod("testGotos6", "var a:Boolean = true;\r\n" + decompileMethod("standard", "testGotos6", "var a:Boolean = true;\r\n" + "var s:String = \"a\";\r\n" + "if(a)\r\n" + "{\r\n" @@ -750,7 +764,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testGotos7() { - decompileMethod("testGotos7", "for(var i:int = 0; i < 10; i++)\r\n" + decompileMethod("standard", "testGotos7", "for(var i:int = 0; i < 10; i++)\r\n" + "{\r\n" + "switch(i)\r\n" + "{\r\n" @@ -779,13 +793,13 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testHello() { - decompileMethod("testHello", "trace(\"hello\");\r\n", + decompileMethod("standard", "testHello", "trace(\"hello\");\r\n", false); } @Test public void testIf() { - decompileMethod("testIf", "var a:* = 5;\r\n" + decompileMethod("standard", "testIf", "var a:* = 5;\r\n" + "if(a == 7)\r\n" + "{\r\n" + "trace(\"onTrue\");\r\n" @@ -795,7 +809,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testIfElse() { - decompileMethod("testIfElse", "var a:* = 5;\r\n" + decompileMethod("standard", "testIfElse", "var a:* = 5;\r\n" + "if(a == 7)\r\n" + "{\r\n" + "trace(\"onTrue\");\r\n" @@ -809,7 +823,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testIfInIf() { - decompileMethod("testIfInIf", "var k:int = 5;\r\n" + decompileMethod("standard", "testIfInIf", "var k:int = 5;\r\n" + "if(k > 5 && k < 20)\r\n" + "{\r\n" + "trace(\"A\");\r\n" @@ -833,7 +847,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testInc2() { - decompileMethod("testInc2", "var a:* = [1];\r\n" + decompileMethod("standard", "testInc2", "var a:* = [1];\r\n" + "a[this.getInt()]++;\r\n" + "var d:* = a[this.getInt()]++;\r\n" + "var e:* = ++a[this.getInt()];\r\n" @@ -846,7 +860,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testIncDec() { - decompileMethod("testIncDec", "var a:* = 5;\r\n" + decompileMethod("standard", "testIncDec", "var a:* = 5;\r\n" + "var b:* = 0;\r\n" + "trace(\"++var\");\r\n" + "b = ++a;\r\n" @@ -885,7 +899,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testInlineFunctions() { - decompileMethod("testInlineFunctions", "var first:String = null;\r\n" + decompileMethod("standard", "testInlineFunctions", "var first:String = null;\r\n" + "first = \"value1\";\r\n" + "var traceParameter:Function = function(aParam:String):String\r\n" + "{\r\n" @@ -907,7 +921,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testInnerFunctions() { - decompileMethod("testInnerFunctions", "var s:int = 0;\r\n" + decompileMethod("standard", "testInnerFunctions", "var s:int = 0;\r\n" + "var innerFunc:Function = function(b:String):*\r\n" + "{\r\n" + "trace(b);\r\n" @@ -923,7 +937,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testInnerIf() { - decompileMethod("testInnerIf", "var a:* = 5;\r\n" + decompileMethod("standard", "testInnerIf", "var a:* = 5;\r\n" + "var b:* = 4;\r\n" + "if(a == 5)\r\n" + "{\r\n" @@ -950,7 +964,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testInnerTry() { - decompileMethod("testInnerTry", "try\r\n" + decompileMethod("standard", "testInnerTry", "try\r\n" + "{\r\n" + "try\r\n" + "{\r\n" @@ -975,7 +989,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testLogicalComputing() { - decompileMethod("testLogicalComputing", "var b:Boolean = false;\r\n" + decompileMethod("standard", "testLogicalComputing", "var b:Boolean = false;\r\n" + "var i:* = 5;\r\n" + "var j:* = 7;\r\n" + "if(i > j)\r\n" @@ -989,14 +1003,14 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testManualConvert() { - decompileMethod("testManualConvert", "trace(\"String(this).length\");\r\n" + decompileMethod("standard", "testManualConvert", "trace(\"String(this).length\");\r\n" + "trace(String(this).length);\r\n", false); } @Test public void testMissingDefault() { - decompileMethod("testMissingDefault", "var jj:int = 1;\r\n" + decompileMethod("standard", "testMissingDefault", "var jj:int = 1;\r\n" + "switch(jj)\r\n" + "{\r\n" + "case 1:\r\n" @@ -1013,7 +1027,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testMultipleCondition() { - decompileMethod("testMultipleCondition", "var a:* = 5;\r\n" + decompileMethod("standard", "testMultipleCondition", "var a:* = 5;\r\n" + "var b:* = 8;\r\n" + "var c:* = 9;\r\n" + "if((a <= 4 || b <= 8) && c == 7)\r\n" @@ -1029,7 +1043,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testNamedAnonFunctions() { - decompileMethod("testNamedAnonFunctions", "var test:* = new function testFunc(param1:*, param2:int, param3:Array):Boolean\r\n" + decompileMethod("standard", "testNamedAnonFunctions", "var test:* = new function testFunc(param1:*, param2:int, param3:Array):Boolean\r\n" + "{\r\n" + "return (param1 as TestClass2).attrib1 == 5;\r\n" + "};\r\n", @@ -1038,7 +1052,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testNames() { - decompileMethod("testNames", "var ns:* = this.getNamespace();\r\n" + decompileMethod("standard", "testNames", "var ns:* = this.getNamespace();\r\n" + "var name:* = this.getName();\r\n" + "var a:* = ns::unnamespacedFunc();\r\n" + "var b:* = ns::[name];\r\n" @@ -1049,19 +1063,19 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testParamNames() { - decompileMethod("testParamNames", "return firstp + secondp + thirdp;\r\n", + decompileMethod("standard", "testParamNames", "return firstp + secondp + thirdp;\r\n", false); } @Test public void testParamsCount() { - decompileMethod("testParamsCount", "return firstp;\r\n", + decompileMethod("standard", "testParamsCount", "return firstp;\r\n", false); } @Test public void testPrecedence() { - decompileMethod("testPrecedence", "var a:* = 0;\r\n" + decompileMethod("standard", "testPrecedence", "var a:* = 0;\r\n" + "a = (5 + 6) * 7;\r\n" + "a = 5 * (2 + 3);\r\n" + "a = 5 + 6 * 7;\r\n" @@ -1078,7 +1092,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testPrecedenceX() { - decompileMethod("testPrecedenceX", "var a:* = 5;\r\n" + decompileMethod("standard", "testPrecedenceX", "var a:* = 5;\r\n" + "var b:* = 2;\r\n" + "var c:* = 3;\r\n" + "var d:* = a << (b >>> c);\r\n" @@ -1088,7 +1102,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testProperty() { - decompileMethod("testProperty", "var d:* = new TestClass1();\r\n" + decompileMethod("standard", "testProperty", "var d:* = new TestClass1();\r\n" + "var k:* = 7 + 8;\r\n" + "if(k == 15)\r\n" + "{\r\n" @@ -1099,7 +1113,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testRegExp() { - decompileMethod("testRegExp", "var a1:* = /[a-z\\r\\n0-9\\\\]+/i;\r\n" + decompileMethod("standard", "testRegExp", "var a1:* = /[a-z\\r\\n0-9\\\\]+/i;\r\n" + "var a2:* = /[a-z\\r\\n0-9\\\\]+/i;\r\n" + "var b1:* = /[0-9AB]+/;\r\n" + "var b2:* = /[0-9AB]+/;\r\n", @@ -1108,14 +1122,14 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testRest() { - decompileMethod("testRest", "trace(\"firstRest:\" + restval[0]);\r\n" + decompileMethod("standard", "testRest", "trace(\"firstRest:\" + restval[0]);\r\n" + "return firstp;\r\n", false); } @Test public void testStrictEquals() { - decompileMethod("testStrictEquals", "var k:int = 6;\r\n" + decompileMethod("standard", "testStrictEquals", "var k:int = 6;\r\n" + "if(this.f() !== this.f())\r\n" + "{\r\n" + "trace(\"is eight\");\r\n" @@ -1125,7 +1139,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testStringConcat() { - decompileMethod("testStringConcat", "var k:int = 8;\r\n" + decompileMethod("standard", "testStringConcat", "var k:int = 8;\r\n" + "this.traceIt(\"hello\" + 5 * 6);\r\n" + "this.traceIt(\"hello\" + (k - 1));\r\n" + "this.traceIt(\"hello\" + 5 + 6);\r\n", @@ -1134,7 +1148,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testStrings() { - decompileMethod("testStrings", "trace(\"hello\");\r\n" + decompileMethod("standard", "testStrings", "trace(\"hello\");\r\n" + "trace(\"quotes:\\\"hello!\\\"\");\r\n" + "trace(\"backslash: \\\\ \");\r\n" + "trace(\"single quotes: \\'hello!\\'\");\r\n" @@ -1144,7 +1158,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testSwitch() { - decompileMethod("testSwitch", "var a:* = 5;\r\n" + decompileMethod("standard", "testSwitch", "var a:* = 5;\r\n" + "switch(a)\r\n" + "{\r\n" + "case 57 * a:\r\n" @@ -1163,7 +1177,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testSwitchComma() { - decompileMethod("testSwitchComma", "var b:int = 5;\r\n" + decompileMethod("standard", "testSwitchComma", "var b:int = 5;\r\n" + "var a:String = \"A\";\r\n" + "switch(a)\r\n" + "{\r\n" @@ -1180,7 +1194,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testSwitchDefault() { - decompileMethod("testSwitchDefault", "var a:* = 5;\r\n" + decompileMethod("standard", "testSwitchDefault", "var a:* = 5;\r\n" + "switch(a)\r\n" + "{\r\n" + "case 57 * a:\r\n" @@ -1202,7 +1216,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testTernarOperator() { - decompileMethod("testTernarOperator", "var a:* = 5;\r\n" + decompileMethod("standard", "testTernarOperator", "var a:* = 5;\r\n" + "var b:* = 4;\r\n" + "var c:* = 4;\r\n" + "var d:* = 78;\r\n" @@ -1213,7 +1227,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testTry() { - decompileMethod("testTry", "var i:int = 0;\r\n" + decompileMethod("standard", "testTry", "var i:int = 0;\r\n" + "i = 7;\r\n" + "try\r\n" + "{\r\n" @@ -1238,7 +1252,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testTryReturn() { - decompileMethod("testTryReturn", "var i:int = 0;\r\n" + decompileMethod("standard", "testTryReturn", "var i:int = 0;\r\n" + "var b:Boolean = false;\r\n" + "try\r\n" + "{\r\n" @@ -1266,7 +1280,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testTryReturn2() { - decompileMethod("testTryReturn2", "var c:Boolean = false;\r\n" + decompileMethod("standard", "testTryReturn2", "var c:Boolean = false;\r\n" + "trace(\"before\");\r\n" + "var a:Boolean = true;\r\n" + "var b:Boolean = false;\r\n" @@ -1309,7 +1323,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testUsagesTry() { - decompileMethod("testUsagesTry", "var k:int = 5;\r\n" + decompileMethod("standard", "testUsagesTry", "var k:int = 5;\r\n" + "switch(k)\r\n" + "{\r\n" + "case 0:\r\n" @@ -1343,7 +1357,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testVector() { - decompileMethod("testVector", "var v:Vector. = new Vector.();\r\n" + decompileMethod("standard", "testVector", "var v:Vector. = new Vector.();\r\n" + "v.push(\"hello\");\r\n" + "v[0] = \"hi\";\r\n" + "v[5 * 8 - 39] = \"hi2\";\r\n" @@ -1353,14 +1367,14 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testVector2() { - decompileMethod("testVector2", "var a:Vector.> = new Vector.>();\r\n" + decompileMethod("standard", "testVector2", "var a:Vector.> = new Vector.>();\r\n" + "var b:Vector. = new [10,20,30];\r\n", false); } @Test public void testWhileAnd() { - decompileMethod("testWhileAnd", "var a:int = 5;\r\n" + decompileMethod("standard", "testWhileAnd", "var a:int = 5;\r\n" + "var b:int = 10;\r\n" + "while(a < 10 && b > 1)\r\n" + "{\r\n" @@ -1374,7 +1388,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testWhileContinue() { - decompileMethod("testWhileContinue", "var a:* = 5;\r\n" + decompileMethod("standard", "testWhileContinue", "var a:* = 5;\r\n" + "while(true)\r\n" + "{\r\n" + "if(a == 9)\r\n" @@ -1396,7 +1410,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testWhileTry() { - decompileMethod("testWhileTry", "while(true)\r\n" + decompileMethod("standard", "testWhileTry", "while(true)\r\n" + "{\r\n" + "try\r\n" + "{\r\n" @@ -1419,7 +1433,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testWhileTry2() { - decompileMethod("testWhileTry2", "var j:* = undefined;\r\n" + decompileMethod("standard", "testWhileTry2", "var j:* = undefined;\r\n" + "for(var i:* = 0; i < 100; i++)\r\n" + "{\r\n" + "try\r\n" @@ -1445,7 +1459,7 @@ public class ActionScript3Test extends ActionScriptTestBase { @Test public void testXml() { - decompileMethod("testXml", "var g:XML = null;\r\n" + decompileMethod("standard", "testXml", "var g:XML = null;\r\n" + "var name:String = \"ahoj\";\r\n" + "var myXML:XML = \r\n" + "\r\n" @@ -1559,6 +1573,24 @@ public class ActionScript3Test extends ActionScriptTestBase { false); } + @Test + public void testDupAssignment() { + decompileMethod("assembled", "testDupAssignment", "var _loc1_:int = 0;\r\n" + + "var _loc2_:int = 10;\r\n" + + "if(_loc1_ = _loc2_)\r\n" + + "{\r\n" + + "trace(_loc2_);\r\n" + + "}\r\n", + false); + } + + @Test + public void testIncrement() { + decompileMethod("assembled", "testIncrement", "super();\r\n" + + "b = a++;\r\n", + false); + } + @Test public void testOptionalParameters() { String methodName = "testOptionalParameters"; @@ -1567,7 +1599,7 @@ public class ActionScript3Test extends ActionScriptTestBase { int clsIndex = -1; DoABC2Tag tag = null; ABC abc = null; - for (Tag t : swf.getTags()) { + for (Tag t : swfMap.get("standard").getTags()) { if (t instanceof DoABC2Tag) { tag = (DoABC2Tag) t; abc = tag.getABC(); diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/generators/AS3Generator.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/generators/AS3Generator.java index 69a354b65..51144ef4a 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/generators/AS3Generator.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/generators/AS3Generator.java @@ -33,7 +33,10 @@ import com.jpexs.decompiler.flash.tags.DoABC2Tag; import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.graph.ScopeStack; import java.io.BufferedInputStream; +import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; @@ -48,13 +51,10 @@ import java.util.TreeMap; */ public class AS3Generator { - public static void main(String[] args) throws Exception { - Configuration.autoDeobfuscate.set(false); - SWF swf = new SWF(new BufferedInputStream(new FileInputStream("testdata/flashdevelop/bin/flashdevelop.swf")), false); + private static void useFile(StringBuilder s, File f, String identifier) throws FileNotFoundException, IOException, InterruptedException { + SWF swf = new SWF(new BufferedInputStream(new FileInputStream(f)), false); DoABC2Tag tag = null; List scriptPacks = swf.getAS3Packs(); - - StringBuilder s = new StringBuilder(); Map sortedPacks = new TreeMap<>(); for (ScriptPack pack : scriptPacks) { sortedPacks.put(pack.getClassPath().toRawString(), pack); @@ -72,10 +72,15 @@ public class AS3Generator { String name = t.getName(abc).getName(abc.constants, null, true, true); String clsName = pack.getClassPath().className; String lower = clsName.substring(0, 1).toLowerCase() + clsName.substring(1); + if (lower.equals("testOptionalParameters")) { //SPECIAL: ignored + continue; + } if (name.equals("run")) { s.append("@Test\r\npublic void "); s.append(lower); s.append("(){\r\ndecompileMethod(\""); + s.append(identifier); + s.append("\",\""); s.append(lower); s.append("\", "); HighlightedTextWriter src = new HighlightedTextWriter(new CodeFormatting(), false); @@ -102,6 +107,16 @@ public class AS3Generator { } } } + } + + public static void main(String[] args) throws Exception { + Configuration.autoDeobfuscate.set(false); + + + StringBuilder s = new StringBuilder(); + + useFile(s, new File("testdata/flashdevelop/bin/flashdevelop.swf"), "standard"); + useFile(s, new File("testdata/custom/bin/custom.swf"), "assembled"); try (PrintWriter pw = new PrintWriter("as3_teststub.java")) { pw.println(s.toString()); diff --git a/libsrc/ffdec_lib/testdata/custom/abc/custom-0.abc b/libsrc/ffdec_lib/testdata/custom/abc/custom-0.abc new file mode 100644 index 0000000000000000000000000000000000000000..a5c5603e0e8580ce0c271c42d5055fb1686ad099 GIT binary patch literal 881 zcmZWnO>5gg6x^r%(#rC;Bd1Ezv^1wu;-!Tid^2?jffgT~*Y?$i~_j`Y%Nx z{XKn>Xh6+7tafK+-^^RoA*TfEEn&NLvhbG=ake@&JCoXspA{eWBTmw0g)fq9^AP_M zmz!;34NKC*a%(c1b+2%pK5ZshmfWY0cumaieww)*mh|`)O}9@e&un~e-mk3Pj7Ot* zvA#2>^Y!Csa`|QSS?jN(yQk#ACh4GNKCaA9>fp3WR+)ZVrxrt-?Qvanky^8j=Qi1y zN_bG`YfTO-u6l}b`4j~o+xg0DJMm&sLf@0j8gyz+rqi?O?bYn|@@jH^*58`P_0H5J z?f-f-Yj)jN;es0fG84Brf`NE1fPe;KpK}tZeV>ydxb2XKov<7B!hSg51Thu*vdLXg zo?s2X*=l!MwUZ-Cj=J3*h`uKWAb7bON^qpZBydTk4!P?D-craZ11!YzKRq5vG?g6~(S0(jXG;!vg-N;nWlNF|8?7ce?uNC9O) zBnT9^sBsm|^*P?BIMBOX=NBYWJ@moB7h4H5}AA)KOkL*Eg+yaI1i+ zgRMT~+K@=4@p5e@%|cT2YiTzzCHo$D};W^$B@C;UE8G&%a%#C((28 e>1Z|p6bk^xMHvfE5?yFvzE`*e*Ko8F2>%5Qu*w?% literal 0 HcmV?d00001 diff --git a/libsrc/ffdec_lib/testdata/custom/abc/custom-0/Main.class.asasm b/libsrc/ffdec_lib/testdata/custom/abc/custom-0/Main.class.asasm new file mode 100644 index 000000000..b7edb79f2 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/custom/abc/custom-0/Main.class.asasm @@ -0,0 +1,87 @@ +class + refid "Main" + instance QName(PackageNamespace(""), "Main") + extends QName(PackageNamespace("flash.display"), "Sprite") + flag SEALED + flag PROTECTEDNS + protectedns ProtectedNamespace("Main") + iinit + refid "Main/instance/init" + body + maxstack 3 + localcount 1 + initscopedepth 9 + maxscopedepth 10 + code + getlocal0 + pushscope + + getlocal0 + constructsuper 0 + + getlex Multiname("stage", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher")]) + iffalse L9 + + getlocal0 + callpropvoid Multiname("init", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher")]), 0 + + jump L15 + +L9: + findpropstrict Multiname("addEventListener", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher")]) + getlex Multiname("Event", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher"), PackageNamespace("flash.events")]) + getproperty Multiname("ADDED_TO_STAGE", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher")]) + getlocal0 + getproperty Multiname("init", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher")]) + callpropvoid Multiname("addEventListener", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher")]), 2 + +L15: + returnvoid + end ; code + end ; body + end ; method + trait method QName(PrivateNamespace(null, "Main/instance"), "init") + method + refid "Main/instance/Main/instance/init" + param QName(PackageNamespace("flash.events"), "Event") + returns QName(PackageNamespace(""), "void") + flag HAS_OPTIONAL + optional Null() + body + maxstack 3 + localcount 2 + initscopedepth 9 + maxscopedepth 10 + code + getlocal0 + pushscope + + findpropstrict Multiname("removeEventListener", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher")]) + getlex Multiname("Event", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher"), PackageNamespace("flash.events")]) + getproperty Multiname("ADDED_TO_STAGE", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher")]) + getlocal0 + getproperty Multiname("init", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher")]) + callpropvoid Multiname("removeEventListener", [PrivateNamespace(null, "Main/instance"), PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), ProtectedNamespace("Main"), StaticProtectedNs("Main"), StaticProtectedNs("flash.display:Sprite"), StaticProtectedNs("flash.display:DisplayObjectContainer"), StaticProtectedNs("flash.display:InteractiveObject"), StaticProtectedNs("flash.display:DisplayObject"), StaticProtectedNs("flash.events:EventDispatcher")]), 2 + + returnvoid + end ; code + end ; body + end ; method + end ; trait + end ; instance + cinit + refid "Main/class/init" + body + maxstack 1 + localcount 1 + initscopedepth 8 + maxscopedepth 9 + code + getlocal0 + pushscope + + returnvoid + end ; code + end ; body + end ; method +end ; class diff --git a/libsrc/ffdec_lib/testdata/custom/abc/custom-0/Main.script.asasm b/libsrc/ffdec_lib/testdata/custom/abc/custom-0/Main.script.asasm new file mode 100644 index 000000000..6bb8477cb --- /dev/null +++ b/libsrc/ffdec_lib/testdata/custom/abc/custom-0/Main.script.asasm @@ -0,0 +1,49 @@ +script + sinit + refid "Main/init" + body + maxstack 2 + localcount 1 + initscopedepth 1 + maxscopedepth 8 + code + getlocal0 + pushscope + + getscopeobject 0 + getlex QName(PackageNamespace(""), "Object") + pushscope + + getlex QName(PackageNamespace("flash.events"), "EventDispatcher") + pushscope + + getlex QName(PackageNamespace("flash.display"), "DisplayObject") + pushscope + + getlex QName(PackageNamespace("flash.display"), "InteractiveObject") + pushscope + + getlex QName(PackageNamespace("flash.display"), "DisplayObjectContainer") + pushscope + + getlex QName(PackageNamespace("flash.display"), "Sprite") + pushscope + + getlex Multiname("Sprite", [PrivateNamespace(null, "Main"), PackageNamespace(""), PackageInternalNs(""), Namespace("http://adobe.com/AS3/2006/builtin"), PackageNamespace("tests"), PackageNamespace("flash.display")]) + newclass "Main" + popscope + popscope + popscope + popscope + popscope + popscope + initproperty QName(PackageNamespace(""), "Main") + + returnvoid + end ; code + end ; body + end ; method + trait class QName(PackageNamespace(""), "Main") slotid 1 + #include "Main.class.asasm" + end ; trait +end ; script diff --git a/libsrc/ffdec_lib/testdata/custom/abc/custom-0/custom-0.main.abc b/libsrc/ffdec_lib/testdata/custom/abc/custom-0/custom-0.main.abc new file mode 100644 index 0000000000000000000000000000000000000000..1479e4356824aeb86d7ffd8b09c1ad3274edfc57 GIT binary patch literal 1058 zcmaJB1nKjhehZ`67*Br6sY2{@BV%P;ELV||jZ2xR(Rw*d zlIS+R*MgHV=katUGen~}QcP(o>E?0prl2|;jZQ~DF2_GEE{A8Q&L~Qjci}_f=9bWx zMXdBBa#hP`$h1&R=W^9JkCj}7Qx$DwQ3zo@oXzsIuTi3;E`o`3a~CG_lUd=gT|$GB z)8T)#mnrtjNpEIom-S*}c0tN)iOJ62VDQhS4(3WN2mO9HTTJB1baCGwUVQ3*^!?BM z$vV1IQB3b2;-sZFz1YaoRmo}{vqXirvh}+4myg1fUX`SqMKtTV#1*FJwisf_?R804 z^njtB<$>4sI-cuwy{$}R+r2%{G980~NwDQKYV~RpZ~_&n1f`+@Vh6;&!3~pBn^T9=8t0Vrs=!R>5=Ml91;^qY z*xApS9iVMwg8hPXlIHO>JYzyEVIhDzAk0A6NC!ZM0m4Nhd$kav$V7wyp@29ril71p zMcCG5rXZ<*racJ=Yd`hVa};bhO@z`hM|C~IwG-GkmGp*>9jx;(!NRJg{&n@4u4XjB zy48o&mnZ-~==edy4_bcE^aINedRJ&SKXal}Dd<58QwBhpk(+A4z?8CX>K~$~L+khB zQS#I@w14e!Tmvn0Z9y{Ut<1u`g55dOwE5ajl-gNYyH0TFWT~&E* O=4H*gS9o`BX!;MF`{_0S literal 0 HcmV?d00001 diff --git a/libsrc/ffdec_lib/testdata/custom/abc/custom-0/custom-0.main.asasm b/libsrc/ffdec_lib/testdata/custom/abc/custom-0/custom-0.main.asasm new file mode 100644 index 000000000..bfefaa9e3 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/custom/abc/custom-0/custom-0.main.asasm @@ -0,0 +1,10 @@ +#version 4 +program + minorversion 16 + majorversion 46 + + #include "Main.script.asasm" + #include "tests/TestDupAssignment.script.asasm" + #include "tests/TestIncrement.script.asasm" + +end ; program diff --git a/libsrc/ffdec_lib/testdata/custom/abc/custom-0/tests/TestDupAssignment.class.asasm b/libsrc/ffdec_lib/testdata/custom/abc/custom-0/tests/TestDupAssignment.class.asasm new file mode 100644 index 000000000..3905318f7 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/custom/abc/custom-0/tests/TestDupAssignment.class.asasm @@ -0,0 +1,77 @@ +class + refid "tests:TestDupAssignment" + instance QName(PackageNamespace("tests"), "TestDupAssignment") + extends QName(PackageNamespace(""), "Object") + flag SEALED + flag PROTECTEDNS + protectedns ProtectedNamespace("tests:TestDupAssignment") + iinit + refid "tests:TestDupAssignment/instance/init" + body + maxstack 1 + localcount 1 + initscopedepth 4 + maxscopedepth 5 + code + getlocal0 + pushscope + + getlocal0 + constructsuper 0 + + returnvoid + end ; code + end ; body + end ; method + trait method QName(PackageNamespace(""), "run") + method + refid "tests:TestDupAssignment/instance/run" + returns QName(PackageNamespace(""), "void") + body + maxstack 2 + localcount 4 + initscopedepth 4 + maxscopedepth 5 + code + getlocal0 + pushscope + + pushbyte 0 + setlocal1 + + pushbyte 10 + setlocal2 + + getlocal2 + dup + convert_i + setlocal1 + iffalse L15 + + findpropstrict Multiname("trace", [PrivateNamespace(null, "tests:TestDupAssignment/instance/run"), PrivateNamespace(null, "tests:TestDupAssignment"), PackageNamespace(""), PackageNamespace("tests"), PackageInternalNs("tests"), Namespace("http://adobe.com/AS3/2006/builtin"), ProtectedNamespace("tests:TestDupAssignment"), StaticProtectedNs("tests:TestDupAssignment")]) + getlocal2 + callpropvoid Multiname("trace", [PrivateNamespace(null, "tests:TestDupAssignment/instance/run"), PrivateNamespace(null, "tests:TestDupAssignment"), PackageNamespace(""), PackageNamespace("tests"), PackageInternalNs("tests"), Namespace("http://adobe.com/AS3/2006/builtin"), ProtectedNamespace("tests:TestDupAssignment"), StaticProtectedNs("tests:TestDupAssignment")]), 1 + +L15: + returnvoid + end ; code + end ; body + end ; method + end ; trait + end ; instance + cinit + refid "tests:TestDupAssignment/class/init" + body + maxstack 1 + localcount 1 + initscopedepth 3 + maxscopedepth 4 + code + getlocal0 + pushscope + + returnvoid + end ; code + end ; body + end ; method +end ; class diff --git a/libsrc/ffdec_lib/testdata/custom/abc/custom-0/tests/TestDupAssignment.script.asasm b/libsrc/ffdec_lib/testdata/custom/abc/custom-0/tests/TestDupAssignment.script.asasm new file mode 100644 index 000000000..22e6ec155 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/custom/abc/custom-0/tests/TestDupAssignment.script.asasm @@ -0,0 +1,29 @@ +script + sinit + refid "tests:TestDupAssignment/init" + body + maxstack 2 + localcount 1 + initscopedepth 1 + maxscopedepth 3 + code + getlocal0 + pushscope + + findpropstrict Multiname("TestDupAssignment", [PackageNamespace("tests")]) + getlex QName(PackageNamespace(""), "Object") + pushscope + + getlex Multiname("Object", [PrivateNamespace(null, "tests:TestDupAssignment"), PackageNamespace(""), PackageNamespace("tests"), PackageInternalNs("tests"), Namespace("http://adobe.com/AS3/2006/builtin")]) + newclass "tests:TestDupAssignment" + popscope + initproperty QName(PackageNamespace("tests"), "TestDupAssignment") + + returnvoid + end ; code + end ; body + end ; method + trait class QName(PackageNamespace("tests"), "TestDupAssignment") + #include "TestDupAssignment.class.asasm" + end ; trait +end ; script diff --git a/libsrc/ffdec_lib/testdata/custom/abc/custom-0/tests/TestIncrement.class.asasm b/libsrc/ffdec_lib/testdata/custom/abc/custom-0/tests/TestIncrement.class.asasm new file mode 100644 index 000000000..9063ae29e --- /dev/null +++ b/libsrc/ffdec_lib/testdata/custom/abc/custom-0/tests/TestIncrement.class.asasm @@ -0,0 +1,71 @@ +class + refid "tests:TestIncrement" + instance QName(PackageNamespace("tests"), "TestIncrement") + extends QName(PackageNamespace(""), "Object") + flag SEALED + flag PROTECTEDNS + protectedns ProtectedNamespace("tests:TestIncrement") + iinit + refid "tests:TestIncrement/instance/init" + body + maxstack 1 + localcount 1 + initscopedepth 4 + maxscopedepth 5 + code + getlocal0 + pushscope + + getlocal0 + constructsuper 0 + + returnvoid + end ; code + end ; body + end ; method + trait method QName(PackageNamespace(""), "run") + method + refid "tests:TestIncrement/instance/run" + returns QName(PackageNamespace(""), "void") + body + maxstack 2 + localcount 4 + initscopedepth 4 + maxscopedepth 5 + code + getlocal0 + pushscope + getlocal0 + constructsuper 0 + getlex QName(PrivateNamespace("myns"),"a") + convert_d + dup + increment + findpropstrict QName(PrivateNamespace("myns"),"a") + swap + setproperty QName(PrivateNamespace("myns"),"a") + findproperty QName(PackageNamespace(""),"b") + swap + setproperty QName(PackageNamespace(""),"b") + returnvoid + end ; code + end ; body + end ; method + end ; trait + end ; instance + cinit + refid "tests:TestIncrement/class/init" + body + maxstack 1 + localcount 1 + initscopedepth 3 + maxscopedepth 4 + code + getlocal0 + pushscope + + returnvoid + end ; code + end ; body + end ; method +end ; class diff --git a/libsrc/ffdec_lib/testdata/custom/abc/custom-0/tests/TestIncrement.script.asasm b/libsrc/ffdec_lib/testdata/custom/abc/custom-0/tests/TestIncrement.script.asasm new file mode 100644 index 000000000..71c49373c --- /dev/null +++ b/libsrc/ffdec_lib/testdata/custom/abc/custom-0/tests/TestIncrement.script.asasm @@ -0,0 +1,29 @@ +script + sinit + refid "tests:TestIncrement/init" + body + maxstack 2 + localcount 1 + initscopedepth 1 + maxscopedepth 3 + code + getlocal0 + pushscope + + findpropstrict Multiname("TestIncrement", [PackageNamespace("tests")]) + getlex QName(PackageNamespace(""), "Object") + pushscope + + getlex Multiname("Object", [PrivateNamespace(null, "tests:TestIncrement"), PackageNamespace(""), PackageNamespace("tests"), PackageInternalNs("tests"), Namespace("http://adobe.com/AS3/2006/builtin")]) + newclass "tests:TestIncrement" + popscope + initproperty QName(PackageNamespace("tests"), "TestIncrement") + + returnvoid + end ; code + end ; body + end ; method + trait class QName(PackageNamespace("tests"), "TestIncrement") + #include "TestIncrement.class.asasm" + end ; trait +end ; script diff --git a/libsrc/ffdec_lib/testdata/custom/bin/custom.swf b/libsrc/ffdec_lib/testdata/custom/bin/custom.swf new file mode 100644 index 0000000000000000000000000000000000000000..987881428221a63622ab16fb03e810cb75dc596f GIT binary patch literal 995 zcmV<9104KAS5qWh1^@tf+I>{rZre5#CM8M~75~PG?Kny6t^oqHv!%F0ff$J~uTF~$ z+X5`P2nuAiEYY!6SrQ~VPOkP0dxSm7u6DH>qd@lzdy9;e5<6~(60pSYobP<+kmp#} z0M7uZgaAB(pjX@g0Q^?^8v<|;Im7nPz1Q{YvFFEajt+N6jD>B(m`5FC%T^f7) z`}>C3GFq($XEfp)pIO%pKYqH~Nd$T{wj(!WZs6Aiwg$n39q#VlsXF#tG@L|UBI(!$ z_2`)TEH?IO(N5P1 z2DJX#qu2Fs>fJ?r!cHlI>?{iHJUFH$qMLRwHo_=yCN{5W$fc6thao~DoD4iS9?_^X z@!$KwG)=Lv3XUC7iv`P!dzS-9cj26#m%zBfs8^`XYFItxsmSdkEO(5j@ zE>jpc#g*jQ{wyHZ?e&g&@6Jx%ot|~y9A$fM9D3GGnytKqUIl!}T%Shyqz2)$n9Xmv zcj&W=HU zb5#Ric7j2HmvE8oXND`YAwJ1UoF~Z=(epF&B6n}j39~G5si!lOf<83+>t?@b_Dg1e z)$HqLzj_X~lQoh#6+vD|npA-hDQc3GBUM63sm#nB@Nq}~=fku3<0}7uU*tcWy{QdanFT+{w@Z$&6T61KWAk)|Bv_e13 zkzQ;4o&u7j&L%&Rbo@gZgY7bt`wO<^ArQVUco)Icx1Iz$4zdt3Vd!_J~za6aTSF^ zv*wWj_qQlBDW*%Qh0S3w+b%KVVDs71dTF1GvFIK}IVLX)XduinxNUQ@0WC30>N}o! zfs~oyyJbqvCJncY%}OA6838v!-x3v2KKE$REi=oZhS;l>^CCrO`0sUmoQT`uOOu;q$6 z<1wpLl5wyqJ7`kX;<6{Fxuz}PE2`~CqyDMTstKsdnp_h_xh7Y--z9J#Qch{r3^Ix| zY?;Y7Ii^WhkbL|$fhUn|CW@qLyV8B;f9`SK)?zc-Ru5WDQM`J@cCFfi%&#QSu{?Cr z+dO47+WT0El2ODo)ND#oJJ!}4Kqmp6SAi}9x(K+2g<_uQx;mdgu9>dfO#WmHmO~fB zwl@V6VL+ECF##orl&8!NIZCpil=6m7F5}+VAx1_(hoWP3OC?`ddg2}8P?yWZU&#pU zyAA|S`>(kLz(c%xfPHqz0>igFF-4=}MthU|rRVb?Scz+2sQcc%_lSyYh1whUsV`!p zKbnU;b*BUBKqL9hX!lleS`s;^YU+TtJS}a8{^W9)Z0I-Gn1C1`i8`)kF72nuKvgp> z7h-#+EfR^Hl + + + + Custom + + + + + + + +
+

Custom

+

Get Adobe Flash player

+
+ + \ No newline at end of file diff --git a/libsrc/ffdec_lib/testdata/custom/bin/js/swfobject.js b/libsrc/ffdec_lib/testdata/custom/bin/js/swfobject.js new file mode 100644 index 000000000..8eafe9dd8 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/custom/bin/js/swfobject.js @@ -0,0 +1,4 @@ +/* SWFObject v2.2 + is released under the MIT License +*/ +var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y0){for(var af=0;af0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad'}}aa.outerHTML='"+af+"";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libsrc/ffdec_lib/testdata/custom/obj/customConfig.old b/libsrc/ffdec_lib/testdata/custom/obj/customConfig.old new file mode 100644 index 000000000..286e9baaf --- /dev/null +++ b/libsrc/ffdec_lib/testdata/custom/obj/customConfig.old @@ -0,0 +1,50 @@ + + + + + 25.0 + false + true + + + CONFIG::debug + false + + + CONFIG::release + true + + + CONFIG::timeStamp + '26.01.2021' + + + CONFIG::air + false + + + CONFIG::mobile + false + + + CONFIG::desktop + false + + false + true + false + + C:\Dropbox\Programovani\JavaSE\FFDec\libsrc\ffdec_lib\testdata\custom\src + C:\Program Files (x86)\FlashDevelop\Library\AS3\classes + + + + C:\Dropbox\Programovani\JavaSE\FFDec\libsrc\ffdec_lib\testdata\custom\src\Main.as + + #FFFFFF + 30 + + 800 + 600 + + \ No newline at end of file diff --git a/libsrc/ffdec_lib/testdata/custom/obj/customConfig.xml b/libsrc/ffdec_lib/testdata/custom/obj/customConfig.xml new file mode 100644 index 000000000..330b76784 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/custom/obj/customConfig.xml @@ -0,0 +1,50 @@ + + + + + 25.0 + false + true + + + CONFIG::debug + false + + + CONFIG::release + true + + + CONFIG::timeStamp + '26.01.2021' + + + CONFIG::air + false + + + CONFIG::mobile + false + + + CONFIG::desktop + false + + false + false + false + + C:\Dropbox\Programovani\JavaSE\FFDec\libsrc\ffdec_lib\testdata\custom\src + C:\Program Files (x86)\FlashDevelop\Library\AS3\classes + + + + C:\Dropbox\Programovani\JavaSE\FFDec\libsrc\ffdec_lib\testdata\custom\src\Main.as + + #FFFFFF + 30 + + 800 + 600 + + \ No newline at end of file diff --git a/libsrc/ffdec_lib/testdata/custom/run_abcexport.bat b/libsrc/ffdec_lib/testdata/custom/run_abcexport.bat new file mode 100644 index 000000000..f95298490 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/custom/run_abcexport.bat @@ -0,0 +1,13 @@ +@echo off +set RABCDASM_PATH=c:\RABCDasm +rd /s /q .\abc +%RABCDASM_PATH%\abcexport.exe .\bin\custom.swf +mkdir .\abc +move .\bin\*.abc abc\>NUL +set ABC_DIR=.\abc + +for /F %%x in ('dir /B/D %ABC_DIR%') do ( + %RABCDASM_PATH%\rabcdasm.exe %ABC_DIR%\%%x +) + +pause \ No newline at end of file diff --git a/libsrc/ffdec_lib/testdata/custom/run_rabcasm.bat b/libsrc/ffdec_lib/testdata/custom/run_rabcasm.bat new file mode 100644 index 000000000..fdabc7fdf --- /dev/null +++ b/libsrc/ffdec_lib/testdata/custom/run_rabcasm.bat @@ -0,0 +1,5 @@ +@echo off +set RABCDASM_PATH=c:\RABCDasm +%RABCDASM_PATH%\rabcasm.exe abc\custom-0\custom-0.main.asasm +%RABCDASM_PATH%\abcreplace.exe bin\custom.swf 0 abc\custom-0\custom-0.main.abc +pause \ No newline at end of file diff --git a/libsrc/ffdec_lib/testdata/custom/src/Main.as b/libsrc/ffdec_lib/testdata/custom/src/Main.as new file mode 100644 index 000000000..711812473 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/custom/src/Main.as @@ -0,0 +1,29 @@ +package +{ + import flash.display.Sprite; + import flash.events.Event; + import tests.*; + + /** + * ... + * @author JPEXS + */ + public class Main extends Sprite + { + TestDupAssignment; + + public function Main() + { + if (stage) init(); + else addEventListener(Event.ADDED_TO_STAGE, init); + } + + private function init(e:Event = null):void + { + removeEventListener(Event.ADDED_TO_STAGE, init); + // entry point + } + + } + +} \ No newline at end of file diff --git a/libsrc/ffdec_lib/testdata/custom/src/tests/TestDupAssignment.as b/libsrc/ffdec_lib/testdata/custom/src/tests/TestDupAssignment.as new file mode 100644 index 000000000..7f94f9a53 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/custom/src/tests/TestDupAssignment.as @@ -0,0 +1,13 @@ +package tests +{ + public class TestDupAssignment + { + + public function run() : void + { + //TODO: replace this using RABCDasm + } + + } + +} \ No newline at end of file diff --git a/libsrc/ffdec_lib/testdata/flashdevelop/bin/flashdevelop.swf b/libsrc/ffdec_lib/testdata/flashdevelop/bin/flashdevelop.swf index 983c5d22f171ab6451f4570b414742f469d1eed0..58438be74be8a54cc6a1c3a3b0382a79d338ca41 100644 GIT binary patch literal 20163 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 syx+LjkG$CA=sb-Fh CONFIG::timeStamp - '25.01.2021' + '26.01.2021' CONFIG::air diff --git a/libsrc/ffdec_lib/testdata/flashdevelop/obj/flashdevelopConfig.xml b/libsrc/ffdec_lib/testdata/flashdevelop/obj/flashdevelopConfig.xml index 25aaf34a7..737c2507a 100644 --- a/libsrc/ffdec_lib/testdata/flashdevelop/obj/flashdevelopConfig.xml +++ b/libsrc/ffdec_lib/testdata/flashdevelop/obj/flashdevelopConfig.xml @@ -16,7 +16,7 @@ CONFIG::timeStamp - '25.01.2021' + '26.01.2021' CONFIG::air diff --git a/libsrc/ffdec_lib/testdata/flashdevelop/src/Main.as b/libsrc/ffdec_lib/testdata/flashdevelop/src/Main.as index 71a5f74bc..28961aa3c 100644 --- a/libsrc/ffdec_lib/testdata/flashdevelop/src/Main.as +++ b/libsrc/ffdec_lib/testdata/flashdevelop/src/Main.as @@ -24,6 +24,7 @@ package TestDefaultNotLastGrouped; TestDoWhile; TestDoWhile2; + TestDup; TestExpressions; TestFinallyZeroJump; TestFor; diff --git a/libsrc/ffdec_lib/testdata/flashdevelop/src/tests/TestDup.as b/libsrc/ffdec_lib/testdata/flashdevelop/src/tests/TestDup.as new file mode 100644 index 000000000..510820c50 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/flashdevelop/src/tests/TestDup.as @@ -0,0 +1,18 @@ +package tests +{ + public class TestDup + { + + public function run() : void + { + var a:Boolean; + var b:Boolean; + + if (a = b) + { + trace(a); + } + } + } + +} \ No newline at end of file diff --git a/libsrc/ffdec_lib/testdata/flashdevelop/src/tests/TestHello.as b/libsrc/ffdec_lib/testdata/flashdevelop/src/tests/TestHello.as index ee5573eff..14adab912 100644 --- a/libsrc/ffdec_lib/testdata/flashdevelop/src/tests/TestHello.as +++ b/libsrc/ffdec_lib/testdata/flashdevelop/src/tests/TestHello.as @@ -8,4 +8,4 @@ package tests trace("hello"); } } -} +} \ No newline at end of file