Fixed: AS decompilation - §§push before loop

This commit is contained in:
Jindra Petřík
2021-04-03 19:25:57 +02:00
parent a290ebac0d
commit 0a4dc74c61
10 changed files with 176 additions and 13 deletions

View File

@@ -1611,7 +1611,7 @@ public class AVM2Graph extends Graph {
}
@Override
protected GraphTargetItem checkLoop(List<GraphTargetItem> output, LoopItem loopItem, BaseLocalData localData, List<Loop> loops, List<ThrowState> throwStates) {
protected GraphTargetItem checkLoop(List<GraphTargetItem> output, LoopItem loopItem, BaseLocalData localData, List<Loop> loops, List<ThrowState> throwStates, TranslateStack stack) {
AVM2LocalData aLocalData = (AVM2LocalData) localData;
if (loopItem instanceof WhileItem) {
WhileItem w = (WhileItem) loopItem;
@@ -1620,6 +1620,22 @@ public class AVM2Graph extends Graph {
HasNextAVM2Item hn = (HasNextAVM2Item) w.expression.get(w.expression.size() - 1);
if (hn.obj != null) {
if (hn.obj.getNotCoerced().getThroughRegister().getNotCoerced() instanceof FilteredCheckAVM2Item) {
//All items are moved from stack to output before entering while,
// this code block moves them back to stack
int pushnum = 0;
for (int i = output.size() - 2 /*last is loop*/; i >= 0; i--) {
if (output.get(i) instanceof PushItem) {
pushnum++;
} else {
break;
}
}
int rem = output.size() - 1 - pushnum;
for (int i = output.size() - 1 - pushnum; i <= output.size() - 2; i++) {
stack.push(((PushItem) output.remove(rem)).value);
}
//---------- end moving back to stack
if (w.commands.size() >= 3) {
int pos = 0;
Set<Integer> localRegsToKill = new HashSet<>();

View File

@@ -35,6 +35,7 @@ import com.jpexs.decompiler.graph.GraphSourceItemPos;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.GraphTargetVisitorInterface;
import com.jpexs.decompiler.graph.SourceGenerator;
import com.jpexs.decompiler.graph.model.BranchStackResistant;
import com.jpexs.decompiler.graph.model.LocalData;
import com.jpexs.helpers.Helper;
import java.util.ArrayList;
@@ -48,7 +49,7 @@ import java.util.Set;
*
* @author JPEXS
*/
public class FunctionActionItem extends ActionItem {
public class FunctionActionItem extends ActionItem implements BranchStackResistant {
public List<GraphTargetItem> actions;

View File

@@ -1350,7 +1350,7 @@ public class Graph {
return printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, parent, part, stopPart, stopPartKind, loops, throwStates, null, staticOperation, path, 0);
}
protected GraphTargetItem checkLoop(List<GraphTargetItem> output, LoopItem loopItem, BaseLocalData localData, List<Loop> loops, List<ThrowState> throwStates) {
protected GraphTargetItem checkLoop(List<GraphTargetItem> output, LoopItem loopItem, BaseLocalData localData, List<Loop> loops, List<ThrowState> throwStates, TranslateStack stack) {
return loopItem;
}
@@ -1901,6 +1901,9 @@ public class Graph {
}
}
if (isLoop) {
makeAllCommands(ret, stack);
}
if (debugPrintGraph) {
System.err.println("loopsize:" + loops.size());
}
@@ -2675,7 +2678,7 @@ public class Graph {
}
currentLoop.phase = 2;
GraphTargetItem replaced = checkLoop(ret, li, localData, loops, throwStates);
GraphTargetItem replaced = checkLoop(ret, li, localData, loops, throwStates, sPreLoop);
if (replaced != li) {
int index = ret.indexOf(li);
ret.remove(index);
@@ -2951,21 +2954,18 @@ public class Graph {
clen--;
}
}
while (stack.size() > 0) {
GraphTargetItem p = stack.pop();
for (int i = stack.size() - 1; i >= 0; i--) {
GraphTargetItem p = stack.get(i);
if (p instanceof BranchStackResistant) {
continue;
}
stack.remove(i);
if (!(p instanceof PopItem)) {
if (p instanceof FunctionActionItem) {
if (isExit) {
//ASC2 leaves some function calls unpopped on stack before returning from a method
commands.add(clen, p);
} else {
if (isExit) {
//ASC2 leaves some function calls unpopped on stack before returning from a method
commands.add(clen, p);
} else {
commands.add(clen, new PushItem(p));
}
commands.add(clen, new PushItem(p));
}
}
}