mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-02 07:24:19 +00:00
AS3 parser - better private namespace handling, body stats calculation fixes
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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--;
|
||||
|
||||
@@ -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--;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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<>();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -9,4 +9,4 @@ TODO List for AS3 parser/compiler:
|
||||
- with
|
||||
- delete property
|
||||
- default xml namespace
|
||||
- better private namespaces handling
|
||||
- custom namespace modifiers
|
||||
@@ -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() {
|
||||
|
||||
@@ -97,7 +97,7 @@ public class Namespace {
|
||||
|
||||
public String getName(ConstantPool constants) {
|
||||
if (name_index == 0) {
|
||||
return "-";
|
||||
return null;
|
||||
}
|
||||
return constants.getString(name_index);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user