diff --git a/CHANGELOG.md b/CHANGELOG.md index 74728161c..b82408689 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. - [#1762] AS call on integer numbers parenthesis - [#1762] AS3 - Auto adding returnvoid/return undefined - [#1762] AS - switch detection (mostcommon pathpart) +- [#1763] AS3 - initialization of activation object in some cases ## [15.0.0] - 2021-11-29 ### Added @@ -2325,6 +2326,7 @@ All notable changes to this project will be documented in this file. [alpha 7]: https://github.com/jindrapetrik/jpexs-decompiler/releases/tag/alpha7 [#1761]: https://www.free-decompiler.com/flash/issues/1761 [#1762]: https://www.free-decompiler.com/flash/issues/1762 +[#1763]: https://www.free-decompiler.com/flash/issues/1763 [#1750]: https://www.free-decompiler.com/flash/issues/1750 [#1485]: https://www.free-decompiler.com/flash/issues/1485 [#1681]: https://www.free-decompiler.com/flash/issues/1681 diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/FinalProcessLocalData.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/FinalProcessLocalData.java index e39342e1a..d129f4959 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/FinalProcessLocalData.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/FinalProcessLocalData.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.graph.Loop; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2FinalProcessLocalData.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2FinalProcessLocalData.java new file mode 100644 index 000000000..941f76f88 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2FinalProcessLocalData.java @@ -0,0 +1,21 @@ +package com.jpexs.decompiler.flash.abc.avm2; + +import com.jpexs.decompiler.flash.FinalProcessLocalData; +import com.jpexs.decompiler.graph.Loop; +import java.util.HashMap; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class AVM2FinalProcessLocalData extends FinalProcessLocalData { + + public HashMap localRegNames; + + public AVM2FinalProcessLocalData(List loops, HashMap localRegNames) { + super(loops); + this.localRegNames = localRegNames; + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java index 061c21b77..c211c9b53 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java @@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.FinalProcessLocalData; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.AVM2LocalData; import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; +import com.jpexs.decompiler.flash.abc.avm2.AVM2FinalProcessLocalData; import com.jpexs.decompiler.flash.abc.avm2.CodeStats; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; @@ -46,6 +47,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushByteIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushScopeIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceAIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertIIns; +import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.ConstructAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.FilteredCheckAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.FindPropertyAVM2Item; @@ -114,6 +116,7 @@ import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; @@ -1966,6 +1969,24 @@ public class AVM2Graph extends Graph { Map localRegNames = body.getLocalRegNames(abc); loopi: for (int i = 0; i < list.size(); i++) { + if (list.get(i) instanceof SetPropertyAVM2Item) { + SetPropertyAVM2Item sp = (SetPropertyAVM2Item) list.get(i); + if (sp.object instanceof FindPropertyAVM2Item) { + if (sp.propertyName instanceof FullMultinameAVM2Item) { + FullMultinameAVM2Item propName = (FullMultinameAVM2Item) sp.propertyName; + if (sp.value instanceof LocalRegAVM2Item) { + LocalRegAVM2Item lr = (LocalRegAVM2Item) sp.value; + AVM2FinalProcessLocalData aLocalData = (AVM2FinalProcessLocalData) localData; + if (Objects.equals(propName.resolvedMultinameName, AVM2Item.localRegName(aLocalData.localRegNames, lr.regIndex))) { + list.remove(i); + i--; + continue loopi; + } + } + + } + } + } if (list.get(i) instanceof SetSlotAVM2Item) { SetSlotAVM2Item sslot = (SetSlotAVM2Item) list.get(i); if (sslot.slotObject instanceof NewActivationAVM2Item) { @@ -2155,7 +2176,7 @@ public class AVM2Graph extends Graph { @Override protected FinalProcessLocalData getFinalData(BaseLocalData localData, List loops, List throwStates) { - FinalProcessLocalData finalProcess = super.getFinalData(localData, loops, throwStates); + FinalProcessLocalData finalProcess = new AVM2FinalProcessLocalData(loops, ((AVM2LocalData) localData).localRegNames); finalProcess.registerUsage = ((AVM2LocalData) localData).setLocalPosToGetLocalPos; return finalProcess; } diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3AssembledDecompileTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3AssembledDecompileTest.java index e95a32d4a..01cf0321f 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3AssembledDecompileTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3AssembledDecompileTest.java @@ -16,6 +16,12 @@ public class ActionScript3AssembledDecompileTest extends ActionScript3DecompileT addSwf("assembled", "testdata/as3_assembled/bin/as3_assembled.swf"); } + @Test + public void testActivationProps() { + decompileMethod("assembled", "testActivationProps", "\r\n", + false); + } + @Test public void testDeclareReg() { decompileMethod("assembled", "testDeclareReg", "with(other)\r\n" diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicAirDecompileTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicAirDecompileTest.java index 3765548e9..4cd5aa870 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicAirDecompileTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicAirDecompileTest.java @@ -1039,7 +1039,6 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile decompileMethod("classic_air", "testInlineFunctions", "var first:String = \"value1\";\r\n" + "var traceParameter:Function = function(aParam:String):String\r\n" + "{\r\n" - + "aParam = aParam;\r\n" + "var second:String = \"value2\";\r\n" + "second = second + \"cc\";\r\n" + "var traceParam2:Function = function(bParam:String):String\r\n" @@ -1057,8 +1056,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testInnerFunctionScope() { - decompileMethod("classic_air", "testInnerFunctionScope", "a = a;\r\n" - + "var innerFunc:Function = function(b:String):*\r\n" + decompileMethod("classic_air", "testInnerFunctionScope", "var innerFunc:Function = function(b:String):*\r\n" + "{\r\n" + "testProm = 4;\r\n" + "trace(testProm);\r\n" @@ -1069,8 +1067,7 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile @Test public void testInnerFunctions() { - decompileMethod("classic_air", "testInnerFunctions", "a = a;\r\n" - + "var s:int = 0;\r\n" + decompileMethod("classic_air", "testInnerFunctions", "var s:int = 0;\r\n" + "var innerFunc:Function = function(b:String):*\r\n" + "{\r\n" + "trace(b);\r\n" diff --git a/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/as3_assembled-0.main.abc b/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/as3_assembled-0.main.abc index 7a52bbf8e..0654c160d 100644 Binary files a/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/as3_assembled-0.main.abc and b/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/as3_assembled-0.main.abc differ diff --git a/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/as3_assembled-0.main.asasm b/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/as3_assembled-0.main.asasm index 489896ae4..0f8b76834 100644 --- a/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/as3_assembled-0.main.asasm +++ b/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/as3_assembled-0.main.asasm @@ -29,5 +29,6 @@ program #include "tests/TestSwitchGoto.script.asasm" #include "tests/TestTryWhile.script.asasm" #include "tests/TestPushWhile.script.asasm" + #include "tests/TestActivationProps.script.asasm" ; place to add next end ; program diff --git a/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestActivationProps.class.asasm b/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestActivationProps.class.asasm new file mode 100644 index 000000000..f2e11ef7d --- /dev/null +++ b/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestActivationProps.class.asasm @@ -0,0 +1,76 @@ +class + refid "tests:TestActivationProps" + instance QName(PackageNamespace("tests"), "TestActivationProps") + extends QName(PackageNamespace(""), "Object") + flag SEALED + flag PROTECTEDNS + protectedns ProtectedNamespace("tests:TestActivationProps") + iinit + refid "tests:TestActivationProps/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:TestActivationProps/instance/run" + flag HAS_OPTIONAL + flag HAS_PARAM_NAMES + flag NEED_ACTIVATION + param QName(PackageNamespace(""),"int") + paramname "myvar" + returns QName(PackageNamespace(""), "void") + body + maxstack 2 + localcount 4 + initscopedepth 4 + maxscopedepth 5 + trait slot QName(PackageInternalNs("testing"),"myvar") + slotid 1 + type QName(PackageNamespace(""),"int") + end ; trait + code + debug 1, "myvar", 0, 0 + getlocal0 + pushscope + newactivation + dup + setlocal 6 + pushscope + findpropstrict QName(PackageInternalNs("testing"),"myvar") + getlocal1 + setproperty QName(PackageInternalNs("testing"),"myvar") + returnvoid + end ; code + end ; body + end ; method + end ; trait + end ; instance + cinit + refid "tests:TestActivationProps/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/as3_assembled/abc/as3_assembled-0/tests/TestActivationProps.script.asasm b/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestActivationProps.script.asasm new file mode 100644 index 000000000..711260a68 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestActivationProps.script.asasm @@ -0,0 +1,29 @@ +script + sinit + refid "tests:TestActivationProps/init" + body + maxstack 2 + localcount 1 + initscopedepth 1 + maxscopedepth 3 + code + getlocal0 + pushscope + + findpropstrict Multiname("TestActivationProps", [PackageNamespace("tests")]) + getlex QName(PackageNamespace(""), "Object") + pushscope + + getlex Multiname("Object", [PrivateNamespace(null, "tests:TestActivationProps"), PackageNamespace(""), PackageNamespace("tests"), PackageInternalNs("tests"), Namespace("http://adobe.com/AS3/2006/builtin")]) + newclass "tests:TestActivationProps" + popscope + initproperty QName(PackageNamespace("tests"), "TestActivationProps") + + returnvoid + end ; code + end ; body + end ; method + trait class QName(PackageNamespace("tests"), "TestActivationProps") + #include "TestActivationProps.class.asasm" + end ; trait +end ; script diff --git a/libsrc/ffdec_lib/testdata/as3_assembled/bin/as3_assembled.swf b/libsrc/ffdec_lib/testdata/as3_assembled/bin/as3_assembled.swf index 6fdb3d7a9..8025de6d4 100644 Binary files a/libsrc/ffdec_lib/testdata/as3_assembled/bin/as3_assembled.swf and b/libsrc/ffdec_lib/testdata/as3_assembled/bin/as3_assembled.swf differ