mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-25 04:11:13 +00:00
AS3 parser: static method scope fix, final attr. fix, Classes resolving
This commit is contained in:
@@ -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<MethodBody, List<Integer>> traitUsages = new HashMap<>();
|
||||
public String pkg = "";
|
||||
public List<GraphTargetItem> scopeStack = new ArrayList<GraphTargetItem>();
|
||||
public boolean documentClass;
|
||||
public ScriptInfo currentScript;
|
||||
|
||||
public SourceGeneratorLocalData(HashMap<String, Integer> registerVars, Integer inFunction, Boolean inMethod, Integer forInLevel) {
|
||||
this.registerVars = registerVars;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+74
-5
@@ -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<MethodBody>(), 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<MethodBody>(), 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<MethodBody>(), 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<GraphTargetItem> commands, boolean documentClass) throws ParseException, CompilationException {
|
||||
public ScriptInfo generateScriptInfo(PackageAVM2Item pkg, SourceGeneratorLocalData localData, List<GraphTargetItem> 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<Integer>(), 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<Integer> parents = new ArrayList<>();
|
||||
parentNamesAddNames(abc, allABCs, abc.instance_info.get(tc.class_info).name_index, parents, new ArrayList<String>(), new ArrayList<String>());
|
||||
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<GraphSourceItem> 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<String>()).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<String>()))) {
|
||||
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<Integer>()), true);
|
||||
}
|
||||
if(type.subtypes.isEmpty()){
|
||||
return name_index;
|
||||
}
|
||||
List<Integer> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -683,7 +683,7 @@ public class ActionScriptParser {
|
||||
List<Integer> indices = new ArrayList<>();
|
||||
List<String> names = new ArrayList<>();
|
||||
List<String> namespaces = new ArrayList<>();
|
||||
AVM2SourceGenerator.parentNamesAddNames(abc, otherABCs, ((TypeItem) ((UnresolvedAVM2Item) extendsStr).resolve(new ArrayList<GraphTargetItem>(), new ArrayList<String>(), abc, otherABCs, new ArrayList<MethodBody>(), new ArrayList<AssignableAVM2Item>())).resolveClass(abc), indices, names, namespaces);
|
||||
AVM2SourceGenerator.parentNamesAddNames(abc, otherABCs, AVM2SourceGenerator.resolveType(((TypeItem) ((UnresolvedAVM2Item) extendsStr).resolve(new ArrayList<GraphTargetItem>(), new ArrayList<String>(), abc, otherABCs, new ArrayList<MethodBody>(), new ArrayList<AssignableAVM2Item>())),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 {
|
||||
|
||||
-1
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
TODO List for AS3 parser/compiler:
|
||||
------------------------------
|
||||
- E4X (XML)
|
||||
- default xml namespace
|
||||
- default xml namespace
|
||||
- calculation of dispid(method override, static methods)
|
||||
@@ -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<GraphSourceItem> generate(SourceGeneratorLocalData localData, TypeItem item) throws CompilationException {
|
||||
//Unsupported in AS1/2
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -65,4 +65,6 @@ public interface SourceGenerator {
|
||||
public List<GraphSourceItem> generate(SourceGeneratorLocalData localData, List<GraphTargetItem> commands) throws CompilationException;
|
||||
|
||||
public List<GraphSourceItem> generate(SourceGeneratorLocalData localData, CommaExpressionItem item) throws CompilationException;
|
||||
|
||||
public List<GraphSourceItem> generate(SourceGeneratorLocalData localData, TypeItem item) throws CompilationException;
|
||||
}
|
||||
|
||||
@@ -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<String>()).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<String>()))) {
|
||||
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<Integer>()), true);
|
||||
}
|
||||
if(subtypes.isEmpty()){
|
||||
return name_index;
|
||||
}
|
||||
List<Integer> 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<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
|
||||
return generator.generate(localData, this);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user