AS3 parser - increment, decrement, body stats fix

This commit is contained in:
Jindra Petk
2014-03-30 22:34:38 +02:00
parent 0b85f4a18f
commit e908703b95
14 changed files with 284 additions and 260 deletions

View File

@@ -1859,14 +1859,16 @@ public class AVM2Code implements Serializable {
int stackDelta = ins.definition.getStackDelta(ins, abc);
stack += stackDelta;
int scopeDelta = ins.definition.getScopeStackDelta(ins, abc);
//System.out.println(""+ins+" stack:"+(stackDelta>0?"+"+stackDelta:stackDelta)+" scope:"+(scopeDelta>0?"+"+scopeDelta:scopeDelta));
scope += scopeDelta;
if (stack > stats.maxstack) {
stats.maxstack = stack;
}
if (scope > stats.maxscope) {
stats.maxscope = scope;
}
//System.out.println(""+ins+" deltaStack:"+(stackDelta>0?"+"+stackDelta:stackDelta)+" deltaScope:"+(scopeDelta>0?"+"+scopeDelta:scopeDelta)+" stack:"+stack+" scope:"+scope);
if ((ins.definition instanceof DXNSIns) || (ins.definition instanceof DXNSLateIns)) {
stats.has_set_dxns = true;
}

View File

@@ -56,13 +56,14 @@ public class FindPropertyIns extends InstructionDefinition {
@Override
public int getStackDelta(AVM2Instruction ins, ABC abc) {
int ret = 1;
int multinameIndex = ins.operands[0];
//FLEX does not calculate following:
/*int multinameIndex = ins.operands[0];
if (abc.constants.getMultiname(multinameIndex).needsName()) {
ret--;
}
if (abc.constants.getMultiname(multinameIndex).needsNs()) {
ret--;
}
}*/
return ret;
}
}

View File

@@ -55,13 +55,14 @@ public class FindPropertyStrictIns extends InstructionDefinition {
@Override
public int getStackDelta(AVM2Instruction ins, ABC abc) {
int ret = 1;
int multinameIndex = ins.operands[0];
//FLEX does not calculate following:
/*int multinameIndex = ins.operands[0];
if (abc.constants.getMultiname(multinameIndex).needsName()) {
ret--;
}
if (abc.constants.getMultiname(multinameIndex).needsNs()) {
ret--;
}
}*/
return ret;
}
}

View File

@@ -71,7 +71,7 @@ public class IntegerValueAVM2Item extends NumberValueAVM2Item {
@Override
public GraphTargetItem returnType() {
return TypeItem.UNBOUNDED;
return new TypeItem("int");
}
@Override

View File

@@ -63,9 +63,7 @@ public class PostDecrementAVM2Item extends AVM2Item implements AssignmentAVM2Ite
@Override
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) {
if (object instanceof AssignableAVM2Item) {
return ((AssignableAVM2Item) object).toSourceChange(localData, generator, null, toSourceMerge(localData, generator,
new AVM2Instruction(0, new DecrementIns(), new int[]{}, new byte[0])
), true);
return ((AssignableAVM2Item) object).toSourceChange(localData, generator, true, true, true);
}
return new ArrayList<>(); //?
}
@@ -73,9 +71,7 @@ public class PostDecrementAVM2Item extends AVM2Item implements AssignmentAVM2Ite
@Override
public List<GraphSourceItem> toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) {
if (object instanceof AssignableAVM2Item) {
return ((AssignableAVM2Item) object).toSourceChange(localData, generator, null, toSourceMerge(localData, generator,
new AVM2Instruction(0, new DecrementIns(), new int[]{}, new byte[0])
), false);
return ((AssignableAVM2Item) object).toSourceChange(localData, generator, true, true, false);
}
return new ArrayList<>(); //?
}

View File

@@ -69,12 +69,10 @@ public class PostIncrementAVM2Item extends AVM2Item implements AssignmentAVM2Ite
return true;
}
@Override
@Override
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) {
if (object instanceof AssignableAVM2Item) {
return ((AssignableAVM2Item) object).toSourceChange(localData, generator, null, toSourceMerge(localData, generator,
new AVM2Instruction(0, new IncrementIns(), new int[]{}, new byte[0])
), true);
return ((AssignableAVM2Item) object).toSourceChange(localData, generator, true, false, true);
}
return new ArrayList<>(); //?
}
@@ -82,9 +80,7 @@ public class PostIncrementAVM2Item extends AVM2Item implements AssignmentAVM2Ite
@Override
public List<GraphSourceItem> toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) {
if (object instanceof AssignableAVM2Item) {
return ((AssignableAVM2Item) object).toSourceChange(localData, generator, null, toSourceMerge(localData, generator,
new AVM2Instruction(0, new IncrementIns(), new int[]{}, new byte[0])
), false);
return ((AssignableAVM2Item) object).toSourceChange(localData, generator, true, false, false);
}
return new ArrayList<>(); //?
}

