diff --git a/trunk/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java b/trunk/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java index 3498bcfe4..0ec66db7d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java +++ b/trunk/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash; import com.jpexs.decompiler.flash.abc.types.ABCException; import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.ScriptInfo; import com.jpexs.decompiler.graph.GraphTargetItem; import java.io.Serializable; import java.util.ArrayList; @@ -47,6 +48,8 @@ public class SourceGeneratorLocalData implements Serializable { public Map> traitUsages = new HashMap<>(); public String pkg = ""; public List scopeStack = new ArrayList(); + public boolean documentClass; + public ScriptInfo currentScript; public SourceGeneratorLocalData(HashMap registerVars, Integer inFunction, Boolean inMethod, Integer forInLevel) { this.registerVars = registerVars; diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/CoerceAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/CoerceAVM2Item.java index 089e898f4..85bda973c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/CoerceAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/CoerceAVM2Item.java @@ -116,7 +116,7 @@ public class CoerceAVM2Item extends AVM2Item { ins = new AVM2Instruction(0, new CoerceSIns(), new int[]{}, new byte[0]); break; default: - int type_index = new TypeItem(type).resolveClass(((AVM2SourceGenerator) generator).abc); + int type_index = AVM2SourceGenerator.resolveType(new TypeItem(type),(((AVM2SourceGenerator) generator).abc)); ins = new AVM2Instruction(0, new CoerceIns(), new int[]{type_index}, new byte[0]); break; } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java index e99627d68..85e487792 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java @@ -36,8 +36,10 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.LookupSwitchIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocal0Ins; import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.KillIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetGlobalScopeIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetLexIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetScopeObjectIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetSlotIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.HasNext2Ins; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.InitPropertyIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.LabelIns; @@ -1077,6 +1079,7 @@ public class AVM2SourceGenerator implements SourceGenerator { Trait[] it = generateTraitsPhase1(pkg, name, superName, false, localData, traitItems, instanceInfo.instance_traits); Trait[] st = generateTraitsPhase1(pkg, name, superName, true, localData, traitItems, classInfo.static_traits); generateTraitsPhase2(pkg.packageName,traitItems, it, openedNamespaces, localData); + generateTraitsPhase2(pkg.packageName,traitItems, st, openedNamespaces, localData); generateTraitsPhase3(initScope, pkg, name, superName, false, localData, traitItems, instanceInfo.instance_traits, it); generateTraitsPhase3(initScope, pkg, name, superName, true, localData, traitItems, classInfo.static_traits, st); if (constructor == null) { @@ -1259,6 +1262,8 @@ public class AVM2SourceGenerator implements SourceGenerator { newlocalData.pkg = localData.pkg; newlocalData.callStack.addAll(localData.callStack); newlocalData.traitUsages = localData.traitUsages; + newlocalData.currentScript = localData.currentScript; + newlocalData.documentClass = localData.documentClass; localData = newlocalData; localData.activationReg = 0; @@ -1714,7 +1719,7 @@ public class AVM2SourceGenerator implements SourceGenerator { if (mai.isStatic() != generateStatic) { continue; } - ((TraitMethodGetterSetter) traits[k]).method_info = method(new ArrayList(), pkg.packageName, mai.needsActivation, mai.subvariables, initScope + 1/*class scope*/, mai.hasRest, mai.line, className, superName, false, localData, mai.paramTypes, mai.paramNames, mai.paramValues, mai.body, mai.retType); + ((TraitMethodGetterSetter) traits[k]).method_info = method(new ArrayList(), pkg.packageName, mai.needsActivation, mai.subvariables, initScope + (mai.isStatic()?0:1), mai.hasRest, mai.line, className, superName, false, localData, mai.paramTypes, mai.paramNames, mai.paramValues, mai.body, mai.retType); } else if (item instanceof FunctionAVM2Item) { FunctionAVM2Item fai = (FunctionAVM2Item) item; ((TraitFunction) traits[k]).method_info = method(new ArrayList(), pkg.packageName, fai.needsActivation, fai.subvariables, initScope, fai.hasRest, fai.line, className, superName, false, localData, fai.paramTypes, fai.paramNames, fai.paramValues, fai.body, fai.retType); @@ -1823,7 +1828,7 @@ public class AVM2SourceGenerator implements SourceGenerator { tmgs.kindType = (item instanceof MethodAVM2Item) ? Trait.TRAIT_METHOD : ((item instanceof GetterAVM2Item) ? Trait.TRAIT_GETTER : Trait.TRAIT_SETTER); //tmgs.name_index = traitName(((MethodAVM2Item) item).namespace, ((MethodAVM2Item) item).functionName); tmgs.disp_id = 0; //0 = disable override optimization; TODO: handle this - if (mai.isFinal()) { + if (mai.isFinal()||mai.isStatic()) { tmgs.kindFlags |= Trait.ATTR_Final; } if (mai.isOverride()) { @@ -1845,8 +1850,9 @@ public class AVM2SourceGenerator implements SourceGenerator { return traits; } - public ScriptInfo generateScriptInfo(PackageAVM2Item pkg, SourceGeneratorLocalData localData, List commands, boolean documentClass) throws ParseException, CompilationException { + public ScriptInfo generateScriptInfo(PackageAVM2Item pkg, SourceGeneratorLocalData localData, List commands) throws ParseException, CompilationException { ScriptInfo si = new ScriptInfo(); + localData.currentScript = si; Trait[] traitArr = generateTraitsPhase1(pkg, null, null, false, localData, commands, si.traits); generateTraitsPhase2(pkg.packageName,commands, traitArr, new ArrayList(), localData); MethodInfo mi = new MethodInfo(new int[0], 0, 0, 0, new ValueKind[0], new int[0]); @@ -1855,6 +1861,7 @@ public class AVM2SourceGenerator implements SourceGenerator { mb.code = new AVM2Code(); mb.code.code.add(ins(new GetLocal0Ins())); mb.code.code.add(ins(new PushScopeIns())); + int traitScope = 1; @@ -1863,7 +1870,7 @@ public class AVM2SourceGenerator implements SourceGenerator { TraitClass tc = (TraitClass) t; List parents = new ArrayList<>(); parentNamesAddNames(abc, allABCs, abc.instance_info.get(tc.class_info).name_index, parents, new ArrayList(), new ArrayList()); - if (documentClass) { + if (localData.documentClass) { mb.code.code.add(ins(new GetScopeObjectIns(), 0)); traitScope++; } else { @@ -1885,7 +1892,7 @@ public class AVM2SourceGenerator implements SourceGenerator { } mb.code.code.add(ins(new ReturnVoidIns())); - mb.autoFillStats(abc, documentClass ? 1 : 0); + mb.autoFillStats(abc, localData.documentClass ? 1 : 0); abc.addMethodBody(mb); si.init_index = mb.method_info; localData.pkg = pkg.packageName; @@ -2067,4 +2074,66 @@ public class AVM2SourceGenerator implements SourceGenerator { } return 0; } + + @Override + public List generate(SourceGeneratorLocalData localData, TypeItem item) throws CompilationException { + String currentFullClassName = localData.currentClass==null?null:(localData.pkg.equals("")?localData.currentClass:localData.pkg+"."+localData.currentClass); + + if(localData.documentClass && item.toString().equals(currentFullClassName)){ + int slotId = 0; + int c = abc.findClassByName(currentFullClassName); + for(Trait t:localData.currentScript.traits.traits){ + if(t instanceof TraitClass){ + TraitClass tc=(TraitClass)t; + if(tc.class_info == c){ + slotId = tc.slot_id; + break; + } + } + } + return GraphTargetItem.toSourceMerge(localData, this, ins(new GetGlobalScopeIns()),ins(new GetSlotIns(),slotId)); + }else{ + return GraphTargetItem.toSourceMerge(localData, this, ins(new GetLexIns(),resolveType(item, abc))); + } + } + + + public static int resolveType(TypeItem type,ABC abc) { + String name = type.fullTypeName; + String pkg = ""; + int name_index = 0; + if (name.contains(".")) { + pkg = name.substring(0, name.lastIndexOf('.')); + name = name.substring(name.lastIndexOf('.') + 1); + } + for (InstanceInfo ii : abc.instance_info) { + Multiname mname = abc.constants.constant_multiname.get(ii.name_index); + if (mname.getName(abc.constants, new ArrayList()).equals(name)) { + if (mname.getNamespace(abc.constants).hasName(pkg, abc.constants)) { + name_index = ii.name_index; + break; + } + } + } + for (int i = 1; i < abc.constants.constant_multiname.size(); i++) { + Multiname mname = abc.constants.constant_multiname.get(i); + if (name.equals(mname.getName(abc.constants, new ArrayList()))) { + if (pkg.equals(mname.getNamespace(abc.constants).getName(abc.constants))) { + name_index = i; + break; + } + } + } + if(name_index == 0){ + name_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(name, true), abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(pkg, true)), 0, true), 0, 0, new ArrayList()), true); + } + if(type.subtypes.isEmpty()){ + return name_index; + } + List params=new ArrayList<>(); + for(String s:type.subtypes){ + params.add(resolveType(new TypeItem(s),abc)); + } + return abc.constants.getMultinameId(new Multiname(Multiname.TYPENAME,0,0,0,name_index,params),true); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java index 01d76a541..ebccda9d1 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java @@ -683,7 +683,7 @@ public class ActionScriptParser { List indices = new ArrayList<>(); List names = new ArrayList<>(); List namespaces = new ArrayList<>(); - AVM2SourceGenerator.parentNamesAddNames(abc, otherABCs, ((TypeItem) ((UnresolvedAVM2Item) extendsStr).resolve(new ArrayList(), new ArrayList(), abc, otherABCs, new ArrayList(), new ArrayList())).resolveClass(abc), indices, names, namespaces); + AVM2SourceGenerator.parentNamesAddNames(abc, otherABCs, AVM2SourceGenerator.resolveType(((TypeItem) ((UnresolvedAVM2Item) extendsStr).resolve(new ArrayList(), new ArrayList(), abc, otherABCs, new ArrayList(), new ArrayList())),abc), indices, names, namespaces); for (int i = 0; i < names.size(); i++) { if (namespaces.get(i).isEmpty()) { continue; @@ -1806,7 +1806,8 @@ public class ActionScriptParser { className = ((ClassAVM2Item) it).className; } } - abc.script_info.add(gen.generateScriptInfo(pkg, localData, pkg.items, documentClass)); + localData.documentClass = documentClass; + abc.script_info.add(gen.generateScriptInfo(pkg, localData, pkg.items)); } public void addScript(String s, boolean documentClass, String fileName) throws ParseException, IOException, CompilationException { diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstructSomethingAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstructSomethingAVM2Item.java index 46e346b0c..4cbd0790e 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstructSomethingAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstructSomethingAVM2Item.java @@ -70,7 +70,6 @@ public class ConstructSomethingAVM2Item extends CallAVM2Item { if (resname instanceof UnresolvedAVM2Item) { resname = ((UnresolvedAVM2Item) resname).resolved; } - if (resname instanceof TypeItem) { TypeItem prop = (TypeItem) resname; if(!prop.subtypes.isEmpty()){ //It's Vector - TypeName diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NameAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NameAVM2Item.java index ab5b929cb..805660f3b 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NameAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NameAVM2Item.java @@ -221,12 +221,12 @@ public class NameAVM2Item extends AssignableAVM2Item { ins = ins(new CoerceSIns()); break; default: - int type_index = type.resolveClass(((AVM2SourceGenerator) generator).abc); + int type_index = AVM2SourceGenerator.resolveType(type,((AVM2SourceGenerator) generator).abc); ins = ins(new CoerceIns(), type_index); break; } } else { - int type_index = type.resolveClass(((AVM2SourceGenerator) generator).abc); + int type_index = AVM2SourceGenerator.resolveType(type,((AVM2SourceGenerator) generator).abc); ins = ins(new CoerceIns(), type_index); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java index 5d148499a..bd83d2694 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java @@ -216,7 +216,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { ins = ins(new CoerceSIns()); break; default: - int type_index = new TypeItem(type).resolveClass(((AVM2SourceGenerator) generator).abc); + int type_index = AVM2SourceGenerator.resolveType(new TypeItem(type),((AVM2SourceGenerator) generator).abc); ins = ins(new CoerceIns(), type_index); break; } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/todo.txt b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/todo.txt index 1f0772e1b..ee46601e9 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/todo.txt +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/todo.txt @@ -1,4 +1,5 @@ TODO List for AS3 parser/compiler: ------------------------------ - E4X (XML) -- default xml namespace \ No newline at end of file +- default xml namespace +- calculation of dispid(method override, static methods) \ No newline at end of file diff --git a/trunk/src/com/jpexs/decompiler/flash/action/parser/script/ActionSourceGenerator.java b/trunk/src/com/jpexs/decompiler/flash/action/parser/script/ActionSourceGenerator.java index 9aeefb3dc..7f9131cce 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/parser/script/ActionSourceGenerator.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/parser/script/ActionSourceGenerator.java @@ -49,6 +49,7 @@ import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.SourceGenerator; +import com.jpexs.decompiler.graph.TypeItem; import com.jpexs.decompiler.graph.model.AndItem; import com.jpexs.decompiler.graph.model.BreakItem; import com.jpexs.decompiler.graph.model.CommaExpressionItem; @@ -763,4 +764,12 @@ public class ActionSourceGenerator implements SourceGenerator { ret.addAll(lastExpr.toSource(localData, this)); return ret; } + + @Override + public List generate(SourceGeneratorLocalData localData, TypeItem item) throws CompilationException { + //Unsupported in AS1/2 + return new ArrayList<>(); + } + + } diff --git a/trunk/src/com/jpexs/decompiler/graph/SourceGenerator.java b/trunk/src/com/jpexs/decompiler/graph/SourceGenerator.java index 7871550bc..b24844a76 100644 --- a/trunk/src/com/jpexs/decompiler/graph/SourceGenerator.java +++ b/trunk/src/com/jpexs/decompiler/graph/SourceGenerator.java @@ -65,4 +65,6 @@ public interface SourceGenerator { public List generate(SourceGeneratorLocalData localData, List commands) throws CompilationException; public List generate(SourceGeneratorLocalData localData, CommaExpressionItem item) throws CompilationException; + + public List generate(SourceGeneratorLocalData localData, TypeItem item) throws CompilationException; } diff --git a/trunk/src/com/jpexs/decompiler/graph/TypeItem.java b/trunk/src/com/jpexs/decompiler/graph/TypeItem.java index 1120a9884..db9245195 100644 --- a/trunk/src/com/jpexs/decompiler/graph/TypeItem.java +++ b/trunk/src/com/jpexs/decompiler/graph/TypeItem.java @@ -16,6 +16,7 @@ */ package com.jpexs.decompiler.graph; +import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.types.InstanceInfo; import com.jpexs.decompiler.flash.abc.types.Multiname; @@ -102,43 +103,10 @@ public class TypeItem extends GraphTargetItem { } - public int resolveClass(ABC abc) { - String name = fullTypeName; - String pkg = ""; - int name_index = 0; - if (name.contains(".")) { - pkg = name.substring(0, name.lastIndexOf('.')); - name = name.substring(name.lastIndexOf('.') + 1); - } - for (InstanceInfo ii : abc.instance_info) { - Multiname mname = abc.constants.constant_multiname.get(ii.name_index); - if (mname.getName(abc.constants, new ArrayList()).equals(name)) { - if (mname.getNamespace(abc.constants).hasName(pkg, abc.constants)) { - name_index = ii.name_index; - break; - } - } - } - for (int i = 1; i < abc.constants.constant_multiname.size(); i++) { - Multiname mname = abc.constants.constant_multiname.get(i); - if (name.equals(mname.getName(abc.constants, new ArrayList()))) { - if (pkg.equals(mname.getNamespace(abc.constants).getName(abc.constants))) { - name_index = i; - break; - } - } - } - if(name_index == 0){ - name_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(name, true), abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(pkg, true)), 0, true), 0, 0, new ArrayList()), true); - } - if(subtypes.isEmpty()){ - return name_index; - } - List params=new ArrayList<>(); - for(String s:subtypes){ - params.add(new TypeItem(s).resolveClass(abc)); - } - return abc.constants.getMultinameId(new Multiname(Multiname.TYPENAME,0,0,0,name_index,params),true); - } + + @Override + public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + return generator.generate(localData, this); + } }