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 5409ca518..97c90f4f8 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 @@ -97,7 +97,7 @@ public class ABC { public List bodies = new ArrayList<>(); - private Map bodyIdxFromMethodIdx; + private ABCMethodIndexing abcMethodIndexing; public static final int MINORwithDECIMAL = 17; @@ -128,7 +128,7 @@ public class ABC { public int addMethodBody(MethodBody body) { bodies.add(body); - bodyIdxFromMethodIdx = null; + abcMethodIndexing = null; return bodies.size() - 1; } @@ -149,7 +149,6 @@ public class ABC { MethodBody methodBody = new MethodBody(); methodBody.method_info = methodInfoId; addMethodBody(methodBody); - methodInfo.setBody(methodBody); TraitMethodGetterSetter trait = new TraitMethodGetterSetter(); trait.name_index = multinameId; @@ -566,13 +565,12 @@ public class ABC { } mb.traits = ais.readTraits("traits"); bodies.add(mb); - method_info.get(mb.method_info).setBody(mb); ais.endDumpLevel(); SWFDecompilerPlugin.fireMethodBodyParsed(mb, swf); } - createBodyIdxFromMethodIdxMap(); + getMethodIndexing(); /*for(int i=0;i map = new HashMap<>(bodies.size()); - for (int i = 0; i < bodies.size(); i++) { - MethodBody mb = bodies.get(i); - map.put(mb.method_info, i); + public final ABCMethodIndexing getMethodIndexing() { + if (abcMethodIndexing == null) { + abcMethodIndexing = new ABCMethodIndexing(this); } - bodyIdxFromMethodIdx = map; - } - - private Map getBodyIdxFromMethodIdx() { - if (bodyIdxFromMethodIdx == null) { - createBodyIdxFromMethodIdxMap(); - } - return bodyIdxFromMethodIdx; + return abcMethodIndexing; } public DottedChain nsValueToName(String valueStr) { @@ -1234,7 +1219,7 @@ public class ABC { removeMethodFromTraits(si.traits, index); } - bodyIdxFromMethodIdx = null; + abcMethodIndexing = null; method_info.remove(index); } @@ -1302,6 +1287,6 @@ public class ABC { } } - createBodyIdxFromMethodIdxMap(); + getMethodIndexing(); } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABCMethodIndexing.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABCMethodIndexing.java new file mode 100644 index 000000000..a00933f83 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABCMethodIndexing.java @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.abc; + +import com.jpexs.decompiler.flash.abc.types.ClassInfo; +import com.jpexs.decompiler.flash.abc.types.InstanceInfo; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.flash.abc.types.traits.Trait; +import com.jpexs.decompiler.flash.abc.types.traits.TraitClass; +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 java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * + * @author JPEXS + */ +public class ABCMethodIndexing { + + private ABC abc; + + private Map bodyIdxFromMethod = new HashMap<>(); + + public ABCMethodIndexing(ABC abc) { + this.abc = abc; + createBodyIdxFromMethodIdxMap(abc); + } + + public final void createBodyIdxFromMethodIdxMap(ABC abc) { + List bodies = abc.bodies; + Map map = new HashMap<>(bodies.size()); + for (int i = 0; i < bodies.size(); i++) { + MethodBody mb = bodies.get(i); + map.put(abc.method_info.get(mb.method_info), i); + } + + bodyIdxFromMethod = map; + } + + public int findMethodBodyIndex(MethodInfo methodInfo) { + Integer bi = bodyIdxFromMethod.get(methodInfo); + if (bi == null) { + return -1; + } + + return bi; + } + + public int findMethodBodyIndex(int methodInfo) { + if (methodInfo < 0 || methodInfo >= abc.method_info.size()) { + return -1; + } + + MethodInfo mi = abc.method_info.get(methodInfo); + return findMethodBodyIndex(mi); + } + + public MethodBody findMethodBody(MethodInfo methodInfo) { + int bi = findMethodBodyIndex(methodInfo); + if (bi != -1) { + return abc.bodies.get(bi); + } + + return null; + } + + public MethodBody findMethodBody(int methodInfo) { + int bi = findMethodBodyIndex(methodInfo); + if (bi != -1) { + return abc.bodies.get(bi); + } + + return null; + } + + public List findMethodTraits(ScriptPack pack, int bodyIndex) { + int methodInfo = abc.bodies.get(bodyIndex).method_info; + List traits = abc.script_info.get(pack.scriptIndex).traits.traits; + List resultTraits = new ArrayList<>(); + for (int ti : pack.traitIndices) { + Trait t = traits.get(ti); + findTraits(abc, t, methodInfo, resultTraits); + } + + return resultTraits; + } + + private static void findTraits(ABC abc, Trait trait, int methodInfo, List result) { + if (trait instanceof TraitSlotConst) { + TraitSlotConst tsc = (TraitSlotConst) trait; + } else if (trait instanceof TraitFunction) { + TraitFunction tf = (TraitFunction) trait; + if (tf.method_info == methodInfo) { + result.add(trait); + } + } else if (trait instanceof TraitMethodGetterSetter) { + TraitMethodGetterSetter tmgs = (TraitMethodGetterSetter) trait; + if (tmgs.method_info == methodInfo) { + result.add(trait); + } + } else if (trait instanceof TraitClass) { + TraitClass tc = (TraitClass) trait; + InstanceInfo instanceInfo = abc.instance_info.get(tc.class_info); + for (Trait t : instanceInfo.instance_traits.traits) { + findTraits(abc, t, methodInfo, result); + } + + ClassInfo classInfo = abc.class_info.get(tc.class_info); + for (Trait t : classInfo.static_traits.traits) { + findTraits(abc, t, methodInfo, result); + } + } + } +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ClassPath.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ClassPath.java index fd6b1c2e3..aec7f3024 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ClassPath.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ClassPath.java @@ -16,7 +16,6 @@ */ package com.jpexs.decompiler.flash.abc; -import com.jpexs.decompiler.flash.IdentifiersDeobfuscation; import com.jpexs.decompiler.graph.DottedChain; import java.util.Objects; 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 5b0109695..9cb66f98f 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 @@ -1674,7 +1674,6 @@ public class AVM2SourceGenerator implements SourceGenerator { List src = body == null ? new ArrayList<>() : generate(localData, body); mbody.method_info = abcIndex.getSelectedAbc().addMethodInfo(mi); - mi.setBody(mbody); ArrayList mbodyCode = toInsList(src); mbody.setCode(new AVM2Code(mbodyCode)); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java index e3045dbfc..5bf65e754 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java @@ -2524,7 +2524,7 @@ public class ActionScript3Parser { abc.class_info = originalAbc.class_info; abc.script_info = originalAbc.script_info; abc.bodies = originalAbc.bodies; - abc.createBodyIdxFromMethodIdxMap(); + abc.getMethodIndexing(); } } } 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 0546b0c33..e93b25261 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 @@ -43,6 +43,7 @@ public class MethodInfo { public void delete(ABC abc, boolean d) { this.deleted = true; + MethodBody body = abc.findBody(this); if (body != null) { for (AVM2Instruction ins : body.getCode().code) { if (ins.definition instanceof NewFunctionIns) { @@ -83,8 +84,6 @@ public class MethodInfo { public int[] paramNames = new int[0]; - private MethodBody body; - public void setFlagIgnore_Rest() { flags |= FLAG_IGNORE_REST; } @@ -383,12 +382,4 @@ public class MethodInfo { } return writer.hilightSpecial(rname, HighlightSpecialType.RETURNS); } - - public void setBody(MethodBody body) { - this.body = body; - } - - public MethodBody getBody() { - return body; - } } diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3ExecuteTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3ExecuteTest.java index 4f91508d2..51b5afdf7 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3ExecuteTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3ExecuteTest.java @@ -124,7 +124,7 @@ public class ActionScript3ExecuteTest { private int addMethod(int classId, String name, boolean isStatic, AVM2Code code) { TraitMethodGetterSetter methodTrait = abc.addMethod(classId, name, isStatic); MethodInfo methodInfo = abc.method_info.get(methodTrait.method_info); - MethodBody methodBody = methodInfo.getBody(); + MethodBody methodBody = abc.findBody(methodInfo); methodBody.max_stack = 10; methodBody.max_regs = 10; methodBody.init_scope_depth = 3; diff --git a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java index d99c12301..c6b70f13c 100644 --- a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java +++ b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java @@ -2059,11 +2059,19 @@ public class CommandLineArgumentParser { if (args.isEmpty()) { badArguments("replace"); } + int bodyIndex = Integer.parseInt(args.pop()); + ABC abc = pack.abc; + List resultTraits = abc.getMethodIndexing().findMethodTraits(pack, bodyIndex); + //int classIndex = 0; //int traitId = 0; Trait trait = null; //abc.findTraitByTraitId(classIndex, traitId); - replaceAS3PCode(repText, pack.abc, bodyIndex, trait); + if (resultTraits.size() == 1) { + trait = resultTraits.get(0); + } + + replaceAS3PCode(repText, abc, bodyIndex, trait); } } } diff --git a/test/com/jpexs/decompiler/flash/gui/AdobeFlashExecutor.java b/test/com/jpexs/decompiler/flash/gui/AdobeFlashExecutor.java index 6f06b9387..629f3194d 100644 --- a/test/com/jpexs/decompiler/flash/gui/AdobeFlashExecutor.java +++ b/test/com/jpexs/decompiler/flash/gui/AdobeFlashExecutor.java @@ -357,7 +357,7 @@ public class AdobeFlashExecutor { private int addMethod(ABC abc, int classId, String name, boolean isStatic, AVM2Code code) { TraitMethodGetterSetter methodTrait = abc.addMethod(classId, name, isStatic); MethodInfo methodInfo = abc.method_info.get(methodTrait.method_info); - MethodBody methodBody = methodInfo.getBody(); + MethodBody methodBody = abc.findBody(methodInfo); methodBody.max_stack = 10; methodBody.max_regs = 10; methodBody.init_scope_depth = 3;