diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java index 34d4d53ba..24d0b7fe3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -866,17 +866,13 @@ public final class SWF implements TreeItem, Timelined { } public List> getAS3Packs() { - List abcTags = new ArrayList<>(); + List> packs = new ArrayList<>(); for (Tag t : tags) { if (t instanceof ABCContainerTag) { - abcTags.add((ABCContainerTag) t); + ABCContainerTag abcTag = (ABCContainerTag) t; + packs.addAll(abcTag.getABC().getScriptPacks()); } } - List> packs = new ArrayList<>(); - for (int i = 0; i < abcTags.size(); i++) { - ABCContainerTag t = abcTags.get(i); - packs.addAll(t.getABC().getScriptPacks()); - } return uniqueAS3Packs(packs); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java index e77b59641..ecf02cd7f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java @@ -171,7 +171,7 @@ public class ABC { public Set getStringUsages() { Set ret = new HashSet<>(); for (MethodBody body : bodies) { - for (AVM2Instruction ins : body.code.code) { + for (AVM2Instruction ins : body.getCode().code) { for (int i = 0; i < ins.definition.operands.length; i++) { if (ins.definition.operands[i] == AVM2Code.DAT_STRING_INDEX) { ret.add(ins.operands[i]); @@ -301,15 +301,15 @@ public class ABC { //process reflection using getDefinitionByName too for (MethodBody body : bodies) { - for (int ip = 0; ip < body.code.code.size(); ip++) { - if (body.code.code.get(ip).definition instanceof CallPropertyIns) { - int mIndex = body.code.code.get(ip).operands[0]; + for (int ip = 0; ip < body.getCode().code.size(); ip++) { + if (body.getCode().code.get(ip).definition instanceof CallPropertyIns) { + int mIndex = body.getCode().code.get(ip).operands[0]; if (mIndex > 0) { Multiname m = constants.getMultiname(mIndex); if (m.getNameWithNamespace(constants, true).equals("flash.utils.getDefinitionByName")) { if (ip > 0) { - if (body.code.code.get(ip - 1).definition instanceof PushStringIns) { - int strIndex = body.code.code.get(ip - 1).operands[0]; + if (body.getCode().code.get(ip - 1).definition instanceof PushStringIns) { + int strIndex = body.getCode().code.get(ip - 1).operands[0]; String fullname = constants.getString(strIndex); String pkg = ""; String name = fullname; @@ -331,7 +331,7 @@ public class ABC { } fullChanged += name; strIndex = constants.getStringId(fullChanged, true); - body.code.code.get(ip - 1).operands[0] = strIndex; + body.getCode().code.get(ip - 1).operands[0] = strIndex; } } } @@ -543,14 +543,6 @@ public class ABC { mb.max_scope_depth = ais.readU30("max_scope_depth"); int code_length = ais.readU30("code_length"); mb.codeBytes = ais.readBytes(code_length, "code"); - try { - ABCInputStream ais2 = new ABCInputStream(new MemoryInputStream(mb.codeBytes)); - mb.code = new AVM2Code(ais2); - } catch (UnknownInstructionCode re) { - mb.code = new AVM2Code(); - logger.log(Level.SEVERE, null, re); - } - mb.code.compact(); int ex_count = ais.readU30("ex_count"); mb.exceptions = new ABCException[ex_count]; for (int j = 0; j < ex_count; j++) { @@ -673,7 +665,7 @@ public class ABC { aos.writeU30(mb.max_regs); aos.writeU30(mb.init_scope_depth); aos.writeU30(mb.max_scope_depth); - byte[] codeBytes = mb.code.getBytes(); + byte[] codeBytes = mb.getCode().getBytes(); aos.writeU30(codeBytes.length); aos.write(codeBytes); aos.writeU30(mb.exceptions.length); @@ -755,13 +747,17 @@ public class ABC { if (classIndex == -1) { return null; } - if (traitId < class_info.get(classIndex).static_traits.traits.size()) { - return class_info.get(classIndex).static_traits.traits.get(traitId); - } else if (traitId < class_info.get(classIndex).static_traits.traits.size() + instance_info.get(classIndex).instance_traits.traits.size()) { - traitId -= class_info.get(classIndex).static_traits.traits.size(); - return instance_info.get(classIndex).instance_traits.traits.get(traitId); + List staticTraits = class_info.get(classIndex).static_traits.traits; + if (traitId < staticTraits.size()) { + return staticTraits.get(traitId); } else { - return null; //Can be class or instance initializer + List instanceTraits = instance_info.get(classIndex).instance_traits.traits; + if (traitId < staticTraits.size() + instanceTraits.size()) { + traitId -= staticTraits.size(); + return instanceTraits.get(traitId); + } else { + return null; //Can be class or instance initializer + } } } @@ -769,27 +765,31 @@ public class ABC { if (classIndex == -1) { return -1; } - if (traitId < class_info.get(classIndex).static_traits.traits.size()) { - if (class_info.get(classIndex).static_traits.traits.get(traitId) instanceof TraitMethodGetterSetter) { - return ((TraitMethodGetterSetter) class_info.get(classIndex).static_traits.traits.get(traitId)).method_info; - } else { - return -1; - } - } else if (traitId < class_info.get(classIndex).static_traits.traits.size() + instance_info.get(classIndex).instance_traits.traits.size()) { - traitId -= class_info.get(classIndex).static_traits.traits.size(); - if (instance_info.get(classIndex).instance_traits.traits.get(traitId) instanceof TraitMethodGetterSetter) { - return ((TraitMethodGetterSetter) instance_info.get(classIndex).instance_traits.traits.get(traitId)).method_info; + List staticTraits = class_info.get(classIndex).static_traits.traits; + if (traitId < staticTraits.size()) { + if (staticTraits.get(traitId) instanceof TraitMethodGetterSetter) { + return ((TraitMethodGetterSetter) staticTraits.get(traitId)).method_info; } else { return -1; } } else { - traitId -= class_info.get(classIndex).static_traits.traits.size() + instance_info.get(classIndex).instance_traits.traits.size(); - if (traitId == 0) { - return instance_info.get(classIndex).iinit_index; - } else if (traitId == 1) { - return class_info.get(classIndex).cinit_index; + List instanceTraits = instance_info.get(classIndex).instance_traits.traits; + if (traitId < staticTraits.size() + instanceTraits.size()) { + traitId -= staticTraits.size(); + if (instanceTraits.get(traitId) instanceof TraitMethodGetterSetter) { + return ((TraitMethodGetterSetter) instanceTraits.get(traitId)).method_info; + } else { + return -1; + } } else { - return -1; + traitId -= staticTraits.size() + instanceTraits.size(); + if (traitId == 0) { + return instance_info.get(classIndex).iinit_index; + } else if (traitId == 1) { + return class_info.get(classIndex).cinit_index; + } else { + return -1; + } } } } @@ -876,7 +876,7 @@ public class ABC { return; } } - for (AVM2Instruction ins : body.code.code) { + for (AVM2Instruction ins : body.getCode().code) { for (int o = 0; o < ins.definition.operands.length; o++) { if (ins.definition.operands[o] == AVM2Code.DAT_MULTINAME_INDEX) { if (ins.operands[o] == multinameIndex) { @@ -1058,7 +1058,7 @@ public class ABC { public void removeClass(int index) { for (MethodBody b : bodies) { - for (AVM2Instruction ins : b.code.code) { + for (AVM2Instruction ins : b.getCode().code) { for (int i = 0; i < ins.definition.operands.length; i++) { if (ins.definition.operands[i] == AVM2Code.DAT_CLASS_INDEX) { if (ins.operands[i] > index) { @@ -1112,7 +1112,7 @@ public class ABC { if (b.method_info > index) { b.method_info--; } - for (AVM2Instruction ins : b.code.code) { + for (AVM2Instruction ins : b.getCode().code) { for (int i = 0; i < ins.definition.operands.length; i++) { if (ins.definition.operands[i] == AVM2Code.DAT_METHOD_INDEX) { if (ins.operands[i] > index) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java index 4d53ccc04..64f4bdc11 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java @@ -47,9 +47,9 @@ import java.util.logging.Logger; */ public class ScriptPack implements TreeElementItem { - public ABC abc; - public int scriptIndex; - public List traitIndices; + public final ABC abc; + public final int scriptIndex; + public final List traitIndices; private final ClassPath path; @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java index 59b79fadd..204f20e0e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java @@ -1238,10 +1238,10 @@ public class AVM2SourceGenerator implements SourceGenerator { MethodBody initBody = null; if (!isInterface) { initBody = abc.findBody(init); - initBody.code.code.addAll(constructor == null ? 0 : 2, initcode);//after getlocal0,pushscope + initBody.getCode().code.addAll(constructor == null ? 0 : 2, initcode);//after getlocal0,pushscope - if (sinitBody.code.code.get(sinitBody.code.code.size() - 1).definition instanceof ReturnVoidIns) { - sinitBody.code.code.addAll(2, sinitcode); //after getlocal0,pushscope + if (sinitBody.getCode().code.get(sinitBody.getCode().code.size() - 1).definition instanceof ReturnVoidIns) { + sinitBody.getCode().code.addAll(2, sinitcode); //after getlocal0,pushscope } } sinitBody.markOffsets(); @@ -1619,8 +1619,9 @@ public class AVM2SourceGenerator implements SourceGenerator { mbody.method_info = abc.addMethodInfo(mi); mi.setBody(mbody); - mbody.code = new AVM2Code(); - mbody.code.code = toInsList(src); + List mbodyCode = toInsList(src); + mbody.setCode(new AVM2Code()); + mbody.getCode().code = mbodyCode; if (needsActivation) { if (localData.traitUsages.containsKey(mbody)) { @@ -1635,7 +1636,7 @@ public class AVM2SourceGenerator implements SourceGenerator { NameAVM2Item d = new NameAVM2Item(type, 0, tsc.getName(abc).getName(abc.constants, new ArrayList(), true), NameAVM2Item.getDefaultValue("" + type), true, new ArrayList()); d.setSlotNumber(tsc.slot_id); d.setSlotScope(slotScope); - mbody.code.code.addAll(0, toInsList(d.toSourceIgnoreReturnValue(localData, this))); + mbodyCode.addAll(0, toInsList(d.toSourceIgnoreReturnValue(localData, this))); } } } @@ -1646,7 +1647,7 @@ public class AVM2SourceGenerator implements SourceGenerator { acts.add(AssignableAVM2Item.generateSetLoc(localData.activationReg)); acts.add(ins(new PushScopeIns())); - mbody.code.code.addAll(0, acts); + mbodyCode.addAll(0, acts); } if (constructor) { @@ -1668,7 +1669,7 @@ public class AVM2SourceGenerator implements SourceGenerator { } } int ac = -1; - for (AVM2Instruction ins : mbody.code.code) { + for (AVM2Instruction ins : mbodyCode) { if (ins.definition instanceof ConstructSuperIns) { ac = ins.operands[0]; if (parentConstMinAC > ac) { @@ -1679,8 +1680,8 @@ public class AVM2SourceGenerator implements SourceGenerator { } if (ac == -1) { if (parentConstMinAC == 0) { - mbody.code.code.add(0, new AVM2Instruction(0, new GetLocal0Ins(), new int[]{})); - mbody.code.code.add(1, new AVM2Instruction(0, new ConstructSuperIns(), new int[]{0})); + mbodyCode.add(0, new AVM2Instruction(0, new GetLocal0Ins(), new int[]{})); + mbodyCode.add(1, new AVM2Instruction(0, new ConstructSuperIns(), new int[]{0})); } else { throw new CompilationException("Parent constructor must be called", line); @@ -1688,12 +1689,12 @@ public class AVM2SourceGenerator implements SourceGenerator { } } if (className != null) {//It's method, not (inner) function - mbody.code.code.add(0, new AVM2Instruction(0, new GetLocal0Ins(), new int[]{})); - mbody.code.code.add(1, new AVM2Instruction(0, new PushScopeIns(), new int[]{})); + mbodyCode.add(0, new AVM2Instruction(0, new GetLocal0Ins(), new int[]{})); + mbodyCode.add(1, new AVM2Instruction(0, new PushScopeIns(), new int[]{})); } boolean addRet = false; - if (!mbody.code.code.isEmpty()) { - InstructionDefinition lastDef = mbody.code.code.get(mbody.code.code.size() - 1).definition; + if (!mbodyCode.isEmpty()) { + InstructionDefinition lastDef = mbodyCode.get(mbodyCode.size() - 1).definition; if (!((lastDef instanceof ReturnVoidIns) || (lastDef instanceof ReturnValueIns))) { addRet = true; } @@ -1702,16 +1703,16 @@ public class AVM2SourceGenerator implements SourceGenerator { } if (addRet) { if (retType.toString().equals("*") || retType.toString().equals("void") || constructor) { - mbody.code.code.add(new AVM2Instruction(0, new ReturnVoidIns(), new int[]{})); + mbodyCode.add(new AVM2Instruction(0, new ReturnVoidIns(), new int[]{})); } else { - mbody.code.code.add(new AVM2Instruction(0, new PushUndefinedIns(), new int[]{})); - mbody.code.code.add(new AVM2Instruction(0, new ReturnValueIns(), new int[]{})); + mbodyCode.add(new AVM2Instruction(0, new PushUndefinedIns(), new int[]{})); + mbodyCode.add(new AVM2Instruction(0, new ReturnValueIns(), new int[]{})); } } mbody.exceptions = localData.exceptions.toArray(new ABCException[localData.exceptions.size()]); int offset = 0; - for (int i = 0; i < mbody.code.code.size(); i++) { - AVM2Instruction ins = mbody.code.code.get(i); + for (int i = 0; i < mbodyCode.size(); i++) { + AVM2Instruction ins = mbodyCode.get(i); if (ins instanceof ExceptionMarkAVM2Instruction) { ExceptionMarkAVM2Instruction m = (ExceptionMarkAVM2Instruction) ins; switch (m.markType) { @@ -1725,7 +1726,7 @@ public class AVM2SourceGenerator implements SourceGenerator { mbody.exceptions[m.exceptionId].target = offset; break; } - mbody.code.code.remove(i); + mbodyCode.remove(i); i--; continue; } @@ -2065,9 +2066,10 @@ public class AVM2SourceGenerator implements SourceGenerator { 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.add(ins(new GetLocal0Ins())); - mb.code.code.add(ins(new PushScopeIns())); + mb.setCode(new AVM2Code()); + List mbCode = mb.getCode().code; + mbCode.add(ins(new GetLocal0Ins())); + mbCode.add(ins(new PushScopeIns())); int traitScope = 2; @@ -2078,37 +2080,37 @@ public class AVM2SourceGenerator implements SourceGenerator { TraitClass tc = (TraitClass) t; List parents = new ArrayList<>(); if (localData.documentClass) { - mb.code.code.add(ins(new GetScopeObjectIns(), 0)); + mbCode.add(ins(new GetScopeObjectIns(), 0)); traitScope++; } else { NamespaceSet nsset = new NamespaceSet(new int[]{abc.constants.constant_multiname.get(tc.name_index).namespace_index}); - mb.code.code.add(ins(new FindPropertyStrictIns(), abc.constants.getMultinameId(new Multiname(Multiname.MULTINAME, abc.constants.constant_multiname.get(tc.name_index).name_index, 0, abc.constants.getNamespaceSetId(nsset, true), 0, new ArrayList()), true))); + mbCode.add(ins(new FindPropertyStrictIns(), abc.constants.getMultinameId(new Multiname(Multiname.MULTINAME, abc.constants.constant_multiname.get(tc.name_index).name_index, 0, abc.constants.getNamespaceSetId(nsset, true), 0, new ArrayList()), true))); } if (abc.instance_info.get(tc.class_info).isInterface()) { - mb.code.code.add(ins(new PushNullIns())); + mbCode.add(ins(new PushNullIns())); } else { parentNamesAddNames(abc, allABCs, abc.instance_info.get(tc.class_info).name_index, parents, new ArrayList(), new ArrayList()); for (int i = parents.size() - 1; i >= 1; i--) { - mb.code.code.add(ins(new GetLexIns(), parents.get(i))); - mb.code.code.add(ins(new PushScopeIns())); + mbCode.add(ins(new GetLexIns(), parents.get(i))); + mbCode.add(ins(new PushScopeIns())); traitScope++; } - mb.code.code.add(ins(new GetLexIns(), parents.get(1))); + mbCode.add(ins(new GetLexIns(), parents.get(1))); } - mb.code.code.add(ins(new NewClassIns(), tc.class_info)); + mbCode.add(ins(new NewClassIns(), tc.class_info)); if (!abc.instance_info.get(tc.class_info).isInterface()) { for (int i = parents.size() - 1; i >= 1; i--) { - mb.code.code.add(ins(new PopScopeIns())); + mbCode.add(ins(new PopScopeIns())); } } - mb.code.code.add(ins(new InitPropertyIns(), tc.name_index)); + mbCode.add(ins(new InitPropertyIns(), tc.name_index)); initScopes.put(t, traitScope); traitScope = 1; } } - mb.code.code.add(ins(new ReturnVoidIns())); + mbCode.add(ins(new ReturnVoidIns())); mb.autoFillStats(abc, 1, false); abc.addMethodBody(mb); si.init_index = mb.method_info; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java index 01c8fa943..489ed6430 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java @@ -17,9 +17,12 @@ package com.jpexs.decompiler.flash.abc.types; import com.jpexs.decompiler.flash.AppResources; import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.ABCInputStream; import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; import com.jpexs.decompiler.flash.abc.avm2.CodeStats; import com.jpexs.decompiler.flash.abc.avm2.ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.UnknownInstructionCode; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.abc.types.traits.Traits; import com.jpexs.decompiler.flash.configuration.Configuration; @@ -31,6 +34,8 @@ import com.jpexs.decompiler.graph.ScopeStack; import com.jpexs.decompiler.graph.model.LocalData; import com.jpexs.helpers.CancellableWorker; import com.jpexs.helpers.Helper; +import com.jpexs.helpers.MemoryInputStream; +import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; @@ -52,27 +57,47 @@ public class MethodBody implements Cloneable, Serializable { public int init_scope_depth; public int max_scope_depth; public byte[] codeBytes; - public AVM2Code code; + private AVM2Code code; public ABCException[] exceptions = new ABCException[0]; public Traits traits = new Traits(); public transient List convertedItems; public transient Throwable convertException; + public synchronized AVM2Code getCode() { + if (code == null) { + AVM2Code avm2Code; + try { + ABCInputStream ais = new ABCInputStream(new MemoryInputStream(codeBytes)); + avm2Code = new AVM2Code(ais); + } catch (UnknownInstructionCode | IOException ex) { + avm2Code = new AVM2Code(); + Logger.getLogger(MethodBody.class.getName()).log(Level.SEVERE, null, ex); + } + avm2Code.compact(); + code = avm2Code; + } + return code; + } + + public void setCode(AVM2Code code) { + this.code = code; + } + public List getExceptionEntries() { List ret = new ArrayList<>(); for (ABCException e : exceptions) { - ret.add(code.adr2pos(e.start)); - ret.add(code.adr2pos(e.end)); - ret.add(code.adr2pos(e.target)); + ret.add(getCode().adr2pos(e.start)); + ret.add(getCode().adr2pos(e.end)); + ret.add(getCode().adr2pos(e.target)); } return ret; } public void markOffsets() { long offset = 0; - for (int i = 0; i < code.code.size(); i++) { - code.code.get(i).offset = offset; - offset += code.code.get(i).getBytes().length; + for (int i = 0; i < getCode().code.size(); i++) { + getCode().code.get(i).offset = offset; + offset += getCode().code.get(i).getBytes().length; } } @@ -80,20 +105,20 @@ public class MethodBody implements Cloneable, Serializable { public String toString() { String s = ""; s += "method_info=" + method_info + " max_stack=" + max_stack + " max_regs=" + max_regs + " scope_depth=" + init_scope_depth + " max_scope=" + max_scope_depth; - s += "\r\nCode:\r\n" + code.toString(); + s += "\r\nCode:\r\n" + getCode().toString(); return s; } public int removeDeadCode(ConstantPool constants, Trait trait, MethodInfo info) throws InterruptedException { - return code.removeDeadCode(constants, trait, info, this); + return getCode().removeDeadCode(constants, trait, info, this); } public void restoreControlFlow(ConstantPool constants, Trait trait, MethodInfo info) throws InterruptedException { - code.restoreControlFlow(constants, trait, info, this); + getCode().restoreControlFlow(constants, trait, info, this); } public int removeTraps(ConstantPool constants, ABC abc, Trait trait, int scriptIndex, int classIndex, boolean isStatic, String path) throws InterruptedException { - return code.removeTraps(constants, trait, abc.method_info.get(method_info), this, abc, scriptIndex, classIndex, isStatic, path); + return getCode().removeTraps(constants, trait, abc.method_info.get(method_info), this, abc, scriptIndex, classIndex, isStatic, path); } public HashMap getLocalRegNames(ABC abc) { @@ -115,7 +140,7 @@ public class MethodBody implements Cloneable, Serializable { pos++; } - HashMap debugRegNames = code.getLocalRegNamesFromDebug(abc); + HashMap debugRegNames = getCode().getLocalRegNamesFromDebug(abc); for (int k : debugRegNames.keySet()) { ret.put(k, debugRegNames.get(k)); } @@ -127,7 +152,7 @@ public class MethodBody implements Cloneable, Serializable { System.err.println("Decompiling " + path); } if (exportMode != ScriptExportMode.AS) { - code.toASMSource(constants, trait, method_info.get(this.method_info), this, exportMode, writer); + getCode().toASMSource(constants, trait, method_info.get(this.method_info), this, exportMode, writer); } else { if (!Configuration.decompile.get()) { writer.appendNoHilight("//" + AppResources.translate("decompilation.skipped")).newLine(); @@ -140,7 +165,7 @@ public class MethodBody implements Cloneable, Serializable { public Void call() throws InterruptedException { MethodBody converted = convertMethodBody(path, isStatic, scriptIndex, classIndex, abc, trait, constants, method_info, scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits); HashMap localRegNames = getLocalRegNames(abc); - convertedItems = converted.code.toGraphTargetItems(path, isStatic, scriptIndex, classIndex, abc, constants, method_info, converted, localRegNames, scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits, Graph.SOP_USE_STATIC, new HashMap(), converted.code.visitCode(converted)); + convertedItems = converted.getCode().toGraphTargetItems(path, isStatic, scriptIndex, classIndex, abc, constants, method_info, converted, localRegNames, scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits, Graph.SOP_USE_STATIC, new HashMap(), converted.getCode().visitCode(converted)); Graph.graphToString(convertedItems, writer, LocalData.create(constants, localRegNames, fullyQualifiedNames)); return null; } @@ -165,7 +190,7 @@ public class MethodBody implements Cloneable, Serializable { public GraphTextWriter toString(final String path, ScriptExportMode exportMode, final ABC abc, final Trait trait, final ConstantPool constants, final List method_info, final GraphTextWriter writer, final List fullyQualifiedNames) throws InterruptedException { if (exportMode != ScriptExportMode.AS) { - code.toASMSource(constants, trait, method_info.get(this.method_info), this, exportMode, writer); + getCode().toASMSource(constants, trait, method_info.get(this.method_info), this, exportMode, writer); } else { if (!Configuration.decompile.get()) { writer.startMethod(this.method_info); @@ -193,7 +218,7 @@ public class MethodBody implements Cloneable, Serializable { public MethodBody convertMethodBody(String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, Trait trait, ConstantPool constants, List method_info, ScopeStack scopeStack, boolean isStaticInitializer, List fullyQualifiedNames, Traits initTraits) throws InterruptedException { MethodBody b = Helper.deepCopy(this); - AVM2Code deobfuscated = b.code; + AVM2Code deobfuscated = b.getCode(); deobfuscated.markMappedOffsets(); if (Configuration.autoDeobfuscate.get()) { try { @@ -224,7 +249,7 @@ public class MethodBody implements Cloneable, Serializable { public boolean autoFillStats(ABC abc, int initScope, boolean hasThis) { //System.out.println("--------------"); - CodeStats stats = code.getStats(abc, this, initScope); + CodeStats stats = getCode().getStats(abc, this, initScope); if (stats == null) { return false; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodInfo.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodInfo.java index bad71767f..d5e7bed22 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodInfo.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodInfo.java @@ -34,7 +34,7 @@ public class MethodInfo { public void delete(ABC abc, boolean d) { this.deleted = true; if (body != null) { - for (AVM2Instruction ins : body.code.code) { + for (AVM2Instruction ins : body.getCode().code) { if (ins.definition instanceof NewFunctionIns) { abc.method_info.get(ins.operands[0]).delete(abc, d); } @@ -269,7 +269,7 @@ public class MethodInfo { public GraphTextWriter getParamStr(GraphTextWriter writer, ConstantPool constants, MethodBody body, ABC abc, List fullyQualifiedNames) { HashMap localRegNames = new HashMap<>(); if (body != null) { - localRegNames = body.code.getLocalRegNamesFromDebug(abc); + localRegNames = body.getCode().getLocalRegNamesFromDebug(abc); } for (int i = 0; i < param_types.length; i++) { if (i > 0) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java index 760185775..87443c380 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java @@ -266,7 +266,7 @@ public class TraitClass extends Trait implements TraitWithSlot { for (ABCException ex : body.exceptions) { parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(ex.type_index), ignorePackage, fullyQualifiedNames); } - for (AVM2Instruction ins : body.code.code) { + for (AVM2Instruction ins : body.getCode().code) { if (ins.definition instanceof NewFunctionIns) { if (ins.operands[0] != method_index) { if (!visitedMethods.contains(ins.operands[0])) { diff --git a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java index d801a5f21..1d4f94e00 100644 --- a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java +++ b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java @@ -1456,14 +1456,7 @@ public class CommandLineArgumentParser { byte[] data = Helper.getBytesFromHexaText(text); MethodBody mb = abc.bodies.get(bodyIndex); mb.codeBytes = data; - try { - ABCInputStream ais = new ABCInputStream(new MemoryInputStream(mb.codeBytes)); - mb.code = new AVM2Code(ais); - } catch (UnknownInstructionCode re) { - mb.code = new AVM2Code(); - Logger.getLogger(CommandLineArgumentParser.class.getName()).log(Level.SEVERE, null, re); - } - mb.code.compact(); + mb.setCode(null); } else { Trait trait = abc.findTraitByTraitId(classIndex, traitId); try { @@ -1490,7 +1483,7 @@ public class CommandLineArgumentParser { } }, abc.bodies.get(bodyIndex), abc.method_info.get(abc.bodies.get(bodyIndex).method_info)); acode.getBytes(abc.bodies.get(bodyIndex).codeBytes); - abc.bodies.get(bodyIndex).code = acode; + abc.bodies.get(bodyIndex).setCode(acode); } catch (com.jpexs.decompiler.flash.abc.avm2.parser.ParseException ex) { System.err.println("%error% on line %line%".replace("%error%", ex.text).replace("%line%", "" + ex.line)); System.exit(1); diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java index e273f11c1..1c5bbb996 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java @@ -872,7 +872,7 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se code.code.add(new AVM2Instruction(0, new GetLocal0Ins(), new int[0])); code.code.add(new AVM2Instruction(0, new PushScopeIns(), new int[0])); code.code.add(new AVM2Instruction(0, new ReturnVoidIns(), new int[0])); - body.code = code; + body.setCode(code); Traits traits = new Traits(); traits.traits = new ArrayList<>(); body.traits = traits; diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java b/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java index c5590b70f..21f25674e 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ASMSourceEditorPane.java @@ -17,9 +17,7 @@ package com.jpexs.decompiler.flash.gui.abc; import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.ABCInputStream; import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; -import com.jpexs.decompiler.flash.abc.avm2.UnknownInstructionCode; import com.jpexs.decompiler.flash.abc.avm2.graph.AVM2Graph; import com.jpexs.decompiler.flash.abc.avm2.parser.ParseException; import com.jpexs.decompiler.flash.abc.avm2.parser.pcode.ASM3Parser; @@ -37,7 +35,6 @@ import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.ScopeStack; import com.jpexs.helpers.Helper; -import com.jpexs.helpers.MemoryInputStream; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; @@ -73,7 +70,7 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi private HilightedText getHilightedText(ScriptExportMode exportMode) { HilightedTextWriter writer = new HilightedTextWriter(Configuration.getCodeFormatting(), true); - abc.bodies.get(bodyIndex).code.toASMSource(abc.constants, trait, abc.method_info.get(abc.bodies.get(bodyIndex).method_info), abc.bodies.get(bodyIndex), exportMode, writer); + abc.bodies.get(bodyIndex).getCode().toASMSource(abc.constants, trait, abc.method_info.get(abc.bodies.get(bodyIndex).method_info), abc.bodies.get(bodyIndex), exportMode, writer); return new HilightedText(writer); } @@ -99,7 +96,7 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi setContentType("text/plain"); if (textHexOnly == null) { HilightedTextWriter writer = new HilightedTextWriter(Configuration.getCodeFormatting(), true); - Helper.byteArrayToHexWithHeader(writer, abc.bodies.get(bodyIndex).code.getBytes()); + Helper.byteArrayToHexWithHeader(writer, abc.bodies.get(bodyIndex).getCode().getBytes()); textHexOnly = new HilightedText(writer); } setText(textHexOnly); @@ -171,7 +168,7 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi public void graph() { try { - AVM2Graph gr = new AVM2Graph(abc.bodies.get(bodyIndex).code, abc, abc.bodies.get(bodyIndex), false, -1, -1, new HashMap(), new ScopeStack(), new HashMap(), new ArrayList(), new HashMap(), abc.bodies.get(bodyIndex).code.visitCode(abc.bodies.get(bodyIndex))); + AVM2Graph gr = new AVM2Graph(abc.bodies.get(bodyIndex).getCode(), abc, abc.bodies.get(bodyIndex), false, -1, -1, new HashMap(), new ScopeStack(), new HashMap(), new ArrayList(), new HashMap(), abc.bodies.get(bodyIndex).getCode().visitCode(abc.bodies.get(bodyIndex))); (new GraphDialog(getAbcPanel().getMainPanel().getMainFrame().getWindow(), gr, name)).setVisible(true); } catch (InterruptedException ex) { Logger.getLogger(ASMSourceEditorPane.class.getName()).log(Level.SEVERE, null, ex); @@ -182,7 +179,7 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi HashMap args = new HashMap<>(); args.put(0, new Object()); //object "this" args.put(1, new Long(466561)); //param1 - Object o = abc.bodies.get(bodyIndex).code.execute(args, abc.constants); + Object o = abc.bodies.get(bodyIndex).getCode().execute(args, abc.constants); View.showMessageDialog(this, "Returned object:" + o.toString()); } @@ -193,14 +190,7 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi byte[] data = Helper.getBytesFromHexaText(text); MethodBody mb = abc.bodies.get(bodyIndex); mb.codeBytes = data; - try { - ABCInputStream ais = new ABCInputStream(new MemoryInputStream(mb.codeBytes)); - mb.code = new AVM2Code(ais); - } catch (UnknownInstructionCode re) { - mb.code = new AVM2Code(); - Logger.getLogger(ASMSourceEditorPane.class.getName()).log(Level.SEVERE, null, re); - } - mb.code.compact(); + mb.setCode(null); } else { AVM2Code acode = ASM3Parser.parse(new StringReader(text), abc.constants, trait, new MissingSymbolHandler() { //no longer ask for adding new constants @@ -225,7 +215,7 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi } }, abc.bodies.get(bodyIndex), abc.method_info.get(abc.bodies.get(bodyIndex).method_info)); acode.getBytes(abc.bodies.get(bodyIndex).codeBytes); - abc.bodies.get(bodyIndex).code = acode; + abc.bodies.get(bodyIndex).setCode(acode); } ((Tag) abc.parentTag).setModified(true); } catch (IOException ex) { diff --git a/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java b/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java index 9d7024534..359b6f777 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java @@ -229,7 +229,7 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL int pos = getCaretPosition(); Highlighting h = Highlighting.search(highlights, pos); if (h != null) { - List list = abc.bodies.get(abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex()).code.code; + List list = abc.bodies.get(abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex()).getCode().code; AVM2Instruction lastIns = null; long inspos = 0; AVM2Instruction selIns = null;