View File

@@ -43,9 +43,7 @@ public class PreDecrementAVM2Item extends UnaryOpItem implements AssignmentAVM2I
@Override
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) {
if (value instanceof AssignableAVM2Item) {
return ((AssignableAVM2Item) value).toSourceChange(localData, generator, toSourceMerge(localData, generator,
new AVM2Instruction(0, new DecrementIns(), new int[]{}, new byte[0])
), null, true);
return ((AssignableAVM2Item) value).toSourceChange(localData, generator, false, true, true);
}
return new ArrayList<>(); //?
}
@@ -53,13 +51,11 @@ public class PreDecrementAVM2Item extends UnaryOpItem implements AssignmentAVM2I
@Override
public List<GraphSourceItem> toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) {
if (value instanceof AssignableAVM2Item) {
return ((AssignableAVM2Item) value).toSourceChange(localData, generator, toSourceMerge(localData, generator,
new AVM2Instruction(0, new DecrementIns(), new int[]{}, new byte[0])
), null, false);
return ((AssignableAVM2Item) value).toSourceChange(localData, generator, false, true, false);
}
return new ArrayList<>(); //?
}
@Override
public GraphTargetItem returnType() {
return value.returnType();

View File

@@ -41,9 +41,7 @@ public class PreIncrementAVM2Item extends UnaryOpItem {
@Override
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) {
if (value instanceof AssignableAVM2Item) {
return ((AssignableAVM2Item) value).toSourceChange(localData, generator, toSourceMerge(localData, generator,
new AVM2Instruction(0, new IncrementIns(), new int[]{}, new byte[0])
), null, true);
return ((AssignableAVM2Item) value).toSourceChange(localData, generator, false, false, true);
}
return new ArrayList<>(); //?
}
@@ -51,9 +49,7 @@ public class PreIncrementAVM2Item extends UnaryOpItem {
@Override
public List<GraphSourceItem> toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) {
if (value instanceof AssignableAVM2Item) {
return ((AssignableAVM2Item) value).toSourceChange(localData, generator, toSourceMerge(localData, generator,
new AVM2Instruction(0, new IncrementIns(), new int[]{}, new byte[0])
), null, false);
return ((AssignableAVM2Item) value).toSourceChange(localData, generator, false, false, false);
}
return new ArrayList<>(); //?
}

View File

@@ -1081,9 +1081,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
}
mb.code.code.add(ins(new ReturnVoidIns()));
System.out.println("---------------script---------------");
mb.autoFillStats(abc, documentClass ? 1 : 0);
System.out.println("/--------------script---------------");
abc.addMethodBody(mb);
si.init_index = mb.method_info;
generateTraitsPhase2(traitScope, pkg, null, null, false, localData, commands, si.traits, traitArr);

View File

