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 61e9cb435..d277042ec 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 @@ -201,6 +201,8 @@ import com.jpexs.decompiler.flash.abc.avm2.model.SetPropertyAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.SetSlotAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.WithAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.clauses.DeclarationAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForEachInAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.clauses.ForInAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.parser.AVM2ParseException; import com.jpexs.decompiler.flash.abc.avm2.parser.pcode.ASM3Parser; import com.jpexs.decompiler.flash.abc.avm2.parser.script.PropertyAVM2Item; @@ -220,6 +222,7 @@ import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.helpers.HilightedTextWriter; +import com.jpexs.decompiler.graph.Block; import com.jpexs.decompiler.graph.Graph; import com.jpexs.decompiler.graph.GraphPart; import com.jpexs.decompiler.graph.GraphSourceItem; @@ -1650,6 +1653,78 @@ public class AVM2Code implements Cloneable { ignoredIns = new ArrayList<>(); } + private void injectDeclarations(List list, boolean[] declaredRegisters, List declaredSlots, ABC abc, MethodBody body) { + //List nowdeclaredRegs=new ArrayList<>(); + //List nowdeclaredSlots=new ArrayList<>(); + for (int i = 0; i < list.size(); i++) { + GraphTargetItem ti = list.get(i); + if (ti instanceof ForEachInAVM2Item) { + ForEachInAVM2Item fei = (ForEachInAVM2Item) ti; + if (fei.expression.object instanceof LocalRegAVM2Item) { + int reg = ((LocalRegAVM2Item) fei.expression.object).regIndex; + if (!declaredRegisters[reg]) { + fei.expression.object = new DeclarationAVM2Item(fei.expression.object); + declaredRegisters[reg] = true; + //nowdeclaredRegs.add(reg); + } + } + } + if (ti instanceof ForInAVM2Item) { + ForInAVM2Item fi = (ForInAVM2Item) ti; + if (fi.expression.object instanceof LocalRegAVM2Item) { + int reg = ((LocalRegAVM2Item) fi.expression.object).regIndex; + if (!declaredRegisters[reg]) { + fi.expression.object = new DeclarationAVM2Item(fi.expression.object); + declaredRegisters[reg] = true; + //nowdeclaredRegs.add(reg); + } + } + } + if (ti instanceof Block) { + Block bl = (Block) ti; + for (List s : bl.getSubs()) { + injectDeclarations(s, declaredRegisters, declaredSlots, abc, body); + } + } + if (ti instanceof SetLocalAVM2Item) { + int reg = ((SetLocalAVM2Item) ti).regIndex; + if (!declaredRegisters[reg]) { + list.set(i, new DeclarationAVM2Item(ti)); + declaredRegisters[reg] = true; + //nowdeclaredRegs.add(reg); + } + } + if (ti instanceof SetSlotAVM2Item) { + SetSlotAVM2Item ssti = (SetSlotAVM2Item) ti; + Slot sl = new Slot(ssti.scope, ssti.slotName); + if (!declaredSlots.contains(sl)) { + GraphTargetItem type = TypeItem.UNBOUNDED; + for (int t = 0; t < body.traits.traits.size(); t++) { + if (body.traits.traits.get(t).getName(abc) == sl.multiname) { + if (body.traits.traits.get(t) instanceof TraitSlotConst) { + type = PropertyAVM2Item.multinameToType(((TraitSlotConst) body.traits.traits.get(t)).type_index, abc.constants); + } + } + } + list.set(i, new DeclarationAVM2Item(ti, type)); + declaredSlots.add(sl); + //nowdeclaredSlots.add(sl); + } + } + } + + + /* + //undeclare registers at the end of the block? + for(int reg:nowdeclaredRegs){ + declaredRegisters[reg] = false; + } + + for(Slot s:nowdeclaredSlots){ + declaredSlots.remove(s); + }*/ + } + public List toGraphTargetItems(String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, AVM2ConstantPool constants, List method_info, MethodBody body, HashMap localRegNames, ScopeStack scopeStack, boolean isStaticInitializer, List fullyQualifiedNames, Traits initTraits, int staticOperation, HashMap localRegAssigmentIps, HashMap> refs) throws InterruptedException { initToSource(); List list; @@ -1709,38 +1784,8 @@ public class AVM2Code implements Cloneable { return list; } } - //Declarations - boolean[] declaredRegisters = new boolean[regCount]; - for (int b = 0; b < declaredRegisters.length; b++) { - declaredRegisters[b] = false; - } - List declaredSlots = new ArrayList<>(); - for (int i = 0; i < list.size(); i++) { - GraphTargetItem ti = list.get(i); - if (ti instanceof SetLocalAVM2Item) { - int reg = ((SetLocalAVM2Item) ti).regIndex; - if (!declaredRegisters[reg]) { - list.set(i, new DeclarationAVM2Item(ti)); - declaredRegisters[reg] = true; - } - } - if (ti instanceof SetSlotAVM2Item) { - SetSlotAVM2Item ssti = (SetSlotAVM2Item) ti; - Slot sl = new Slot(ssti.scope, ssti.slotName); - if (!declaredSlots.contains(sl)) { - GraphTargetItem type = TypeItem.UNBOUNDED; - for (int t = 0; t < body.traits.traits.size(); t++) { - if (body.traits.traits.get(t).getName(abc) == sl.multiname) { - if (body.traits.traits.get(t) instanceof TraitSlotConst) { - type = PropertyAVM2Item.multinameToType(((TraitSlotConst) body.traits.traits.get(t)).type_index, abc.constants); - } - } - } - list.set(i, new DeclarationAVM2Item(ti, type)); - declaredSlots.add(sl); - } - } - } + //Declarations + injectDeclarations(list, new boolean[regCount], new ArrayList(), abc, body); int lastPos = list.size() - 1; if (lastPos < 0) { 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 7db686022..d157e87ba 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 @@ -667,6 +667,7 @@ public class AVM2Graph extends Graph { WhileItem w = (WhileItem) loopItem; if ((!w.expression.isEmpty()) && (w.expression.get(w.expression.size() - 1) instanceof HasNextAVM2Item)) { + HasNextAVM2Item hn=(HasNextAVM2Item)w.expression.get(w.expression.size() - 1); if (((HasNextAVM2Item) w.expression.get(w.expression.size() - 1)).collection != null) { if (((HasNextAVM2Item) w.expression.get(w.expression.size() - 1)).collection.getNotCoerced().getThroughRegister() instanceof FilteredCheckAVM2Item) { //GraphTargetItem gti = ((HasNextAVM2Item) ((HasNextAVM2Item) w.expression.get(w.expression.size() - 1))).collection.getNotCoerced().getThroughRegister(); @@ -701,9 +702,9 @@ public class AVM2Graph extends Graph { SetTypeAVM2Item sti = (SetTypeAVM2Item) w.commands.remove(0); GraphTargetItem gti = sti.getValue().getNotCoerced(); if (gti instanceof NextValueAVM2Item) { - return new ForEachInAVM2Item(w.src, w.loop, new InAVM2Item(null, sti.getObject(), ((HasNextAVM2Item) w.expression.get(w.expression.size() - 1)).collection), w.commands); + return new ForEachInAVM2Item(w.src, w.loop, new InAVM2Item(hn.instruction, sti.getObject(), ((HasNextAVM2Item) w.expression.get(w.expression.size() - 1)).collection), w.commands); } else if (gti instanceof NextNameAVM2Item) { - return new ForInAVM2Item(w.src, w.loop, new InAVM2Item(null, sti.getObject(), ((HasNextAVM2Item) w.expression.get(w.expression.size() - 1)).collection), w.commands); + return new ForInAVM2Item(w.src, w.loop, new InAVM2Item(hn.instruction,sti.getObject(), ((HasNextAVM2Item) w.expression.get(w.expression.size() - 1)).collection), w.commands); } } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/AVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/AVM2Item.java index a3501314b..12306b89f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/AVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/AVM2Item.java @@ -40,6 +40,9 @@ public abstract class AVM2Item extends GraphTargetItem { public AVM2Item(GraphSourceItem instruction, int precedence) { super(instruction, precedence); + if(instruction instanceof AVM2Instruction){ + this.instruction = (AVM2Instruction)instruction; + } } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/GetSlotAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/GetSlotAVM2Item.java index 7e783c250..0fd34cc9c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/GetSlotAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/GetSlotAVM2Item.java @@ -39,11 +39,22 @@ public class GetSlotAVM2Item extends AVM2Item { if (slotName == null) { return writer.append("/*UnknownSlot*/"); } - srcData.put("localName", slotName.getName(localData.constantsAvm2, localData.fullyQualifiedNames, false)); + srcData.put("localName", getNameAsStr(localData)); return writer.append(slotName.getName(localData.constantsAvm2, localData.fullyQualifiedNames, false)); } + public String getNameAsStr(LocalData localData){ + return slotName.getName(localData.constantsAvm2, localData.fullyQualifiedNames, false); + } + + public GraphTextWriter getName(GraphTextWriter writer, LocalData localData) { + if (slotName == null) { + return writer.append("/*UnknownSlot*/"); + } + return writer.append(slotName.getName(localData.constantsAvm2, localData.fullyQualifiedNames, false)); + } + @Override public GraphTargetItem returnType() { return TypeItem.UNBOUNDED; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetSlotAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetSlotAVM2Item.java index 525c8e0b0..bd3655dd1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetSlotAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetSlotAVM2Item.java @@ -55,18 +55,7 @@ public class SetSlotAVM2Item extends AVM2Item implements SetTypeAVM2Item, Assign return slotName.getName(localData.constantsAvm2, localData.fullyQualifiedNames, false); } - public GraphTextWriter getName(GraphTextWriter writer, LocalData localData) { - /*ret = scope.toString(constants, localRegNames) + "."; - if (!(scope instanceof NewActivationAVM2Item)) { - ret = scope.toString(constants, localRegNames) + "."; - } - if (scope instanceof LocalRegAVM2Item) { - if (((LocalRegAVM2Item) scope).computedValue != null) { - if (((LocalRegAVM2Item) scope).computedValue instanceof NewActivationAVM2Item) { - ret = ""; - } - } - }*/ + public GraphTextWriter getName(GraphTextWriter writer, LocalData localData) { if (slotName == null) { return writer.append("/*UnknownSlot*/"); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/clauses/DeclarationAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/clauses/DeclarationAVM2Item.java index 53facbd52..6006cc7c5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/clauses/DeclarationAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/clauses/DeclarationAVM2Item.java @@ -20,6 +20,8 @@ import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.CoerceAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.ConvertAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.GetSlotAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.SetLocalAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.SetSlotAVM2Item; import com.jpexs.decompiler.flash.abc.types.InstanceInfo; @@ -52,6 +54,25 @@ public class DeclarationAVM2Item extends AVM2Item { @Override public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { + if(assignment instanceof LocalRegAVM2Item){ //for..in + LocalRegAVM2Item lti=(LocalRegAVM2Item)assignment; + String localName = localRegName(localData.localRegNames, lti.regIndex); + srcData.put("localName",localName); + srcData.put("declaration", "true"); + writer.append("var "); + writer.append(localName); + return writer; + } + + if(assignment instanceof GetSlotAVM2Item){ //for..in + GetSlotAVM2Item sti=(GetSlotAVM2Item)assignment; + srcData.put("localName",sti.getNameAsStr(localData)); + srcData.put("declaration", "true"); + writer.append("var "); + sti.getName(writer, localData); + return writer; + } + if (assignment instanceof SetLocalAVM2Item) { SetLocalAVM2Item lti = (SetLocalAVM2Item) assignment; String localName = localRegName(localData.localRegNames, lti.regIndex); 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 f3d9c47b5..298dc6109 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 @@ -284,8 +284,10 @@ public class MethodInfo { pdata.put("localName", localRegNames.get(i + 1)); //assuming it is a slot writer.hilightSpecial(IdentifiersDeobfuscation.printIdentifier(true,localRegNames.get(i + 1)),"paramname",i,pdata); } else if ((paramNames.length > i) && (paramNames[i] != 0) && Configuration.paramNamesEnable.get()) { + pdata.put("localName", constants.getString(paramNames[i])); writer.hilightSpecial(IdentifiersDeobfuscation.printIdentifier(true,constants.getString(paramNames[i])),"paramname",i,pdata); } else { + pdata.put("localName","param"+(i+1)); writer.hilightSpecial("param" + (i + 1),"paramname",i,pdata); } writer.appendNoHilight(":"); @@ -314,11 +316,11 @@ public class MethodInfo { } else { restName = "rest"; } - restAdd += restName; pdata=new HashMap<>(); pdata.put("declaration", "true"); - pdata.put("localName",restName); - writer.hilightSpecial(restAdd, "flag.NEED_REST",0,pdata); + pdata.put("localName",restName); + writer.append(restAdd); + writer.hilightSpecial(restName, "flag.NEED_REST",0,pdata); } return writer; }