Fixed #1763 AS3 - initialization of activation object in some cases

This commit is contained in:
Jindra Petřík
2021-12-04 08:28:48 +01:00
parent 9e6548ceb0
commit 4197e4913b
11 changed files with 161 additions and 7 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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<Integer, String> localRegNames;
public AVM2FinalProcessLocalData(List<Loop> loops, HashMap<Integer, String> localRegNames) {
super(loops);
this.localRegNames = localRegNames;
}
}

View File

@@ -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<Integer, String> 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<Loop> loops, List<ThrowState> throwStates) {
FinalProcessLocalData finalProcess = super.getFinalData(localData, loops, throwStates);
FinalProcessLocalData finalProcess = new AVM2FinalProcessLocalData(loops, ((AVM2LocalData) localData).localRegNames);
finalProcess.registerUsage = ((AVM2LocalData) localData).setLocalPosToGetLocalPos;
return finalProcess;
}

View File

@@ -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"

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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