@@ -118,7 +118,7 @@ import java.util.logging.Logger;
public class ActionScriptParser {
private long uniqLast = 0;
private final boolean debugMode = true;
private final boolean debugMode = false;
private static final String AS3_NAMESPACE = "http://adobe.com/AS3/2006/builtin";
private ABC abc;

View File

@@ -17,6 +17,19 @@
package com.jpexs.decompiler.flash.abc.avm2.parser.script;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocal0Ins;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocal1Ins;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocal2Ins;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocal3Ins;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocalIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.KillIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocal0Ins;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocal1Ins;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocal2Ins;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocal3Ins;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.DupIns;
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
@@ -41,7 +54,7 @@ public abstract class AssignableAVM2Item extends AVM2Item {
this.assignedValue = storeValue;
}
public abstract List<GraphSourceItem> toSourceChange(SourceGeneratorLocalData localData, SourceGenerator generator, List<GraphSourceItem> pre, List<GraphSourceItem> post, boolean needsReturn);
public abstract List<GraphSourceItem> toSourceChange(SourceGeneratorLocalData localData, SourceGenerator generator, boolean post,boolean decrement, boolean needsReturn);
public GraphTargetItem getAssignedValue() {
return assignedValue;
@@ -51,4 +64,80 @@ public abstract class AssignableAVM2Item extends AVM2Item {
this.assignedValue = storeValue;
}
protected List<GraphSourceItem> dupSetTemp(SourceGeneratorLocalData localData, SourceGenerator generator, Reference<Integer> register) {
register.setVal(getFreeRegister(localData, generator));
List<GraphSourceItem> ret = new ArrayList<>();
ret.add(ins(new DupIns()));
ret.add(generateSetLoc(register.getVal()));
return ret;
}
protected List<GraphSourceItem> setTemp(SourceGeneratorLocalData localData, SourceGenerator generator, Reference<Integer> register) {
register.setVal(getFreeRegister(localData, generator));
List<GraphSourceItem> ret = new ArrayList<>();
ret.add(generateSetLoc(register.getVal()));
return ret;
}
protected List<GraphSourceItem> getTemp(SourceGeneratorLocalData localData, SourceGenerator generator, Reference<Integer> register) {
if (register.getVal() < 0) {
return new ArrayList<>();
}
List<GraphSourceItem> ret = new ArrayList<>();
ret.add(generateGetLoc(register.getVal()));
return ret;
}
/*protected List<GraphSourceItem> getAndKillTemp(SourceGeneratorLocalData localData, SourceGenerator generator, Reference<Integer> register) {
killRegister(localData, generator, register.getVal());
List<GraphSourceItem> ret = new ArrayList<>();
ret.add(generateGetLoc(register.getVal()));
ret.add(ins(new KillIns(), register.getVal()));
return ret;
}*/
@SuppressWarnings("unchecked")
protected List<GraphSourceItem> killTemp(SourceGeneratorLocalData localData, SourceGenerator generator, List<Reference<Integer>> registers) {
List<GraphSourceItem> ret = new ArrayList<>();
for (Reference<Integer> register : registers) {
if (register.getVal() < 0) {
continue;
}
killRegister(localData, generator, register.getVal());
ret.add(ins(new KillIns(), register.getVal()));
}
return ret;
}
protected AVM2Instruction generateSetLoc(int regNumber) {
switch (regNumber) {
case 0:
return ins(new SetLocal0Ins());
case 1:
return ins(new SetLocal1Ins());
case 2:
return ins(new SetLocal2Ins());
case 3:
return ins(new SetLocal3Ins());
default:
return ins(new SetLocalIns(), regNumber);
}
}
protected AVM2Instruction generateGetLoc(int regNumber) {
switch (regNumber) {
case 0:
return ins(new GetLocal0Ins());
case 1:
return ins(new GetLocal1Ins());
case 2:
return ins(new GetLocal2Ins());
case 3:
return ins(new GetLocal3Ins());
default:
return ins(new GetLocalIns(), regNumber);
}
}
}

View File

@@ -19,17 +19,10 @@ package com.jpexs.decompiler.flash.abc.avm2.parser.script;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocal0Ins;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocal1Ins;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocal2Ins;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocal3Ins;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocalIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.KillIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocal0Ins;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocal1Ins;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocal2Ins;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocal3Ins;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.DecrementIIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.DecrementIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.IncrementIIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.IncrementIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetPropertyIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetPropertyIns;
@@ -38,10 +31,8 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PopIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceAIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceSIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertDIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertSIns;
import com.jpexs.decompiler.flash.abc.avm2.model.CoerceAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.flash.abc.types.Namespace;
import com.jpexs.decompiler.flash.abc.types.NamespaceSet;
@@ -52,6 +43,7 @@ import com.jpexs.decompiler.graph.SourceGenerator;
import com.jpexs.decompiler.graph.TypeItem;
import com.jpexs.decompiler.graph.model.LocalData;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
@@ -156,36 +148,6 @@ public class NameAVM2Item extends AssignableAVM2Item {
return abc.constants.getNamespaceSetId(new NamespaceSet(nssa), true);
}
private AVM2Instruction generateSetLoc(int regNumber) {
switch (regNumber) {
case 0:
return ins(new SetLocal0Ins());
case 1:
return ins(new SetLocal1Ins());
case 2:
return ins(new SetLocal2Ins());
case 3:
return ins(new SetLocal3Ins());
default:
return ins(new SetLocalIns(), regNumber);
}
}
private AVM2Instruction generateGetLoc(int regNumber) {
switch (regNumber) {
case 0:
return ins(new GetLocal0Ins());
case 1:
return ins(new GetLocal1Ins());
case 2:
return ins(new GetLocal2Ins());
case 3:
return ins(new GetLocal3Ins());
default:
return ins(new GetLocalIns(), regNumber);
}
}
private AVM2Instruction generateCoerce(SourceGenerator generator, String type) {
AVM2Instruction ins;
switch (type) {
@@ -211,82 +173,58 @@ public class NameAVM2Item extends AssignableAVM2Item {
return new ArrayList<>();
}
AVM2SourceGenerator g = (AVM2SourceGenerator) generator;
Reference<Integer> ns_temp = new Reference<>(-1);
Reference<Integer> index_temp = new Reference<>(-1);
Reference<Integer> ret_temp = new Reference<>(-1);
if (variableName == null && ns != null && index != null) {
if (assignedValue != null) {
List<GraphSourceItem> ret = toSourceMerge(localData, generator,
return toSourceMerge(localData, generator,
ns, generateCoerce(generator, "Namespace"), index, ins(new ConvertSIns()), ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<Integer>()), true)),
ns, generateCoerce(generator, "Namespace"), index, ins(new ConvertSIns()), assignedValue);
int tempReg = -1;
if (needsReturn) {
tempReg = getFreeRegister(localData, generator);
ret.add(ins(new DupIns()));
ret.add(generateSetLoc(tempReg));
}
ret.addAll(toSourceMerge(localData, generator,
ins(new SetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<Integer>()), true))
));
if (needsReturn) {
ret.add(generateGetLoc(tempReg));
ret.add(ins(new KillIns(), tempReg));
killRegister(localData, generator, tempReg);
}
return ret;
ns, generateCoerce(generator, "Namespace"), index, ins(new ConvertSIns()), assignedValue,
needsReturn ? dupSetTemp(localData, generator, ret_temp) : null,
ins(new SetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<Integer>()), true)),
needsReturn ? getTemp(localData, generator, ret_temp) : null,
killTemp(localData, generator, Arrays.asList(ns_temp, index_temp, ret_temp))
);
} else {
return toSourceMerge(localData, generator,
ns, generateCoerce(generator, "Namespace"), index, ins(new ConvertSIns()), ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<Integer>()), true)),
ns, generateCoerce(generator, "Namespace"), index, ins(new ConvertSIns()), ins(new GetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<Integer>()), true)),
needsReturn ? null : ins(new PopIns())
needsReturn ? null : ins(new PopIns()),
killTemp(localData, generator, Arrays.asList(ns_temp, index_temp, ret_temp))
);
}
}
if (variableName != null && ns != null && index == null) {
if (assignedValue != null) {
List<GraphSourceItem> ret = toSourceMerge(localData, generator,
return toSourceMerge(localData, generator,
ns, generateCoerce(generator, "Namespace"), ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAME, g.abc.constants.getStringId(variableName, true), 0, 0, 0, new ArrayList<Integer>()), true)),
ns, generateCoerce(generator, "Namespace"), assignedValue);
int tempReg = -1;
if (needsReturn) {
tempReg = getFreeRegister(localData, generator);
ret.add(ins(new DupIns()));
ret.add(generateSetLoc(tempReg));
}
ret.addAll(toSourceMerge(localData, generator,
ins(new SetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAME, g.abc.constants.getStringId(variableName, true), 0, 0, 0, new ArrayList<Integer>()), true))
));
if (needsReturn) {
ret.add(generateGetLoc(tempReg));
ret.add(ins(new KillIns(), tempReg));
killRegister(localData, generator, tempReg);
}
return ret;
ns, generateCoerce(generator, "Namespace"), assignedValue,
needsReturn ? dupSetTemp(localData, generator, ret_temp) : null,
ins(new SetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAME, g.abc.constants.getStringId(variableName, true), 0, 0, 0, new ArrayList<Integer>()), true)),
needsReturn ? getTemp(localData, generator, ret_temp) : null,
killTemp(localData, generator, Arrays.asList(ns_temp, index_temp, ret_temp))
);
} else {
return toSourceMerge(localData, generator,
ns, generateCoerce(generator, "Namespace"), ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAME, g.abc.constants.getStringId(variableName, true), 0, 0, 0, new ArrayList<Integer>()), true)),
ns, generateCoerce(generator, "Namespace"), ins(new GetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAME, g.abc.constants.getStringId(variableName, true), 0, 0, 0, new ArrayList<Integer>()), true)),
needsReturn ? null : ins(new PopIns())
needsReturn ? null : ins(new PopIns()),
killTemp(localData, generator, Arrays.asList(ns_temp, index_temp, ret_temp))
);
}
}
if (index != null) {
if (assignedValue != null) {
List<GraphSourceItem> ret = toSourceMerge(localData, generator,
generateGetLoc(regNumber), index, assignedValue);
int tempReg = -1;
if (needsReturn) {
tempReg = getFreeRegister(localData, generator);
ret.add(ins(new DupIns()));
ret.add(generateSetLoc(tempReg));
}
ret.addAll(toSourceMerge(localData, generator, ins(new SetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList<Integer>()), true))
));
if (needsReturn) {
ret.add(generateGetLoc(tempReg));
ret.add(ins(new KillIns(), tempReg));
killRegister(localData, generator, tempReg);
}
return ret;
return toSourceMerge(localData, generator,
generateGetLoc(regNumber), index, assignedValue,
needsReturn ? dupSetTemp(localData, generator, ret_temp) : null,
ins(new SetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList<Integer>()), true)),
needsReturn ? getTemp(localData, generator, ret_temp) : null,
killTemp(localData, generator, Arrays.asList(ns_temp, index_temp, ret_temp))
);
} else {
return toSourceMerge(localData, generator,
generateGetLoc(regNumber), index,
@@ -297,7 +235,7 @@ public class NameAVM2Item extends AssignableAVM2Item {
}
if (assignedValue != null) {
return toSourceMerge(localData, generator, assignedValue, generateCoerce(generator, type.toString()), needsReturn
return toSourceMerge(localData, generator, assignedValue, (!(assignedValue.returnType().toString().equals("int")&&type.toString().equals("int")))?generateCoerce(generator, type.toString()):null, needsReturn
? ins(new DupIns()) : null, generateSetLoc(regNumber));
} else {
return toSourceMerge(localData, generator, generateGetLoc(regNumber),
@@ -348,101 +286,107 @@ public class NameAVM2Item extends AssignableAVM2Item {
if (index != null) {
return TypeItem.UNBOUNDED;
}
if(type == null){
return TypeItem.UNBOUNDED;
}
return type;
}
@Override
public List<GraphSourceItem> toSourceChange(SourceGeneratorLocalData localData, SourceGenerator generator, List<GraphSourceItem> pre, List<GraphSourceItem> post, boolean needsReturn) {
public List<GraphSourceItem> toSourceChange(SourceGeneratorLocalData localData, SourceGenerator generator, boolean post, boolean decrement, boolean needsReturn) {
if (redirect != null) {
return ((AssignableAVM2Item) redirect).toSourceChange(localData, generator, pre, post, needsReturn);
return ((AssignableAVM2Item) redirect).toSourceChange(localData, generator, post, decrement, needsReturn);
}
AVM2SourceGenerator g = (AVM2SourceGenerator) generator;
Reference<Integer> ns_temp = new Reference<>(-1);
Reference<Integer> name_temp = new Reference<>(-1);
Reference<Integer> index_temp = new Reference<>(-1);
Reference<Integer> ret_temp = new Reference<>(-1);
boolean isInteger = returnType().toString().equals("int");
/*
*/
if (variableName == null && ns != null && index != null) {
List<GraphSourceItem> ret = toSourceMerge(localData, generator,
ns, generateCoerce(generator, "Namespace"), index, ins(new ConvertSIns()), ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<Integer>()), true)),
return toSourceMerge(localData, generator,
ns, generateCoerce(generator, "Namespace"), index, ins(new ConvertSIns()),
ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<Integer>()), true)),
dupSetTemp(localData, generator, name_temp),
ns, generateCoerce(generator, "Namespace"),
dupSetTemp(localData, generator, ns_temp),
//getTemp(localData, generator, ns_temp), generateCoerce(generator, "Namespace"), getTemp(localData, generator, index_temp), ins(new ConvertSIns()),
//Start get original
ns, generateCoerce(generator, "Namespace"), index, ins(new ConvertSIns()), ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<Integer>()), true)),
ns, generateCoerce(generator, "Namespace"), index, ins(new ConvertSIns()), ins(new GetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<Integer>()), true)),
//getTemp(localData, generator, ns_temp), generateCoerce(generator, "Namespace"), getTemp(localData, generator, index_temp), ins(new ConvertSIns()), ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<Integer>()), true)),
//getTemp(localData, generator, ns_temp), generateCoerce(generator, "Namespace"), getTemp(localData, generator, index_temp), ins(new ConvertSIns()),
ins(new GetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList<Integer>()), true)),
!isInteger ? ins(new ConvertDIns()) : null,
//End get original
pre);
int tempReg = -1;
if (needsReturn) {
tempReg = getFreeRegister(localData, generator);
ret.add(ins(new DupIns()));
ret.add(generateSetLoc(tempReg));
}
ret.addAll(toSourceMerge(localData, generator,
post,
ins(new SetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<Integer>()), true))
));
if (needsReturn) {
ret.add(generateGetLoc(tempReg));
ret.add(ins(new KillIns(), tempReg));
killRegister(localData, generator, tempReg);
}
return ret;
(!post) ? (decrement ? ins(isInteger ? new DecrementIIns() : new DecrementIns()) : ins(isInteger ? new IncrementIIns() : new IncrementIns())) : null,
needsReturn ? ins(new DupIns()) : null,
(post) ? (decrement ? ins(isInteger ? new DecrementIIns() : new DecrementIns()) : ins(isInteger ? new IncrementIIns() : new IncrementIns())) : null,
setTemp(localData, generator, ret_temp),
getTemp(localData, generator, name_temp),
getTemp(localData, generator, ns_temp),
getTemp(localData, generator, ret_temp),
ins(new SetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList<Integer>()), true)),
killTemp(localData, generator, Arrays.asList(ret_temp, name_temp, ns_temp)));
}
if (variableName != null && ns != null && index == null) {
List<GraphSourceItem> ret = toSourceMerge(localData, generator,
ns, generateCoerce(generator, "Namespace"), ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAME, g.abc.constants.getStringId(variableName, true), 0, 0, 0, new ArrayList<Integer>()), true)),
return toSourceMerge(localData, generator,
ns, generateCoerce(generator, "Namespace"),
ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAME, g.abc.constants.getStringId(variableName, true), 0, 0, 0, new ArrayList<Integer>()), true)),
dupSetTemp(localData, generator, name_temp),
ns, generateCoerce(generator, "Namespace"),
dupSetTemp(localData, generator, ns_temp),
//Start get original
ns, generateCoerce(generator, "Namespace"), ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAME, g.abc.constants.getStringId(variableName, true), 0, 0, 0, new ArrayList<Integer>()), true)),
ns, generateCoerce(generator, "Namespace"), ins(new GetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAME, g.abc.constants.getStringId(variableName, true), 0, 0, 0, new ArrayList<Integer>()), true)),
//getTemp(localData, generator, ns_temp), generateCoerce(generator, "Namespace"), ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAME, g.abc.constants.getStringId(variableName, true), 0, 0, 0, new ArrayList<Integer>()), true)),
//getTemp(localData, generator, ns_temp), generateCoerce(generator, "Namespace"),
ins(new GetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList<Integer>()), true)),
!isInteger ? ins(new ConvertDIns()) : null,
//End get original
pre);
int tempReg = -1;
if (needsReturn) {
tempReg = getFreeRegister(localData, generator);
ret.add(ins(new DupIns()));
ret.add(generateSetLoc(tempReg));
}
ret.addAll(toSourceMerge(localData, generator,
post,
ins(new SetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAME, g.abc.constants.getStringId(variableName, true), 0, 0, 0, new ArrayList<Integer>()), true))
));
if (needsReturn) {
ret.add(generateGetLoc(tempReg));
ret.add(ins(new KillIns(), tempReg));
killRegister(localData, generator, tempReg);
}
return ret;
(!post) ? (decrement ? ins(isInteger ? new DecrementIIns() : new DecrementIns()) : ins(isInteger ? new IncrementIIns() : new IncrementIns())) : null,
needsReturn ? ins(new DupIns()) : null,
(post) ? (decrement ? ins(isInteger ? new DecrementIIns() : new DecrementIns()) : ins(isInteger ? new IncrementIIns() : new IncrementIns())) : null,
setTemp(localData, generator, ret_temp),
getTemp(localData, generator, name_temp),
getTemp(localData, generator, ns_temp),
getTemp(localData, generator, ret_temp),
ins(new SetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList<Integer>()), true)),
killTemp(localData, generator, Arrays.asList(ret_temp, name_temp, ns_temp))
);
}
if (index != null) {
List<GraphSourceItem> ret = toSourceMerge(localData, generator,
generateGetLoc(regNumber), index,
return toSourceMerge(localData, generator,
generateGetLoc(regNumber), dupSetTemp(localData, generator, name_temp), index, dupSetTemp(localData, generator, index_temp),
//Start get original
generateGetLoc(regNumber), index,
//generateGetLoc(regNumber), getTemp(localData, generator, index_temp),
ins(new GetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList<Integer>()), true)),
!isInteger ? ins(new ConvertDIns()) : null,
//End get original
pre);
int tempReg = -1;
if (needsReturn) {
tempReg = getFreeRegister(localData, generator);
ret.add(ins(new DupIns()));
ret.add(generateSetLoc(tempReg));
}
ret.addAll(toSourceMerge(localData, generator,
post,
ins(new SetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList<Integer>()), true))
));
if (needsReturn) {
ret.add(generateGetLoc(tempReg));
ret.add(ins(new KillIns(), tempReg));
killRegister(localData, generator, tempReg);
}
return ret;
(!post) ? (decrement ? ins(isInteger ? new DecrementIIns() : new DecrementIns()) : ins(isInteger ? new IncrementIIns() : new IncrementIns())) : null,
needsReturn ? ins(new DupIns()) : null,
(post) ? (decrement ? ins(isInteger ? new DecrementIIns() : new DecrementIns()) : ins(isInteger ? new IncrementIIns() : new IncrementIns())) : null,
setTemp(localData, generator, ret_temp),
getTemp(localData, generator, name_temp),
getTemp(localData, generator, index_temp),
getTemp(localData, generator, ret_temp),
ins(new SetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList<Integer>()), true)),
killTemp(localData, generator, Arrays.asList(ret_temp, name_temp, index_temp))
);
}
return toSourceMerge(localData, generator,
//Start get original
generateGetLoc(regNumber),
//End get original
pre, generateCoerce(generator, type.toString()), needsReturn
? ins(new DupIns()) : null, post, generateSetLoc(regNumber));
!isInteger ? ins(new ConvertDIns()) : null,
//End get original
(!post) ? (decrement ? ins(isInteger ? new DecrementIIns() : new DecrementIns()) : ins(isInteger ? new IncrementIIns() : new IncrementIns())) : null,
needsReturn ? ins(new DupIns()) : null,
(post) ? (decrement ? ins(isInteger ? new DecrementIIns() : new DecrementIns()) : ins(isInteger ? new IncrementIIns() : new IncrementIns())) : null,
generateSetLoc(regNumber));
}
}

