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 539d2fdb5..9137cbea2 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 @@ -27,7 +27,6 @@ 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.DecLocalAVM2Item; 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.GetPropertyAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.IncLocalAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item; @@ -47,11 +46,10 @@ import com.jpexs.decompiler.graph.DottedChain; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; import com.jpexs.decompiler.graph.TypeItem; -import com.jpexs.decompiler.graph.model.CommaExpressionItem; import com.jpexs.decompiler.graph.model.DuplicateItem; import com.jpexs.decompiler.graph.model.DuplicateSourceItem; +import com.jpexs.decompiler.graph.model.PushItem; import com.jpexs.decompiler.graph.model.SetTemporaryItem; -import com.jpexs.decompiler.graph.model.TemporaryItem; import java.util.List; /** @@ -126,6 +124,24 @@ public abstract class GetLocalTypeIns extends InstructionDefinition { stack.finishBlock(output); + if (!output.isEmpty()) { + if (output.get(output.size() - 1) instanceof SetLocalAVM2Item) { + SetLocalAVM2Item setLocal = (SetLocalAVM2Item) output.get(output.size() - 1); + if (setLocal.regIndex == regId) { + if (setLocal.getSrc() != null) { + if (localData.getSetLocalUsages(localData.code.adr2pos(setLocal.getSrc().getAddress())).size() == 1) { + if (output.size() >= 2 && output.get(output.size() - 2) instanceof PushItem) { + output.remove(output.size() - 1); + stack.moveToStack(output); + stack.push(setLocal.value); + return; + } + } + } + } + } + } + //TestIncDec7 AIR if (!output.isEmpty()) { GraphTargetItem lastOutput = output.get(output.size() - 1); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/SetTemporaryItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/SetTemporaryItem.java index 8913f4a83..874e76ca2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/SetTemporaryItem.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/model/SetTemporaryItem.java @@ -29,7 +29,7 @@ import java.util.List; import java.util.Set; /** - * Duplicate item. + * Set temporary item. * * @author JPEXS */ 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 d7762750c..b7ef968e9 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 @@ -92,8 +92,8 @@ public class ActionScript3AssembledDecompileTest extends ActionScript3DecompileT @Test public void testCollidingPublicTraits() { - decompileMethod("assembled", "testCollidingPublicTraits", "trace(\"ns1 = \" + this.a#87);\r\n" - + "trace(\"ns2 = \" + this.a#88);\r\n", + decompileMethod("assembled", "testCollidingPublicTraits", "trace(\"ns1 = \" + this.a#89);\r\n" + + "trace(\"ns2 = \" + this.a#90);\r\n", false); } @@ -363,6 +363,12 @@ public class ActionScript3AssembledDecompileTest extends ActionScript3DecompileT false); } + @Test + public void testSetGetLocalOnStack() { + decompileMethod("assembled", "testSetGetLocalOnStack", "this.arr[this.cnt++] = param1;\r\n", + false); + } + @Test public void testSetSlotDup() { decompileMethod("assembled", "testSetSlotDup", "var myslot:int;\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 0fab91785..52d7d2259 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 c12e584cb..31eebceb2 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 @@ -42,5 +42,6 @@ program #include "tests/TestPushPlacement.script.asasm" #include "tests/TestConstructDynamically.script.asasm" #include "tests/TestCollidingPublicTraits.script.asasm" + #include "tests/TestSetGetLocalOnStack.script.asasm" ; place to add next end ; program diff --git a/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestSetGetLocalOnStack.class.asasm b/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestSetGetLocalOnStack.class.asasm new file mode 100644 index 000000000..534768059 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestSetGetLocalOnStack.class.asasm @@ -0,0 +1,78 @@ +class + refid "tests:TestSetGetLocalOnStack" + instance QName(PackageNamespace("tests"), "TestSetGetLocalOnStack") + extends QName(PackageNamespace(""), "Object") + flag SEALED + flag PROTECTEDNS + protectedns ProtectedNamespace("tests:TestSetGetLocalOnStack") + iinit + refid "tests:TestSetGetLocalOnStack/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:TestSetGetLocalOnStack/instance/run" + param QName(PackageNamespace(""),"Object") + returns QName(PackageNamespace(""), "void") + body + maxstack 2 + localcount 4 + initscopedepth 4 + maxscopedepth 5 + code + getlocal0 + pushscope + getlocal0 + getproperty QName(PackageNamespace(""),"arr") + getlocal0 + dup + setlocal3 + getproperty QName(PackageNamespace(""),"cnt") + dup + increment_i + setlocal 4 + getlocal3 + getlocal 4 + setproperty QName(PackageNamespace(""),"cnt") + kill 4 + kill 3 + setlocal2 + getlocal2 + getlocal1 + setproperty MultinameL([PackageNamespace(""), PackageNamespace("MyTest")]) + returnvoid + end ; code + end ; body + end ; method + end ; trait + end ; instance + cinit + refid "tests:TestSetGetLocalOnStack/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/TestSetGetLocalOnStack.script.asasm b/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestSetGetLocalOnStack.script.asasm new file mode 100644 index 000000000..c980b6f46 --- /dev/null +++ b/libsrc/ffdec_lib/testdata/as3_assembled/abc/as3_assembled-0/tests/TestSetGetLocalOnStack.script.asasm @@ -0,0 +1,29 @@ +script + sinit + refid "tests:TestSetGetLocalOnStack/init" + body + maxstack 2 + localcount 1 + initscopedepth 1 + maxscopedepth 3 + code + getlocal0 + pushscope + + findpropstrict Multiname("TestSetGetLocalOnStack", [PackageNamespace("tests")]) + getlex QName(PackageNamespace(""), "Object") + pushscope + + getlex Multiname("Object", [PrivateNamespace(null, "tests:TestSetGetLocalOnStack"), PackageNamespace(""), PackageNamespace("tests"), PackageInternalNs("tests"), Namespace("http://adobe.com/AS3/2006/builtin")]) + newclass "tests:TestSetGetLocalOnStack" + popscope + initproperty QName(PackageNamespace("tests"), "TestSetGetLocalOnStack") + + returnvoid + end ; code + end ; body + end ; method + trait class QName(PackageNamespace("tests"), "TestSetGetLocalOnStack") + #include "TestSetGetLocalOnStack.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 8bdb6ef11..f968761bd 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