AS3 parser - better private namespace handling, body stats calculation fixes

This commit is contained in:
Jindra Petk
2014-04-01 19:51:12 +02:00
parent e972b28a89
commit 196e740c71
32 changed files with 772 additions and 584 deletions

View File

@@ -94,10 +94,10 @@ public class ABC {
constants.constant_double.add(null);
constants.constant_int.add(null);
constants.constant_uint.add(null);
constants.constant_string.add("");
constants.constant_string.add("");
constants.constant_multiname.add(null);
constants.constant_namespace.add(null);
constants.constant_namespace_set.add(null);
constants.constant_namespace_set.add(null);
}
public int addMethodBody(MethodBody body) {
@@ -895,7 +895,6 @@ public class ABC {
return ret;
}
public int findMethodInfoByName(int classId, String methodName) {
if (classId > -1) {
for (Trait t : instance_info.get(classId).instance_traits.traits) {

View File

@@ -161,12 +161,17 @@ public class ABCOutputStream extends OutputStream {
public void writeNamespace(Namespace ns) throws IOException {
write(ns.kind);
boolean found = false;
for (int k = 0; k < Namespace.nameSpaceKinds.length; k++) {
if (Namespace.nameSpaceKinds[k] == ns.kind) {
writeU30(ns.name_index);
found = true;
break;
}
}
if (!found) {
throw new RuntimeException("Invalid ns kind:" + ns.kind);
}
}
public void writeMultiname(Multiname m) throws IOException {

View File

@@ -1857,18 +1857,21 @@ public class AVM2Code implements Serializable {
stats.instructionStats[pos].scopepos = scope;
AVM2Instruction ins = code.get(pos);
int stackDelta = ins.definition.getStackDelta(ins, abc);
int scopeDelta = ins.definition.getScopeStackDelta(ins, abc);
int oldStack = stack;
//+" deltaScope:"+(scopeDelta>0?"+"+scopeDelta:scopeDelta)+" stack:"+stack+" scope:"+scope);
stack += stackDelta;
int scopeDelta = ins.definition.getScopeStackDelta(ins, abc);
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);
//System.out.println("stack "+oldStack+(stackDelta>=0?"+"+stackDelta:stackDelta)+" max:"+stats.maxstack+" "+ins);
if ((ins.definition instanceof DXNSIns) || (ins.definition instanceof DXNSLateIns)) {
stats.has_set_dxns = true;
}
@@ -1885,7 +1888,7 @@ public class AVM2Code implements Serializable {
handleRegister(stats, ins.operands[i]);
}
}
}
}
if (ins.definition instanceof ReturnValueIns) {
//check stack=1
return true;
@@ -1927,7 +1930,7 @@ public class AVM2Code implements Serializable {
}
public CodeStats getStats(ABC abc, MethodBody body, int initScope) {
CodeStats stats = new CodeStats(this);
CodeStats stats = new CodeStats(this);
if (!walkCode(stats, 0, 0, initScope, abc)) {
return null;
}

View File

@@ -221,6 +221,9 @@ public class ConstantPool {
}
public int getStringId(String val) {
if (val == null) {
return 0;
}
for (int i = 1; i < constant_string.size(); i++) {
if (constant_string.get(i).equals(val)) {
return i;
@@ -262,6 +265,9 @@ public class ConstantPool {
}
public int getStringId(String val, boolean add) {
if (val == null) {
return 0;
}
int id = getStringId(val);
if (add && id == 0) {
id = addString(val);

View File

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

View File

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

View File

@@ -25,6 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.graph.GraphTargetItem;
import java.util.HashMap;
import java.util.List;
@@ -48,8 +49,11 @@ public class GetPropertyIns extends InstructionDefinition {
public int getStackDelta(AVM2Instruction ins, ABC abc) {
int ret = -1 + 1;
int multinameIndex = ins.operands[0];
if (abc.constants.getMultiname(multinameIndex).needsName()) {
ret--;
int kind=abc.constants.getMultiname(multinameIndex).kind;
if(kind != Multiname.MULTINAMEL && kind!= Multiname.MULTINAMELA){
if (abc.constants.getMultiname(multinameIndex).needsName()) {
ret--;
}
}
if (abc.constants.getMultiname(multinameIndex).needsNs()) {
ret--;

View File

@@ -35,6 +35,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreDecrementAVM2Item
import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreIncrementAVM2Item;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.flash.abc.types.MethodInfo;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.graph.GraphTargetItem;
import java.util.HashMap;
import java.util.List;
@@ -133,6 +134,10 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns
public int getStackDelta(AVM2Instruction ins, ABC abc) {
int ret = -2;
int multinameIndex = ins.operands[0];
int multinameKind = abc.constants.getMultiname(multinameIndex).kind;
if(multinameKind == Multiname.MULTINAMEL || multinameKind == Multiname.MULTINAMELA){
return 0;
}
if (abc.constants.getMultiname(multinameIndex).needsName()) {
ret--;
}

View File

@@ -18,8 +18,6 @@ package com.jpexs.decompiler.flash.abc.avm2.model;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.DecrementIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.IncrementIns;
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.AssignmentAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.parser.script.AssignableAVM2Item;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;

View File

@@ -18,19 +18,8 @@ package com.jpexs.decompiler.flash.abc.avm2.model;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
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.stack.DupIns;
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.AssignmentAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.parser.script.AVM2SourceGenerator;
import com.jpexs.decompiler.flash.abc.avm2.parser.script.AssignableAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.parser.script.NameAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.parser.script.PropertyAVM2Item;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;

View File

@@ -18,7 +18,6 @@ package com.jpexs.decompiler.flash.abc.avm2.model;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushNullIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushUndefinedIns;
import com.jpexs.decompiler.flash.ecma.Undefined;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;

View File

@@ -18,8 +18,6 @@ package com.jpexs.decompiler.flash.abc.avm2.model.operations;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.DecrementIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.IncrementIns;
import com.jpexs.decompiler.flash.abc.avm2.model.clauses.AssignmentAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.parser.script.AssignableAVM2Item;
import com.jpexs.decompiler.graph.GraphSourceItem;

View File

@@ -18,7 +18,6 @@ package com.jpexs.decompiler.flash.abc.avm2.model.operations;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.IncrementIns;
import com.jpexs.decompiler.flash.abc.avm2.parser.script.AssignableAVM2Item;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;

View File

@@ -32,7 +32,6 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocalIns;
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.GetLexIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetPropertyIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetScopeObjectIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.InitPropertyIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnValueIns;
@@ -80,7 +79,6 @@ import com.jpexs.decompiler.graph.model.DoWhileItem;
import com.jpexs.decompiler.graph.model.DuplicateItem;
import com.jpexs.decompiler.graph.model.ForItem;
import com.jpexs.decompiler.graph.model.IfItem;
import com.jpexs.decompiler.graph.model.LocalData;
import com.jpexs.decompiler.graph.model.NotItem;
import com.jpexs.decompiler.graph.model.OrItem;
import com.jpexs.decompiler.graph.model.SwitchItem;
@@ -564,7 +562,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
return abc;
}
public void generateClass(int initScope, PackageAVM2Item pkg, ClassInfo classInfo, InstanceInfo instanceInfo, SourceGeneratorLocalData localData, boolean isInterface, String name, String superName, GraphTargetItem extendsVal, List<GraphTargetItem> implementsStr, GraphTargetItem constructor, List<GraphTargetItem> traitItems) throws ParseException {
public void generateClass(int namespace, int initScope, PackageAVM2Item pkg, ClassInfo classInfo, InstanceInfo instanceInfo, SourceGeneratorLocalData localData, boolean isInterface, String name, String superName, GraphTargetItem extendsVal, List<GraphTargetItem> implementsStr, GraphTargetItem constructor, List<GraphTargetItem> traitItems) throws ParseException {
localData.currentClass = pkg.packageName.equals("") ? name : pkg.packageName + "." + name;
List<GraphSourceItem> ret = new ArrayList<>();
if (extendsVal == null && !isInterface) {
@@ -597,11 +595,11 @@ public class AVM2SourceGenerator implements SourceGenerator {
if (ti instanceof SlotAVM2Item) {
SlotAVM2Item si = (SlotAVM2Item) ti;
if (si.isStatic()) {
mb.code.code.add(ins(new FindPropertyStrictIns(), traitName(pkg.packageName, name, si.getNsKind(), si.var)));
mb.code.code.add(ins(new FindPropertyStrictIns(), traitName(namespace, si.var)));
List<GraphTargetItem> tis = new ArrayList<>();
tis.add(si.value);
mb.code.code.addAll(toInsList(generate(localData, tis)));
mb.code.code.add(ins(new InitPropertyIns(), traitName(pkg.packageName, name, si.getNsKind(), si.var)));
mb.code.code.add(ins(new InitPropertyIns(), traitName(namespace, si.var)));
}
}
}
@@ -634,7 +632,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
return ret;
}
public int generateClass(ClassInfo ci, InstanceInfo ii, int initScope, PackageAVM2Item pkg, SourceGeneratorLocalData localData, AVM2Item cls) throws ParseException {
public int generateClass(int namespace, ClassInfo ci, InstanceInfo ii, int initScope, PackageAVM2Item pkg, SourceGeneratorLocalData localData, AVM2Item cls) throws ParseException {
/*ClassInfo ci = new ClassInfo();
InstanceInfo ii = new InstanceInfo();
abc.class_info.add(ci);
@@ -642,7 +640,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
*/
if (cls instanceof ClassAVM2Item) {
ClassAVM2Item cai = (ClassAVM2Item) cls;
generateClass(initScope, pkg, ci, ii, localData, false, cai.className, cai.extendsOp.toString(), cai.extendsOp, cai.implementsOp, cai.constructor, cai.traits);
generateClass(namespace, initScope, pkg, ci, ii, localData, false, cai.className, cai.extendsOp.toString(), cai.extendsOp, cai.implementsOp, cai.constructor, cai.traits);
if (!cai.isDynamic) {
ii.flags |= InstanceInfo.CLASS_SEALED;
}
@@ -650,19 +648,19 @@ public class AVM2SourceGenerator implements SourceGenerator {
ii.flags |= InstanceInfo.CLASS_FINAL;
}
ii.flags |= InstanceInfo.CLASS_PROTECTEDNS;
ii.protectedNS = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PROTECTED, abc.constants.getStringId(pkg.packageName + ":" + cai.className, true)), 0, true);
ii.protectedNS = cai.protectedNs;
}
if (cls instanceof InterfaceAVM2Item) {
InterfaceAVM2Item iai = (InterfaceAVM2Item) cls;
generateClass(initScope, pkg, ci, ii, localData, true, iai.name, null, null, iai.superInterfaces, null, iai.methods);
generateClass(namespace, initScope, pkg, ci, ii, localData, true, iai.name, null, null, iai.superInterfaces, null, iai.methods);
ii.flags |= InstanceInfo.CLASS_INTERFACE;
}
return abc.instance_info.size() - 1;
}
public int traitName(String pkg, String className, int nsKind, String var) {
return abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str(var), namespace(nsKind, nsKind != Namespace.KIND_PACKAGE && className != null ? (pkg + ":" + className) : ""), 0, 0, new ArrayList<Integer>()), true);
public int traitName(int namespace, String var) {
return abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str(var), namespace, 0, 0, new ArrayList<Integer>()), true);
}
public int typeName(SourceGeneratorLocalData localData, GraphTargetItem type) {
@@ -900,11 +898,11 @@ public class AVM2SourceGenerator implements SourceGenerator {
continue;
}
if (item instanceof InterfaceAVM2Item) {
generateClass(abc.class_info.get(((TraitClass) traits[k]).class_info), abc.instance_info.get(((TraitClass) traits[k]).class_info), initScope, pkg, localData, (InterfaceAVM2Item) item);
generateClass(((InterfaceAVM2Item) item).namespace, abc.class_info.get(((TraitClass) traits[k]).class_info), abc.instance_info.get(((TraitClass) traits[k]).class_info), initScope, pkg, localData, (InterfaceAVM2Item) item);
}
if (item instanceof ClassAVM2Item) {
generateClass(abc.class_info.get(((TraitClass) traits[k]).class_info), abc.instance_info.get(((TraitClass) traits[k]).class_info), initScope, pkg, localData, (ClassAVM2Item) item);
generateClass(((ClassAVM2Item) item).namespace, abc.class_info.get(((TraitClass) traits[k]).class_info), abc.instance_info.get(((TraitClass) traits[k]).class_info), initScope, pkg, localData, (ClassAVM2Item) item);
}
if ((item instanceof MethodAVM2Item) || (item instanceof GetterAVM2Item) || (item instanceof SetterAVM2Item)) {
MethodAVM2Item mai = (MethodAVM2Item) item;
@@ -912,7 +910,6 @@ public class AVM2SourceGenerator implements SourceGenerator {
continue;
}
Reference<Boolean> hasArgs = new Reference<>(Boolean.FALSE);
calcRegisters(localData, mai, hasArgs);
((TraitMethodGetterSetter) traits[k]).method_info = method(initScope + 1/*class scope*/, mai.hasRest, hasArgs.getVal(), mai.line, className, superName, false, localData, mai.paramTypes, mai.paramNames, mai.paramValues, mai.body, mai.retType);
} else if (item instanceof FunctionAVM2Item) {
@@ -937,7 +934,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
abc.instance_info.add(ii);
tc.class_info = abc.instance_info.size() - 1;
tc.kindType = Trait.TRAIT_CLASS;
tc.name_index = traitName(pkg.packageName, className, ((InterfaceAVM2Item) item).namespaceKind, ((InterfaceAVM2Item) item).name);
tc.name_index = traitName(((InterfaceAVM2Item) item).namespace, ((InterfaceAVM2Item) item).name);
tc.slot_id = slot_id++;
ts.traits.add(tc);
traits[k] = tc;
@@ -961,7 +958,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
}
tc.kindType = Trait.TRAIT_CLASS;
tc.name_index = traitName(pkg.packageName, className, ((ClassAVM2Item) item).namespaceKind, ((ClassAVM2Item) item).className);
tc.name_index = traitName(((ClassAVM2Item) item).namespace, ((ClassAVM2Item) item).className);
tc.slot_id = slot_id++;
ts.traits.add(tc);
traits[k] = tc;
@@ -974,7 +971,8 @@ public class AVM2SourceGenerator implements SourceGenerator {
GraphTargetItem val = null;
GraphTargetItem type = null;
boolean isNamespace = false;
int nsKind = 0;
int namespace = 0;
boolean isStatic = false;
if (item instanceof SlotAVM2Item) {
SlotAVM2Item sai = (SlotAVM2Item) item;
if (sai.isStatic() != generateStatic) {
@@ -983,7 +981,8 @@ public class AVM2SourceGenerator implements SourceGenerator {
var = sai.var;
val = sai.value;
type = sai.type;
nsKind = sai.getNsKind();
isStatic = sai.isStatic();
namespace = sai.getNamespace();
}
if (item instanceof ConstAVM2Item) {
ConstAVM2Item cai = (ConstAVM2Item) item;
@@ -993,20 +992,21 @@ public class AVM2SourceGenerator implements SourceGenerator {
var = cai.var;
val = cai.value;
type = cai.type;
nsKind = cai.getNsKind();
namespace = cai.getNamespace();
isNamespace = type.toString().equals("Namespace");
isStatic = cai.isStatic();
}
tsc.name_index = traitName(pkg.packageName, className, nsKind, var);
tsc.name_index = traitName(namespace, var);
tsc.type_index = isNamespace ? 0 : typeName(localData, type);
ValueKind vk = getValueKind(nsKind, type, val);
ValueKind vk = getValueKind(abc.constants.constant_namespace.get(namespace).kind, type, val);
if (vk == null) {
tsc.value_kind = ValueKind.CONSTANT_Undefined;
} else {
tsc.value_kind = vk.value_kind;
tsc.value_index = vk.value_index;
}
tsc.slot_id = slot_id++;
tsc.slot_id = isStatic ? slot_id++ : 0;
ts.traits.add(tsc);
traits[k] = tsc;
}
@@ -1017,7 +1017,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
}
TraitMethodGetterSetter tmgs = new TraitMethodGetterSetter();
tmgs.kindType = (item instanceof MethodAVM2Item) ? Trait.TRAIT_METHOD : ((item instanceof GetterAVM2Item) ? Trait.TRAIT_GETTER : Trait.TRAIT_SETTER);
tmgs.name_index = traitName(pkg.packageName, className, ((MethodAVM2Item) item).namespaceKind, ((MethodAVM2Item) item).functionName);
tmgs.name_index = traitName(((MethodAVM2Item) item).namespace, ((MethodAVM2Item) item).functionName);
tmgs.disp_id = 0; //0 = disable override optimization; TODO: handle this
if (mai.isFinal()) {
tmgs.kindFlags |= Trait.ATTR_Final;
@@ -1032,7 +1032,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
TraitFunction tf = new TraitFunction();
tf.slot_id = slot_id++;
tf.kindType = Trait.TRAIT_FUNCTION;
tf.name_index = traitName(pkg.packageName, className, Namespace.KIND_PACKAGE, ((FunctionAVM2Item) item).functionName);
tf.name_index = traitName(((FunctionAVM2Item) item).namespace, ((FunctionAVM2Item) item).functionName);
ts.traits.add(tf);
traits[k] = tf;
}
@@ -1110,17 +1110,44 @@ public class AVM2SourceGenerator implements SourceGenerator {
}
}
public static boolean searchProperty(List<ABC> abcs, String pkg, String obj, String propertyName, Reference<String> outName, Reference<String> outNs, Reference<String> outPropNs, Reference<Integer> outPropNsKind) {
public static GraphTargetItem getTraitReturnType(ABC abc, Trait t) {
if (t instanceof TraitSlotConst) {
TraitSlotConst tsc = (TraitSlotConst) t;
if (tsc.type_index == 0) {
return TypeItem.UNBOUNDED;
}
return new TypeItem(abc.constants.constant_multiname.get(tsc.type_index).getNameWithNamespace(abc.constants));
}
if (t instanceof TraitMethodGetterSetter) {
TraitMethodGetterSetter tmgs = (TraitMethodGetterSetter) t;
if (tmgs.kindType == Trait.TRAIT_GETTER) {
return new TypeItem(abc.constants.constant_multiname.get(abc.method_info.get(tmgs.method_info).ret_type).getNameWithNamespace(abc.constants));
}
if (tmgs.kindType == Trait.TRAIT_SETTER) {
return new TypeItem(abc.constants.constant_multiname.get(abc.method_info.get(tmgs.method_info).param_types[0]).getNameWithNamespace(abc.constants));
}
}
if (t instanceof TraitFunction) {
return new TypeItem("Function");
}
return TypeItem.UNBOUNDED;
}
public static boolean searchPrototypeChain(boolean instanceOnly, List<ABC> abcs, String pkg, String obj, String propertyName, Reference<String> outName, Reference<String> outNs, Reference<String> outPropNs, Reference<Integer> outPropNsKind, Reference<String> outPropType) {
for (ABC abc : abcs) {
for (ScriptInfo ii : abc.script_info) {
for (Trait t : ii.traits.traits) {
if (pkg.equals(t.getName(abc).getNamespace(abc.constants).getName(abc.constants))) {
if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList<String>()))) {
outName.setVal(obj);
outNs.setVal(pkg);
outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants));
outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind);
return true;
if (!instanceOnly) {
for (ScriptInfo ii : abc.script_info) {
for (Trait t : ii.traits.traits) {
if (pkg.equals(t.getName(abc).getNamespace(abc.constants).getName(abc.constants))) {
if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList<String>()))) {
outName.setVal(obj);
outNs.setVal(pkg);
outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants));
outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind);
outPropType.setVal(getTraitReturnType(abc, t).toString());
return true;
}
}
}
}
@@ -1138,23 +1165,27 @@ public class AVM2SourceGenerator implements SourceGenerator {
outNs.setVal(pkg);
outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants));
outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind);
outPropType.setVal(getTraitReturnType(abc, t).toString());
return true;
}
}
for (Trait t : abc.class_info.get(i).static_traits.traits) {
if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList<String>()))) {
outName.setVal(obj);
outNs.setVal(pkg);
outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants));
outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind);
return true;
if (!instanceOnly) {
for (Trait t : abc.class_info.get(i).static_traits.traits) {
if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList<String>()))) {
outName.setVal(obj);
outNs.setVal(pkg);
outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants));
outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind);
outPropType.setVal(getTraitReturnType(abc, t).toString());
return true;
}
}
}
Multiname superName = abc.constants.constant_multiname.get(ii.super_index);
if (superName != null) {
return searchProperty(abcs, superName.getNamespace(abc.constants).getName(abc.constants), superName.getName(abc.constants, new ArrayList<String>()), propertyName, outName, outNs, outPropNs, outPropNsKind);
return searchPrototypeChain(instanceOnly, abcs, superName.getNamespace(abc.constants).getName(abc.constants), superName.getName(abc.constants, new ArrayList<String>()), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropType);
} else {
return false;
}
@@ -1221,36 +1252,30 @@ public class AVM2SourceGenerator implements SourceGenerator {
List<ABC> abcs = new ArrayList<>();
abcs.add(abc);
abcs.addAll(allABCs);
String parts[] = new String[]{n.getVariableName()};
if (n.getVariableName().contains(".")) {
parts = n.getVariableName().split("\\.");
}
loopi:
for (int i = 0; i < n.openedNamespaces.size(); i++) {
String ns = n.openedNamespaces.get(i);
String nspkg = ns;
String nsclass = null;
int nsKind = n.openedNamespacesKind.get(i);
if (nspkg.contains(":") && nsKind != Namespace.KIND_NAMESPACE) {
nsclass = nspkg.substring(nspkg.indexOf(":") + 1);
nspkg = nspkg.substring(0, nspkg.indexOf(":"));
}
for (int h = 0; h < abc.instance_info.size(); h++) {
InstanceInfo ii = abc.instance_info.get(h);
Multiname mn = abc.constants.constant_multiname.get(ii.name_index);
if (mn.getNamespace(abc.constants).getName(abc.constants).equals(nspkg) && (nsclass == null || (mn.getName(abc.constants, new ArrayList<String>()).equals(nsclass)))) {
//found opened class
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, nspkg, mn.getName(abc.constants, new ArrayList<String>()), parts[0], outName, outNs, outPropNs, outPropNsKind)) {
resolved = new PropertyAVM2Item(null, parts[0], n.getIndex(), abcs, n.openedNamespaces, n.openedNamespacesKind);
break loopi;
int nsIndex = n.openedNamespaces.get(i);
Namespace ns = abc.constants.constant_namespace.get(nsIndex);
int nsKind = ns.kind;
loopabc:
for (ABC a : abcs) {
for (int h = 0; h < a.instance_info.size(); h++) {
InstanceInfo ii = a.instance_info.get(h);
Multiname nm = a.constants.constant_multiname.get(ii.name_index);
if (nm.getNamespace(a.constants).getName(a.constants).equals(ns.getName(abc.constants)) && nm.getNamespace(a.constants).kind == nsKind) {
//found opened class
Reference<String> outName = new Reference<>("");
Reference<String> outNs = new Reference<>("");
Reference<String> outPropNs = new Reference<>("");
Reference<Integer> outPropNsKind = new Reference<>(1);
Reference<String> outPropType = new Reference<>("");
if (AVM2SourceGenerator.searchPrototypeChain(false, abcs, nm.getNamespace(a.constants).getName(a.constants), nm.getName(a.constants, new ArrayList<String>()), n.getVariableName(), outName, outNs, outPropNs, outPropNsKind, outPropType)) {
resolved = new PropertyAVM2Item(null, n.getVariableName(), n.getIndex(), abc, allABCs, n.openedNamespaces);
}
}
}
}
}
n.redirect = resolved;
if (resolved == null) {

View File

@@ -19,9 +19,9 @@
package com.jpexs.decompiler.flash.abc.avm2.parser.script;
import com.jpexs.decompiler.flash.abc.avm2.parser.ParseException;
import java.util.Stack;
import java.util.List;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
/**
* This class is a scanner generated by

View File

@@ -54,7 +54,7 @@ public abstract class AssignableAVM2Item extends AVM2Item {
this.assignedValue = storeValue;
}
public abstract List<GraphSourceItem> toSourceChange(SourceGeneratorLocalData localData, SourceGenerator generator, boolean post,boolean decrement, boolean needsReturn);
public abstract List<GraphSourceItem> toSourceChange(SourceGeneratorLocalData localData, SourceGenerator generator, boolean post, boolean decrement, boolean needsReturn);
public GraphTargetItem getAssignedValue() {
return assignedValue;
@@ -71,7 +71,7 @@ public abstract class AssignableAVM2Item extends AVM2Item {
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<>();
@@ -89,13 +89,12 @@ public abstract class AssignableAVM2Item extends AVM2Item {
}
/*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;
}*/
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<>();

View File

@@ -23,9 +23,6 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallPropVoidIn
import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallPropertyIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns;
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item;
import com.jpexs.decompiler.flash.abc.types.InstanceInfo;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
@@ -33,7 +30,6 @@ import com.jpexs.decompiler.graph.SourceGenerator;
import com.jpexs.decompiler.graph.TypeFunctionItem;
import com.jpexs.decompiler.graph.TypeItem;
import com.jpexs.decompiler.graph.model.LocalData;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
@@ -80,12 +76,13 @@ public class CallAVM2Item extends AVM2Item {
Reference<String> outNs = new Reference<>("");
Reference<String> outPropNs = new Reference<>("");
Reference<Integer> outPropNsKind = new Reference<>(1);
if (AVM2SourceGenerator.searchProperty(allAbcs, pkgName, cname, n.getVariableName(), outName, outNs, outPropNs, outPropNsKind)) {
NameAVM2Item nobj = new NameAVM2Item(new TypeItem(localData.currentClass), n.line, "this", null, false, n.openedNamespaces, n.openedNamespacesKind);
Reference<String> outPropType = new Reference<>("");
if (AVM2SourceGenerator.searchPrototypeChain(true, allAbcs, pkgName, cname, n.getVariableName(), outName, outNs, outPropNs, outPropNsKind, outPropType)) {
NameAVM2Item nobj = new NameAVM2Item(new TypeItem(localData.currentClass), n.line, "this", null, false, n.openedNamespaces);
nobj.setRegNumber(0);
obj = nobj;
}
PropertyAVM2Item p = new PropertyAVM2Item(obj, n.getVariableName(), n.getIndex(), allAbcs, n.openedNamespaces, n.openedNamespacesKind);
PropertyAVM2Item p = new PropertyAVM2Item(obj, n.getVariableName(), n.getIndex(), g.abc, g.allABCs, n.openedNamespaces);
p.setAssignedValue(n.getAssignedValue());
callable = p;
}
@@ -111,10 +108,7 @@ public class CallAVM2Item extends AVM2Item {
GraphTargetItem callable = name;
if (callable instanceof NameAVM2Item) {
NameAVM2Item n = (NameAVM2Item) callable;
List<ABC> allAbcs = new ArrayList<>();
allAbcs.add(g.abc);
allAbcs.addAll(g.allABCs);
PropertyAVM2Item p = new PropertyAVM2Item(null, n.getVariableName(), n.getIndex(), allAbcs, n.openedNamespaces, n.openedNamespacesKind);
PropertyAVM2Item p = new PropertyAVM2Item(null, n.getVariableName(), n.getIndex(), g.abc, g.allABCs, n.openedNamespaces);
p.setAssignedValue(n.getAssignedValue());
callable = p;
}

View File

@@ -33,7 +33,8 @@ public class ClassAVM2Item extends AVM2Item implements Block {
public List<GraphTargetItem> implementsOp;
public String className;
public GraphTargetItem constructor;
public int namespaceKind;
public int namespace;
public int protectedNs;
public boolean isDynamic;
public boolean isFinal;
@@ -46,14 +47,15 @@ public class ClassAVM2Item extends AVM2Item implements Block {
return ret;
}
public ClassAVM2Item(boolean isDynamic, boolean isFinal, int namespaceKind, String className, GraphTargetItem extendsOp, List<GraphTargetItem> implementsOp, GraphTargetItem constructor, List<GraphTargetItem> traits) {
public ClassAVM2Item(int protectedNs, boolean isDynamic, boolean isFinal, int namespace, String className, GraphTargetItem extendsOp, List<GraphTargetItem> implementsOp, GraphTargetItem constructor, List<GraphTargetItem> traits) {
super(null, NOPRECEDENCE);
this.protectedNs = protectedNs;
this.className = className;
this.traits = traits;
this.extendsOp = extendsOp;
this.implementsOp = implementsOp;
this.constructor = constructor;
this.namespaceKind = namespaceKind;
this.namespace = namespace;
this.isDynamic = isDynamic;
this.isFinal = isFinal;
}

View File

@@ -27,22 +27,22 @@ import com.jpexs.decompiler.graph.model.LocalData;
*/
public class ConstAVM2Item extends AVM2Item {
private final int nsKind;
private final int namespace;
private boolean isStatic;
public String var;
public GraphTargetItem type;
public int getNsKind() {
return nsKind;
public int getNamespace() {
return namespace;
}
public boolean isStatic() {
return isStatic;
}
public ConstAVM2Item(boolean isStatic, int nsKind, String var, GraphTargetItem type, GraphTargetItem value) {
public ConstAVM2Item(boolean isStatic, int namespace, String var, GraphTargetItem type, GraphTargetItem value) {
super(null, NOPRECEDENCE);
this.nsKind = nsKind;
this.namespace = namespace;
this.value = value;
this.isStatic = isStatic;
this.var = var;

View File

@@ -19,7 +19,6 @@ 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.construction.ConstructPropIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallPropertyIns;
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;

View File

@@ -30,6 +30,7 @@ public class FunctionAVM2Item extends AVM2Item {
public String calculatedFunctionName;
public String functionName;
public int namespace;
public List<String> paramNames;
public List<GraphTargetItem> body;
public List<NameAVM2Item> subvariables;
@@ -39,8 +40,9 @@ public class FunctionAVM2Item extends AVM2Item {
public int line;
public boolean hasRest;
public FunctionAVM2Item(boolean hasRest, int line, String functionName, List<GraphTargetItem> paramTypes, List<String> paramNames, List<GraphTargetItem> paramValues, List<GraphTargetItem> body, List<NameAVM2Item> subvariables, GraphTargetItem retType) {
public FunctionAVM2Item(int namespace, boolean hasRest, int line, String functionName, List<GraphTargetItem> paramTypes, List<String> paramNames, List<GraphTargetItem> paramValues, List<GraphTargetItem> body, List<NameAVM2Item> subvariables, GraphTargetItem retType) {
super(null, NOPRECEDENCE);
this.namespace = namespace;
this.paramNames = paramNames;
this.body = body;
this.functionName = functionName;

View File

@@ -25,8 +25,8 @@ import java.util.List;
*/
public class GetterAVM2Item extends MethodAVM2Item {
public GetterAVM2Item(boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespaceKind, String methodName, List<GraphTargetItem> paramTypes, List<String> paramNames, List<GraphTargetItem> paramValues, List<GraphTargetItem> body, List<NameAVM2Item> subvariables, GraphTargetItem retType) {
super(hasRest, line, override, isFinal, isStatic, namespaceKind, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType);
public GetterAVM2Item(boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespace, String methodName, List<GraphTargetItem> paramTypes, List<String> paramNames, List<GraphTargetItem> paramValues, List<GraphTargetItem> body, List<NameAVM2Item> subvariables, GraphTargetItem retType) {
super(hasRest, line, override, isFinal, isStatic, namespace, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType);
}
}

View File

@@ -32,15 +32,15 @@ public class InterfaceAVM2Item extends AVM2Item {
public String name;
public List<GraphTargetItem> superInterfaces;
public List<GraphTargetItem> methods;
public int namespaceKind;
public int namespace;
public boolean isFinal;
public InterfaceAVM2Item(boolean isFinal, int namespaceKind, String name, List<GraphTargetItem> superInterfaces, List<GraphTargetItem> traits) {
public InterfaceAVM2Item(boolean isFinal, int namespace, String name, List<GraphTargetItem> superInterfaces, List<GraphTargetItem> traits) {
super(null, NOPRECEDENCE);
this.name = name;
this.superInterfaces = superInterfaces;
this.methods = traits;
this.namespaceKind = namespaceKind;
this.namespace = namespace;
this.isFinal = isFinal;
}

View File

@@ -27,14 +27,12 @@ import java.util.List;
*/
public class MethodAVM2Item extends FunctionAVM2Item {
public int namespaceKind;
private boolean isStatic;
private boolean isFinal;
private boolean override;
public MethodAVM2Item(boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespaceKind, String methodName, List<GraphTargetItem> paramTypes, List<String> paramNames, List<GraphTargetItem> paramValues, List<GraphTargetItem> body, List<NameAVM2Item> subvariables, GraphTargetItem retType) {
super(hasRest, line, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType);
this.namespaceKind = namespaceKind;
public MethodAVM2Item(boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespace, String methodName, List<GraphTargetItem> paramTypes, List<String> paramNames, List<GraphTargetItem> paramValues, List<GraphTargetItem> body, List<NameAVM2Item> subvariables, GraphTargetItem retType) {
super(namespace, hasRest, line, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType);
this.isStatic = isStatic;
this.override = override;
this.isFinal = isFinal;

View File

@@ -34,7 +34,6 @@ 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.types.Multiname;
import com.jpexs.decompiler.flash.abc.types.Namespace;
import com.jpexs.decompiler.flash.abc.types.NamespaceSet;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.GraphSourceItem;
@@ -57,8 +56,7 @@ public class NameAVM2Item extends AssignableAVM2Item {
private boolean definition;
private GraphTargetItem index;
private int nsKind = -1;
public List<String> openedNamespaces;
public List<Integer> openedNamespacesKind;
public List<Integer> openedNamespaces;
public int line;
public GraphTargetItem type;
private GraphTargetItem ns = null;
@@ -116,7 +114,7 @@ public class NameAVM2Item extends AssignableAVM2Item {
return variableName;
}
public NameAVM2Item(GraphTargetItem type, int line, String variableName, GraphTargetItem storeValue, boolean definition, List<String> openedNamespaces, List<Integer> openedNamespacesKind) {
public NameAVM2Item(GraphTargetItem type, int line, String variableName, GraphTargetItem storeValue, boolean definition, List<Integer> openedNamespaces) {
super(storeValue);
this.variableName = variableName;
this.assignedValue = storeValue;
@@ -124,7 +122,6 @@ public class NameAVM2Item extends AssignableAVM2Item {
this.line = line;
this.type = type;
this.openedNamespaces = openedNamespaces;
this.openedNamespacesKind = openedNamespacesKind;
}
public boolean isDefinition() {
@@ -143,7 +140,7 @@ public class NameAVM2Item extends AssignableAVM2Item {
private int allNsSet(ABC abc) {
int nssa[] = new int[openedNamespaces.size()];
for (int i = 0; i < openedNamespaces.size(); i++) {
nssa[i] = (abc.constants.getNamespaceId(new Namespace(openedNamespacesKind.get(i), abc.constants.getStringId(openedNamespaces.get(i), true)), 0, true));
nssa[i] = openedNamespaces.get(i);
}
return abc.constants.getNamespaceSetId(new NamespaceSet(nssa), true);
}
@@ -235,7 +232,7 @@ public class NameAVM2Item extends AssignableAVM2Item {
}
if (assignedValue != null) {
return toSourceMerge(localData, generator, assignedValue, (!(assignedValue.returnType().toString().equals("int")&&type.toString().equals("int")))?generateCoerce(generator, type.toString()):null, needsReturn
return toSourceMerge(localData, generator, assignedValue, (!("int".equals("" + assignedValue.returnType()) && "int".equals("" + type))) ? generateCoerce(generator, "" + type) : null, needsReturn
? ins(new DupIns()) : null, generateSetLoc(regNumber));
} else {
return toSourceMerge(localData, generator, generateGetLoc(regNumber),
@@ -286,7 +283,7 @@ public class NameAVM2Item extends AssignableAVM2Item {
if (index != null) {
return TypeItem.UNBOUNDED;
}
if(type == null){
if (type == null) {
return TypeItem.UNBOUNDED;
}
return type;

View File

@@ -23,32 +23,23 @@ 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.GetLexIns;
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;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.flash.abc.types.Namespace;
import com.jpexs.decompiler.flash.abc.types.NamespaceSet;
import com.jpexs.decompiler.flash.abc.types.ScriptInfo;
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction;
import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.SourceGenerator;
import com.jpexs.decompiler.graph.TypeFunctionItem;
import com.jpexs.decompiler.graph.TypeItem;
import com.jpexs.decompiler.graph.model.LocalData;
import java.util.ArrayList;
@@ -63,18 +54,18 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
public String propertyName;
public GraphTargetItem object;
public List<ABC> abcs;
public ABC abc;
public List<ABC> otherABCs;
public GraphTargetItem index;
private List<String> openedNamespaces;
private List<Integer> openedNamespacesKind;
private List<Integer> openedNamespaces;
public PropertyAVM2Item(GraphTargetItem object, String propertyName, GraphTargetItem index, List<ABC> abcs, List<String> openedNamespaces, List<Integer> openedNamespacesKind) {
public PropertyAVM2Item(GraphTargetItem object, String propertyName, GraphTargetItem index, ABC abc, List<ABC> otherABCs, List<Integer> openedNamespaces) {
this.propertyName = propertyName;
this.object = object;
this.abcs = abcs;
this.otherABCs = otherABCs;
this.abc = abc;
this.index = index;
this.openedNamespaces = openedNamespaces;
this.openedNamespacesKind = openedNamespacesKind;
}
@Override
@@ -85,199 +76,329 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
private int allNsSet() {
int nssa[] = new int[openedNamespaces.size()];
for (int i = 0; i < openedNamespaces.size(); i++) {
nssa[i] = (abcs.get(0).constants.getNamespaceId(new Namespace(openedNamespacesKind.get(i), abcs.get(0).constants.getStringId(openedNamespaces.get(i), true)), 0, true));
nssa[i] = openedNamespaces.get(i);
}
return abcs.get(0).constants.getNamespaceSetId(new NamespaceSet(nssa), true);
return abc.constants.getNamespaceSetId(new NamespaceSet(nssa), true);
}
private String resolveObjectType() {
private void resolve(Reference<String> objectType, Reference<String> propertyType, Reference<Integer> propertyIndex) {
String objType = object == null ? null : object.returnType().toString();
String propType = "";
int propIndex = 0;
if (objType == null) {
loopo:
loopobjType:
for (int i = 0; i < openedNamespaces.size(); i++) {
String ns = openedNamespaces.get(i);
String nspkg = ns;
String nsclass = null;
int nsKind = openedNamespacesKind.get(i);
if (nspkg.contains(":") && nsKind != Namespace.KIND_NAMESPACE) {
nsclass = nspkg.substring(nspkg.indexOf(":") + 1);
nspkg = nspkg.substring(0, nspkg.indexOf(":"));
int nsindex = openedNamespaces.get(i);
int nsKind = abc.constants.constant_namespace.get(openedNamespaces.get(i)).kind;
String nsname = abc.constants.constant_namespace.get(openedNamespaces.get(i)).getName(abc.constants);
int name_index = 0;
for (int m = 1; m < abc.constants.constant_multiname.size(); m++) {
Multiname mname = abc.constants.constant_multiname.get(m);
if (mname.kind == Multiname.QNAME && mname.getName(abc.constants, new ArrayList<String>()).equals(propertyName) && mname.namespace_index == nsindex) {
name_index = m;
break;
}
}
loopabc:
for (ABC a : abcs) {
for (int h = 0; h < a.instance_info.size(); h++) {
InstanceInfo ii = a.instance_info.get(h);
Multiname n = a.constants.constant_multiname.get(ii.name_index);
if (n.getNamespace(a.constants).getName(a.constants).equals(nspkg) && (nsclass == null || (n.getName(a.constants, new ArrayList<String>()).equals(nsclass)))) {
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, nspkg, n.getName(a.constants, new ArrayList<String>()), propertyName, outName, outNs, outPropNs, outPropNsKind)) {
objType = "".equals(outNs.getVal()) ? outName.getVal() : outNs.getVal() + "." + outName.getVal();
break loopo;
if (name_index > 0) {
for (int c = 0; c < abc.instance_info.size(); c++) {
for (Trait t : abc.instance_info.get(c).instance_traits.traits) {
if (t.name_index == name_index) {
objType = abc.instance_info.get(c).getName(abc.constants).getNameWithNamespace(abc.constants);
propType = AVM2SourceGenerator.getTraitReturnType(abc, t).toString();
propIndex = t.name_index;
break loopobjType;
}
}
for (Trait t : abc.class_info.get(c).static_traits.traits) {
if (t.name_index == name_index) {
objType = abc.instance_info.get(c).getName(abc.constants).getNameWithNamespace(abc.constants);
propType = AVM2SourceGenerator.getTraitReturnType(abc, t).toString();
propIndex = t.name_index;
break loopobjType;
}
}
}
}
if (nsKind == Namespace.KIND_PACKAGE) {
List<ABC> abcs = new ArrayList<>();
abcs.add(abc);
abcs.addAll(otherABCs);
loopabc:
for (ABC a : otherABCs) {
for (int h = 0; h < a.instance_info.size(); h++) {
InstanceInfo ii = a.instance_info.get(h);
Multiname n = a.constants.constant_multiname.get(ii.name_index);
if (n.getNamespace(a.constants).kind == Namespace.KIND_PACKAGE && n.getNamespace(a.constants).getName(a.constants).equals(nsname)) {
Reference<String> outName = new Reference<>("");
Reference<String> outNs = new Reference<>("");
Reference<String> outPropNs = new Reference<>("");
Reference<Integer> outPropNsKind = new Reference<>(1);
Reference<String> outPropType = new Reference<>("");
if (AVM2SourceGenerator.searchPrototypeChain(false, abcs, nsname, n.getName(a.constants, new ArrayList<String>()), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropType)) {
objType = "".equals(outNs.getVal()) ? outName.getVal() : outNs.getVal() + "." + outName.getVal();
propType = outPropType.getVal();
propIndex = abc.constants.getMultinameId(new Multiname(Multiname.QNAME,
abc.constants.getStringId(propertyName, true),
abc.constants.getNamespaceId(new Namespace(outPropNsKind.getVal(), abc.constants.getStringId(outPropNs.getVal(), true)), 0, true), 0, 0, new ArrayList<Integer>()), true
);
break loopobjType;
}
}
}
}
}
}
}
if (objType == null) {
throw new RuntimeException("Unresolved object type");
}
return objType;
}
} else {
List<ABC> abcs = new ArrayList<>();
abcs.add(abc);
abcs.addAll(otherABCs);
loopa:
for (ABC a : abcs) {
for (InstanceInfo ii : a.instance_info) {
Multiname m = ii.getName(a.constants);
if (m.getNameWithNamespace(a.constants).equals(objType)) {
Reference<String> outName = new Reference<>("");
Reference<String> outNs = new Reference<>("");
Reference<String> outPropNs = new Reference<>("");
Reference<Integer> outPropNsKind = new Reference<>(1);
Reference<String> outPropType = new Reference<>("");
if (AVM2SourceGenerator.searchPrototypeChain(false, abcs, m.getNamespace(a.constants).getName(a.constants), m.getName(a.constants, new ArrayList<String>()), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropType)) {
objType = "".equals(outNs.getVal()) ? outName.getVal() : outNs.getVal() + "." + outName.getVal();
propType = outPropType.getVal();
propIndex = abc.constants.getMultinameId(new Multiname(Multiname.QNAME,
abc.constants.getStringId(propertyName, true),
abc.constants.getNamespaceId(new Namespace(outPropNsKind.getVal(), abc.constants.getStringId(outPropNs.getVal(), true)), 0, true), 0, 0, new ArrayList<Integer>()), true
);
public GraphTargetItem resolvePropertyType() {
if (index != null) {
return TypeItem.UNBOUNDED;
}
String objType = resolveObjectType();
for (ABC a : abcs) {
int ci = a.findClassByName(objType);
if (ci != -1) {
for (Trait t : a.instance_info.get(ci).instance_traits.traits) {
String tnames = t.getName(a).getName(a.constants, new ArrayList<String>());
if (tnames.equals(propertyName)) {
if (t instanceof TraitSlotConst) {
TraitSlotConst tsc = (TraitSlotConst) t;
if (tsc.type_index == 0) {
return TypeItem.UNBOUNDED;
}
return new TypeItem(a.constants.constant_multiname.get(tsc.type_index).getNameWithNamespace(a.constants));
break loopa;
}
if (t instanceof TraitMethodGetterSetter) {
TraitMethodGetterSetter tmgs = (TraitMethodGetterSetter) t;
if (tmgs.kindType == Trait.TRAIT_GETTER) {
return new TypeItem(a.constants.constant_multiname.get(a.method_info.get(tmgs.method_info).ret_type).getNameWithNamespace(a.constants));
}
if (tmgs.kindType == Trait.TRAIT_SETTER) {
return new TypeItem(a.constants.constant_multiname.get(a.method_info.get(tmgs.method_info).param_types[0]).getNameWithNamespace(a.constants));
}
}
if (t instanceof TraitFunction) {
return new TypeItem("Function");
}
return TypeItem.UNBOUNDED;
}
}
break;
}
}
return TypeItem.UNBOUNDED;
if (propIndex == 0) {
propIndex = abc.constants.getMultinameId(new Multiname(Multiname.MULTINAME,
abc.constants.getStringId(propertyName, true), 0,
allNsSet(), 0, new ArrayList<Integer>()), true);
propType = "*";
objType = "*";
}
propertyIndex.setVal(propIndex);
propertyType.setVal(propType);
objectType.setVal(objType);
}
public int resolveProperty() {
if (index != null) {
return abcs.get(0).constants.getMultinameId(new Multiname(Multiname.MULTINAMEL,
abcs.get(0).constants.getStringId(propertyName, true), 0,
allNsSet(), 0, new ArrayList<Integer>()), true);
}
String objType = resolveObjectType();
for (ABC a : abcs) {
int ci = a.findClassByName(objType);
if (ci != -1) {
for (Trait t : a.instance_info.get(ci).instance_traits.traits) {
Multiname tname = t.getName(a);
String tnames = t.getName(a).getName(a.constants, new ArrayList<String>());
if (tnames.equals(propertyName)) {
return abcs.get(0).constants.getMultinameId(new Multiname(tname.kind,
abcs.get(0).constants.getStringId(tnames, true),
abcs.get(0).constants.getNamespaceId(new Namespace(tname.getNamespace(a.constants).kind, abcs.get(0).constants.getStringId(tname.getNamespace(a.constants).getName(a.constants), true)), 0, true), 0, 0, new ArrayList<Integer>()), true);
}
}
for (Trait t : a.class_info.get(ci).static_traits.traits) {
Multiname tname = t.getName(a);
String tnames = t.getName(a).getName(a.constants, new ArrayList<String>());
if (tnames.equals(propertyName)) {
return abcs.get(0).constants.getMultinameId(new Multiname(tname.kind,
abcs.get(0).constants.getStringId(tnames, true),
abcs.get(0).constants.getNamespaceId(new Namespace(tname.getNamespace(a.constants).kind, abcs.get(0).constants.getStringId(tname.getNamespace(a.constants).getName(a.constants), true)), 0, true), 0, 0, new ArrayList<Integer>()), true);
}
}
break;
}
}
for (ABC a : abcs) {
for (ScriptInfo si : a.script_info) {
for (Trait t : si.traits.traits) {
Multiname tname = t.getName(a);
String tnames = t.getName(a).getName(a.constants, new ArrayList<String>());
if (tnames.equals(propertyName)) {
return abcs.get(0).constants.getMultinameId(new Multiname(tname.kind,
abcs.get(0).constants.getStringId(tnames, true),
abcs.get(0).constants.getNamespaceId(new Namespace(tname.getNamespace(a.constants).kind, abcs.get(0).constants.getStringId(tname.getNamespace(a.constants).getName(a.constants), true)), 0, true), 0, 0, new ArrayList<Integer>()), true);
}
}
}
}
return abcs.get(0).constants.getMultinameId(new Multiname(Multiname.MULTINAME,
abcs.get(0).constants.getStringId(propertyName, true), 0,
allNsSet(), 0, new ArrayList<Integer>()), true);
Reference<String> objType = new Reference<>("");
Reference<String> propType = new Reference<>("");
Reference<Integer> propIndex = new Reference<>(0);
resolve(objType, propType, propIndex);
return propIndex.getVal();
}
/*
private String resolveObjectType() {
String objType = object == null ? null : object.returnType().toString();
if (objType == null) {
loopo:
for (int i = 0; i < openedNamespaces.size(); i++) {
int nsindex = openedNamespaces.get(i);
int nsKind = abc.constants.constant_namespace.get(openedNamespaces.get(i)).kind;
String nsname = abc.constants.constant_namespace.get(openedNamespaces.get(i)).getName(abc.constants);
int name_index = 0;
for (int m = 1; m < abc.constants.constant_multiname.size(); m++) {
Multiname mname = abc.constants.constant_multiname.get(m);
if (mname.kind == Multiname.QNAME && mname.getName(abc.constants, new ArrayList<String>()).equals(propertyName) && mname.namespace_index == nsindex) {
name_index = m;
break;
}
}
if (name_index > 0) {
for (int s = 0; s < abc.script_info.size(); s++) {
for (Trait t : abc.script_info.get(s).traits.traits) {
if (t.name_index == name_index) {
return getTraitReturnType(abc, t).toString();
}
}
}
for (int c = 0; c < abc.instance_info.size(); c++) {
for (Trait t : abc.instance_info.get(c).instance_traits.traits) {
if (t.name_index == name_index) {
return getTraitReturnType(abc, t).toString();
}
}
for (Trait t : abc.class_info.get(c).static_traits.traits) {
if (t.name_index == name_index) {
return getTraitReturnType(abc, t).toString();
}
}
}
}
if (nsKind == Namespace.KIND_PACKAGE) {
List<ABC> abcs = new ArrayList<>();
abcs.add(abc);
abcs.addAll(otherABCs);
loopabc:
for (ABC a : otherABCs) {
for (int h = 0; h < a.instance_info.size(); h++) {
InstanceInfo ii = a.instance_info.get(h);
Multiname n = a.constants.constant_multiname.get(ii.name_index);
if (n.getNamespace(a.constants).kind == Namespace.KIND_PACKAGE && n.getNamespace(a.constants).getName(a.constants).equals(nsname)) {
Reference<String> outName = new Reference<>("");
Reference<String> outNs = new Reference<>("");
Reference<String> outPropNs = new Reference<>("");
Reference<Integer> outPropNsKind = new Reference<>(1);
if (AVM2SourceGenerator.searchPrototypeChain(abcs, nsname, n.getName(a.constants, new ArrayList<String>()), propertyName, outName, outNs, outPropNs, outPropNsKind)) {
return "".equals(outNs.getVal()) ? outName.getVal() : outNs.getVal() + "." + outName.getVal();
}
}
}
}
}
}
}
if (objType == null) {
throw new RuntimeException("Unresolved object type");
}
return objType;
}*/
/*
public GraphTargetItem resolvePropertyType() {
if (index != null) {
return TypeItem.UNBOUNDED;
}
String objType = resolveObjectType();
for (ABC a : abcs) {
int ci = a.findClassByName(objType);
if (ci != -1) {
for (Trait t : a.instance_info.get(ci).instance_traits.traits) {
String tnames = t.getName(a).getName(a.constants, new ArrayList<String>());
if (tnames.equals(propertyName)) {
if (t instanceof TraitSlotConst) {
TraitSlotConst tsc = (TraitSlotConst) t;
if (tsc.type_index == 0) {
return TypeItem.UNBOUNDED;
}
return new TypeItem(a.constants.constant_multiname.get(tsc.type_index).getNameWithNamespace(a.constants));
}
if (t instanceof TraitMethodGetterSetter) {
TraitMethodGetterSetter tmgs = (TraitMethodGetterSetter) t;
if (tmgs.kindType == Trait.TRAIT_GETTER) {
return new TypeItem(a.constants.constant_multiname.get(a.method_info.get(tmgs.method_info).ret_type).getNameWithNamespace(a.constants));
}
if (tmgs.kindType == Trait.TRAIT_SETTER) {
return new TypeItem(a.constants.constant_multiname.get(a.method_info.get(tmgs.method_info).param_types[0]).getNameWithNamespace(a.constants));
}
}
if (t instanceof TraitFunction) {
return new TypeItem("Function");
}
return TypeItem.UNBOUNDED;
}
}
break;
}
}
return TypeItem.UNBOUNDED;
}
*/
/* public int resolveProperty() {
if (index != null) {
return abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL,
abc.constants.getStringId(propertyName, true), 0,
allNsSet(), 0, new ArrayList<Integer>()), true);
}
String objType = resolveObjectType();
for (ABC a : abcs) {
int ci = a.findClassByName(objType);
if (ci != -1) {
for (Trait t : a.instance_info.get(ci).instance_traits.traits) {
Multiname tname = t.getName(a);
String tnames = t.getName(a).getName(a.constants, new ArrayList<String>());
if (tnames.equals(propertyName)) {
return abc.constants.getMultinameId(new Multiname(tname.kind,
abc.constants.getStringId(tnames, true),
abc.constants.getNamespaceId(new Namespace(tname.getNamespace(a.constants).kind, abc.constants.getStringId(tname.getNamespace(a.constants).getName(a.constants), true)), 0, true), 0, 0, new ArrayList<Integer>()), true);
}
}
for (Trait t : a.class_info.get(ci).static_traits.traits) {
Multiname tname = t.getName(a);
String tnames = t.getName(a).getName(a.constants, new ArrayList<String>());
if (tnames.equals(propertyName)) {
return abc.constants.getMultinameId(new Multiname(tname.kind,
abc.constants.getStringId(tnames, true),
abc.constants.getNamespaceId(new Namespace(tname.getNamespace(a.constants).kind, abc.constants.getStringId(tname.getNamespace(a.constants).getName(a.constants), true)), 0, true), 0, 0, new ArrayList<Integer>()), true);
}
}
break;
}
}
for (ABC a : abcs) {
for (ScriptInfo si : a.script_info) {
for (Trait t : si.traits.traits) {
Multiname tname = t.getName(a);
String tnames = t.getName(a).getName(a.constants, new ArrayList<String>());
if (tnames.equals(propertyName)) {
return abc.constants.getMultinameId(new Multiname(tname.kind,
abc.constants.getStringId(tnames, true),
abc.constants.getNamespaceId(new Namespace(tname.getNamespace(a.constants).kind, abc.constants.getStringId(tname.getNamespace(a.constants).getName(a.constants), true)), 0, true), 0, 0, new ArrayList<Integer>()), true);
}
}
}
}
return abc.constants.getMultinameId(new Multiname(Multiname.MULTINAME,
abc.constants.getStringId(propertyName, true), 0,
allNsSet(), 0, new ArrayList<Integer>()), true);
}*/
@Override
public GraphTargetItem returnType() {
if (index != null) {
return TypeItem.UNBOUNDED;
}
String objType = resolveObjectType();
Reference<String> objType = new Reference<>("");
Reference<String> propType = new Reference<>("");
Reference<Integer> propIndex = new Reference<>(0);
resolve(objType, propType, propIndex);
if (objType == null) {
return TypeItem.UNBOUNDED;
}
for (ABC a : abcs) {
int ci = a.findClassByName(objType);
if (ci != -1) {
for (Trait t : a.instance_info.get(ci).instance_traits.traits) {
String tname = t.getName(a).getName(a.constants, new ArrayList<String>());
if (tname.equals(propertyName)) {
if (t instanceof TraitSlotConst) {
TraitSlotConst tsc = (TraitSlotConst) t;
if (tsc.type_index == 0) {
return TypeItem.UNBOUNDED;
}
return new TypeItem(a.constants.constant_multiname.get(tsc.type_index).getNameWithNamespace(a.constants));
}
if (t instanceof TraitMethodGetterSetter) {
TraitMethodGetterSetter tmgs = (TraitMethodGetterSetter) t;
return new TypeFunctionItem(a.constants.constant_multiname.get(a.method_info.get(tmgs.method_info).ret_type).getNameWithNamespace(a.constants));
}
if (t instanceof TraitFunction) {
TraitFunction tf = (TraitFunction) t;
return new TypeFunctionItem(a.constants.constant_multiname.get(a.method_info.get(tf.method_info).ret_type).getNameWithNamespace(a.constants));
}
}
}
break;
}
}
return TypeItem.UNBOUNDED;
return new TypeItem(propType.getVal());
}
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator, boolean needsReturn) {
int propertyId = resolveProperty();
Reference<String> objType = new Reference<>("");
Reference<String> propType = new Reference<>("");
Reference<Integer> propIndex = new Reference<>(0);
resolve(objType, propType, propIndex);
int propertyId = propIndex.getVal();
Object obj = resolveObject(localData, generator);
Reference<Integer> ret_temp=new Reference<>(0);
Reference<Integer> ret_temp = new Reference<>(-1);
if (assignedValue != null) {
String targetType = resolvePropertyType().toString();
String targetType = propType.getVal();
String srcType = assignedValue.returnType().toString();
GraphTargetItem st = assignedValue;
if (!targetType.equals(srcType)) {
st = new CoerceAVM2Item(null, assignedValue, targetType);
}
return toSourceMerge(localData, generator, obj, index, st,
needsReturn?dupSetTemp(localData, generator, ret_temp):null,
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)));
needsReturn ? getTemp(localData, generator, ret_temp) : null,
killTemp(localData, generator, Arrays.asList(ret_temp)));
} else {
if (obj instanceof AVM2Instruction && (((AVM2Instruction) obj).definition instanceof FindPropertyStrictIns) && index == null) {
return toSourceMerge(localData, generator, ins(new GetLexIns(), propertyId),
needsReturn ? null : ins(new PopIns())
);
}
return toSourceMerge(localData, generator, obj, index,
ins(new GetPropertyIns(), propertyId),
needsReturn ? null : ins(new PopIns())
@@ -300,12 +421,11 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
return true;
}
private Object resolveObject(SourceGeneratorLocalData localData, SourceGenerator generator){
private Object resolveObject(SourceGeneratorLocalData localData, SourceGenerator generator) {
Object obj = object;
int propertyId = resolveProperty();
if(obj==null){
String cname;
if (obj == null) {
String cname;
String pkgName = "";
cname = localData.currentClass;
if (cname.contains(".")) {
@@ -316,46 +436,59 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
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);
Reference<String> outPropType = new Reference<>("");
List<ABC> abcs = new ArrayList<>();
abcs.add(abc);
abcs.addAll(otherABCs);
if (AVM2SourceGenerator.searchPrototypeChain(true, abcs, pkgName, cname, propertyName, outName, outNs, outPropNs, outPropNsKind, outPropType)) {
NameAVM2Item nobj = new NameAVM2Item(new TypeItem(localData.currentClass), 0, "this", null, false, openedNamespaces);
nobj.setRegNumber(0);
obj = nobj;
} else {
obj = ins(new FindPropertyStrictIns(), propertyId);
Reference<String> objType = new Reference<>("");
Reference<String> propType = new Reference<>("");
Reference<Integer> propIndex = new Reference<>(0);
resolve(objType, propType, propIndex);
obj = ins(new FindPropertyStrictIns(), propIndex.getVal());
}
}
return obj;
}
@Override
public List<GraphSourceItem> toSourceChange(SourceGeneratorLocalData localData, SourceGenerator generator, boolean post,boolean decrement, boolean needsReturn) {
int propertyId = resolveProperty();
public List<GraphSourceItem> toSourceChange(SourceGeneratorLocalData localData, SourceGenerator generator, boolean post, boolean decrement, boolean needsReturn) {
Reference<String> objType = new Reference<>("");
Reference<String> propType = new Reference<>("");
Reference<Integer> propIndex = new Reference<>(0);
resolve(objType, propType, propIndex);
int propertyId = propIndex.getVal();
Object obj = resolveObject(localData, generator);
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,
boolean isInteger = propType.getVal().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
//getTemp(localData, generator, obj_temp),
//index!=null?getTemp(localData, generator, index_temp):null,
ins(new GetPropertyIns(), propertyId),
!isInteger?ins(new ConvertDIns()):null,
!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,
(!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,
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)));
killTemp(localData, generator, Arrays.asList(ret_temp, obj_temp, index_temp)));
return ret;
}

View File

@@ -25,8 +25,8 @@ import java.util.List;
*/
public class SetterAVM2Item extends MethodAVM2Item {
public SetterAVM2Item(boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespaceKind, String methodName, List<GraphTargetItem> paramTypes, List<String> paramNames, List<GraphTargetItem> paramValues, List<GraphTargetItem> body, List<NameAVM2Item> subvariables, GraphTargetItem retType) {
super(hasRest, line, override, isFinal, isStatic, namespaceKind, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType);
public SetterAVM2Item(boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespace, String methodName, List<GraphTargetItem> paramTypes, List<String> paramNames, List<GraphTargetItem> paramValues, List<GraphTargetItem> body, List<NameAVM2Item> subvariables, GraphTargetItem retType) {
super(hasRest, line, override, isFinal, isStatic, namespace, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType);
}
}

View File

@@ -27,22 +27,22 @@ import com.jpexs.decompiler.graph.model.LocalData;
*/
public class SlotAVM2Item extends AVM2Item {
private final int nsKind;
private final int namespace;
private boolean isStatic;
public String var;
public GraphTargetItem type;
public int getNsKind() {
return nsKind;
public int getNamespace() {
return namespace;
}
public boolean isStatic() {
return isStatic;
}
public SlotAVM2Item(boolean isStatic, int nsKind, String var, GraphTargetItem type, GraphTargetItem value) {
public SlotAVM2Item(boolean isStatic, int namespace, String var, GraphTargetItem type, GraphTargetItem value) {
super(null, NOPRECEDENCE);
this.nsKind = nsKind;
this.namespace = namespace;
this.value = value;
this.isStatic = isStatic;
this.var = var;

View File

@@ -9,4 +9,4 @@ TODO List for AS3 parser/compiler:
- with
- delete property
- default xml namespace
- better private namespaces handling
- custom namespace modifiers

View File

@@ -42,6 +42,16 @@ public class Multiname {
public int qname_index = -1; //for TypeName
public List<Integer> params; //for TypeName
public boolean validType() {
boolean cnt = false;
for (int i = 0; i < multinameKinds.length; i++) {
if (multinameKinds[i] == kind) {
cnt = true;
}
}
return cnt;
}
public Multiname(int kind, int name_index, int namespace_index, int namespace_set_index, int qname_index, List<Integer> params) {
this.kind = kind;
this.name_index = name_index;
@@ -49,6 +59,9 @@ public class Multiname {
this.namespace_set_index = namespace_set_index;
this.qname_index = qname_index;
this.params = params;
if (!validType()) {
throw new RuntimeException("Invalid multiname kind:" + kind);
}
}
public boolean isAttribute() {

View File

@@ -97,7 +97,7 @@ public class Namespace {
public String getName(ConstantPool constants) {
if (name_index == 0) {
return "-";
return null;
}
return constants.getString(name_index);
}