View File

@@ -19,14 +19,20 @@ package com.jpexs.decompiler.flash.abc.avm2.parser.script;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.DecrementIIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.DecrementIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.IncrementIIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.IncrementIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocalIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.KillIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetPropertyIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetPropertyIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ThrowIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.DupIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PopIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertDIns;
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.CoerceAVM2Item;
import com.jpexs.decompiler.flash.abc.types.InstanceInfo;
@@ -46,6 +52,7 @@ import com.jpexs.decompiler.graph.TypeFunctionItem;
import com.jpexs.decompiler.graph.TypeItem;
import com.jpexs.decompiler.graph.model.LocalData;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
@@ -256,48 +263,20 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator, boolean needsReturn) {
int propertyId = resolveProperty();
Object obj = object;
if (obj == null) {
String cname;
String pkgName = "";
cname = localData.currentClass;
if (cname.contains(".")) {
pkgName = cname.substring(0, cname.lastIndexOf("."));
cname = cname.substring(cname.lastIndexOf(".") + 1);
}
Reference<String> outName = new Reference<>("");
Reference<String> outNs = new Reference<>("");
Reference<String> outPropNs = new Reference<>("");
Reference<Integer> outPropNsKind = new Reference<>(1);
if (AVM2SourceGenerator.searchProperty(abcs, pkgName, cname, propertyName, outName, outNs, outPropNs, outPropNsKind)) {
NameAVM2Item nobj = new NameAVM2Item(new TypeItem(localData.currentClass), 0/*?*/, "this", null, false, openedNamespaces, openedNamespacesKind);
nobj.setRegNumber(0);
obj = nobj;
} else {
obj = ins(new FindPropertyStrictIns(), propertyId);
}
}
Object obj = resolveObject(localData, generator);
Reference<Integer> ret_temp=new Reference<>(0);
if (assignedValue != null) {
int temp_reg = getFreeRegister(localData, generator);
String targetType = resolvePropertyType().toString();
String srcType = assignedValue.returnType().toString();
GraphTargetItem st = assignedValue;
if (!targetType.equals(srcType)) {
st = new CoerceAVM2Item(null, assignedValue, targetType);
}
List<GraphSourceItem> ret = toSourceMerge(localData, generator, obj, index, st);
if (needsReturn) {
ret.add(ins(new DupIns()));
ret.add(ins(new SetLocalIns(), temp_reg));
}
ret.add(ins(new SetPropertyIns(), propertyId));
if (needsReturn) {
ret.add(ins(new GetLocalIns(), temp_reg));
ret.add(ins(new KillIns(), temp_reg));
killRegister(localData, generator, temp_reg);
}
return ret;
return toSourceMerge(localData, generator, obj, index, st,
needsReturn?dupSetTemp(localData, generator, ret_temp):null,
ins(new SetPropertyIns(), propertyId),
needsReturn?getTemp(localData, generator, ret_temp):null,
killTemp(localData, generator, Arrays.asList(ret_temp)));
} else {
return toSourceMerge(localData, generator, obj, index,
ins(new GetPropertyIns(), propertyId),
@@ -321,37 +300,63 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
return true;
}
@Override
public List<GraphSourceItem> toSourceChange(SourceGeneratorLocalData localData, SourceGenerator generator, List<GraphSourceItem> pre, List<GraphSourceItem> post, boolean needsReturn) {
int propertyId = resolveProperty();
private Object resolveObject(SourceGeneratorLocalData localData, SourceGenerator generator){
Object obj = object;
if (obj == null) {
obj = ins(new FindPropertyStrictIns(), propertyId);
int propertyId = resolveProperty();
if(obj==null){
String cname;
String pkgName = "";
cname = localData.currentClass;
if (cname.contains(".")) {
pkgName = cname.substring(0, cname.lastIndexOf("."));
cname = cname.substring(cname.lastIndexOf(".") + 1);
}
Reference<String> outName = new Reference<>("");
Reference<String> outNs = new Reference<>("");
Reference<String> outPropNs = new Reference<>("");
Reference<Integer> outPropNsKind = new Reference<>(1);
if (AVM2SourceGenerator.searchProperty(abcs, pkgName, cname, propertyName, outName, outNs, outPropNs, outPropNsKind)) {
NameAVM2Item nobj = new NameAVM2Item(new TypeItem(localData.currentClass), 0/*?*/, "this", null, false, openedNamespaces, openedNamespacesKind);
nobj.setRegNumber(0);
obj = nobj;
} else {
obj = ins(new FindPropertyStrictIns(), propertyId);
}
}
return obj;
}
@Override
public List<GraphSourceItem> toSourceChange(SourceGeneratorLocalData localData, SourceGenerator generator, boolean post,boolean decrement, boolean needsReturn) {
int propertyId = resolveProperty();
Object obj = resolveObject(localData, generator);
int temp_reg = getFreeRegister(localData, generator);
List<GraphSourceItem> ret = toSourceMerge(localData, generator, obj, index,
Reference<Integer> ret_temp = new Reference<>(-1);
Reference<Integer> obj_temp = new Reference<>(-1);
Reference<Integer> index_temp = new Reference<>(-1);
boolean isInteger = resolvePropertyType().toString().equals("int");
List<GraphSourceItem> ret= toSourceMerge(localData, generator, obj, dupSetTemp(localData, generator, obj_temp), index,index!=null?dupSetTemp(localData, generator, index_temp):null,
//Start get original
obj,
index,
//getTemp(localData, generator, obj_temp),
//index!=null?getTemp(localData, generator, index_temp):null,
ins(new GetPropertyIns(), propertyId),
!isInteger?ins(new ConvertDIns()):null,
//End get original
pre
);
if (needsReturn) {
ret.add(ins(new DupIns()));
ret.add(ins(new SetLocalIns(), temp_reg));
}
ret.addAll(post);
ret.add(ins(new SetPropertyIns(), propertyId));
if (needsReturn) {
ret.add(ins(new GetLocalIns(), temp_reg));
ret.add(ins(new KillIns(), temp_reg));
killRegister(localData, generator, temp_reg);
}
(!post)?(decrement?ins(isInteger?new DecrementIIns():new DecrementIns()):ins(isInteger?new IncrementIIns():new IncrementIns())):null,
needsReturn?ins(new DupIns()):null,
(post)?(decrement?ins(isInteger?new DecrementIIns():new DecrementIns()):ins(isInteger?new IncrementIIns():new IncrementIns())):null,
setTemp(localData, generator, ret_temp),
getTemp(localData, generator, obj_temp),
index!=null?getTemp(localData, generator, index_temp):null,
getTemp(localData, generator, ret_temp),
ins(new SetPropertyIns(), propertyId),
//needsReturn?getTemp(localData, generator, ret_temp):null,
killTemp(localData, generator, Arrays.asList(ret_temp,obj_temp,index_temp)));
return ret;
}
}

View File

@@ -6,7 +6,7 @@ TODO List for AS3 parser/compiler:
- for in/ for each
- typenames (Vectors)
- inner functions (activation, slots, etc.)
- pre/post in/decrements
- with
- delete property
- default xml namespace
- default xml namespace
- better private namespaces handling