mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-10 20:22:46 +00:00
for (each) in
This commit is contained in:
@@ -1651,9 +1651,6 @@ public class AVM2Code implements Cloneable {
|
||||
Set<Integer> usages = setLocalPosToGetLocalPos.get(ip);
|
||||
|
||||
if (usages.size() == 1 && (usages.iterator().next().equals(ip + 1)) && (insAfter.definition instanceof GetLocalTypeIns) && (((GetLocalTypeIns) insAfter.definition).getRegisterId(insAfter) == ((SetLocalTypeIns) ins.definition).getRegisterId(ins))) {
|
||||
/*GraphTargetItem before = stack.peek();
|
||||
ins.definition.translate(setLocalPosToGetLocalPos, lineStartItem, isStatic, scriptIndex, classIndex, localRegs, stack, scopeStack, ins, output, body, abc, localRegNames, fullyQualifiedNames, path, localRegAssigmentIps, ip, refs, this, thisHasDefaultToPrimitive);
|
||||
stack.push(before);*/
|
||||
ip += 2;
|
||||
continue iploop;
|
||||
} else {
|
||||
|
||||
@@ -27,10 +27,17 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.debug.DebugLineIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.IfStrictEqIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.JumpIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.jumps.LookupSwitchIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.DecLocalIIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.DecLocalIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocalTypeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.IncLocalIIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.IncLocalIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.KillIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalTypeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.HasNext2Ins;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnValueIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.DecLocalPIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other2.IncLocalPIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.FilteredCheckAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.HasNextAVM2Item;
|
||||
@@ -161,8 +168,28 @@ public class AVM2Graph extends Graph {
|
||||
registerToLastSetLocalPos.put(regId, ip);
|
||||
setLocalPosToGetLocalPos.put(ip, new TreeSet<>());
|
||||
}
|
||||
List<Integer> usedRegs = new ArrayList<>();
|
||||
if (ins.definition instanceof GetLocalTypeIns) {
|
||||
int regId = ((GetLocalTypeIns) ins.definition).getRegisterId(ins);
|
||||
usedRegs.add(regId);
|
||||
}
|
||||
if ((ins.definition instanceof IncLocalIns)
|
||||
|| (ins.definition instanceof IncLocalIIns)
|
||||
|| (ins.definition instanceof IncLocalPIns)
|
||||
|| (ins.definition instanceof DecLocalIns)
|
||||
|| (ins.definition instanceof DecLocalIIns)
|
||||
|| (ins.definition instanceof DecLocalPIns)) {
|
||||
usedRegs.add(ins.operands[0]);
|
||||
}
|
||||
if ((ins.definition instanceof IncLocalPIns)
|
||||
|| (ins.definition instanceof DecLocalPIns)) {
|
||||
usedRegs.add(ins.operands[1]);
|
||||
}
|
||||
if (ins.definition instanceof HasNext2Ins) {
|
||||
usedRegs.add(ins.operands[0]);
|
||||
usedRegs.add(ins.operands[1]);
|
||||
}
|
||||
for (int regId : usedRegs) {
|
||||
if (registerToLastSetLocalPos.containsKey(regId)) {
|
||||
int setLocalPos = registerToLastSetLocalPos.get(regId);
|
||||
setLocalPosToGetLocalPos.get(setLocalPos).add(ip);
|
||||
@@ -564,7 +591,7 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
ret = new ArrayList<>();
|
||||
ret.addAll(output);
|
||||
GraphTargetItem lop = checkLoop(part, stopPart, loops);
|
||||
GraphTargetItem lop = checkLoop(new ArrayList<GraphTargetItem>(), part, stopPart, loops);
|
||||
if (lop == null) {
|
||||
TranslateStack st = (TranslateStack) stack.clone();
|
||||
st.clear();
|
||||
@@ -777,7 +804,7 @@ public class AVM2Graph extends Graph {
|
||||
List<List<GraphTargetItem>> caseCommands = new ArrayList<>();
|
||||
GraphPart next = breakPart;
|
||||
|
||||
GraphTargetItem ti = checkLoop(next, stopPart, loops);
|
||||
GraphTargetItem ti = checkLoop(new ArrayList<GraphTargetItem>() /*??*/, next, stopPart, loops);
|
||||
|
||||
//create switch as new loop break command detection to work
|
||||
currentLoop = new Loop(loops.size(), null, next);
|
||||
@@ -964,7 +991,7 @@ public class AVM2Graph extends Graph {
|
||||
|
||||
|
||||
@Override
|
||||
protected GraphTargetItem checkLoop(LoopItem loopItem, BaseLocalData localData, List<Loop> loops) {
|
||||
protected GraphTargetItem checkLoop(List<GraphTargetItem> output, LoopItem loopItem, BaseLocalData localData, List<Loop> loops) {
|
||||
AVM2LocalData aLocalData = (AVM2LocalData) localData;
|
||||
if (loopItem instanceof WhileItem) {
|
||||
WhileItem w = (WhileItem) loopItem;
|
||||
@@ -1007,10 +1034,97 @@ public class AVM2Graph extends Graph {
|
||||
if (w.commands.get(0) instanceof SetTypeAVM2Item) {
|
||||
SetTypeAVM2Item sti = (SetTypeAVM2Item) w.commands.remove(0);
|
||||
GraphTargetItem gti = sti.getValue().getNotCoerced();
|
||||
GraphTargetItem varName = sti.getObject();
|
||||
GraphTargetItem collection = hn.obj;
|
||||
|
||||
if (hn.obj instanceof LocalRegAVM2Item) {
|
||||
int objRegIndex = ((LocalRegAVM2Item) hn.obj).regIndex;
|
||||
for (int i = output.size() - 2 /*last is loop*/; i >= 0; i--) {
|
||||
if (output.get(i) instanceof SetLocalAVM2Item) {
|
||||
SetLocalAVM2Item setLocal = (SetLocalAVM2Item) output.get(i);
|
||||
if (setLocal.regIndex == objRegIndex) {
|
||||
int setLocalIp = aLocalData.code.adr2pos(setLocal.getSrc().getAddress());
|
||||
Set<Integer> objUsages = new HashSet<>(aLocalData.setLocalPosToGetLocalPos.get(setLocalIp));
|
||||
int hnUsageIp = aLocalData.code.adr2pos(hn.getSrc().getAddress());
|
||||
objUsages.remove(hnUsageIp);
|
||||
|
||||
if (gti instanceof NextValueAVM2Item) {
|
||||
NextValueAVM2Item nextVal = (NextValueAVM2Item) gti;
|
||||
if (nextVal.obj instanceof LocalRegAVM2Item) {
|
||||
LocalRegAVM2Item nextValObjReg = (LocalRegAVM2Item) nextVal.obj;
|
||||
if (nextValObjReg.regIndex == objRegIndex) {
|
||||
int nextValUsage = aLocalData.code.adr2pos(nextValObjReg.getSrc().getAddress());
|
||||
objUsages.remove(nextValUsage);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gti instanceof NextNameAVM2Item) {
|
||||
NextNameAVM2Item nextName = (NextNameAVM2Item) gti;
|
||||
if (nextName.obj instanceof LocalRegAVM2Item) {
|
||||
LocalRegAVM2Item nextValObjReg = (LocalRegAVM2Item) nextName.obj;
|
||||
if (nextValObjReg.regIndex == objRegIndex) {
|
||||
int nextNameUsage = aLocalData.code.adr2pos(nextValObjReg.getSrc().getAddress());
|
||||
objUsages.remove(nextNameUsage);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (objUsages.isEmpty()) {
|
||||
output.remove(i);
|
||||
collection = setLocal.value;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hn.index instanceof LocalRegAVM2Item) {
|
||||
int indexRegIndex = ((LocalRegAVM2Item) hn.index).regIndex;
|
||||
for (int i = output.size() - 2 /*last is loop*/; i >= 0; i--) {
|
||||
if (output.get(i) instanceof SetLocalAVM2Item) {
|
||||
SetLocalAVM2Item setLocal = (SetLocalAVM2Item) output.get(i);
|
||||
if (setLocal.regIndex == indexRegIndex) {
|
||||
int setLocalIp = aLocalData.code.adr2pos(setLocal.getSrc().getAddress());
|
||||
Set<Integer> objUsages = new HashSet<>(aLocalData.setLocalPosToGetLocalPos.get(setLocalIp));
|
||||
int hnUsageIp = aLocalData.code.adr2pos(hn.getSrc().getAddress());
|
||||
objUsages.remove(hnUsageIp);
|
||||
|
||||
if (gti instanceof NextValueAVM2Item) {
|
||||
NextValueAVM2Item nextVal = (NextValueAVM2Item) gti;
|
||||
if (nextVal.index instanceof LocalRegAVM2Item) {
|
||||
LocalRegAVM2Item nextValIndexReg = (LocalRegAVM2Item) nextVal.index;
|
||||
if (nextValIndexReg.regIndex == indexRegIndex) {
|
||||
int nextValUsage = aLocalData.code.adr2pos(nextValIndexReg.getSrc().getAddress());
|
||||
objUsages.remove(nextValUsage);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gti instanceof NextNameAVM2Item) {
|
||||
NextNameAVM2Item nextName = (NextNameAVM2Item) gti;
|
||||
if (nextName.index instanceof LocalRegAVM2Item) {
|
||||
LocalRegAVM2Item nextValIndexReg = (LocalRegAVM2Item) nextName.index;
|
||||
if (nextValIndexReg.regIndex == indexRegIndex) {
|
||||
int nextNameUsage = aLocalData.code.adr2pos(nextValIndexReg.getSrc().getAddress());
|
||||
objUsages.remove(nextNameUsage);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (objUsages.isEmpty()) {
|
||||
output.remove(i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (gti instanceof NextValueAVM2Item) {
|
||||
return new ForEachInAVM2Item(w.getSrc(), w.getLineStartItem(), w.loop, new InAVM2Item(hn.getInstruction(), hn.getLineStartIns(), sti.getObject(), ((HasNextAVM2Item) w.expression.get(w.expression.size() - 1)).obj), w.commands);
|
||||
return new ForEachInAVM2Item(w.getSrc(), w.getLineStartItem(), w.loop, new InAVM2Item(hn.getInstruction(), hn.getLineStartIns(), varName, collection), w.commands);
|
||||
} else if (gti instanceof NextNameAVM2Item) {
|
||||
return new ForInAVM2Item(w.getSrc(), w.getLineStartItem(), w.loop, new InAVM2Item(hn.getInstruction(), hn.getLineStartIns(), sti.getObject(), ((HasNextAVM2Item) w.expression.get(w.expression.size() - 1)).obj), w.commands);
|
||||
return new ForInAVM2Item(w.getSrc(), w.getLineStartItem(), w.loop, new InAVM2Item(hn.getInstruction(), hn.getLineStartIns(), varName, collection), w.commands);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.abc.avm2.instructions.other;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
@@ -41,7 +42,10 @@ public class HasNext2Ins extends InstructionDefinition {
|
||||
int objectReg = ins.operands[0];
|
||||
int indexReg = ins.operands[1];
|
||||
//stack.push("_loc_" + objectReg + ".hasNext(cnt=_loc_" + indexReg + ")");
|
||||
//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))
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -34,9 +34,9 @@ import java.util.List;
|
||||
*/
|
||||
public class NextNameAVM2Item extends AVM2Item {
|
||||
|
||||
GraphTargetItem index;
|
||||
public GraphTargetItem index;
|
||||
|
||||
GraphTargetItem obj;
|
||||
public GraphTargetItem obj;
|
||||
|
||||
public NextNameAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem index, GraphTargetItem obj) {
|
||||
super(instruction, lineStartIns, NOPRECEDENCE);
|
||||
|
||||
@@ -34,9 +34,9 @@ import java.util.List;
|
||||
*/
|
||||
public class NextValueAVM2Item extends AVM2Item {
|
||||
|
||||
GraphTargetItem index;
|
||||
public GraphTargetItem index;
|
||||
|
||||
GraphTargetItem obj;
|
||||
public GraphTargetItem obj;
|
||||
|
||||
public NextValueAVM2Item(GraphSourceItem instruction, GraphSourceItem lineStartIns, GraphTargetItem index, GraphTargetItem obj) {
|
||||
super(instruction, lineStartIns, NOPRECEDENCE);
|
||||
|
||||
@@ -471,7 +471,7 @@ public class ActionGraph extends Graph {
|
||||
List<List<GraphTargetItem>> caseCommands = new ArrayList<>();
|
||||
GraphPart next = breakPart;
|
||||
|
||||
GraphTargetItem ti = checkLoop(next, stopPart, loops);
|
||||
GraphTargetItem ti = checkLoop(new ArrayList<GraphTargetItem>(), next, stopPart, loops);
|
||||
|
||||
//create switch as new loop break command detection to work
|
||||
currentLoop = new Loop(loops.size(), null, next);
|
||||
|
||||
@@ -1460,7 +1460,7 @@ public class Graph {
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected GraphTargetItem checkLoop(GraphPart part, List<GraphPart> stopPart, List<Loop> loops) {
|
||||
protected GraphTargetItem checkLoop(List<GraphTargetItem> output, GraphPart part, List<GraphPart> stopPart, List<Loop> loops) {
|
||||
if (stopPart.contains(part)) {
|
||||
return null;
|
||||
}
|
||||
@@ -1817,7 +1817,7 @@ public class Graph {
|
||||
return printGraph(foundGotos, gotoTargets, partCodes, partCodePos, new HashSet<>(), localData, stack, allParts, parent, part, stopPart, loops, null, staticOperation, path, 0);
|
||||
}
|
||||
|
||||
protected GraphTargetItem checkLoop(LoopItem loopItem, BaseLocalData localData, List<Loop> loops) {
|
||||
protected GraphTargetItem checkLoop(List<GraphTargetItem> output, LoopItem loopItem, BaseLocalData localData, List<Loop> loops) {
|
||||
return loopItem;
|
||||
}
|
||||
|
||||
@@ -2927,7 +2927,7 @@ public class Graph {
|
||||
}
|
||||
currentLoop.phase = 2;
|
||||
|
||||
GraphTargetItem replaced = checkLoop(li, localData, loops);
|
||||
GraphTargetItem replaced = checkLoop(ret, li, localData, loops);
|
||||
if (replaced != li) {
|
||||
int index = ret.indexOf(li);
|
||||
ret.remove(index);
|
||||
|
||||
Reference in New Issue
Block a user