mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-03 10:35:39 +00:00
AS3 - some simplifications
This commit is contained in:
@@ -72,6 +72,8 @@ public class AVM2LocalData extends BaseLocalData {
|
||||
|
||||
public AVM2Code code;
|
||||
|
||||
public boolean thisHasDefaultToPrimitive;
|
||||
|
||||
public AVM2LocalData() {
|
||||
|
||||
}
|
||||
@@ -94,6 +96,7 @@ public class AVM2LocalData extends BaseLocalData {
|
||||
ip = localData.ip;
|
||||
refs = localData.refs;
|
||||
code = localData.code;
|
||||
thisHasDefaultToPrimitive = localData.thisHasDefaultToPrimitive;
|
||||
}
|
||||
|
||||
public AVM2ConstantPool getConstants() {
|
||||
|
||||
@@ -1480,7 +1480,7 @@ public class AVM2Code implements Cloneable {
|
||||
return pos2adr(fixIPAfterDebugLine(adr2pos(addr, true)));
|
||||
}
|
||||
|
||||
public ConvertOutput toSourceOutput(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, List<DottedChain> fullyQualifiedNames, boolean[] visited, HashMap<Integer, Integer> localRegAssigmentIps, HashMap<Integer, List<Integer>> refs) throws ConvertException, InterruptedException {
|
||||
public ConvertOutput toSourceOutput(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, List<DottedChain> fullyQualifiedNames, boolean[] visited, HashMap<Integer, Integer> localRegAssigmentIps, HashMap<Integer, List<Integer>> refs) throws ConvertException, InterruptedException {
|
||||
calcKilledStats(body);
|
||||
boolean debugMode = DEBUG_MODE;
|
||||
if (debugMode) {
|
||||
@@ -1585,12 +1585,12 @@ public class AVM2Code implements Cloneable {
|
||||
AVM2Instruction insAfter = code.get(ip + 1);
|
||||
if ((insAfter.definition instanceof GetLocalTypeIns) && (((GetLocalTypeIns) insAfter.definition).getRegisterId(insAfter) == ((SetLocalTypeIns) ins.definition).getRegisterId(ins))) {
|
||||
GraphTargetItem before = stack.peek();
|
||||
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this);
|
||||
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
|
||||
stack.push(before);
|
||||
ip += 2;
|
||||
continue iploop;
|
||||
} else {
|
||||
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this);
|
||||
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
|
||||
ip++;
|
||||
continue iploop;
|
||||
}
|
||||
@@ -1599,7 +1599,7 @@ public class AVM2Code implements Cloneable {
|
||||
do {
|
||||
AVM2Instruction insAfter = ip + 1 < code.size() ? code.get(ip + 1) : null;
|
||||
if (insAfter == null) {
|
||||
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this);
|
||||
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
|
||||
ip++;
|
||||
break;
|
||||
}
|
||||
@@ -1633,7 +1633,7 @@ public class AVM2Code implements Cloneable {
|
||||
if (((GetLocalTypeIns) code.get(t).definition).getRegisterId(code.get(t)) == reg) {
|
||||
if (code.get(t + 1).definition instanceof KillIns) {
|
||||
if (code.get(t + 1).operands[0] == reg) {
|
||||
ConvertOutput assignment = toSourceOutput(lineStartItem, path, part, processJumps, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, abc, body, ip + 2, t - 1, localRegNames, fullyQualifiedNames, visited, localRegAssigmentIps, refs);
|
||||
ConvertOutput assignment = toSourceOutput(thisHasDefaultToPrimitive, lineStartItem, path, part, processJumps, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, abc, body, ip + 2, t - 1, localRegNames, fullyQualifiedNames, visited, localRegAssigmentIps, refs);
|
||||
if (!assignment.output.isEmpty()) {
|
||||
GraphTargetItem tar = assignment.output.remove(assignment.output.size() - 1);
|
||||
tar.firstPart = part;
|
||||
@@ -1667,21 +1667,21 @@ public class AVM2Code implements Cloneable {
|
||||
}
|
||||
stack.push(vx);
|
||||
} else {
|
||||
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this);
|
||||
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
|
||||
}
|
||||
ip++;
|
||||
break;
|
||||
//}
|
||||
|
||||
} else {
|
||||
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this);
|
||||
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, 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(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this);
|
||||
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
|
||||
//ip = end + 1;
|
||||
break;
|
||||
} else if (ins.definition instanceof NewFunctionIns) {
|
||||
@@ -1717,13 +1717,13 @@ public class AVM2Code implements Cloneable {
|
||||
}
|
||||
}
|
||||
// What to do when hasDup is false?
|
||||
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this);
|
||||
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
|
||||
NewFunctionAVM2Item nft = (NewFunctionAVM2Item) stack.peek();
|
||||
nft.functionName = functionName;
|
||||
ip++;
|
||||
} else {
|
||||
try {
|
||||
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this);
|
||||
ins.definition.translate(lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
|
||||
} catch (RuntimeException re) {
|
||||
/*String last="";
|
||||
int len=5;
|
||||
@@ -1944,7 +1944,7 @@ public class AVM2Code implements Cloneable {
|
||||
}*/
|
||||
}
|
||||
|
||||
public List<GraphTargetItem> toGraphTargetItems(ConvertData convertData, String path, int methodIndex, boolean isStatic, int scriptIndex, int classIndex, ABC abc, MethodBody body, HashMap<Integer, String> localRegNames, ScopeStack scopeStack, int initializerType, List<DottedChain> fullyQualifiedNames, List<Traits> initTraits, int staticOperation, HashMap<Integer, Integer> localRegAssigmentIps, HashMap<Integer, List<Integer>> refs) throws InterruptedException {
|
||||
public List<GraphTargetItem> toGraphTargetItems(boolean thisHasDefaultToPrimitive, ConvertData convertData, String path, int methodIndex, boolean isStatic, int scriptIndex, int classIndex, ABC abc, MethodBody body, HashMap<Integer, String> localRegNames, ScopeStack scopeStack, int initializerType, List<DottedChain> fullyQualifiedNames, List<Traits> initTraits, int staticOperation, HashMap<Integer, Integer> localRegAssigmentIps, HashMap<Integer, List<Integer>> refs) throws InterruptedException {
|
||||
initToSource();
|
||||
List<GraphTargetItem> list;
|
||||
HashMap<Integer, GraphTargetItem> localRegs = new HashMap<>();
|
||||
@@ -1955,7 +1955,7 @@ public class AVM2Code implements Cloneable {
|
||||
}
|
||||
|
||||
//try {
|
||||
list = AVM2Graph.translateViaGraph(path, this, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localRegNames, fullyQualifiedNames, staticOperation, localRegAssigmentIps, refs);
|
||||
list = AVM2Graph.translateViaGraph(path, this, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localRegNames, fullyQualifiedNames, staticOperation, localRegAssigmentIps, refs, thisHasDefaultToPrimitive);
|
||||
|
||||
if (initTraits != null) {
|
||||
loopi:
|
||||
|
||||
@@ -105,10 +105,11 @@ public class AVM2Graph extends Graph {
|
||||
|
||||
}
|
||||
|
||||
public static List<GraphTargetItem> translateViaGraph(String path, 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, int staticOperation, HashMap<Integer, Integer> localRegAssigmentIps, HashMap<Integer, List<Integer>> refs) throws InterruptedException {
|
||||
public static List<GraphTargetItem> translateViaGraph(String path, 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, int staticOperation, HashMap<Integer, Integer> localRegAssigmentIps, HashMap<Integer, List<Integer>> refs, boolean thisHasDefaultToPrimitive) throws InterruptedException {
|
||||
AVM2Graph g = new AVM2Graph(code, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localRegNames, fullyQualifiedNames, localRegAssigmentIps, refs);
|
||||
|
||||
AVM2LocalData localData = new AVM2LocalData();
|
||||
localData.thisHasDefaultToPrimitive = thisHasDefaultToPrimitive;
|
||||
localData.isStatic = isStatic;
|
||||
localData.classIndex = classIndex;
|
||||
localData.localRegs = localRegs;
|
||||
|
||||
@@ -105,7 +105,7 @@ public class AVM2GraphSource extends GraphSource {
|
||||
List<GraphTargetItem> ret = new ArrayList<>();
|
||||
ScopeStack newstack = ((AVM2LocalData) localData).scopeStack;
|
||||
Reference<GraphSourceItem> lineStartItem = new Reference<>(localData.lineStartInstruction);
|
||||
ConvertOutput co = code.toSourceOutput(lineStartItem, path, part, false, isStatic, scriptIndex, classIndex, localRegs, stack, newstack, abc, body, start, end, localRegNames, fullyQualifiedNames, new boolean[size()], localRegAssigmentIps, refs);
|
||||
ConvertOutput co = code.toSourceOutput(((AVM2LocalData) localData).thisHasDefaultToPrimitive, lineStartItem, path, part, false, isStatic, scriptIndex, classIndex, localRegs, stack, newstack, abc, body, start, end, localRegNames, fullyQualifiedNames, new boolean[size()], localRegAssigmentIps, refs);
|
||||
localData.lineStartInstruction = lineStartItem.getVal();
|
||||
ret.addAll(co.output);
|
||||
return ret;
|
||||
|
||||
@@ -40,6 +40,7 @@ import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.ScopeStack;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
@@ -145,7 +146,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(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, List<DottedChain> fullyQualifiedNames, String path, HashMap<Integer, Integer> localRegsAssignmentIps, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code) throws InterruptedException {
|
||||
public void translate(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, List<DottedChain> fullyQualifiedNames, String path, HashMap<Integer, Integer> localRegsAssignmentIps, int ip, HashMap<Integer, List<Integer>> refs, AVM2Code code, boolean thisHasDefaultToPrimitive) throws InterruptedException {
|
||||
AVM2LocalData localData = new AVM2LocalData();
|
||||
localData.isStatic = isStatic;
|
||||
localData.scriptIndex = scriptIndex;
|
||||
@@ -161,6 +162,7 @@ public abstract class InstructionDefinition implements Serializable {
|
||||
localData.ip = ip;
|
||||
localData.refs = refs;
|
||||
localData.code = code;
|
||||
localData.thisHasDefaultToPrimitive = thisHasDefaultToPrimitive;
|
||||
translate(localData, stack, ins, output, path);
|
||||
lineStartItem.setVal(localData.lineStartInstruction);
|
||||
}
|
||||
@@ -198,7 +200,7 @@ public abstract class InstructionDefinition implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
return new FullMultinameAVM2Item(property, ins, localData.lineStartInstruction, multinameIndex, name, ns);
|
||||
return new FullMultinameAVM2Item(property, ins, localData.lineStartInstruction, multinameIndex, localData.abc.constants.getMultiname(multinameIndex).getName(localData.getConstants(), new ArrayList<>(), true), name, ns);
|
||||
}
|
||||
|
||||
protected int getMultinameRequiredStackSize(AVM2ConstantPool constants, int multinameIndex) {
|
||||
|
||||
@@ -41,8 +41,8 @@ public class AddIns extends InstructionDefinition {
|
||||
|
||||
@Override
|
||||
public boolean execute(LocalDataArea lda, AVM2ConstantPool constants, AVM2Instruction ins) {
|
||||
Object right = lda.operandStack.pop();
|
||||
Object left = lda.operandStack.pop();
|
||||
Object right = EcmaScript.toPrimitive(lda.operandStack.pop(), "");
|
||||
Object left = EcmaScript.toPrimitive(lda.operandStack.pop(), "");
|
||||
if (EcmaScript.type(left) == EcmaType.STRING || EcmaScript.type(right) == EcmaType.STRING) {
|
||||
String ret = EcmaScript.toString(left) + EcmaScript.toString(right);
|
||||
lda.operandStack.push(ret);
|
||||
|
||||
@@ -69,22 +69,7 @@ public abstract class GetLocalTypeIns extends InstructionDefinition {
|
||||
} else {
|
||||
|
||||
List<Trait> ts = localData.getInstanceInfo().get(localData.classIndex).instance_traits.traits;
|
||||
boolean isBasicObject = true;
|
||||
if (!"Object".equals(localData.getConstants().getMultiname(localData.getInstanceInfo().get(localData.classIndex).super_index).getNameWithNamespace(localData.getConstants()).toRawString())) {
|
||||
//TODO: check for toString and valueOf in parent object
|
||||
isBasicObject = false;
|
||||
} else {
|
||||
for (Trait t : ts) {
|
||||
if (t instanceof TraitMethodGetterSetter) {
|
||||
if ("toString".equals(t.getName(localData.abc).getName(localData.getConstants(), new ArrayList<>(), true))) {
|
||||
isBasicObject = false;
|
||||
}
|
||||
if ("valueOf".equals(t.getName(localData.abc).getName(localData.getConstants(), new ArrayList<>(), true))) {
|
||||
isBasicObject = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean isBasicObject = localData.thisHasDefaultToPrimitive;
|
||||
Multiname m = localData.getInstanceInfo().get(localData.classIndex).getName(localData.getConstants());
|
||||
stack.push(new ThisAVM2Item(ins, localData.lineStartInstruction, m, m.getNameWithNamespace(localData.getConstants()), isBasicObject));
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.types.Multiname;
|
||||
import com.jpexs.decompiler.flash.ecma.ArrayType;
|
||||
import com.jpexs.decompiler.flash.ecma.EcmaScript;
|
||||
import com.jpexs.decompiler.flash.ecma.EcmaType;
|
||||
import com.jpexs.decompiler.flash.ecma.ObjectType;
|
||||
import com.jpexs.decompiler.flash.ecma.Undefined;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
@@ -50,6 +51,7 @@ public class GetPropertyIns extends InstructionDefinition {
|
||||
if (constants.getMultiname(ins.operands[0]).kind == Multiname.MULTINAMEL) {
|
||||
String name = EcmaScript.toString(lda.operandStack.pop());
|
||||
Object obj = lda.operandStack.pop();
|
||||
|
||||
if (obj == ArrayType.EMPTY_ARRAY) {
|
||||
if ("length".equals(name)) {
|
||||
lda.operandStack.push(0L);
|
||||
|
||||
@@ -26,8 +26,10 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.operations.AsTypeAVM2Item;
|
||||
import com.jpexs.decompiler.flash.ecma.NotCompileTime;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -55,7 +57,7 @@ public class AsTypeIns extends InstructionDefinition {
|
||||
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
|
||||
GraphTargetItem val = stack.pop();
|
||||
|
||||
stack.push(new AsTypeAVM2Item(ins, localData.lineStartInstruction, val, new FullMultinameAVM2Item(false, ins, localData.lineStartInstruction, ins.operands[0])));
|
||||
stack.push(new AsTypeAVM2Item(ins, localData.lineStartInstruction, val, new FullMultinameAVM2Item(false, ins, localData.lineStartInstruction, ins.operands[0], localData.abc.constants.getMultiname(ins.operands[0]).getName(localData.getConstants(), new ArrayList<>(), true))));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.operations.IsTypeAVM2Item;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -41,7 +42,7 @@ public class IsTypeIns extends InstructionDefinition {
|
||||
public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List<GraphTargetItem> output, String path) {
|
||||
int multinameIndex = ins.operands[0];
|
||||
GraphTargetItem value = stack.pop();
|
||||
stack.push(new IsTypeAVM2Item(ins, localData.lineStartInstruction, value, new FullMultinameAVM2Item(false, ins, localData.lineStartInstruction, multinameIndex)));
|
||||
stack.push(new IsTypeAVM2Item(ins, localData.lineStartInstruction, value, new FullMultinameAVM2Item(false, ins, localData.lineStartInstruction, multinameIndex, localData.abc.constants.getMultiname(multinameIndex).getName(localData.getConstants(), new ArrayList<>(), true))));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.model;
|
||||
|
||||
import com.jpexs.decompiler.graph.model.Callable;
|
||||
import com.jpexs.decompiler.flash.ecma.EcmaScript;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
|
||||
@@ -67,7 +67,7 @@ public class CoerceAVM2Item extends AVM2Item {
|
||||
return false;
|
||||
}
|
||||
dependencies.add(value);
|
||||
return value.isCompileTime(dependencies);
|
||||
return value.isConvertedCompileTime(dependencies);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,10 +81,7 @@ public class CoerceAVM2Item extends AVM2Item {
|
||||
if (ret == Undefined.INSTANCE) {
|
||||
return Null.INSTANCE;
|
||||
}
|
||||
if (ret == null) {
|
||||
return null;
|
||||
}
|
||||
return ret.toString();
|
||||
return value.getResultAsString();
|
||||
case "*":
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ public class ConvertAVM2Item extends AVM2Item {
|
||||
case "uint":
|
||||
return EcmaScript.toUint32(value.getResult());
|
||||
case "String":
|
||||
return value.getResult().toString();
|
||||
return value.getResultAsString();
|
||||
case "Object":
|
||||
return value.getResult(); //if not object throw TypeError
|
||||
default:
|
||||
@@ -80,7 +80,7 @@ public class ConvertAVM2Item extends AVM2Item {
|
||||
return false;
|
||||
}
|
||||
dependencies.add(value);
|
||||
return value.isCompileTime(dependencies);
|
||||
return value.isConvertedCompileTime(dependencies);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -42,28 +42,33 @@ public class FullMultinameAVM2Item extends AVM2Item {
|
||||
|
||||
public boolean property;
|
||||
|
||||
public FullMultinameAVM2Item(boolean property, GraphSourceItem instruction, GraphSourceItem lineStartIns, int multinameIndex, GraphTargetItem name) {
|
||||
public String resolvedMultinameName;
|
||||
|
||||
public FullMultinameAVM2Item(boolean property, GraphSourceItem instruction, GraphSourceItem lineStartIns, int multinameIndex, String resolvedMultinameName, GraphTargetItem name) {
|
||||
super(instruction, lineStartIns, PRECEDENCE_PRIMARY);
|
||||
this.multinameIndex = multinameIndex;
|
||||
this.name = name;
|
||||
this.namespace = null;
|
||||
this.property = property;
|
||||
this.resolvedMultinameName = resolvedMultinameName;
|
||||
}
|
||||
|
||||
public FullMultinameAVM2Item(boolean property, GraphSourceItem instruction, GraphSourceItem lineStartIns, int multinameIndex) {
|
||||
public FullMultinameAVM2Item(boolean property, GraphSourceItem instruction, GraphSourceItem lineStartIns, int multinameIndex, String resolvedMultinameName) {
|
||||
super(instruction, lineStartIns, PRECEDENCE_PRIMARY);
|
||||
this.multinameIndex = multinameIndex;
|
||||
this.resolvedMultinameName = resolvedMultinameName;
|
||||
this.name = null;
|
||||
this.namespace = null;
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
public FullMultinameAVM2Item(boolean property, GraphSourceItem instruction, GraphSourceItem lineStartIns, int multinameIndex, GraphTargetItem name, GraphTargetItem namespace) {
|
||||
public FullMultinameAVM2Item(boolean property, GraphSourceItem instruction, GraphSourceItem lineStartIns, int multinameIndex, String resolvedMultinameName, GraphTargetItem name, GraphTargetItem namespace) {
|
||||
super(instruction, lineStartIns, PRECEDENCE_PRIMARY);
|
||||
this.multinameIndex = multinameIndex;
|
||||
this.name = name;
|
||||
this.namespace = namespace;
|
||||
this.property = property;
|
||||
this.resolvedMultinameName = resolvedMultinameName;
|
||||
}
|
||||
|
||||
public boolean isRuntime() {
|
||||
|
||||
@@ -20,11 +20,15 @@ import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.AVM2SourceGenerator;
|
||||
import com.jpexs.decompiler.flash.ecma.EcmaScript;
|
||||
import com.jpexs.decompiler.flash.ecma.EcmaType;
|
||||
import com.jpexs.decompiler.flash.ecma.ObjectType;
|
||||
import com.jpexs.decompiler.flash.ecma.Undefined;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.SimpleValue;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
import com.jpexs.decompiler.graph.TypeItem;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
@@ -41,8 +45,30 @@ public class GetPropertyAVM2Item extends AVM2Item {
|
||||
|
||||
public GraphTargetItem propertyName;
|
||||
|
||||
@Override
|
||||
public boolean isConvertedCompileTime(Set<GraphTargetItem> dependencies) {
|
||||
if (object != null && object.isCompileTime() && (propertyName instanceof FullMultinameAVM2Item) && (((FullMultinameAVM2Item) propertyName).name != null) && (((FullMultinameAVM2Item) propertyName).name.isCompileTime()) && "constructor".equals(((FullMultinameAVM2Item) propertyName).name.getResult())) {
|
||||
Object obj = object.getResult();
|
||||
EcmaType t = EcmaScript.type(obj);
|
||||
if (t != EcmaType.OBJECT) {
|
||||
if (t.getClassName() != null) {
|
||||
//Note: it's for toString only :-(
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (obj instanceof ObjectType) {
|
||||
//Note: it's for toString only :-(
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return isCompileTime(dependencies);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompileTime(Set<GraphTargetItem> dependencies) {
|
||||
if ((object instanceof SimpleValue) && (((SimpleValue) object).isSimpleValue())) {
|
||||
return true;
|
||||
}
|
||||
if (object instanceof NewArrayAVM2Item) {
|
||||
if (((NewArrayAVM2Item) object).values.isEmpty()) {
|
||||
return true;
|
||||
@@ -56,8 +82,30 @@ public class GetPropertyAVM2Item extends AVM2Item {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResultAsString() {
|
||||
if (object.isCompileTime() && (propertyName instanceof FullMultinameAVM2Item) && (((FullMultinameAVM2Item) propertyName).name.isCompileTime()) && "constructor".equals(((FullMultinameAVM2Item) propertyName).name.getResult())) {
|
||||
Object obj = object.getResult();
|
||||
EcmaType t = EcmaScript.type(obj);
|
||||
if (t != EcmaType.OBJECT) {
|
||||
if (t.getClassName() != null) {
|
||||
return "[class " + t.getClassName() + "]";
|
||||
}
|
||||
}
|
||||
if (obj instanceof ObjectType) {
|
||||
return "[class " + ((ObjectType) obj).getTypeName() + "]";
|
||||
}
|
||||
}
|
||||
return super.getResultAsString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getResult() {
|
||||
Object ores = object.getResult();
|
||||
EcmaType type = EcmaScript.type(ores);
|
||||
if (type != EcmaType.OBJECT && (propertyName instanceof FullMultinameAVM2Item) && (((FullMultinameAVM2Item) propertyName).resolvedMultinameName != null)) {
|
||||
return type.getProperty(ores, ((FullMultinameAVM2Item) propertyName).resolvedMultinameName);
|
||||
}
|
||||
if (object instanceof NewArrayAVM2Item) {
|
||||
if (((NewArrayAVM2Item) object).values.isEmpty()) {
|
||||
return Undefined.INSTANCE;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.jpexs.decompiler.flash.abc.avm2.model;
|
||||
|
||||
import com.jpexs.decompiler.graph.model.Callable;
|
||||
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
|
||||
|
||||
@@ -68,8 +68,10 @@ public class AddAVM2Item extends BinaryOpItem {
|
||||
public Object getResult() {
|
||||
Object leftResult = leftSide.getResult();
|
||||
Object rightResult = rightSide.getResult();
|
||||
leftResult = EcmaScript.toPrimitive(leftResult, "");
|
||||
rightResult = EcmaScript.toPrimitive(rightResult, "");
|
||||
if (EcmaScript.type(leftResult) == EcmaType.STRING || EcmaScript.type(rightResult) == EcmaType.STRING) {
|
||||
return "" + leftResult + rightResult;
|
||||
return EcmaScript.toString(leftResult) + EcmaScript.toString(rightResult);
|
||||
}
|
||||
return EcmaScript.toNumber(leftResult) + EcmaScript.toNumber(rightResult);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ public class ConvertData {
|
||||
|
||||
public Map<TraitSlotConst, AssignedValue> assignedValues = new HashMap<>();
|
||||
|
||||
public boolean thisHasDefaultToPrimitive;
|
||||
|
||||
public ConvertData() {
|
||||
deobfuscationMode = Configuration.autoDeobfuscate.get() ? 1 : 0;
|
||||
}
|
||||
|
||||
@@ -310,7 +310,7 @@ public final class MethodBody implements Cloneable {
|
||||
HashMap<Integer, String> localRegNames = getLocalRegNames(abc);
|
||||
List<GraphTargetItem> convertedItems1;
|
||||
try (Statistics s = new Statistics("AVM2Code.toGraphTargetItems")) {
|
||||
convertedItems1 = converted.getCode().toGraphTargetItems(convertData, path, methodIndex, isStatic, scriptIndex, classIndex, abc, converted, localRegNames, scopeStack, initializerType, fullyQualifiedNames, initTraits, Graph.SOP_USE_STATIC, new HashMap<>(), converted.getCode().visitCode(converted));
|
||||
convertedItems1 = converted.getCode().toGraphTargetItems(convertData.thisHasDefaultToPrimitive, convertData, path, methodIndex, isStatic, scriptIndex, classIndex, abc, converted, localRegNames, scopeStack, initializerType, fullyQualifiedNames, initTraits, Graph.SOP_USE_STATIC, new HashMap<>(), converted.getCode().visitCode(converted));
|
||||
}
|
||||
try (Statistics s = new Statistics("Graph.graphToString")) {
|
||||
Graph.graphToString(convertedItems1, writer, LocalData.create(abc.constants, localRegNames, fullyQualifiedNames));
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.decompiler.flash.abc.types.traits;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.AbcIndexing;
|
||||
import com.jpexs.decompiler.flash.abc.types.ClassInfo;
|
||||
import com.jpexs.decompiler.flash.abc.types.ConvertData;
|
||||
import com.jpexs.decompiler.flash.abc.types.InstanceInfo;
|
||||
@@ -28,6 +29,7 @@ import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.NulWriter;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import com.jpexs.decompiler.graph.ScopeStack;
|
||||
import com.jpexs.decompiler.graph.TypeItem;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -219,6 +221,10 @@ public class TraitClass extends Trait implements TraitWithSlot {
|
||||
String instanceInfoName = instanceInfo.getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false);
|
||||
ClassInfo classInfo = abc.class_info.get(class_info);
|
||||
|
||||
AbcIndexing index = new AbcIndexing(abc.getSwf());
|
||||
//for simplification of String(this)
|
||||
convertData.thisHasDefaultToPrimitive = null == index.findProperty(new AbcIndexing.PropertyDef("toString", new TypeItem(instanceInfo.getName(abc.constants).getNameWithNamespace(abc.constants)), abc, abc.constants.getNamespaceId(Namespace.KIND_PACKAGE, DottedChain.TOPLEVEL, abc.constants.getStringId("", true), true)), false, true);
|
||||
|
||||
//class initializer
|
||||
int bodyIndex = abc.findBodyIndex(classInfo.cinit_index);
|
||||
if (bodyIndex != -1) {
|
||||
|
||||
@@ -112,9 +112,10 @@ public class EcmaScript {
|
||||
//TODO: logic similar to 8.12.8
|
||||
return o.call("toString", new ArrayList<>());
|
||||
case "Number":
|
||||
default:
|
||||
//TODO: logic similar to 8.12.8
|
||||
return o.call("valueOf", new ArrayList<>());
|
||||
default:
|
||||
return o.toPrimitive();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,19 +12,46 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.ecma;
|
||||
|
||||
import com.jpexs.decompiler.graph.model.Callable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public enum EcmaType {
|
||||
|
||||
|
||||
NULL,
|
||||
STRING,
|
||||
NUMBER,
|
||||
UNDEFINED,
|
||||
OBJECT,
|
||||
NULL(null),
|
||||
STRING("String"),
|
||||
NUMBER("Number"),
|
||||
UNDEFINED(null),
|
||||
OBJECT("Object"),
|
||||
BOOLEAN("Boolean");
|
||||
|
||||
private String clsName;
|
||||
|
||||
private EcmaType(String clsName) {
|
||||
this.clsName = clsName;
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return clsName;
|
||||
}
|
||||
|
||||
public Object getProperty(Object val, String propName) {
|
||||
String cls = getClassName();
|
||||
if (cls == null) {
|
||||
return null;
|
||||
}
|
||||
if ("String".equals(cls)) {
|
||||
switch (propName) {
|
||||
case "length":
|
||||
return EcmaScript.toString(val).length();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.ecma;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.Callable;
|
||||
import com.jpexs.decompiler.graph.model.Callable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -57,7 +57,15 @@ public class ObjectType implements Callable {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[object Object]";
|
||||
return "[object " + getTypeName() + "]";
|
||||
}
|
||||
|
||||
public String getTypeName() {
|
||||
return "Object";
|
||||
}
|
||||
|
||||
public Object toPrimitive() {
|
||||
return toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -386,6 +386,10 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
|
||||
return EcmaScript.toNumberAs2(getResult());
|
||||
}
|
||||
|
||||
public String getResultAsString() {
|
||||
return EcmaScript.toString(getResult());
|
||||
}
|
||||
|
||||
public String toStringNoQuotes(LocalData localData) {
|
||||
// todo: honfika: this method should not be called, maybe we should throw an exception
|
||||
return toString();
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.model;
|
||||
package com.jpexs.decompiler.graph.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
Reference in New Issue
Block a user