Fixed AS3 - getouterscope instruction support

This commit is contained in:
Jindra Petřík
2023-03-11 22:50:30 +01:00
parent e8e2668354
commit e9063e487b
30 changed files with 227 additions and 68 deletions

View File

@@ -50,6 +50,8 @@ public class AVM2LocalData extends BaseLocalData {
public HashMap<Integer, GraphTargetItem> 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;

View File

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

View File

@@ -1486,7 +1486,7 @@ public class AVM2Code implements Cloneable {
return pos2adr(getIpThroughJumpAndDebugLine(adr2pos(addr, true)));
}
public ConvertOutput toSourceOutput(Set<GraphPart> switchParts, List<MethodBody> callStack, AbcIndexing abcIndex, Map<Integer, Set<Integer>> setLocalPosToGetLocalPos, boolean thisHasDefaultToPrimitive, Reference<GraphSourceItem> lineStartItem, String path, GraphPart part, boolean processJumps, boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, TranslateStack stack, ScopeStack scopeStack, ABC abc, MethodBody body, int start, int end, HashMap<Integer, String> localRegNames, HashMap<Integer, GraphTargetItem> localRegTypes, List<DottedChain> fullyQualifiedNames, boolean[] visited, HashMap<Integer, Integer> localRegAssigmentIps) throws ConvertException, InterruptedException {
public ConvertOutput toSourceOutput(Set<GraphPart> switchParts, List<MethodBody> callStack, AbcIndexing abcIndex, Map<Integer, Set<Integer>> setLocalPosToGetLocalPos, boolean thisHasDefaultToPrimitive, Reference<GraphSourceItem> lineStartItem, String path, GraphPart part, boolean processJumps, boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, TranslateStack stack, ScopeStack scopeStack, ScopeStack localScopeStack, ABC abc, MethodBody body, int start, int end, HashMap<Integer, String> localRegNames, HashMap<Integer, GraphTargetItem> localRegTypes, List<DottedChain> fullyQualifiedNames, boolean[] visited, HashMap<Integer, Integer> 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:

View File

@@ -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<MethodBody> callStack = new ArrayList<>();
callStack.add(body);
localData.callStack = callStack;

View File

@@ -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<MethodBody> callStack = new ArrayList<>();
callStack.add(body);
localData.callStack = callStack;

View File

@@ -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<Integer, GraphTargetItem> localRegs, ScopeStack scopeStack, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames, HashMap<Integer, Integer> 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<Integer, GraphTargetItem> localRegs, ScopeStack scopeStack, ScopeStack localScopeStack, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames, HashMap<Integer, Integer> 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<GraphTargetItem> targetOutput;
try {
@@ -626,7 +627,8 @@ public class AVM2Graph extends Graph {
}
public static List<GraphTargetItem> translateViaGraph(SecondPassData secondPassData, List<MethodBody> callStack, AbcIndexing abcIndex, String path, AVM2Code code, ABC abc, MethodBody body, boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, ScopeStack scopeStack, HashMap<Integer, String> localRegNames, HashMap<Integer, GraphTargetItem> localRegTypes, List<DottedChain> fullyQualifiedNames, int staticOperation, HashMap<Integer, Integer> 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<GraphPart> stopPart2 = new ArrayList<>(stopPart);
List<StopPartKind> 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;
}

View File

@@ -53,8 +53,6 @@ public class AVM2GraphSource extends GraphSource {
HashMap<Integer, GraphTargetItem> 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<Integer, GraphTargetItem> localRegs, ScopeStack scopeStack, ABC abc, MethodBody body, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames, HashMap<Integer, Integer> localRegAssigmentIp) {
public AVM2GraphSource(AVM2Code code, boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, ABC abc, MethodBody body, HashMap<Integer, String> localRegNames, List<DottedChain> fullyQualifiedNames, HashMap<Integer, Integer> 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<GraphTargetItem> translatePart(Graph graph, GraphPart part, BaseLocalData localData, TranslateStack stack, int start, int end, int staticOperation, String path) throws InterruptedException {
List<GraphTargetItem> ret = new ArrayList<>();
ScopeStack newstack = ((AVM2LocalData) localData).scopeStack;
Reference<GraphSourceItem> 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;

View File

@@ -193,7 +193,7 @@ public abstract class InstructionDefinition implements Serializable {
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) throws InterruptedException {
}
public void translate(Set<GraphPart> switchParts, List<MethodBody> callStack, AbcIndexing abcIndex, Map<Integer, Set<Integer>> setLocalPosToGetLocalPos, Reference<GraphSourceItem> lineStartItem, boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2Instruction ins, List<GraphTargetItem> output, MethodBody body, ABC abc, HashMap<Integer, String> localRegNames, HashMap<Integer, GraphTargetItem> localRegTypes, List<DottedChain> fullyQualifiedNames, String path, HashMap<Integer, Integer> localRegsAssignmentIps, int ip, AVM2Code code, boolean thisHasDefaultToPrimitive) throws InterruptedException {
public void translate(Set<GraphPart> switchParts, List<MethodBody> callStack, AbcIndexing abcIndex, Map<Integer, Set<Integer>> setLocalPosToGetLocalPos, Reference<GraphSourceItem> lineStartItem, boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, TranslateStack stack, ScopeStack scopeStack, ScopeStack localScopeStack, AVM2Instruction ins, List<GraphTargetItem> output, MethodBody body, ABC abc, HashMap<Integer, String> localRegNames, HashMap<Integer, GraphTargetItem> localRegTypes, List<DottedChain> fullyQualifiedNames, String path, HashMap<Integer, Integer> 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;

View File

@@ -40,7 +40,10 @@ public class NewFunctionIns extends InstructionDefinition {
@Override
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> 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);
}

View File

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

View File

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

View File

@@ -38,7 +38,7 @@ public class GetScopeObjectIns extends InstructionDefinition {
@Override
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
int index = ins.operands[0];
stack.push(localData.scopeStack.get(index));
stack.push(localData.localScopeStack.get(index));
}
@Override

View File

@@ -46,7 +46,7 @@ public class PopScopeIns extends InstructionDefinition {
@Override
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> 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));

View File

@@ -65,7 +65,7 @@ public class PushScopeIns extends InstructionDefinition {
}
}
localData.scopeStack.push(top);
localData.localScopeStack.push(top);
}
@Override

View File

@@ -40,7 +40,7 @@ public class PushWithIns extends InstructionDefinition {
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> 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));
}

View File

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

View File

@@ -92,7 +92,7 @@ public class NewFunctionAVM2Item extends AVM2Item {
if (body != null) {
List<MethodBody> 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();

View File

@@ -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");
}

View File

@@ -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<DottedChain> 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<DottedChain> 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<DottedChain> 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<DottedChain> 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<DottedChain> 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) {

View File

@@ -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<DottedChain> 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<DottedChain> 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<Traits> ts = new ArrayList<>();
ts.add(classInfo.static_traits);
List<MethodBody> 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<AbcIndexing.ClassIndex> 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

View File

@@ -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<DottedChain> 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<DottedChain> 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<MethodBody> 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();
}

View File

@@ -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<DottedChain> 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<DottedChain> 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<MethodBody> 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<>());
}
}
}

View File

@@ -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<DottedChain> 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<DottedChain> fullyQualifiedNames, boolean parallel, ScopeStack scopeStack) throws InterruptedException {
getNameStr(writer, abc, fullyQualifiedNames);
if (hasValueStr(abc, convertData)) {
getValueStr(abcIndex,exportMode, parent, convertData, writer, abc, fullyQualifiedNames);

View File

@@ -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<DottedChain> 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<DottedChain> 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<DottedChain> 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<DottedChain> 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<Void> future = executor.submit(task);
futureResults.add(future);
}

View File

@@ -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<AbcIndexing.ClassIndex> 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];

View File

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