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 0bf9f70cb..c0e35e6af 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -419,6 +419,27 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { } public AbcIndexing getAbcIndex() { + if (abcIndex != null) { + return abcIndex; + } + boolean air = false; + SwfSpecificCustomConfiguration conf = Configuration.getSwfSpecificCustomConfiguration(getShortPathTitle()); + if (conf != null) { + if (conf.getCustomData(CustomConfigurationKeys.KEY_LIBRARY, "" + LIBRARY_FLASH).equals("" + LIBRARY_AIR)) { + air = true; + } + } + try { + SWF.initPlayer(); + } catch (IOException | InterruptedException ex) { + Logger.getLogger(SWF.class.getName()).log(Level.SEVERE, null, ex); + } + abcIndex = new AbcIndexing(air ? SWF.getAirGlobalAbcIndex() : SWF.getPlayerGlobalAbcIndex()); + for (Tag tag:tags) { + if (tag instanceof ABCContainerTag) { + abcIndex.addAbc(((ABCContainerTag)tag).getABC()); + } + } return abcIndex; } @@ -1460,21 +1481,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { clearScriptCache(); } - getASMs(true); // Add scriptNames to ASMs - - boolean air = false; - SwfSpecificCustomConfiguration conf = Configuration.getSwfSpecificCustomConfiguration(getShortPathTitle()); - if (conf != null) { - if (conf.getCustomData(CustomConfigurationKeys.KEY_LIBRARY, "" + LIBRARY_FLASH).equals("" + LIBRARY_AIR)) { - air = true; - } - } - abcIndex = new AbcIndexing(air ? SWF.getAirGlobalAbcIndex() : SWF.getPlayerGlobalAbcIndex()); - for (Tag tag:tags) { - if (tag instanceof ABCContainerTag) { - abcIndex.addAbc(((ABCContainerTag)tag).getABC()); - } - } + getASMs(true); // Add scriptNames to ASMs } private void resolveImported(UrlResolver resolver) { @@ -3090,7 +3097,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { } } - return decompilerPool.decompile(swf.abcIndex, pack); + return decompilerPool.decompile(swf.getAbcIndex(), pack); } public static Future getCachedFuture(ASMSource src, ActionList actions, ScriptDecompiledListener listener) throws InterruptedException { @@ -3125,7 +3132,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { } } - return decompilerPool.submitTask(swf.abcIndex, pack, listener); + return decompilerPool.submitTask(swf.getAbcIndex(), pack, listener); } public DecompilerPool getDecompilerPool() { @@ -4036,7 +4043,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { int mi = ((TraitMethodGetterSetter) t).method_info; try { - documentPack.abc.findBody(mi).convert(abcIndex, new ConvertData(), "??", ScriptExportMode.AS, true, mi, documentPack.scriptIndex, cindex, documentPack.abc, t, new ScopeStack(), 0, new NulWriter(), new ArrayList<>(), new ArrayList<>(), true, new HashSet<>()); + documentPack.abc.findBody(mi).convert(getAbcIndex(), new ConvertData(), "??", ScriptExportMode.AS, true, mi, documentPack.scriptIndex, cindex, documentPack.abc, t, new ScopeStack(), 0, new NulWriter(), new ArrayList<>(), new ArrayList<>(), true, new HashSet<>()); List infos = documentPack.abc.findBody(mi).convertedItems; if (!infos.isEmpty()) { if (infos.get(0) instanceof IfItem) { @@ -4112,7 +4119,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable { if (tr instanceof TraitClass) { int ci = ((TraitClass) tr).class_info; int cinit = p.abc.class_info.get(ci).cinit_index; - p.abc.findBody(cinit).convert(abcIndex, new ConvertData(), "??", ScriptExportMode.AS, true, cinit, p.scriptIndex, cindex, p.abc, t, new ScopeStack(), 0, new NulWriter(), new ArrayList<>(), new ArrayList<>(), true, new HashSet<>()); + p.abc.findBody(cinit).convert(getAbcIndex(), new ConvertData(), "??", ScriptExportMode.AS, true, cinit, p.scriptIndex, cindex, p.abc, t, new ScopeStack(), 0, new NulWriter(), new ArrayList<>(), new ArrayList<>(), true, new HashSet<>()); List cinitBody = p.abc.findBody(cinit).convertedItems; for (GraphTargetItem cit : cinitBody) { if (cit instanceof SetPropertyAVM2Item) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/AVM2LocalData.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/AVM2LocalData.java index e0fe8729c..f187b4a54 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/AVM2LocalData.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/AVM2LocalData.java @@ -58,6 +58,8 @@ public class AVM2LocalData extends BaseLocalData { public AbcIndexing abcIndex; public HashMap localRegNames; + + public HashMap localRegTypes; public List fullyQualifiedNames; @@ -146,6 +148,7 @@ public class AVM2LocalData extends BaseLocalData { abc = localData.abc; abcIndex = localData.abcIndex; localRegNames = localData.localRegNames; + localRegTypes = localData.localRegTypes; fullyQualifiedNames = localData.fullyQualifiedNames; parsedExceptions = localData.parsedExceptions; finallyJumps = localData.finallyJumps; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java index 77bfd4357..c060b062d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java @@ -1589,7 +1589,7 @@ public class AVM2Code implements Cloneable { return pos2adr(getIpThroughJumpAndDebugLine(adr2pos(addr, true))); } - public ConvertOutput toSourceOutput(Map> setLocalPosToGetLocalPos, boolean thisHasDefaultToPrimitive, Reference lineStartItem, String path, GraphPart part, boolean processJumps, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, ABC abc, MethodBody body, int start, int end, HashMap localRegNames, List fullyQualifiedNames, boolean[] visited, HashMap localRegAssigmentIps, HashMap> refs) throws ConvertException, InterruptedException { + public ConvertOutput toSourceOutput(AbcIndexing abcIndex, Map> setLocalPosToGetLocalPos, boolean thisHasDefaultToPrimitive, Reference lineStartItem, String path, GraphPart part, boolean processJumps, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, ABC abc, MethodBody body, int start, int end, HashMap localRegNames, HashMap localRegTypes, List fullyQualifiedNames, boolean[] visited, HashMap localRegAssigmentIps, HashMap> refs) throws ConvertException, InterruptedException { calcKilledStats(body); boolean debugMode = DEBUG_MODE; if (debugMode) { @@ -1664,7 +1664,7 @@ public class AVM2Code implements Cloneable { do { AVM2Instruction insAfter = ip + 1 < code.size() ? code.get(ip + 1) : null; if (insAfter == null) { - ins.definition.translate(setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive); + ins.definition.translate(abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive); ip++; break; } @@ -1686,14 +1686,14 @@ public class AVM2Code implements Cloneable { //stack.add("(" + stack.pop() + ")||"); isAnd = false; } else { - ins.definition.translate(setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive); + ins.definition.translate(abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive); ip++; break; //throw new ConvertException("Unknown pattern after DUP:" + insComparsion.toString()); } } while (ins.definition instanceof DupIns); } else if ((ins.definition instanceof ReturnValueIns) || (ins.definition instanceof ReturnVoidIns) || (ins.definition instanceof ThrowIns)) { - ins.definition.translate(setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive); + ins.definition.translate(abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive); //ip = end + 1; break; } else if (ins.definition instanceof NewFunctionIns) { @@ -1729,13 +1729,13 @@ public class AVM2Code implements Cloneable { } } // What to do when hasDup is false? - ins.definition.translate(setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive); + ins.definition.translate(abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive); NewFunctionAVM2Item nft = (NewFunctionAVM2Item) stack.peek(); nft.functionName = functionName; ip++; } else { try { - ins.definition.translate(setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive); + ins.definition.translate(abcIndex, setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, localRegTypes, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive); } catch (RuntimeException re) { /*String last=""; int len=5; @@ -2136,9 +2136,13 @@ public class AVM2Code implements Cloneable { for (int i = 0; i < regCount; i++) { localRegs.put(0, new UndefinedAVM2Item(null, null)); } + HashMap localRegTypes = new HashMap<>(); + for (int i = 0; i < abc.method_info.get(methodIndex).param_types.length; i++) { + localRegTypes.put(i + 1, PropertyAVM2Item.multinameToType(abc.method_info.get(methodIndex).param_types[i], abc.constants)); + } //try { - list = AVM2Graph.translateViaGraph(abcIndex, path, this, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localRegNames, fullyQualifiedNames, staticOperation, localRegAssigmentIps, refs, thisHasDefaultToPrimitive); + list = AVM2Graph.translateViaGraph(abcIndex, path, this, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localRegNames, localRegTypes, fullyQualifiedNames, staticOperation, localRegAssigmentIps, refs, thisHasDefaultToPrimitive); if (initTraits != null) { loopi: diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorGetSet.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorGetSet.java index 12fb1129e..bd066a657 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorGetSet.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorGetSet.java @@ -112,6 +112,7 @@ public class AVM2DeobfuscatorGetSet extends SWFDecompilerAdapter { localData.methodBody = body; localData.abc = abc; localData.localRegNames = new HashMap<>(); + localData.localRegTypes = new HashMap<>(); localData.scriptIndex = scriptIndex; localData.ip = 0; localData.code = body.getCode(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimpleOld.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimpleOld.java index 60b873730..52164d7ed 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimpleOld.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/deobfuscation/AVM2DeobfuscatorSimpleOld.java @@ -202,6 +202,7 @@ public class AVM2DeobfuscatorSimpleOld extends AVM2DeobfuscatorZeroJumpsNullPush localData.methodBody = body; localData.abc = abc; localData.localRegNames = new HashMap<>(); + localData.localRegTypes = new HashMap<>(); localData.scriptIndex = scriptIndex; localData.ip = 0; localData.code = body.getCode(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java index a6a83e04a..062442bdd 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java @@ -633,7 +633,7 @@ public class AVM2Graph extends Graph { return setLocalPosToGetLocalPos; } - public static List translateViaGraph(AbcIndexing abcIndex, String path, AVM2Code code, ABC abc, MethodBody body, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, ScopeStack scopeStack, HashMap localRegNames, List fullyQualifiedNames, int staticOperation, HashMap localRegAssigmentIps, HashMap> refs, boolean thisHasDefaultToPrimitive) throws InterruptedException { + public static List translateViaGraph(AbcIndexing abcIndex, String path, AVM2Code code, ABC abc, MethodBody body, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, ScopeStack scopeStack, HashMap localRegNames, HashMap localRegTypes, List fullyQualifiedNames, int staticOperation, HashMap localRegAssigmentIps, HashMap> refs, boolean thisHasDefaultToPrimitive) throws InterruptedException { AVM2Graph g = new AVM2Graph(abcIndex, code, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localRegNames, fullyQualifiedNames, localRegAssigmentIps, refs); AVM2LocalData localData = new AVM2LocalData(); @@ -644,7 +644,9 @@ public class AVM2Graph extends Graph { localData.scopeStack = scopeStack; localData.methodBody = body; localData.abc = abc; + localData.abcIndex = abcIndex; localData.localRegNames = localRegNames; + localData.localRegTypes = localRegTypes; localData.fullyQualifiedNames = fullyQualifiedNames; localData.scriptIndex = scriptIndex; localData.ip = 0; @@ -1505,11 +1507,11 @@ public class AVM2Graph extends Graph { List otherSide = new ArrayList<>(); if (leftReg > 0) { - switchedObject = new LocalRegAVM2Item(null, null, leftReg, null); + switchedObject = new LocalRegAVM2Item(null, null, leftReg, null, TypeItem.UNBOUNDED /*?*/); caseValuesMap = caseValuesMapRight; otherSide = caseValuesMapLeft; } else if (rightReg > 0) { - switchedObject = new LocalRegAVM2Item(null, null, rightReg, null); + switchedObject = new LocalRegAVM2Item(null, null, rightReg, null, TypeItem.UNBOUNDED /*?*/); otherSide = caseValuesMapRight; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphSource.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphSource.java index 1a415b378..b0bc1cf24 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphSource.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2GraphSource.java @@ -119,7 +119,7 @@ public class AVM2GraphSource extends GraphSource { List ret = new ArrayList<>(); ScopeStack newstack = ((AVM2LocalData) localData).scopeStack; Reference lineStartItem = new Reference<>(localData.lineStartInstruction); - ConvertOutput co = code.toSourceOutput(((AVM2LocalData) localData).setLocalPosToGetLocalPos, ((AVM2LocalData) localData).thisHasDefaultToPrimitive, lineStartItem, path, part, false, isStatic, scriptIndex, classIndex, localRegs, stack, newstack, abc, body, start, end, localRegNames, fullyQualifiedNames, new boolean[size()], localRegAssigmentIps, refs); + ConvertOutput co = code.toSourceOutput(((AVM2LocalData) localData).abcIndex, ((AVM2LocalData) localData).setLocalPosToGetLocalPos, ((AVM2LocalData) localData).thisHasDefaultToPrimitive, lineStartItem, path, part, false, isStatic, scriptIndex, classIndex, localRegs, stack, newstack, abc, body, start, end, localRegNames, ((AVM2LocalData) localData).localRegTypes, fullyQualifiedNames, new boolean[size()], localRegAssigmentIps, refs); localData.lineStartInstruction = lineStartItem.getVal(); ret.addAll(co.output); return ret; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/InstructionDefinition.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/InstructionDefinition.java index 2eab41426..3c06bb785 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/InstructionDefinition.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/InstructionDefinition.java @@ -36,6 +36,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.GlobalAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.NewActivationAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.ThisAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ExceptionAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.parser.script.AbcIndexing; import com.jpexs.decompiler.flash.abc.types.MethodBody; import com.jpexs.decompiler.flash.abc.types.Multiname; import com.jpexs.decompiler.flash.abc.types.traits.Trait; @@ -170,7 +171,7 @@ public abstract class InstructionDefinition implements Serializable { public void translate(AVM2LocalData localData, TranslateStack stack, AVM2Instruction ins, List output, String path) throws InterruptedException { } - public void translate(Map> setLocalPosToGetLocalPos, Reference lineStartItem, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2Instruction ins, List output, MethodBody body, ABC abc, HashMap localRegNames, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code, boolean thisHasDefaultToPrimitive) throws InterruptedException { + public void translate(AbcIndexing abcIndex, Map> setLocalPosToGetLocalPos, Reference lineStartItem, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, TranslateStack stack, ScopeStack scopeStack, AVM2Instruction ins, List output, MethodBody body, ABC abc, HashMap localRegNames, HashMap localRegTypes, List fullyQualifiedNames, String path, HashMap localRegsAssignmentIps, int ip, HashMap> refs, AVM2Code code, boolean thisHasDefaultToPrimitive) throws InterruptedException { AVM2LocalData localData = new AVM2LocalData(); localData.isStatic = isStatic; localData.scriptIndex = scriptIndex; @@ -180,7 +181,9 @@ public abstract class InstructionDefinition implements Serializable { localData.scopeStack = scopeStack; localData.methodBody = body; localData.abc = abc; + localData.abcIndex = abcIndex; localData.localRegNames = localRegNames; + localData.localRegTypes = localRegTypes; localData.fullyQualifiedNames = fullyQualifiedNames; localData.localRegAssignmentIps = localRegsAssignmentIps; localData.ip = ip; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/SetTypeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/SetTypeIns.java index c8fd59110..487cdcf31 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/SetTypeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/SetTypeIns.java @@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.ConvertAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.TypeItem; import com.jpexs.decompiler.graph.model.DuplicateItem; import java.util.List; @@ -59,7 +60,7 @@ public interface SetTypeIns { result.value = value; output.add(result); for (int i = 0; i < numDups; i++) { - stack.push(new LocalRegAVM2Item(null, localData.lineStartInstruction, regId, value)); + stack.push(new LocalRegAVM2Item(null, localData.lineStartInstruction, regId, value, localData.localRegTypes.containsKey(regId) ? localData.localRegTypes.get(regId) : TypeItem.UNBOUNDED)); } return; } else { @@ -74,7 +75,7 @@ public interface SetTypeIns { if (regId > -1 && AVM2Item.mustStayIntact2(insideDup.getNotCoerced())) { //hack output.add(result); - stack.push(new LocalRegAVM2Item(null, localData.lineStartInstruction, regId, value)); + stack.push(new LocalRegAVM2Item(null, localData.lineStartInstruction, regId, value, localData.localRegTypes.containsKey(regId) ? localData.localRegTypes.get(regId) : TypeItem.UNBOUNDED)); return; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallPropLexIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallPropLexIns.java index 7974dac8d..cdc2947d2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallPropLexIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallPropLexIns.java @@ -96,6 +96,13 @@ public class CallPropLexIns extends CallPropertyIns { break; } } + } else { + if (localData.abcIndex != null) { + GraphTargetItem receiverType = receiver.returnType(); + if (!receiverType.equals(TypeItem.UNBOUNDED)) { + type = localData.abcIndex.findPropertyCallType(localData.abc, receiverType, multiname.resolvedMultinameName, localData.abc.constants.getMultiname(multinameIndex).namespace_index,true, true); + } + } } stack.push(new CallPropertyAVM2Item(ins, localData.lineStartInstruction, false, receiver, multiname, args, type)); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallPropVoidIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallPropVoidIns.java index 6f882341e..529b54e86 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallPropVoidIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallPropVoidIns.java @@ -96,6 +96,13 @@ public class CallPropVoidIns extends InstructionDefinition { break; } } + } else { + if (localData.abcIndex != null) { + GraphTargetItem receiverType = receiver.returnType(); + if (!receiverType.equals(TypeItem.UNBOUNDED)) { + type = localData.abcIndex.findPropertyCallType(localData.abc, receiverType, multiname.resolvedMultinameName, localData.abc.constants.getMultiname(multinameIndex).namespace_index,true, true); + } + } } output.add(new CallPropertyAVM2Item(ins, localData.lineStartInstruction, true, receiver, multiname, args, type)); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallPropertyIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallPropertyIns.java index 83ff2e13a..3984eab37 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallPropertyIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/executing/CallPropertyIns.java @@ -93,9 +93,16 @@ public class CallPropertyIns extends InstructionDefinition { case "Number": case "String": type = new TypeItem(multiname.resolvedMultinameName); - break; + break; } } + } else { + if (localData.abcIndex != null) { + GraphTargetItem receiverType = receiver.returnType(); + if (!receiverType.equals(TypeItem.UNBOUNDED)) { + type = localData.abcIndex.findPropertyCallType(localData.abc, receiverType, multiname.resolvedMultinameName, localData.abc.constants.getMultiname(multinameIndex).namespace_index,true, true); + } + } } stack.push(new CallPropertyAVM2Item(ins, localData.lineStartInstruction, false, receiver, multiname, args, type)); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalTypeIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalTypeIns.java index f9291666b..35dcedfb5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalTypeIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/localregs/GetLocalTypeIns.java @@ -43,6 +43,7 @@ import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.ecma.Undefined; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.TypeItem; import com.jpexs.decompiler.graph.model.DuplicateItem; import java.util.List; @@ -167,8 +168,14 @@ public abstract class GetLocalTypeIns extends InstructionDefinition { } } } - - stack.push(new LocalRegAVM2Item(ins, localData.lineStartInstruction, regId, computedValue)); + GraphTargetItem type = TypeItem.UNBOUNDED; + + if (localData.localRegTypes.containsKey(regId)) { + type = localData.localRegTypes.get(regId); + } else if (computedValue != null) { + type = computedValue.returnType(); + } + stack.push(new LocalRegAVM2Item(ins, localData.lineStartInstruction, regId, computedValue, type)); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetLexIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetLexIns.java index 921cd96f9..fe7e85603 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetLexIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetLexIns.java @@ -27,7 +27,6 @@ import com.jpexs.decompiler.flash.abc.avm2.parser.script.PropertyAVM2Item; import com.jpexs.decompiler.flash.abc.types.Multiname; import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; -import com.jpexs.decompiler.graph.DottedChain; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; import com.jpexs.decompiler.graph.TypeItem; @@ -50,7 +49,7 @@ public class GetLexIns extends InstructionDefinition { int multinameIndex = ins.operands[0]; Multiname multiname = localData.getConstants().getMultiname(multinameIndex); String multinameStr = multiname.getName(localData.abc.constants, new ArrayList<>(), true, true); - GraphTargetItem slotType = TypeItem.UNBOUNDED; + GraphTargetItem slotType = null; for (Trait t : localData.methodBody.traits.traits) { if (t instanceof TraitSlotConst) { TraitSlotConst tsc = (TraitSlotConst) t; @@ -63,6 +62,27 @@ public class GetLexIns extends InstructionDefinition { } } } + + if (slotType == null) { + if (localData.abcIndex != null) { + String currentClassName = localData.classIndex == -1 ? null : localData.abc.instance_info.get(localData.classIndex).getName(localData.abc.constants).getNameWithNamespace(localData.abc.constants, true).toRawString(); + GraphTargetItem thisPropType = currentClassName == null ? TypeItem.UNBOUNDED : localData.abcIndex.findPropertyType(localData.abc, new TypeItem(currentClassName), multinameStr, localData.abc.constants.getMultiname(multinameIndex).namespace_index, true, true); + if (!thisPropType.equals(TypeItem.UNBOUNDED)) { + slotType = thisPropType; + } + + if (slotType == null) { + TypeItem ti = new TypeItem(multiname.getNameWithNamespace(localData.abc.constants, true)); + if (localData.abcIndex.findClass(ti) != null) { + slotType = ti; + } + } + } + } + + if (slotType == null) { + slotType = TypeItem.UNBOUNDED; + } stack.push(new GetLexAVM2Item(ins, localData.lineStartInstruction, multiname, localData.getConstants(), slotType)); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetPropertyIns.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetPropertyIns.java index 9cceb4423..a39a599ab 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetPropertyIns.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetPropertyIns.java @@ -26,6 +26,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; import com.jpexs.decompiler.flash.abc.avm2.model.FindPropertyAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.GetLexAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item; @@ -128,22 +129,55 @@ public class GetPropertyIns extends InstructionDefinition { } } - GraphTargetItem propertyType = TypeItem.UNBOUNDED; + GraphTargetItem type = null; String multinameStr = localData.abc.constants.getMultiname(multiname.multinameIndex).getName(localData.abc.constants, new ArrayList<>(), true, true); - - for (Trait t : localData.methodBody.traits.traits) { - if (t instanceof TraitSlotConst) { - TraitSlotConst tsc = (TraitSlotConst) t; - if (Objects.equals( - tsc.getName(localData.abc).getName(localData.abc.constants, new ArrayList<>(), true, true), - multinameStr - )) { - propertyType = PropertyAVM2Item.multinameToType(tsc.type_index, localData.abc.constants); - break; + if (obj instanceof FindPropertyAVM2Item) { + FindPropertyAVM2Item fprop = (FindPropertyAVM2Item) obj; + if (fprop.propertyName.equals(multiname)) { + for (Trait t : localData.methodBody.traits.traits) { + if (t instanceof TraitSlotConst) { + TraitSlotConst tsc = (TraitSlotConst) t; + if (Objects.equals( + tsc.getName(localData.abc).getName(localData.abc.constants, new ArrayList<>(), true, true), + multinameStr + )) { + type = PropertyAVM2Item.multinameToType(tsc.type_index, localData.abc.constants); + break; + } + } + } + + if (type == null) { + if (localData.abcIndex != null) { + String currentClassName = localData.classIndex == -1 ? null : localData.abc.instance_info.get(localData.classIndex).getName(localData.abc.constants).getNameWithNamespace(localData.abc.constants, true).toRawString(); + GraphTargetItem thisPropType = currentClassName == null ? TypeItem.UNBOUNDED : localData.abcIndex.findPropertyType(localData.abc, new TypeItem(currentClassName), multinameStr, localData.abc.constants.getMultiname(multinameIndex).namespace_index, true, true); + if (!thisPropType.equals(TypeItem.UNBOUNDED)) { + type = thisPropType; + } + + if (type == null) { + TypeItem ti = new TypeItem(localData.abc.constants.getMultiname(multinameIndex).getNameWithNamespace(localData.abc.constants, true)); + if (localData.abcIndex.findClass(ti) != null) { + type = ti; + } + } + } } } + } else { + if (localData.abcIndex != null) { + GraphTargetItem receiverType = obj.returnType(); + if (!receiverType.equals(TypeItem.UNBOUNDED)) { + type = localData.abcIndex.findPropertyType(localData.abc, receiverType, multiname.resolvedMultinameName, localData.abc.constants.getMultiname(multinameIndex).namespace_index,true, true); + } + } } - stack.push(new GetPropertyAVM2Item(ins, localData.lineStartInstruction, obj, multiname, propertyType)); + + if (type == null) { + type = TypeItem.UNBOUNDED; + } + + stack.push(new GetPropertyAVM2Item(ins, localData.lineStartInstruction, obj, multiname, type)); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/HasNext2Ins.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/HasNext2Ins.java index 9e53027dc..effd15ef8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/HasNext2Ins.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/HasNext2Ins.java @@ -25,6 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.HasNextAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.TranslateStack; +import com.jpexs.decompiler.graph.TypeItem; import java.util.List; /** @@ -43,8 +44,8 @@ public class HasNext2Ins extends InstructionDefinition { int indexReg = ins.operands[1]; //stack.push("_loc_" + objectReg + ".hasNext(cnt=_loc_" + indexReg + ")"); stack.push(new HasNextAVM2Item(ins, localData.lineStartInstruction, - new LocalRegAVM2Item(ins, localData.lineStartInstruction, indexReg, localData.localRegs.get(indexReg)), - new LocalRegAVM2Item(ins, localData.lineStartInstruction, objectReg, localData.localRegs.get(objectReg)) + new LocalRegAVM2Item(ins, localData.lineStartInstruction, indexReg, localData.localRegs.get(indexReg), TypeItem.UNBOUNDED /*?*/), + new LocalRegAVM2Item(ins, localData.lineStartInstruction, objectReg, localData.localRegs.get(objectReg), TypeItem.UNBOUNDED /*?*/) )); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/LocalRegAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/LocalRegAVM2Item.java index e13074690..b658da49f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/LocalRegAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/LocalRegAVM2Item.java @@ -40,11 +40,13 @@ public class LocalRegAVM2Item extends AVM2Item { public GraphTargetItem computedValue; + public GraphTargetItem type; + private final Object computedResult; - private boolean isCT = false; + private boolean isCT = false; - public LocalRegAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, int regIndex, GraphTargetItem computedValue) { + public LocalRegAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, int regIndex, GraphTargetItem computedValue, GraphTargetItem type) { super(instruction, lineStartIns, PRECEDENCE_PRIMARY); this.regIndex = regIndex; if (computedValue == null) { @@ -56,6 +58,7 @@ public class LocalRegAVM2Item extends AVM2Item { computedResult = null; } this.computedValue = computedValue; + this.type = type; } @Override @@ -131,10 +134,7 @@ public class LocalRegAVM2Item extends AVM2Item { @Override public GraphTargetItem returnType() { - if (computedValue != null) { - return computedValue.returnType(); - } - return TypeItem.UNBOUNDED; + return type; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetLocalAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetLocalAVM2Item.java index 868ba1b28..3c8c2dc2a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetLocalAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetLocalAVM2Item.java @@ -80,7 +80,7 @@ public class SetLocalAVM2Item extends AVM2Item implements SetTypeAVM2Item, Assig @Override public GraphTargetItem getObject() { - return new LocalRegAVM2Item(getInstruction(), getLineStartIns(), regIndex, null); + return new LocalRegAVM2Item(getInstruction(), getLineStartIns(), regIndex, null, value.returnType()); } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ThisAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ThisAVM2Item.java index 7e9ccdd58..883ec6d2d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ThisAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ThisAVM2Item.java @@ -95,7 +95,7 @@ public class ThisAVM2Item extends AVM2Item { @Override public GraphTargetItem returnType() { - return TypeItem.UNBOUNDED; + return new TypeItem(className); } @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 25a3bae04..fd18f2419 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 @@ -324,7 +324,7 @@ public class AVM2SourceGenerator implements SourceGenerator { AssignableAVM2Item.dupSetTemp(localData, this, tempVal2), ins(AVM2Instructions.PushWith) )); - localData.scopeStack.add(new LocalRegAVM2Item(null, null, tempVal2.getVal(), null)); + localData.scopeStack.add(new LocalRegAVM2Item(null, null, tempVal2.getVal(), null, new TypeItem("Object") /*?*/)); forBody.addAll(toInsList(item.value.toSource(localData, this))); List trueBody = new ArrayList<>(); trueBody.addAll(toInsList(AssignableAVM2Item.getTemp(localData, this, xmlListReg))); @@ -547,7 +547,7 @@ public class AVM2SourceGenerator implements SourceGenerator { ret.addAll(item.scope.toSource(localData, this)); Reference tempReg = new Reference<>(0); ret.addAll(AssignableAVM2Item.dupSetTemp(localData, this, tempReg)); - localData.scopeStack.add(new WithObjectAVM2Item(null, null, new LocalRegAVM2Item(null, null, tempReg.getVal(), null))); + localData.scopeStack.add(new WithObjectAVM2Item(null, null, new LocalRegAVM2Item(null, null, tempReg.getVal(), null, new TypeItem("Object") /*?*/))); ret.add(ins(AVM2Instructions.PushWith)); ret.addAll(generate(localData, item.items)); ret.add(ins(AVM2Instructions.PopScope)); @@ -842,7 +842,7 @@ public class AVM2SourceGenerator implements SourceGenerator { } } localData.catchesTempRegs.add(tempReg.getVal()); - localData.scopeStack.add(new LocalRegAVM2Item(null, null, tempReg.getVal(), null)); + localData.scopeStack.add(new LocalRegAVM2Item(null, null, tempReg.getVal(), null, new TypeItem("Object") /*?*/)); localData.catchesOpenedLoops.add(new ArrayList<>(localData.openedLoops)); catchCmd.addAll(generateToInsList(localData, item.catchCommands.get(c))); localData.catchesOpenedLoops.remove(localData.catchesOpenedLoops.size() - 1); @@ -1657,7 +1657,7 @@ public class AVM2SourceGenerator implements SourceGenerator { if (className != null) { String fullClassName = pkg.addWithSuffix(className).toRawString(); registerTypes.add(new TypeItem(fullClassName)); - localData.scopeStack.add(new LocalRegAVM2Item(null, null, registerNames.size(), null)); + localData.scopeStack.add(new LocalRegAVM2Item(null, null, registerNames.size(), null, new TypeItem(fullClassName))); registerNames.add("this"); registerLines.add(0); //? @@ -1704,7 +1704,7 @@ public class AVM2SourceGenerator implements SourceGenerator { registerLines.add(0); //? localData.activationReg = registerNames.size() - 1; registerTypes.add(new TypeItem("Object")); - localData.scopeStack.add(new LocalRegAVM2Item(null, null, localData.activationReg, null)); + localData.scopeStack.add(new LocalRegAVM2Item(null, null, localData.activationReg, null, new TypeItem("Object"))); } String mask = Configuration.registerNameFormat.get(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java index b62ec7bdc..0c32851ad 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java @@ -150,7 +150,8 @@ public final class AbcIndexing { hash = 17 * hash + Objects.hashCode(this.propName); hash = 17 * hash + Objects.hashCode(this.parent); hash = 17 * hash + this.propNsIndex; - hash = 17 * hash + System.identityHashCode(this.abc); + //? + //hash = 17 * hash + System.identityHashCode(this.abc); return hash; } @@ -172,7 +173,8 @@ public final class AbcIndexing { if (this.propNsIndex != other.propNsIndex) { return false; } - return (this.abc == other.abc); + return true; //? + //return (this.abc == other.abc); } } @@ -254,15 +256,18 @@ public final class AbcIndexing { public ABC abc; public GraphTargetItem returnType; + + public GraphTargetItem callReturnType; public ValueKind value; public GraphTargetItem objType; - public TraitIndex(Trait trait, ABC abc, GraphTargetItem type, ValueKind value, GraphTargetItem objType) { + public TraitIndex(Trait trait, ABC abc, GraphTargetItem type, GraphTargetItem callType, ValueKind value, GraphTargetItem objType) { this.trait = trait; this.abc = abc; this.returnType = type; + this.callReturnType = callType; this.value = value; this.objType = objType; } @@ -299,7 +304,7 @@ public final class AbcIndexing { private final Map classNsProperties = new HashMap<>(); private final Map scriptProperties = new HashMap<>(); - + public ClassIndex findClass(GraphTargetItem cls) { if (!classes.containsKey(cls)) { if (parent == null) { @@ -309,6 +314,22 @@ public final class AbcIndexing { } return classes.get(cls); } + + public GraphTargetItem findPropertyType(ABC abc, GraphTargetItem cls, String propName, int ns, boolean findStatic, boolean findInstance) { + TraitIndex traitIndex = findProperty(new PropertyDef(propName, cls, abc, ns), findStatic, findInstance); + if (traitIndex == null) { + return TypeItem.UNBOUNDED; + } + return traitIndex.returnType; + } + + public GraphTargetItem findPropertyCallType(ABC abc, GraphTargetItem cls, String propName, int ns, boolean findStatic, boolean findInstance) { + TraitIndex traitIndex = findProperty(new PropertyDef(propName, cls, abc, ns), findStatic, findInstance); + if (traitIndex == null) { + return TypeItem.UNBOUNDED; + } + return traitIndex.callReturnType; + } public TraitIndex findScriptProperty(DottedChain ns) { return findScriptProperty(ns.getLast(), ns.getWithoutLast()); @@ -354,8 +375,15 @@ public final class AbcIndexing { return null; } - public TraitIndex findProperty(PropertyDef prop, boolean findStatic, boolean findInstance) { - + public TraitIndex findProperty(PropertyDef prop, boolean findStatic, boolean findInstance) { + /*System.out.println("searching " + prop); + for(PropertyDef p:instanceProperties.keySet()) { + if (p.parent.equals(new TypeItem("MyClass"))) { + System.out.println("- "+p); + } + } + System.out.println("-----------");*/ + //search all static first if (findStatic && classProperties.containsKey(prop)) { if (!classProperties.containsKey(prop)) { @@ -383,7 +411,7 @@ public final class AbcIndexing { return instanceProperties.get(prop); } } - + //now search parent class AbcIndexing.ClassIndex ci = findClass(prop.parent); if (ci != null && ci.parent != null && (prop.abc == null || prop.propNsIndex == 0)) { @@ -395,9 +423,19 @@ public final class AbcIndexing { return pti; } //parent public - return findProperty(new PropertyDef(prop.propName, new TypeItem(parentClass), null, 0), findStatic, findInstance); + pti = findProperty(new PropertyDef(prop.propName, new TypeItem(parentClass), null, 0), findStatic, findInstance); + if (pti != null) { + return pti; + } } - + + if (parent != null) { + TraitIndex pti = parent.findProperty(prop, findStatic, findInstance); + if (pti != null) { + return pti; + } + } + return null; } @@ -418,6 +456,29 @@ public final class AbcIndexing { } } + private static GraphTargetItem getTraitCallReturnType(ABC abc, Trait t) { + if (t instanceof TraitSlotConst) { + return TypeItem.UNBOUNDED; + } + if (t instanceof TraitMethodGetterSetter) { + TraitMethodGetterSetter tmgs = (TraitMethodGetterSetter) t; + if (tmgs.kindType == Trait.TRAIT_GETTER) { + return TypeItem.UNBOUNDED; + } + if (tmgs.kindType == Trait.TRAIT_SETTER) { + return TypeItem.UNBOUNDED; + } + return PropertyAVM2Item.multinameToType(abc.method_info.get(tmgs.method_info).ret_type, abc.constants); + } + + if (t instanceof TraitFunction) { + TraitFunction tf = (TraitFunction) t; + return PropertyAVM2Item.multinameToType(abc.method_info.get(tf.method_info).ret_type, abc.constants); + + } + return TypeItem.UNBOUNDED; + } + private static GraphTargetItem getTraitReturnType(ABC abc, Trait t) { if (t instanceof TraitSlotConst) { TraitSlotConst tsc = (TraitSlotConst) t; @@ -438,7 +499,9 @@ public final class AbcIndexing { return TypeItem.UNBOUNDED; } } - } + return new TypeItem(DottedChain.FUNCTION); + } + if (t instanceof TraitFunction) { return new TypeItem(DottedChain.FUNCTION); } @@ -454,12 +517,12 @@ public final class AbcIndexing { } if (map != null) { PropertyDef dp = new PropertyDef(t.getName(abc).getName(abc.constants, new ArrayList<>() /*?*/, true, false), multinameToType(name_index, abc.constants), abc, abc.constants.getMultiname(t.name_index).namespace_index); - map.put(dp, new TraitIndex(t, abc, getTraitReturnType(abc, t), propValue, multinameToType(name_index, abc.constants))); + map.put(dp, new TraitIndex(t, abc, getTraitReturnType(abc, t), getTraitCallReturnType(abc, t), propValue, multinameToType(name_index, abc.constants))); } if (mapNs != null) { Multiname m = abc.constants.getMultiname(t.name_index); PropertyNsDef ndp = new PropertyNsDef(t.getName(abc).getName(abc.constants, new ArrayList<>() /*?*/, true, true/*FIXME ???*/), m == null || m.namespace_index == 0 ? DottedChain.EMPTY : m.getNamespace(abc.constants).getName(abc.constants), abc, m == null ? 0 : m.namespace_index); - TraitIndex ti = new TraitIndex(t, abc, getTraitReturnType(abc, t), propValue, multinameToType(name_index, abc.constants)); + TraitIndex ti = new TraitIndex(t, abc, getTraitReturnType(abc, t), getTraitCallReturnType(abc, t), propValue, multinameToType(name_index, abc.constants)); if (!mapNs.containsKey(ndp)) { mapNs.put(ndp, ti); } 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 a11476162..af60a48a7 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 @@ -1525,7 +1525,7 @@ public class ActionScript3Parser { ParsedSymbol ss2 = lex(); if (ss2.type == SymbolType.PARENT_OPEN) { List args = call(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables); - ret = new ConstructSuperAVM2Item(null, null, new LocalRegAVM2Item(null, null, 0, null), args); + ret = new ConstructSuperAVM2Item(null, null, new LocalRegAVM2Item(null, null, 0, null, new TypeItem("Object") /*?*/), args); } else {//no costructor call, but it could be calling parent methods... => handle in expression lexer.pushback(ss2); lexer.pushback(s);