Issue #539 For(each)..in declaration fixed

Goto parameter declaration fixed
This commit is contained in:
Jindra Petřík
2014-11-09 09:02:05 +01:00
parent 806cd640f8
commit 7f4672e43b
7 changed files with 122 additions and 50 deletions

View File

@@ -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<GraphTargetItem> list, boolean[] declaredRegisters, List<Slot> declaredSlots, ABC abc, MethodBody body) {
//List<Integer> nowdeclaredRegs=new ArrayList<>();
//List<Slot> 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<GraphTargetItem> 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<GraphTargetItem> toGraphTargetItems(String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, AVM2ConstantPool constants, List<MethodInfo> method_info, MethodBody body, HashMap<Integer, String> localRegNames, ScopeStack scopeStack, boolean isStaticInitializer, List<String> fullyQualifiedNames, Traits initTraits, int staticOperation, HashMap<Integer, Integer> localRegAssigmentIps, HashMap<Integer, List<Integer>> refs) throws InterruptedException {
initToSource();
List<GraphTargetItem> 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<Slot> 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<Slot>(), abc, body);
int lastPos = list.size() - 1;
if (lastPos < 0) {

View File

@@ -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);
}
}
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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*/");
}

View File

@@ -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);

View File

@@ -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;
}