diff --git a/CHANGELOG.md b/CHANGELOG.md index ee911187b..a365abdd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file. ### Fixed - [#1769] AS3 - Missing some body trait variable declaration - [#1769], [#1888] AS3 - Missing casts like int() +- [#1890] AS3 - Chained assignments in some special cases ## [17.0.2] - 2022-11-22 ### Fixed @@ -2651,6 +2652,7 @@ All notable changes to this project will be documented in this file. [alpha 7]: https://github.com/jindrapetrik/jpexs-decompiler/releases/tag/alpha7 [#1769]: https://www.free-decompiler.com/flash/issues/1769 [#1888]: https://www.free-decompiler.com/flash/issues/1888 +[#1890]: https://www.free-decompiler.com/flash/issues/1890 [#1882]: https://www.free-decompiler.com/flash/issues/1882 [#1880]: https://www.free-decompiler.com/flash/issues/1880 [#1881]: https://www.free-decompiler.com/flash/issues/1881 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 35dcedfb5..04013c522 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 @@ -128,50 +128,52 @@ public abstract class GetLocalTypeIns extends InstructionDefinition { } } } - } - else if (setItem.value.getNotCoerced() instanceof SetLocalAVM2Item) { + } else 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; - } + int setLocalIp = localData.code.adr2pos(setLocal.getSrc().getAddress()); + if (localData.setLocalPosToGetLocalPos.get(setLocalIp).size() == 1) { + if ((setItem.value instanceof CoerceAVM2Item) || (setItem.value instanceof ConvertAVM2Item)) { + setItem.value.value = setLocal.value; + } else { + setItem.value = setLocal.value; + } - output.remove(output.size() - 1); + output.remove(output.size() - 1); - if (setItem instanceof SetPropertyAVM2Item) { - if ((setItem.value instanceof IncrementAVM2Item) || (setItem.value instanceof DecrementAVM2Item)) { - boolean isIncrement = (setItem.value instanceof IncrementAVM2Item); - if (setItem.value.value instanceof GetPropertyAVM2Item) { - SetPropertyAVM2Item setProp = (SetPropertyAVM2Item) setItem; - GetPropertyAVM2Item getProp = (GetPropertyAVM2Item) setItem.value.value; - if (getProp.object.getThroughDuplicate() == setProp.object) { - if (((FullMultinameAVM2Item) setProp.propertyName).compareSame((FullMultinameAVM2Item) getProp.propertyName)) { - if (getProp.object instanceof DuplicateItem) { - getProp.object = getProp.object.value; - } - if (isIncrement) { - setItem = new PreIncrementAVM2Item(setProp.getSrc(), localData.lineStartInstruction, getProp); - } else { - setItem = new PreDecrementAVM2Item(setProp.getSrc(), localData.lineStartInstruction, getProp); + if (setItem instanceof SetPropertyAVM2Item) { + if ((setItem.value instanceof IncrementAVM2Item) || (setItem.value instanceof DecrementAVM2Item)) { + boolean isIncrement = (setItem.value instanceof IncrementAVM2Item); + if (setItem.value.value instanceof GetPropertyAVM2Item) { + SetPropertyAVM2Item setProp = (SetPropertyAVM2Item) setItem; + GetPropertyAVM2Item getProp = (GetPropertyAVM2Item) setItem.value.value; + if (getProp.object.getThroughDuplicate() == setProp.object) { + if (((FullMultinameAVM2Item) setProp.propertyName).compareSame((FullMultinameAVM2Item) getProp.propertyName)) { + if (getProp.object instanceof DuplicateItem) { + getProp.object = getProp.object.value; + } + if (isIncrement) { + setItem = new PreIncrementAVM2Item(setProp.getSrc(), localData.lineStartInstruction, getProp); + } else { + setItem = new PreDecrementAVM2Item(setProp.getSrc(), localData.lineStartInstruction, getProp); + } } } } } } - } - stack.add(setItem); - return; + stack.add(setItem); + return; + } } } } } GraphTargetItem type = TypeItem.UNBOUNDED; - + if (localData.localRegTypes.containsKey(regId)) { - type = localData.localRegTypes.get(regId); + type = localData.localRegTypes.get(regId); } else if (computedValue != null) { type = computedValue.returnType(); } 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 23f1466e2..6886a654d 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 @@ -95,10 +95,16 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile + "var b:int = 0;\r\n" + "var c:int = 0;\r\n" + "var d:int = 0;\r\n" + + "var f:int = 0;\r\n" + "d = c = b = a = 5;\r\n" + "var e:TestClass2 = TestClass2.createMe(\"test\");\r\n" + "e.attrib1 = e.attrib2 = e.attrib3 = this.getCounter();\r\n" - + "this.traceIt(e.toString());\r\n", + + "this.traceIt(e.toString());\r\n" + + "prop = f = a = 4;\r\n" + + "if(f == 2)\r\n" + + "{\r\n" + + "trace(\"OK: \" + f);\r\n" + + "}\r\n", false); } diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicDecompileTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicDecompileTest.java index 9f5c00d2f..3d1dd02f9 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicDecompileTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassicDecompileTest.java @@ -95,10 +95,16 @@ public class ActionScript3ClassicDecompileTest extends ActionScript3DecompileTes + "var b:int = 0;\r\n" + "var c:int = 0;\r\n" + "var d:int = 0;\r\n" + + "var f:int = 0;\r\n" + "d = c = b = a = 5;\r\n" + "var e:TestClass2 = TestClass2.createMe(\"test\");\r\n" + "e.attrib1 = e.attrib2 = e.attrib3 = this.getCounter();\r\n" - + "this.traceIt(e.toString());\r\n", + + "this.traceIt(e.toString());\r\n" + + "this.prop = f = a = 4;\r\n" + + "if(f == 2)\r\n" + + "{\r\n" + + "trace(\"OK: \" + f);\r\n" + + "}\r\n", false); } diff --git a/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.air.swf b/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.air.swf index f7d28ee03..24d0585de 100644 Binary files a/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.air.swf and b/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.air.swf differ diff --git a/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.flex.swf b/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.flex.swf index 98a94258c..ddefa4b53 100644 Binary files a/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.flex.swf and b/libsrc/ffdec_lib/testdata/as3_new/bin/as3_new.flex.swf differ diff --git a/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestChainedAssignments.as b/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestChainedAssignments.as index 3972c2cf8..b40b9e4c0 100644 --- a/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestChainedAssignments.as +++ b/libsrc/ffdec_lib/testdata/as3_new/src/tests/TestChainedAssignments.as @@ -3,16 +3,23 @@ package tests public class TestChainedAssignments { + private var prop:int; + public function run():* { var a:int = 0; var b:int = 0; var c:int = 0; var d:int = 0; + var f:int = 0; d = c = b = a = 5; var e:TestClass2 = TestClass2.createMe("test"); e.attrib1 = e.attrib2 = e.attrib3 = this.getCounter(); this.traceIt(e.toString()); + prop = f = a = 4; + if (f == 2) { + trace("OK: " + f); + } } private function getCounter() : int