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 0a965c3fd..f8cff906c 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 @@ -1153,7 +1153,7 @@ public class AVM2SourceGenerator implements SourceGenerator { return abc; } - public void generateClass(List openedNamespaces, int namespace, int initScope, PackageAVM2Item pkg, ClassInfo classInfo, InstanceInfo instanceInfo, SourceGeneratorLocalData localData, boolean isInterface, String name, String superName, GraphTargetItem extendsVal, List implementsStr, GraphTargetItem constructor, List traitItems) throws ParseException, CompilationException { + public void generateClass(List sinitVariables,boolean staticNeedsActivation, List staticInit,List openedNamespaces, int namespace, int initScope, PackageAVM2Item pkg, ClassInfo classInfo, InstanceInfo instanceInfo, SourceGeneratorLocalData localData, boolean isInterface, String name, String superName, GraphTargetItem extendsVal, List implementsStr, GraphTargetItem constructor, List traitItems) throws ParseException, CompilationException { localData.currentClass = pkg.packageName.isEmpty() ? name : pkg.packageName + "." + name; List ret = new ArrayList<>(); if (extendsVal == null && !isInterface) { @@ -1174,32 +1174,31 @@ public class AVM2SourceGenerator implements SourceGenerator { instanceInfo.iinit_index = method(new ArrayList(), pkg.packageName, m.needsActivation, m.subvariables, initScope + 1, m.hasRest, m.line, name, extendsVal != null ? extendsVal.toString() : null, true, localData, m.paramTypes, m.paramNames, m.paramValues, m.body, TypeItem.UNBOUNDED/*?? FIXME*/); } + + //Class initializer - MethodInfo mi = new MethodInfo(new int[0], 0, 0, 0, new ValueKind[0], new int[0]); - MethodBody mb = new MethodBody(); - mb.method_info = abc.addMethodInfo(mi); - mb.code = new AVM2Code(); - mb.code.code = new ArrayList<>(); - mb.code.code.add(ins(new GetLocal0Ins())); - mb.code.code.add(ins(new PushScopeIns())); + int staticMi = method(new ArrayList(), pkg.packageName, staticNeedsActivation, sinitVariables, initScope, false,0, name, superName, false, localData, new ArrayList(),new ArrayList(),new ArrayList(), staticInit, TypeItem.UNBOUNDED); + MethodBody mb=abc.findBody(staticMi); + + /*List initcode = new ArrayList<>(); for (GraphTargetItem ti : traitItems) { if (ti instanceof SlotAVM2Item) { SlotAVM2Item si = (SlotAVM2Item) ti; if (si.isStatic()) { - mb.code.code.add(ins(new FindPropertyStrictIns(), traitName(namespace, si.var))); + initcode.add(ins(new FindPropertyStrictIns(), traitName(namespace, si.var))); List tis = new ArrayList<>(); tis.add(si.value); - mb.code.code.addAll(toInsList(generate(localData, tis))); - mb.code.code.add(ins(new InitPropertyIns(), traitName(namespace, si.var))); + initcode.addAll(toInsList(generate(localData, tis))); + initcode.add(ins(new InitPropertyIns(), traitName(namespace, si.var))); } } } - mb.code.code.add(ins(new ReturnVoidIns())); - mb.autoFillStats(abc, initScope); + if(mb.code.code.get(mb.code.code.size()-1).definition instanceof ReturnVoidIns){ + mb.code.code.addAll(mb.code.code.size()-1,initcode); + } + mb.autoFillStats(abc, initScope);*/ - abc.addMethodBody(mb); - - classInfo.cinit_index = mb.method_info; + classInfo.cinit_index = staticMi; instanceInfo.interfaces = new int[implementsStr.size()]; for (int i = 0; i < implementsStr.size(); i++) { @@ -1231,7 +1230,7 @@ public class AVM2SourceGenerator implements SourceGenerator { */ if (cls instanceof ClassAVM2Item) { ClassAVM2Item cai = (ClassAVM2Item) cls; - generateClass(cai.openedNamespaces, namespace, initScope, pkg, ci, ii, localData, false, cai.className, cai.extendsOp.toString(), cai.extendsOp, cai.implementsOp, cai.constructor, cai.traits); + generateClass(cai.sinitVariables,cai.staticInitActivation,cai.staticInit,cai.openedNamespaces, 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; } @@ -1243,7 +1242,7 @@ public class AVM2SourceGenerator implements SourceGenerator { } if (cls instanceof InterfaceAVM2Item) { InterfaceAVM2Item iai = (InterfaceAVM2Item) cls; - generateClass(iai.openedNamespaces, namespace, initScope, pkg, ci, ii, localData, true, iai.name, null, null, iai.superInterfaces, null, iai.methods); + generateClass(new ArrayList(),false,new ArrayList(),iai.openedNamespaces, namespace, initScope, pkg, ci, ii, localData, true, iai.name, null, null, iai.superInterfaces, null, iai.methods); ii.flags |= InstanceInfo.CLASS_INTERFACE; } 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 e1cd7edd7..81cb98d98 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 @@ -456,7 +456,7 @@ public class ActionScriptParser { return new FunctionAVM2Item(needsActivation2.getVal(), namespace, hasRest, line, functionName, paramTypes, paramNames, paramValues, body, subvariables, retType); } - private GraphTargetItem traits(List importedClasses, int privateNs, int protectedNs, int publicNs, int packageInternalNs, int protectedStaticNs, List openedNamespaces, String packageName, String classNameStr, boolean isInterface, List traits) throws ParseException, IOException, CompilationException { + private GraphTargetItem traits(List sinitVariables,Reference sinitNeedsActivation,List staticInitializer, List importedClasses, int privateNs, int protectedNs, int publicNs, int packageInternalNs, int protectedStaticNs, List openedNamespaces, String packageName, String classNameStr, boolean isInterface, List traits) throws ParseException, IOException, CompilationException { ParsedSymbol s; GraphTargetItem constr = null; List variables = new ArrayList<>(); @@ -472,7 +472,14 @@ public class ActionScriptParser { boolean isFinal = false; boolean isDynamic = false; String customAccess = null; - //TODO: namespace name + + + if(s.type == SymbolType.CURLY_OPEN){ + staticInitializer.addAll(commands(sinitNeedsActivation, importedClasses, openedNamespaces, new Stack(), new HashMap(), new HashMap(), true, false, 0, sinitVariables)); + expectedType(SymbolType.CURLY_CLOSE); + s = lex(); + } + //TODO: final, dynamic while (s.isType(SymbolType.STATIC, SymbolType.PUBLIC, SymbolType.PRIVATE, SymbolType.PROTECTED, SymbolType.OVERRIDE, SymbolType.FINAL, SymbolType.DYNAMIC, SymbolType.IDENTIFIER)) { if (s.type == SymbolType.FINAL) { @@ -767,12 +774,15 @@ public class ActionScriptParser { openedNamespaces.add(abc.constants.getNamespaceId(new Namespace(Namespace.KIND_STATIC_PROTECTED, abc.constants.getStringId(namespaces.get(i) + ":" + names.get(i), true)), 0, true)); } - GraphTargetItem constr = traits(importedClasses, privateNs, protectedNs, publicNs, packageInternalNs, protectedStaticNs, openedNamespaces, packageName, classNameStr, isInterface, traits); + Reference staticNeedsActivation = new Reference<>(false); + List staticInit = new ArrayList<>(); + List sinitVariables = new ArrayList<>(); + GraphTargetItem constr = traits(sinitVariables,staticNeedsActivation,staticInit,importedClasses, privateNs, protectedNs, publicNs, packageInternalNs, protectedStaticNs, openedNamespaces, packageName, classNameStr, isInterface, traits); if (isInterface) { return new InterfaceAVM2Item(openedNamespaces, isFinal, namespace, classNameStr, implementsStr, traits); } else { - return new ClassAVM2Item(openedNamespaces, protectedNs, isDynamic, isFinal, namespace, classNameStr, extendsStr, implementsStr, constr, traits); + return new ClassAVM2Item(openedNamespaces, protectedNs, isDynamic, isFinal, namespace, classNameStr, extendsStr, implementsStr, staticInit,staticNeedsActivation.getVal(),sinitVariables,constr, traits); } } @@ -2093,7 +2103,7 @@ public class ActionScriptParser { } lexer.pushback(s); - traits(importedClasses, privateNs, 0, publicNs, packageInternalNs, 0, openedNamespaces, name, null, false, items); + traits(new ArrayList(),new Reference(false),new ArrayList(),importedClasses, privateNs, 0, publicNs, packageInternalNs, 0, openedNamespaces, name, null, false, items); expectedType(SymbolType.CURLY_CLOSE); return new PackageAVM2Item(name, items); } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ClassAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ClassAVM2Item.java index c32797a76..221406469 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ClassAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ClassAVM2Item.java @@ -38,6 +38,9 @@ public class ClassAVM2Item extends AVM2Item implements Block { public boolean isDynamic; public boolean isFinal; public List openedNamespaces; + public List staticInit; + public boolean staticInitActivation; + public List sinitVariables; @Override public List> getSubs() { @@ -48,7 +51,7 @@ public class ClassAVM2Item extends AVM2Item implements Block { return ret; } - public ClassAVM2Item(List openedNamespaces, int protectedNs, boolean isDynamic, boolean isFinal, int namespace, String className, GraphTargetItem extendsOp, List implementsOp, GraphTargetItem constructor, List traits) { + public ClassAVM2Item(List openedNamespaces, int protectedNs, boolean isDynamic, boolean isFinal, int namespace, String className, GraphTargetItem extendsOp, List implementsOp, List staticInit,boolean staticInitActivation, List sinitVariables, GraphTargetItem constructor, List traits) { super(null, NOPRECEDENCE); this.protectedNs = protectedNs; this.className = className; @@ -60,6 +63,9 @@ public class ClassAVM2Item extends AVM2Item implements Block { this.isDynamic = isDynamic; this.isFinal = isFinal; this.openedNamespaces = openedNamespaces; + this.staticInit = staticInit; + this.staticInitActivation = staticInitActivation; + this.sinitVariables = sinitVariables; } @Override