From e9063e487b4320b96a3dc1017225823c55146dd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sat, 11 Mar 2023 22:50:30 +0100 Subject: [PATCH] Fixed AS3 - getouterscope instruction support --- CHANGELOG.md | 2 +- .../decompiler/flash/abc/AVM2LocalData.java | 3 ++ .../decompiler/flash/abc/ScriptPack.java | 9 +++- .../decompiler/flash/abc/avm2/AVM2Code.java | 21 +++++----- .../deobfuscation/AVM2DeobfuscatorGetSet.java | 2 + .../AVM2DeobfuscatorSimpleOld.java | 2 + .../flash/abc/avm2/graph/AVM2Graph.java | 23 +++++++---- .../flash/abc/avm2/graph/AVM2GraphSource.java | 8 +--- .../instructions/InstructionDefinition.java | 5 ++- .../construction/NewFunctionIns.java | 5 ++- .../localregs/GetLocalTypeIns.java | 11 +++-- .../instructions/other/GetOuterScopeIns.java | 20 +++++++++ .../instructions/other/GetScopeObjectIns.java | 2 +- .../avm2/instructions/stack/PopScopeIns.java | 2 +- .../avm2/instructions/stack/PushScopeIns.java | 2 +- .../avm2/instructions/stack/PushWithIns.java | 2 +- .../flash/abc/avm2/model/ClassAVM2Item.java | 15 +++++++ .../abc/avm2/model/NewFunctionAVM2Item.java | 2 +- .../flash/abc/avm2/model/ThisAVM2Item.java | 16 ++++++- .../flash/abc/types/traits/Trait.java | 9 ++-- .../flash/abc/types/traits/TraitClass.java | 36 ++++++++++++---- .../flash/abc/types/traits/TraitFunction.java | 4 +- .../types/traits/TraitMethodGetterSetter.java | 4 +- .../abc/types/traits/TraitSlotConst.java | 3 +- .../flash/abc/types/traits/Traits.java | 16 ++++--- .../exporters/script/DependencyParser.java | 28 +++++++++++++ .../script/PcodeGraphVizExporter.java | 2 +- .../as3decompile/ActionScript3ClassTest.java | 39 ++++++++++++++++++ .../testdata/getouterscope/getouterscope.swf | Bin 0 -> 1029 bytes .../flash/gui/abc/ASMSourceEditorPane.java | 2 +- 30 files changed, 227 insertions(+), 68 deletions(-) create mode 100644 libsrc/ffdec_lib/testdata/getouterscope/getouterscope.swf diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d4bf9924..0dbb46685 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,7 @@ All notable changes to this project will be documented in this file. - AS3 p-code docs - deldescendants, negate_p operands - AS3 p-code - IGNORE_REST method flag incorrectly shown as EXPLICIT - [#1989] AS3 - Slow deobfuscation (AVM2DeobfuscatorSimpleOld) -- AS3 p-code - getouterscope instruction docs +- AS3 - getouterscope instruction support ### Changed - AS1/2/3 P-code - format Number values with EcmaScript toString function diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/AVM2LocalData.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/AVM2LocalData.java index 83a81bd82..8d403b46e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/AVM2LocalData.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/AVM2LocalData.java @@ -50,6 +50,8 @@ public class AVM2LocalData extends BaseLocalData { public HashMap localRegs; public ScopeStack scopeStack; + + public ScopeStack localScopeStack; public MethodBody methodBody; @@ -145,6 +147,7 @@ public class AVM2LocalData extends BaseLocalData { classIndex = localData.classIndex; localRegs = localData.localRegs; scopeStack = localData.scopeStack; + localScopeStack = localData.localScopeStack; methodBody = localData.methodBody; callStack = localData.callStack; abc = localData.abc; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java index 3a2aa3fe5..c603377c5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java @@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions; import com.jpexs.decompiler.flash.abc.avm2.instructions.debug.DebugFileIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.debug.DebugIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.debug.DebugLineIns; +import com.jpexs.decompiler.flash.abc.avm2.model.GlobalAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.parser.script.AbcIndexing; import com.jpexs.decompiler.flash.abc.types.ConvertData; import com.jpexs.decompiler.flash.abc.types.MethodBody; @@ -197,14 +198,18 @@ public class ScriptPack extends AS3ClassTreeItem { scriptInitializerIsEmpty = !writer.getMark(); } + ScopeStack scopeStack = new ScopeStack(); + scopeStack.push(new GlobalAVM2Item(null, null)); + + for (int t : traitIndices) { Trait trait = traits.get(t); Multiname name = trait.getName(abc); Namespace ns = name.getNamespace(abc.constants); if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) { - trait.convertPackaged(abcIndex, null, convertData, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList<>(), parallel); + trait.convertPackaged(abcIndex, null, convertData, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList<>(), parallel, scopeStack); } else { - trait.convert(abcIndex, null, convertData, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList<>(), parallel); + trait.convert(abcIndex, null, convertData, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList<>(), parallel, scopeStack); } } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java index 0f89ffa3d..431b480a8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java @@ -1486,7 +1486,7 @@ public class AVM2Code implements Cloneable { return pos2adr(getIpThroughJumpAndDebugLine(adr2pos(addr, true))); } - public ConvertOutput toSourceOutput(Set switchParts, List callStack, AbcIndexing abcIndex, Map> setLocalPosToGetLocalPos, boolean thisHasDefaultToPrimitive, Reference lineStartItem, String path, GraphPart part, boolean processJumps, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, ABC abc, MethodBody body, int start, int end, HashMap localRegNames, HashMap localRegTypes, List fullyQualifiedNames, boolean[] visited, HashMap localRegAssigmentIps) throws ConvertException, InterruptedException { + public ConvertOutput toSourceOutput(Set switchParts, List callStack, AbcIndexing abcIndex, Map> setLocalPosToGetLocalPos, boolean thisHasDefaultToPrimitive, Reference lineStartItem, String path, GraphPart part, boolean processJumps, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, ScopeStack localScopeStack, ABC abc, MethodBody body, int start, int end, HashMap localRegNames, HashMap localRegTypes, List fullyQualifiedNames, boolean[] visited, HashMap localRegAssigmentIps) throws ConvertException, InterruptedException { boolean debugMode = DEBUG_MODE; if (debugMode) { System.err.println("OPEN SubSource:" + start + "-" + end + " " + code.get(start).toString() + " to " + code.get(end).toString()); @@ -1531,7 +1531,7 @@ public class AVM2Code implements Cloneable { } if (debugMode) { - System.err.println("translating ip " + ip + " ins " + ins.toString() + " stack:" + stack.toString() + " scopeStack:" + scopeStack.toString()); + System.err.println("translating ip " + ip + " ins " + ins.toString() + " stack:" + stack.toString() + " localScopeStack:" + localScopeStack.toString()); } if (ins.definition instanceof NewFunctionIns) { if (ip + 1 <= end) { @@ -1560,7 +1560,7 @@ public class AVM2Code implements Cloneable { do { AVM2Instruction insAfter = ip + 1 < code.size() ? code.get(ip + 1) : null; if (insAfter == null) { - ins.definition.translate(switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, this, thisHasDefaultToPrimitive); + ins.definition.translate(switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, localScopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, this, thisHasDefaultToPrimitive); ip++; break; } @@ -1582,14 +1582,14 @@ public class AVM2Code implements Cloneable { //stack.add("(" + stack.pop() + ")||"); isAnd = false; } else { - ins.definition.translate(switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, this, thisHasDefaultToPrimitive); + ins.definition.translate(switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, localScopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, this, thisHasDefaultToPrimitive); ip++; break; //throw new ConvertException("Unknown pattern after DUP:" + insComparsion.toString()); } } while (ins.definition instanceof DupIns); } else if ((ins.definition instanceof ReturnValueIns) || (ins.definition instanceof ReturnVoidIns) || (ins.definition instanceof ThrowIns)) { - ins.definition.translate(switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, this, thisHasDefaultToPrimitive); + ins.definition.translate(switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, localScopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, this, thisHasDefaultToPrimitive); //ip = end + 1; break; } else if (ins.definition instanceof NewFunctionIns) { @@ -1607,12 +1607,12 @@ public class AVM2Code implements Cloneable { } AVM2Instruction psco = code.get(ip + 1 + plus); if (psco.definition instanceof GetScopeObjectIns) { - if (psco.operands[0] == scopeStack.size() - 1) { + if (psco.operands[0] == localScopeStack.size() - 1) { if (code.get(ip + plus + 2).definition instanceof SwapIns) { if (code.get(ip + plus + 4).definition instanceof PopScopeIns) { if (code.get(ip + plus + 3).definition instanceof SetPropertyIns) { functionName = abc.constants.getMultiname(code.get(ip + plus + 3).operands[0]).getName(abc.constants, fullyQualifiedNames, true, true); - scopeStack.pop();// with + localScopeStack.pop();// with output.remove(output.size() - 1); // with ip = ip + plus + 4; // +1 below } @@ -1625,13 +1625,13 @@ public class AVM2Code implements Cloneable { } } // What to do when hasDup is false? - ins.definition.translate(switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, this, thisHasDefaultToPrimitive); + ins.definition.translate(switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, localScopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, this, thisHasDefaultToPrimitive); NewFunctionAVM2Item nft = (NewFunctionAVM2Item) stack.peek(); nft.functionName = functionName; ip++; } else { try { - ins.definition.translate(switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, this, thisHasDefaultToPrimitive); + ins.definition.translate(switchParts, callStack, abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, localScopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, this, thisHasDefaultToPrimitive); } catch (RuntimeException re) { /*String last=""; int len=5; @@ -2059,11 +2059,10 @@ public class AVM2Code implements Cloneable { localRegTypes.put(i + 1, AbcIndexing.multinameToType(abc.method_info.get(methodIndex).param_types[i], abc.constants)); } - ScopeStack prevScopeStack = (ScopeStack) scopeStack.clone(); try { list = AVM2Graph.translateViaGraph(null, callStack, abcIndex, path, this, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localRegNames, localRegTypes, fullyQualifiedNames, staticOperation, localRegAssigmentIps, thisHasDefaultToPrimitive); } catch (SecondPassException spe) { - list = AVM2Graph.translateViaGraph(spe.getData(), callStack, abcIndex, path, this, abc, body, isStatic, scriptIndex, classIndex, localRegs, prevScopeStack, localRegNames, localRegTypes, fullyQualifiedNames, staticOperation, localRegAssigmentIps, thisHasDefaultToPrimitive); + list = AVM2Graph.translateViaGraph(spe.getData(), callStack, abcIndex, path, this, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localRegNames, localRegTypes, fullyQualifiedNames, staticOperation, localRegAssigmentIps, thisHasDefaultToPrimitive); } if (initTraits != null) { loopi: diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorGetSet.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorGetSet.java index d43e1d2c9..c201658b3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorGetSet.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorGetSet.java @@ -87,6 +87,7 @@ public class AVM2DeobfuscatorGetSet extends SWFDecompilerAdapter { } localData.scopeStack.clear(); + localData.localScopeStack.clear(); localData.localRegs.clear(); localData.localRegAssignmentIps.clear(); localData.localRegs.clear(); @@ -109,6 +110,7 @@ public class AVM2DeobfuscatorGetSet extends SWFDecompilerAdapter { localData.localRegs = new HashMap<>(body.max_regs); localData.localRegAssignmentIps = new HashMap<>(); localData.scopeStack = new ScopeStack(true); + localData.localScopeStack = new ScopeStack(true); List callStack = new ArrayList<>(); callStack.add(body); localData.callStack = callStack; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimpleOld.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimpleOld.java index d7638f687..b0e4bbef0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimpleOld.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimpleOld.java @@ -179,6 +179,7 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush } localData.scopeStack.clear(); + localData.localScopeStack.clear(); localData.localRegs.clear(); localData.localRegAssignmentIps.clear(); localData.localRegs.clear(); @@ -202,6 +203,7 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush localData.localRegs = new HashMap<>(body.max_regs); localData.localRegAssignmentIps = new HashMap<>(); localData.scopeStack = new ScopeStack(true); + localData.localScopeStack = new ScopeStack(true); List callStack = new ArrayList<>(); callStack.add(body); localData.callStack = callStack; 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 376ae42fa..ddb92e670 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 @@ -161,8 +161,8 @@ public class AVM2Graph extends Graph { return ret; } - public AVM2Graph(AbcIndexing abcIndex, AVM2Code code, ABC abc, MethodBody body, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, ScopeStack scopeStack, HashMap localRegNames, List fullyQualifiedNames, HashMap localRegAssigmentIps) { - super(new AVM2GraphSource(code, isStatic, scriptIndex, classIndex, localRegs, scopeStack, abc, body, localRegNames, fullyQualifiedNames, localRegAssigmentIps), getExceptionEntries(body)); + public AVM2Graph(AbcIndexing abcIndex, AVM2Code code, ABC abc, MethodBody body, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, ScopeStack scopeStack, ScopeStack localScopeStack, HashMap localRegNames, List fullyQualifiedNames, HashMap localRegAssigmentIps) { + super(new AVM2GraphSource(code, isStatic, scriptIndex, classIndex, localRegs, abc, body, localRegNames, fullyQualifiedNames, localRegAssigmentIps), getExceptionEntries(body)); this.avm2code = code; this.abc = abc; this.body = body; @@ -248,7 +248,8 @@ public class AVM2Graph extends Graph { TranslateStack finallyTryTargetStack = (TranslateStack) new TranslateStack("try_target"); AVM2LocalData localData2 = new AVM2LocalData(localData); - localData2.scopeStack = new ScopeStack(); + //localData2.scopeStack = new ScopeStack(); + localData2.localScopeStack = new ScopeStack(); List targetOutput; try { @@ -626,7 +627,8 @@ public class AVM2Graph extends Graph { } public static List translateViaGraph(SecondPassData secondPassData, List callStack, AbcIndexing abcIndex, String path, AVM2Code code, ABC abc, MethodBody body, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, ScopeStack scopeStack, HashMap localRegNames, HashMap localRegTypes, List fullyQualifiedNames, int staticOperation, HashMap localRegAssigmentIps, boolean thisHasDefaultToPrimitive) throws InterruptedException { - AVM2Graph g = new AVM2Graph(abcIndex, code, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localRegNames, fullyQualifiedNames, localRegAssigmentIps); + ScopeStack localScopeStack = new ScopeStack(); + AVM2Graph g = new AVM2Graph(abcIndex, code, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localScopeStack, localRegNames, fullyQualifiedNames, localRegAssigmentIps); AVM2LocalData localData = new AVM2LocalData(); localData.secondPassData = secondPassData; @@ -635,6 +637,7 @@ public class AVM2Graph extends Graph { localData.classIndex = classIndex; localData.localRegs = localRegs; localData.scopeStack = scopeStack; + localData.localScopeStack = localScopeStack; localData.methodBody = body; localData.callStack = callStack; localData.abc = abc; @@ -1063,7 +1066,8 @@ public class AVM2Graph extends Graph { st2.clear(); st2.add(new ExceptionAVM2Item(finallyException)); AVM2LocalData localData2 = new AVM2LocalData(localData); - localData2.scopeStack = new ScopeStack(); + //localData2.scopeStack = new ScopeStack(); + localData2.localScopeStack = new ScopeStack(); try { //We are assuming Finally target has only 1 part @@ -1181,7 +1185,8 @@ public class AVM2Graph extends Graph { } } AVM2LocalData localData2 = new AVM2LocalData(localData); - localData2.scopeStack = new ScopeStack(); + //localData2.scopeStack = new ScopeStack(); + localData2.localScopeStack = new ScopeStack(); List stopPart2 = new ArrayList<>(stopPart); List stopPartKind2 = new ArrayList<>(stopPartKind); @@ -1202,7 +1207,7 @@ public class AVM2Graph extends Graph { WithAVM2Item w = (WithAVM2Item) currentCatchCommands.get(0); if (w.scope instanceof LocalRegAVM2Item) { int regId = ((LocalRegAVM2Item) w.scope).regIndex; - for (GraphTargetItem item : localData.scopeStack) { + for (GraphTargetItem item : localData.localScopeStack) { if (item instanceof WithObjectAVM2Item) { WithObjectAVM2Item wo = (WithObjectAVM2Item) item; @@ -2381,8 +2386,8 @@ public class AVM2Graph extends Graph { AVM2LocalData aLocalData = (AVM2LocalData) localData; AVM2LocalData ret = new AVM2LocalData(aLocalData); ScopeStack copyScopeStack = new ScopeStack(); - copyScopeStack.addAll(ret.scopeStack); - ret.scopeStack = copyScopeStack; + copyScopeStack.addAll(ret.localScopeStack); + ret.localScopeStack = copyScopeStack; return ret; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphSource.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphSource.java index e424afaf0..ac252e6e0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphSource.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphSource.java @@ -53,8 +53,6 @@ public class AVM2GraphSource extends GraphSource { HashMap localRegs; - ScopeStack scopeStack; - ABC abc; MethodBody body; @@ -69,12 +67,11 @@ public class AVM2GraphSource extends GraphSource { return code; } - public AVM2GraphSource(AVM2Code code, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, ScopeStack scopeStack, ABC abc, MethodBody body, HashMap localRegNames, List fullyQualifiedNames, HashMap localRegAssigmentIp) { + public AVM2GraphSource(AVM2Code code, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, ABC abc, MethodBody body, HashMap localRegNames, List fullyQualifiedNames, HashMap localRegAssigmentIp) { this.code = code; this.isStatic = isStatic; this.classIndex = classIndex; this.localRegs = localRegs; - this.scopeStack = scopeStack; this.abc = abc; this.body = body; this.localRegNames = localRegNames; @@ -115,9 +112,8 @@ public class AVM2GraphSource extends GraphSource { @Override public List translatePart(Graph graph, GraphPart part, BaseLocalData localData, TranslateStack stack, int start, int end, int staticOperation, String path) throws InterruptedException { List ret = new ArrayList<>(); - ScopeStack newstack = ((AVM2LocalData) localData).scopeStack; Reference lineStartItem = new Reference<>(localData.lineStartInstruction); - ConvertOutput co = code.toSourceOutput(localData.allSwitchParts, ((AVM2LocalData) localData).callStack, ((AVM2LocalData) localData).abcIndex, ((AVM2LocalData) localData).setLocalPosToGetLocalPos, ((AVM2LocalData) localData).thisHasDefaultToPrimitive, lineStartItem, path, part, false, isStatic, scriptIndex, classIndex, localRegs, stack, newstack, abc, body, start, end, localRegNames, ((AVM2LocalData) localData).localRegTypes, fullyQualifiedNames, new boolean[size()], localRegAssigmentIps); + ConvertOutput co = code.toSourceOutput(localData.allSwitchParts, ((AVM2LocalData) localData).callStack, ((AVM2LocalData) localData).abcIndex, ((AVM2LocalData) localData).setLocalPosToGetLocalPos, ((AVM2LocalData) localData).thisHasDefaultToPrimitive, lineStartItem, path, part, false, isStatic, scriptIndex, classIndex, localRegs, stack, ((AVM2LocalData) localData).scopeStack, ((AVM2LocalData) localData).localScopeStack, abc, body, start, end, localRegNames, ((AVM2LocalData) localData).localRegTypes, fullyQualifiedNames, new boolean[size()], localRegAssigmentIps); localData.lineStartInstruction = lineStartItem.getVal(); ret.addAll(co.output); return ret; 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 b5cbaa7b9..0522d8b92 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 @@ -193,7 +193,7 @@ public abstract class InstructionDefinition implements Serializable { public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List output, String path) throws InterruptedException { } - public void translate(Set switchParts, List callStack, AbcIndexing abcIndex, Map> setLocalPosToGetLocalPos, Reference lineStartItem, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2Instruction ins, List output, MethodBody body, ABC abc, HashMap localRegNames, HashMap localRegTypes, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, AVM2Code code, boolean thisHasDefaultToPrimitive) throws InterruptedException { + public void translate(Set switchParts, List callStack, AbcIndexing abcIndex, Map> setLocalPosToGetLocalPos, Reference lineStartItem, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, ScopeStack localScopeStack, AVM2Instruction ins, List output, MethodBody body, ABC abc, HashMap localRegNames, HashMap localRegTypes, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, AVM2Code code, boolean thisHasDefaultToPrimitive) throws InterruptedException { AVM2LocalData localData = new AVM2LocalData(); localData.allSwitchParts = switchParts; localData.isStatic = isStatic; @@ -202,6 +202,7 @@ public abstract class InstructionDefinition implements Serializable { localData.lineStartInstruction = lineStartItem.getVal(); localData.localRegs = localRegs; localData.scopeStack = scopeStack; + localData.localScopeStack = localScopeStack; localData.methodBody = body; localData.callStack = callStack; localData.abc = abc; @@ -365,7 +366,7 @@ public abstract class InstructionDefinition implements Serializable { if (obj instanceof FindPropertyAVM2Item) { FindPropertyAVM2Item findProp = (FindPropertyAVM2Item) obj; - for (GraphTargetItem item : localData.scopeStack) { + for (GraphTargetItem item : localData.localScopeStack) { Multiname ret = searchSlotName(slotIndex, localData, item, ((FullMultinameAVM2Item) findProp.propertyName).multinameIndex, realObj); if (ret != null) { return ret; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewFunctionIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewFunctionIns.java index 95feb43fa..d139e73f7 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewFunctionIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/construction/NewFunctionIns.java @@ -40,7 +40,10 @@ public class NewFunctionIns extends InstructionDefinition { @Override public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List output, String path) { int methodIndex = ins.operands[0]; - NewFunctionAVM2Item function = new NewFunctionAVM2Item(ins, localData.lineStartInstruction, "", path, false, localData.scriptIndex, localData.classIndex, localData.abc, methodIndex, (ScopeStack) localData.scopeStack.clone()); + ScopeStack newScopeStack = new ScopeStack(); + newScopeStack.addAll(localData.scopeStack); + newScopeStack.addAll(localData.localScopeStack); + NewFunctionAVM2Item function = new NewFunctionAVM2Item(ins, localData.lineStartInstruction, "", path, false, localData.scriptIndex, localData.classIndex, localData.abc, methodIndex, newScopeStack); stack.push(function); } 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 bd2a190e0..c5682b845 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 @@ -28,6 +28,7 @@ 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.FullMultinameAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.GlobalAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.IncrementAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item; @@ -71,8 +72,12 @@ public abstract class GetLocalTypeIns extends InstructionDefinition { int regId = getRegisterId(ins); if (regId == 0) { - if ((localData.classIndex >= localData.getInstanceInfo().size()) || localData.classIndex < 0) { - stack.push(new ThisAVM2Item(ins, localData.lineStartInstruction, DottedChain.OBJECT /*?*/, false)); + if (localData.classIndex == -1) { + stack.push(new ThisAVM2Item(ins, localData.lineStartInstruction, DottedChain.parseNoSuffix("global"), false, false)); + return; + } + if ((localData.classIndex >= localData.getInstanceInfo().size())) { + stack.push(new ThisAVM2Item(ins, localData.lineStartInstruction, DottedChain.OBJECT /*?*/, false, false)); return; } if (localData.isStatic) { @@ -81,7 +86,7 @@ public abstract class GetLocalTypeIns extends InstructionDefinition { List ts = localData.getInstanceInfo().get(localData.classIndex).instance_traits.traits; boolean isBasicObject = localData.thisHasDefaultToPrimitive; Multiname m = localData.getInstanceInfo().get(localData.classIndex).getName(localData.getConstants()); - stack.push(new ThisAVM2Item(ins, localData.lineStartInstruction, m.getNameWithNamespace(localData.getConstants(), true), isBasicObject)); + stack.push(new ThisAVM2Item(ins, localData.lineStartInstruction, m.getNameWithNamespace(localData.getConstants(), true), isBasicObject, false)); } return; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetOuterScopeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetOuterScopeIns.java index a26d9d3bd..08aabae48 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetOuterScopeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetOuterScopeIns.java @@ -17,9 +17,16 @@ package com.jpexs.decompiler.flash.abc.avm2.instructions.other; 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.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.avm2.model.GlobalAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ThisAVM2Item; +import com.jpexs.decompiler.graph.DottedChain; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.TranslateStack; +import java.util.List; /** * @@ -31,6 +38,19 @@ public class GetOuterScopeIns extends InstructionDefinition { super(0x67, "getouterscope", new int[]{AVM2Code.DAT_SCOPE_INDEX}, false); } + @Override + public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List output, String path) { + int index = ins.operands[0]; + GraphTargetItem item = localData.scopeStack.get(index); + if (item instanceof ThisAVM2Item) { + if (((ThisAVM2Item)item).className.equals(DottedChain.parseNoSuffix("global"))) { + stack.push(new GlobalAVM2Item(null, null)); + return; + } + } + stack.push(item); + } + @Override public int getStackPopCount(AVM2Instruction ins, ABC abc) { return 0; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetScopeObjectIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetScopeObjectIns.java index 6c8c21aca..ff3f250e0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetScopeObjectIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetScopeObjectIns.java @@ -38,7 +38,7 @@ public class GetScopeObjectIns extends InstructionDefinition { @Override public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List output, String path) { int index = ins.operands[0]; - stack.push(localData.scopeStack.get(index)); + stack.push(localData.localScopeStack.get(index)); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PopScopeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PopScopeIns.java index 1295f3545..805f24216 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PopScopeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PopScopeIns.java @@ -46,7 +46,7 @@ public class PopScopeIns extends InstructionDefinition { @Override public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List output, String path) { - GraphTargetItem scope = localData.scopeStack.pop(); + GraphTargetItem scope = localData.localScopeStack.pop(); if (scope instanceof WithObjectAVM2Item) { scope = ((WithObjectAVM2Item) scope).scope; output.add(new WithEndAVM2Item(ins, localData.lineStartInstruction, scope)); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushScopeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushScopeIns.java index 450b6fb5a..8abb5962a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushScopeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushScopeIns.java @@ -65,7 +65,7 @@ public class PushScopeIns extends InstructionDefinition { } } - localData.scopeStack.push(top); + localData.localScopeStack.push(top); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushWithIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushWithIns.java index ab4530bf7..b05247642 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushWithIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/stack/PushWithIns.java @@ -40,7 +40,7 @@ public class PushWithIns extends InstructionDefinition { public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List output, String path) { GraphTargetItem w = stack.pop(); WithObjectAVM2Item wot = new WithObjectAVM2Item(ins, localData.lineStartInstruction, w); - localData.scopeStack.push(wot); + localData.localScopeStack.push(wot); output.add(new WithAVM2Item(ins, localData.lineStartInstruction, w)); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ClassAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ClassAVM2Item.java index 47689735b..0e7173a23 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ClassAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ClassAVM2Item.java @@ -16,8 +16,10 @@ */ package com.jpexs.decompiler.flash.abc.avm2.model; +import com.jpexs.decompiler.flash.IdentifiersDeobfuscation; import com.jpexs.decompiler.flash.abc.types.Multiname; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.graph.DottedChain; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TypeItem; import com.jpexs.decompiler.graph.model.LocalData; @@ -29,14 +31,27 @@ import com.jpexs.decompiler.graph.model.LocalData; public class ClassAVM2Item extends AVM2Item { public Multiname className; + + public DottedChain classNameAsStr; public ClassAVM2Item(Multiname className) { super(null, null, PRECEDENCE_PRIMARY); this.className = className; } + + public ClassAVM2Item(DottedChain className) { + super(null, null, PRECEDENCE_PRIMARY); + this.classNameAsStr = className; + } @Override public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) { + if (classNameAsStr != null) { + if (localData.fullyQualifiedNames != null && localData.fullyQualifiedNames.contains(classNameAsStr)) { + return writer.append(classNameAsStr.toPrintableString(true)); + } + return writer.append(IdentifiersDeobfuscation.printIdentifier(true, classNameAsStr.getLast())); + } return writer.append(className.getName(localData.constantsAvm2, localData.fullyQualifiedNames, false, true)); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/NewFunctionAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/NewFunctionAVM2Item.java index 71621e882..04e75bd3b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/NewFunctionAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/NewFunctionAVM2Item.java @@ -92,7 +92,7 @@ public class NewFunctionAVM2Item extends AVM2Item { if (body != null) { List callStack = new ArrayList<>(localData.callStack); callStack.add(body); - body.convert(callStack, localData.abcIndex, new ConvertData(), path + "/inner", ScriptExportMode.AS, isStatic, methodIndex, scriptIndex, classIndex, abc, null, new ScopeStack(), 0, new NulWriter(), localData.fullyQualifiedNames, null, false, new HashSet<>(localData.seenMethods)); + body.convert(callStack, localData.abcIndex, new ConvertData(), path + "/inner", ScriptExportMode.AS, isStatic, methodIndex, scriptIndex, classIndex, abc, null, scopeStack, 0, new NulWriter(), localData.fullyQualifiedNames, null, false, new HashSet<>(localData.seenMethods)); body.toString(callStack, localData.abcIndex, path + "/inner", ScriptExportMode.AS, abc, null, writer, localData.fullyQualifiedNames, new HashSet<>(localData.seenMethods)); } writer.endBlock(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ThisAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ThisAVM2Item.java index 64836b9c1..eb7448ac2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ThisAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ThisAVM2Item.java @@ -16,6 +16,7 @@ */ package com.jpexs.decompiler.flash.abc.avm2.model; +import com.jpexs.decompiler.flash.IdentifiersDeobfuscation; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions; @@ -41,12 +42,15 @@ public class ThisAVM2Item extends AVM2Item { public DottedChain className; public boolean basicObject; + + public boolean showClassName; - public ThisAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, DottedChain className, boolean basicObject) { + public ThisAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, DottedChain className, boolean basicObject, boolean showClassName) { super(instruction, lineStartIns, PRECEDENCE_PRIMARY); this.className = className; this.basicObject = basicObject; - getSrcData().localName = "this"; + this.showClassName = showClassName; + getSrcData().localName = "this"; } public boolean isBasicObject() { @@ -84,6 +88,14 @@ public class ThisAVM2Item extends AVM2Item { @Override public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) { + if (showClassName) { + if (className != null) { + if (localData.fullyQualifiedNames != null && localData.fullyQualifiedNames.contains(className)) { + return writer.append(className.toPrintableString(true)).append(".this"); + } + return writer.append(IdentifiersDeobfuscation.printIdentifier(true, className.getLast())).append(".this"); + } + } return writer.append("this"); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java index b5339ae73..45db33cd7 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java @@ -38,6 +38,7 @@ import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType; import com.jpexs.decompiler.flash.search.MethodId; import com.jpexs.decompiler.flash.tags.ABCContainerTag; import com.jpexs.decompiler.graph.DottedChain; +import com.jpexs.decompiler.graph.ScopeStack; import com.jpexs.helpers.Helper; import java.io.Serializable; import java.util.AbstractMap.SimpleEntry; @@ -391,7 +392,7 @@ public abstract class Trait implements Cloneable, Serializable { return writer; } - public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel, ScopeStack scopeStack) throws InterruptedException { } public abstract GraphTextWriter convertTraitHeader(ABC abc, GraphTextWriter writer); @@ -486,11 +487,11 @@ public abstract class Trait implements Cloneable, Serializable { return writer; } - public void convertPackaged(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + public void convertPackaged(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel, ScopeStack scopeStack) throws InterruptedException { Namespace ns = abc.constants.getMultiname(name_index).getNamespace(abc.constants); if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) { String nsname = ns.getName(abc.constants).toPrintableString(true); - convert(abcIndex, parent, convertData, path + nsname, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); + convert(abcIndex, parent, convertData, path + nsname, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel, scopeStack); } } @@ -500,7 +501,7 @@ public abstract class Trait implements Cloneable, Serializable { } public void convertHeader(Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { - convert(null, parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); + convert(null, parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel, new ScopeStack()); } public final Multiname getName(ABC abc) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java index 3d531a7db..9b1a6e400 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java @@ -18,9 +18,11 @@ package com.jpexs.decompiler.flash.abc.types.traits; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.avm2.model.CallPropertyAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.ClassAVM2Item; 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.GlobalAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.IntegerValueAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.ThisAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.parser.script.AbcIndexing; @@ -214,7 +216,7 @@ public class TraitClass extends Trait implements TraitWithSlot { } @Override - public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel, ScopeStack scopeStack) throws InterruptedException { fullyQualifiedNames = new ArrayList<>(); @@ -234,8 +236,8 @@ public class TraitClass extends Trait implements TraitWithSlot { } } else { convertData.thisHasDefaultToPrimitive = true; - } - + } + ScopeStack newScopeStack = (ScopeStack)scopeStack.clone(); //class initializer int bodyIndex = abc.findBodyIndex(classInfo.cinit_index); if (bodyIndex != -1) { @@ -243,11 +245,27 @@ public class TraitClass extends Trait implements TraitWithSlot { List ts = new ArrayList<>(); ts.add(classInfo.static_traits); List callStack = new ArrayList<>(); - callStack.add(abc.bodies.get(bodyIndex)); - abc.bodies.get(bodyIndex).convert(callStack, abcIndex, convertData, path +/*packageName +*/ "/" + instanceInfoName + ".staticinitializer", exportMode, true, classInfo.cinit_index, scriptIndex, class_info, abc, this, new ScopeStack(), GraphTextWriter.TRAIT_CLASS_INITIALIZER, writer, fullyQualifiedNames, ts, true, new HashSet<>()); + callStack.add(abc.bodies.get(bodyIndex)); + + if (!abc.instance_info.get(class_info).isInterface()) { + AbcIndexing.ClassIndex cls = abcIndex.findClass(AbcIndexing.multinameToType(abc.instance_info.get(class_info).name_index, abc.constants), abc, scriptIndex); + List clsList = new ArrayList<>(); + cls = cls.parent; + while(cls != null) { + clsList.add(0, cls); + cls = cls.parent; + } + for (AbcIndexing.ClassIndex cls2: clsList) { + newScopeStack.push(new ClassAVM2Item(cls2.abc.instance_info.get(cls2.index).getName(cls2.abc.constants).getNameWithNamespace(cls2.abc.constants, true))); + } + } + + abc.bodies.get(bodyIndex).convert(callStack, abcIndex, convertData, path +/*packageName +*/ "/" + instanceInfoName + ".staticinitializer", exportMode, true, classInfo.cinit_index, scriptIndex, class_info, abc, this, newScopeStack, GraphTextWriter.TRAIT_CLASS_INITIALIZER, writer, fullyQualifiedNames, ts, true, new HashSet<>()); + + newScopeStack.push(new ClassAVM2Item(abc.instance_info.get(class_info).getName(abc.constants))); classInitializerIsEmpty = !writer.getMark(); - } - + } + //constructor - instance initializer if (!instanceInfo.isInterface()) { bodyIndex = abc.findBodyIndex(instanceInfo.iinit_index); @@ -312,9 +330,9 @@ public class TraitClass extends Trait implements TraitWithSlot { } //static variables,constants & methods - classInfo.static_traits.convert(abcIndex, this, convertData, path +/*packageName +*/ "/" + instanceInfoName, abc, true, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel); + classInfo.static_traits.convert(abcIndex, this, convertData, path +/*packageName +*/ "/" + instanceInfoName, abc, true, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel, newScopeStack); - instanceInfo.instance_traits.convert(abcIndex, this, convertData, path +/*packageName +*/ "/" + instanceInfoName, abc, false, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel); + instanceInfo.instance_traits.convert(abcIndex, this, convertData, path +/*packageName +*/ "/" + instanceInfoName, abc, false, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel, newScopeStack); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitFunction.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitFunction.java index 66f880fc2..9b694b19b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitFunction.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitFunction.java @@ -103,7 +103,7 @@ public class TraitFunction extends Trait implements TraitWithSlot { } @Override - public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel, ScopeStack scopeStack) throws InterruptedException { fullyQualifiedNames = new ArrayList<>(); writeImports(abcIndex, scriptIndex, classIndex, false, abc, writer, getPackage(abc), fullyQualifiedNames); writer.startMethod(method_info); @@ -112,7 +112,7 @@ public class TraitFunction extends Trait implements TraitWithSlot { if (bodyIndex != -1) { List callStack = new ArrayList<>(); callStack.add(abc.bodies.get(bodyIndex)); - abc.bodies.get(bodyIndex).convert(callStack, abcIndex, convertData, path + "." + abc.constants.getMultiname(name_index).getName(abc.constants, fullyQualifiedNames, false, true), exportMode, isStatic, method_info, scriptIndex, classIndex, abc, this, new ScopeStack(), 0, writer, fullyQualifiedNames, null, true, new HashSet<>()); + abc.bodies.get(bodyIndex).convert(callStack, abcIndex, convertData, path + "." + abc.constants.getMultiname(name_index).getName(abc.constants, fullyQualifiedNames, false, true), exportMode, isStatic, method_info, scriptIndex, classIndex, abc, this, scopeStack, 0, writer, fullyQualifiedNames, null, true, new HashSet<>()); } writer.endMethod(); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitMethodGetterSetter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitMethodGetterSetter.java index 0bf7646b2..4e9ce2a84 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitMethodGetterSetter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitMethodGetterSetter.java @@ -108,7 +108,7 @@ public class TraitMethodGetterSetter extends Trait { } @Override - public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel, ScopeStack scopeStack) throws InterruptedException { if (classIndex < 0) { writeImports(abcIndex, scriptIndex, classIndex, isStatic, abc, writer, getPackage(abc), fullyQualifiedNames); } @@ -121,7 +121,7 @@ public class TraitMethodGetterSetter extends Trait { if (bodyIndex != -1) { List callStack = new ArrayList<>(); callStack.add(abc.bodies.get(bodyIndex)); - abc.bodies.get(bodyIndex).convert(callStack, abcIndex, convertData, path, exportMode, isStatic, method_info, scriptIndex, classIndex, abc, this, new ScopeStack(), 0, writer, fullyQualifiedNames, null, true, new HashSet<>()); + abc.bodies.get(bodyIndex).convert(callStack, abcIndex, convertData, path, exportMode, isStatic, method_info, scriptIndex, classIndex, abc, this, scopeStack, 0, writer, fullyQualifiedNames, null, true, new HashSet<>()); } } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java index cf913f855..2df3581b4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java @@ -37,6 +37,7 @@ import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType; import com.jpexs.decompiler.flash.search.MethodId; import com.jpexs.decompiler.graph.DottedChain; import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; import com.jpexs.decompiler.graph.model.LocalData; import com.jpexs.helpers.Helper; import java.util.ArrayList; @@ -193,7 +194,7 @@ public class TraitSlotConst extends Trait implements TraitWithSlot { } @Override - public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel, ScopeStack scopeStack) throws InterruptedException { getNameStr(writer, abc, fullyQualifiedNames); if (hasValueStr(abc, convertData)) { getValueStr(abcIndex,exportMode, parent, convertData, writer, abc, fullyQualifiedNames); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Traits.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Traits.java index e7fae60ed..dd78b0036 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Traits.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Traits.java @@ -32,6 +32,7 @@ import com.jpexs.decompiler.flash.helpers.NulWriter; import com.jpexs.decompiler.flash.search.MethodId; import com.jpexs.decompiler.graph.DottedChain; import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.ScopeStack; import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -133,8 +134,10 @@ public class Traits implements Cloneable, Serializable { ConvertData convertData; AbcIndexing abcIndex; + + ScopeStack scopeStack; - public TraitConvertTask(AbcIndexing abcIndex, Trait trait, Trait parent, ConvertData convertData, boolean makePackages, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, int traitIndex, boolean parallel) { + public TraitConvertTask(AbcIndexing abcIndex, Trait trait, Trait parent, ConvertData convertData, boolean makePackages, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, int traitIndex, boolean parallel, ScopeStack scopeStack) { this.trait = trait; this.parent = parent; this.convertData = convertData; @@ -150,14 +153,15 @@ public class Traits implements Cloneable, Serializable { this.traitIndex = traitIndex; this.parallel = parallel; this.abcIndex = abcIndex; + this.scopeStack = scopeStack; } @Override public Void call() throws InterruptedException { if (makePackages) { - trait.convertPackaged(abcIndex, parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); + trait.convertPackaged(abcIndex, parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel, scopeStack); } else { - trait.convert(abcIndex, parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel); + trait.convert(abcIndex, parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel, scopeStack); } return null; } @@ -248,10 +252,10 @@ public class Traits implements Cloneable, Serializable { return writer; } - public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, boolean makePackages, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException { + public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, boolean makePackages, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel, ScopeStack scopeStack) throws InterruptedException { if (!parallel || traits.size() < 2) { for (int t = 0; t < traits.size(); t++) { - TraitConvertTask task = new TraitConvertTask(abcIndex, traits.get(t), parent, convertData, makePackages, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, t, parallel); + TraitConvertTask task = new TraitConvertTask(abcIndex, traits.get(t), parent, convertData, makePackages, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, t, parallel, scopeStack); task.call(); } } else { @@ -261,7 +265,7 @@ public class Traits implements Cloneable, Serializable { futureResults = new ArrayList<>(); for (int t = 0; t < traits.size(); t++) { // each convert task needs a separate NulWriter, because they are executed parallel - TraitConvertTask task = new TraitConvertTask(abcIndex, traits.get(t), parent, convertData, makePackages, path, abc, isStatic, exportMode, scriptIndex, classIndex, new NulWriter(), fullyQualifiedNames, t, parallel); + TraitConvertTask task = new TraitConvertTask(abcIndex, traits.get(t), parent, convertData, makePackages, path, abc, isStatic, exportMode, scriptIndex, classIndex, new NulWriter(), fullyQualifiedNames, t, parallel, scopeStack); Future future = executor.submit(task); futureResults.add(future); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/DependencyParser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/DependencyParser.java index f917446c0..98a56be2b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/DependencyParser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/DependencyParser.java @@ -26,12 +26,14 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewFunction import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetLexIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetOuterScopeIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetPropertyIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetSuperIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetPropertyIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetSuperIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.types.AsTypeIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceIns; +import com.jpexs.decompiler.flash.abc.avm2.model.ClassAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.InitVectorAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.parser.script.AbcIndexing; import com.jpexs.decompiler.flash.abc.types.ABCException; @@ -42,6 +44,8 @@ import com.jpexs.decompiler.flash.abc.types.NamespaceSet; import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.graph.DottedChain; +import com.jpexs.decompiler.graph.TypeItem; +import java.util.ArrayList; import java.util.List; public class DependencyParser { @@ -153,6 +157,30 @@ public class DependencyParser { } } } + if (classIndex > -1 && ins.definition instanceof GetOuterScopeIns) { + if (ins.operands[0] > 0) { //first is global + DottedChain type = abc.instance_info.get(classIndex).getName(abc.constants).getNameWithNamespace(abc.constants, true); + AbcIndexing.ClassIndex cls = abcIndex.findClass(new TypeItem(type), abc, scriptIndex); + List clsList = new ArrayList<>(); + cls = cls.parent; + while(cls != null) { + clsList.add(0, cls); + cls = cls.parent; + } + if (ins.operands[0] < 1 + clsList.size()) { + AbcIndexing.ClassIndex cls2 = clsList.get(ins.operands[0] - 1); + DottedChain nimport = cls2.abc.instance_info.get(cls2.index).getName(cls2.abc.constants).getNameWithNamespace(cls2.abc.constants, true); + Dependency depExp = new Dependency(nimport, DependencyType.EXPRESSION); + if (!dependencies.contains(depExp)) { + dependencies.add(depExp); + } + } + } + + /*for (AbcIndexing.ClassIndex cls2: clsList) { + newScopeStack.push(new ClassAVM2Item(cls2.abc.instance_info.get(cls2.index).getName(cls2.abc.constants).getNameWithNamespace(cls2.abc.constants, true))); + } */ + } for (int k = 0; k < ins.definition.operands.length; k++) { if (ins.definition.operands[k] == AVM2Code.DAT_MULTINAME_INDEX) { int m = ins.operands[k]; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/PcodeGraphVizExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/PcodeGraphVizExporter.java index d642c2cac..7c244632c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/PcodeGraphVizExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/PcodeGraphVizExporter.java @@ -86,7 +86,7 @@ public class PcodeGraphVizExporter { } public void exportAs3(AbcIndexing abcIndex, ABC abc, MethodBody body, GraphTextWriter writer) throws InterruptedException { - AVM2Graph gr = new AVM2Graph(abcIndex, body.getCode(), abc, body, false, -1, -1, new HashMap<>(), new ScopeStack(), new HashMap<>(), new ArrayList<>(), new HashMap<>()); // body.getCode().visitCode(body)); + AVM2Graph gr = new AVM2Graph(abcIndex, body.getCode(), abc, body, false, -1, -1, new HashMap<>(), new ScopeStack(), new ScopeStack(), new HashMap<>(), new ArrayList<>(), new HashMap<>()); // body.getCode().visitCode(body)); export(gr, writer); } diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassTest.java index 8d10ec26a..1d1dda64b 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/as3decompile/ActionScript3ClassTest.java @@ -44,6 +44,7 @@ public class ActionScript3ClassTest extends ActionScript3DecompileTestBase { public void init() throws IOException, InterruptedException { addSwf("standard", "testdata/as3_new/bin/as3_new.flex.swf"); addSwf("assembled", "testdata/as3_assembled/bin/as3_assembled.swf"); + addSwf("getouterscope", "testdata/getouterscope/getouterscope.swf"); } private void decompileScriptPack(String swfId, String path, String expectedResult) { @@ -491,4 +492,42 @@ public class ActionScript3ClassTest extends ActionScript3DecompileTestBase { + " }\n" + "}"); } + + @Test + public void testGetOuterScope() { + decompileScriptPack("getouterscope", "mypkg.MainClass", "package mypkg\n" + + "{\n" + + " import flash.display.DisplayObject;\n" + + " import flash.display.DisplayObjectContainer;\n" + + " import flash.display.InteractiveObject;\n" + + " import flash.display.MovieClip;\n" + + " import flash.display.Sprite;\n" + + " import flash.events.EventDispatcher;\n" + + " import flash.text.TextField;\n" + + " \n" + + " public class MainClass extends MovieClip\n" + + " {\n" + + " \n" + + " \n" + + " private var myTextBox:TextField;\n" + + " \n" + + " public function MainClass()\n" + + " {\n" + + " super();\n" + + " this.myTextBox = new TextField();\n" + + " this.myTextBox.text = \"\";\n" + + " this.myTextBox.width = 1024;\n" + + " this.myTextBox.height = 1024;\n" + + " this.myTextBox.multiline = true;\n" + + " addChild(this.myTextBox);\n" + + " this.test();\n" + + " }\n" + + " \n" + + " internal function test() : void\n" + + " {\n" + + " this.myTextBox.text = \"scopes:\\n\" + global + \"\\n\" + Object + \"\\n\" + EventDispatcher + \"\\n\" + DisplayObject + \"\\n\" + InteractiveObject + \"\\n\" + DisplayObjectContainer + \"\\n\" + Sprite + \"\\n\" + MovieClip + \"\\n\" + MainClass + \"\\n\";\n" + + " }\n" + + " }\n" + + "}"); + } } diff --git a/libsrc/ffdec_lib/testdata/getouterscope/getouterscope.swf b/libsrc/ffdec_lib/testdata/getouterscope/getouterscope.swf new file mode 100644 index 0000000000000000000000000000000000000000..eda924edf440f1c560573fe64f9c2389396a02b8 GIT binary patch literal 1029 zcmV+g1p50!S5ptk2LJ$goTXG-bJ|82T_MB*wqrYXh zJGLMCk|}Fxfo*gfX)*BB{uKX{{007zyAl^Wv71TT9r1nIPv;zV&t5`M1OVIua3BC{ z_kh3uxwj($a1uEK{lea_vVL5_PH;^scHk*f94cxBDTxjT z>1ISQ3!0u7`oKPiJ&qq$D_c0 zH^DcgJV>lQQSO2Nbx3?>z22u6-1C$bI%XGS@M&~>H4BMyLE>N>*@VMiEjLWBr=R&T z!@f<PpQD>~Z4TQqB1n zY7eL@weyG$Dc`bBsG7C5(XBNNwOdm=rm8kNX5DHV4P+SIw$Vf@)h8s@Vp9K|GY>hy4BRbo@>uTCG^WYmweu4PnBt8G0!u}9REn)7%<^=93wb~tuDT|6uFf*VRqmxkLZ zPG92+-t3A@Sv!~(7YxRGg{0J_#C5Wa#4MZCqzQG{C^sT>IAR5F>@w<7pX9OQm?M4x zNRQFs-huOSCWgEQ9mEsK}ce~C=`n&p(K{111Nz~;iXvG%YOl$ zLm>k*St#b9l!v(@gd0%Ugu)gSoAS!3IKRvVp1;S% zw;Md4ZwT}A9N_fKKBvFobk6y52yS10bvqQ&m`S6U#%vm;H0II>)0j^phFnL?@FD#$ zM+EdYQGW~dpP~LX>hGZbF6xW?`3-!tXrl~=|G2lmoN2mQD(lSx-tgMrt-eZITAlWO literal 0 HcmV?d00001 diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java b/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java index 352a41873..9f0042fd5 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java @@ -265,7 +265,7 @@ public class ASMSourceEditorPane extends DebuggableEditorPane implements CaretLi public void graph() { try { - AVM2Graph gr = new AVM2Graph(null /*?*/, abc.bodies.get(bodyIndex).getCode(), abc, abc.bodies.get(bodyIndex), false, -1, -1, new HashMap<>(), new ScopeStack(), new HashMap<>(), new ArrayList<>(), new HashMap<>()); //, abc.bodies.get(bodyIndex).getCode().visitCode(abc.bodies.get(bodyIndex))); + AVM2Graph gr = new AVM2Graph(null /*?*/, abc.bodies.get(bodyIndex).getCode(), abc, abc.bodies.get(bodyIndex), false, -1, -1, new HashMap<>(), new ScopeStack(), new ScopeStack(), new HashMap<>(), new ArrayList<>(), new HashMap<>()); //, abc.bodies.get(bodyIndex).getCode().visitCode(abc.bodies.get(bodyIndex))); (new GraphDialog(getAbcPanel().getMainPanel().getMainFrame().getWindow(), gr, name)).setVisible(true); } catch (InterruptedException ex) { Logger.getLogger(ASMSourceEditorPane.class.getName()).log(Level.SEVERE, null, ex);