Fixed: #2493 Incorrect placement of §§push instructions

This commit is contained in:
Jindra Petřík
2025-07-24 21:12:24 +02:00
parent 84b92a9d46
commit 7559970c17
18 changed files with 225 additions and 64 deletions
@@ -27,7 +27,6 @@ import com.jpexs.decompiler.graph.model.BinaryOpItem;
import com.jpexs.decompiler.graph.model.BranchStackResistant;
import com.jpexs.decompiler.graph.model.BreakItem;
import com.jpexs.decompiler.graph.model.CommaExpressionItem;
import com.jpexs.decompiler.graph.model.CommentItem;
import com.jpexs.decompiler.graph.model.ContinueItem;
import com.jpexs.decompiler.graph.model.DefaultItem;
import com.jpexs.decompiler.graph.model.DoWhileItem;
@@ -2354,7 +2353,7 @@ public class Graph {
//@SuppressWarnings("unchecked")
protected final GraphTargetItem translatePartGetStack(BaseLocalData localData, GraphPart part, TranslateStack stack, int staticOperation) throws InterruptedException, GraphPartChangeException {
stack = (TranslateStack) stack.clone();
translatePart(localData, part, stack, staticOperation, null);
translatePart(new ArrayList<>(), localData, part, stack, staticOperation, null);
return stack.pop();
}
@@ -2373,13 +2372,14 @@ public class Graph {
protected final GraphTargetItem translatePartGetStack(BaseLocalData localData, GraphPart part, TranslateStack stack, int staticOperation, List<GraphTargetItem> output) throws InterruptedException, GraphPartChangeException {
stack = (TranslateStack) stack.clone();
output.clear();
output.addAll(translatePart(localData, part, stack, staticOperation, null));
translatePart(output, localData, part, stack, staticOperation, null);
return stack.pop();
}
/**
* Translates part.
*
* @param output Output
* @param localData Local data
* @param part Part
* @param stack Translate stack
@@ -2389,9 +2389,8 @@ public class Graph {
* @throws InterruptedException On interrupt
* @throws GraphPartChangeException On graph part change
*/
protected final List<GraphTargetItem> translatePart(BaseLocalData localData, GraphPart part, TranslateStack stack, int staticOperation, String path) throws InterruptedException, GraphPartChangeException {
protected final void translatePart(List<GraphTargetItem> output, BaseLocalData localData, GraphPart part, TranslateStack stack, int staticOperation, String path) throws InterruptedException, GraphPartChangeException {
List<GraphPart> sub = part.getSubParts();
List<GraphTargetItem> ret = new ArrayList<>();
int end;
for (GraphPart p : sub) {
if (p.end == -1) {
@@ -2404,9 +2403,8 @@ public class Graph {
}
end = p.end;
int start = p.start;
ret.addAll(code.translatePart(this, part, localData, stack, start, end, staticOperation, path));
code.translatePart(output, this, part, localData, stack, start, end, staticOperation, path);
}
return ret;
}
/**
@@ -3469,6 +3467,7 @@ public class Graph {
if (currentRet instanceof GraphPartMarkedArrayList) {
((GraphPartMarkedArrayList) currentRet).startPart(part);
}
stack.setConnectedOutput(0, currentRet);
if (checkPartOutput(currentRet, foundGotos, partCodes, partCodePos, visited, code, localData, allParts, stack, parent, part, stopPart, stopPartKind, loops, throwStates, currentLoop, staticOperation, path, recursionLevel)) {
parseNext = false;
} else {
@@ -3477,9 +3476,10 @@ public class Graph {
do {
exHappened = false;
try {
output.addAll(code.translatePart(this, part, localData, stack, ipStart, part.end, staticOperation, path));
stack.setConnectedOutput(currentRet.size(), output);
code.translatePart(output, this, part, localData, stack, ipStart, part.end, staticOperation, path);
} catch (GraphPartChangeException ex) { //Special case for ifFrameLoaded when it's over multiple parts
output.addAll(ex.getOutput());
//output.addAll(ex.getOutput());
for (GraphPart p : allParts) {
if (p.containsIP(ex.getIp())) {
if (ex.getIp() == p.start) {
@@ -4542,7 +4542,12 @@ public class Graph {
//ASC2 leaves some function calls unpopped on stack before returning from a method
commands.add(clen, p);
} else {
commands.add(clen, new PushItem(p));
int pos = 0;
if (p.outputPos < commands.size()) {
commands.add(p.outputPos, new PushItem(p));
} else {
commands.add(clen + pos, new PushItem(p));
}
}
}
}
@@ -62,6 +62,7 @@ public abstract class GraphSource implements Serializable {
/**
* Translates the part of the graph source
*
* @param output Output
* @param graph Graph
* @param part Graph part
* @param localData Local data
@@ -70,11 +71,10 @@ public abstract class GraphSource implements Serializable {
* @param end End position
* @param staticOperation Unused
* @param path Path
* @return List of graph target items
* @throws InterruptedException On interrupt
* @throws GraphPartChangeException On graph part change
*/
public abstract List<GraphTargetItem> translatePart(Graph graph, GraphPart part, BaseLocalData localData, TranslateStack stack, int start, int end, int staticOperation, String path) throws InterruptedException, GraphPartChangeException;
public abstract void translatePart(List<GraphTargetItem> output, Graph graph, GraphPart part, BaseLocalData localData, TranslateStack stack, int start, int end, int staticOperation, String path) throws InterruptedException, GraphPartChangeException;
/**
* Gets the important addresses
@@ -128,7 +128,12 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
* Dialect
*/
public GraphTargetDialect dialect;
/**
* Position in output - current list of GraphTargetItems
*/
public int outputPos = -1;
/**
* Gets the line start item
*
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.graph;
import com.jpexs.decompiler.graph.model.PopItem;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.logging.Level;
@@ -39,9 +40,25 @@ public class TranslateStack extends Stack<GraphTargetItem> {
* Path
*/
private final String path;
private List<GraphTargetItem> connectedOutput = null;
private int prevOutputSize = 0;
private Map<String, GraphTargetItem> marks = new HashMap<>();
public void setConnectedOutput(int prevOutputSize, List<GraphTargetItem> connectedOutput) {
this.prevOutputSize = prevOutputSize;
this.connectedOutput = connectedOutput;
}
@Override
public GraphTargetItem push(GraphTargetItem item) {
if (connectedOutput != null && item != null) {
item.outputPos = prevOutputSize + connectedOutput.size();
}
return super.push(item);
}
/**
* Sets mark.