mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-03 18:44:46 +00:00
fix: push commands in as2 left in code (#2654)
If the code does not contain any §§pop() instructions, then all §§push instructions are converted to their values with comment "unpopped". Fixes #2654
This commit is contained in:
@@ -1101,6 +1101,7 @@ public class AVM2Graph extends Graph {
|
||||
/**
|
||||
* Checks try.
|
||||
*
|
||||
* @param hasEmptyStackPops Has empty stack pops
|
||||
* @param currentRet Current return
|
||||
* @param foundGotos Found gotos
|
||||
* @param partCodes Part codes
|
||||
@@ -1120,7 +1121,7 @@ public class AVM2Graph extends Graph {
|
||||
* @return True if try is found
|
||||
* @throws InterruptedException On interrupt
|
||||
*/
|
||||
private boolean checkTry(List<GraphTargetItem> currentRet, List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, Set<GraphPart> visited, AVM2LocalData localData, GraphPart part, List<GraphPart> stopPart, List<StopPartKind> stopPartKind, List<Loop> loops, List<ThrowState> throwStates, Set<GraphPart> allParts, TranslateStack stack, int staticOperation, String path, int recursionLevel) throws InterruptedException {
|
||||
private boolean checkTry(Reference<Boolean> hasEmptyStackPops, List<GraphTargetItem> currentRet, List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, Set<GraphPart> visited, AVM2LocalData localData, GraphPart part, List<GraphPart> stopPart, List<StopPartKind> stopPartKind, List<Loop> loops, List<ThrowState> throwStates, Set<GraphPart> allParts, TranslateStack stack, int staticOperation, String path, int recursionLevel) throws InterruptedException {
|
||||
if (localData.parsedExceptions == null) {
|
||||
localData.parsedExceptions = new ArrayList<>();
|
||||
}
|
||||
@@ -1255,7 +1256,7 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
}
|
||||
stack = (TranslateStack) stack.clone();
|
||||
tryCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, part, stopPart2, stopPartKind2, loops, throwStates, staticOperation, path);
|
||||
tryCommands = printGraph(hasEmptyStackPops, foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, part, stopPart2, stopPartKind2, loops, throwStates, staticOperation, path);
|
||||
}
|
||||
|
||||
boolean inlinedFinally = false;
|
||||
@@ -1376,7 +1377,7 @@ public class AVM2Graph extends Graph {
|
||||
tryStopPartKind.add(StopPartKind.OTHER);
|
||||
}
|
||||
|
||||
tryCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, part, tryStopPart, tryStopPartKind, loops, throwStates, staticOperation, path);
|
||||
tryCommands = printGraph(hasEmptyStackPops, foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, part, tryStopPart, tryStopPartKind, loops, throwStates, staticOperation, path);
|
||||
makeAllCommands(tryCommands, stack);
|
||||
processIfs(tryCommands);
|
||||
|
||||
@@ -1394,7 +1395,7 @@ public class AVM2Graph extends Graph {
|
||||
finallyStopPartKind.add(StopPartKind.OTHER);
|
||||
}
|
||||
if (finallyPart != null) {
|
||||
finallyCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, finallyPart, finallyStopPart, finallyStopPartKind, loops, throwStates, staticOperation, path);
|
||||
finallyCommands = printGraph(hasEmptyStackPops, foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, finallyPart, finallyStopPart, finallyStopPartKind, loops, throwStates, staticOperation, path);
|
||||
}
|
||||
if (switchPart != null) {
|
||||
try {
|
||||
@@ -1446,7 +1447,7 @@ public class AVM2Graph extends Graph {
|
||||
stopPartKind2.add(StopPartKind.OTHER);
|
||||
}
|
||||
|
||||
List<GraphTargetItem> currentCatchCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData2, st2, allParts, null, catchPart, stopPart2, stopPartKind2, loops, throwStates, staticOperation, path);
|
||||
List<GraphTargetItem> currentCatchCommands = printGraph(hasEmptyStackPops, foundGotos, partCodes, partCodePos, visited, localData2, st2, allParts, null, catchPart, stopPart2, stopPartKind2, loops, throwStates, staticOperation, path);
|
||||
st2.finishBlock(currentCatchCommands, true);
|
||||
int tempExceptionPos = 0;
|
||||
if (!currentCatchCommands.isEmpty() && currentCatchCommands.get(0) instanceof WithAVM2Item) {
|
||||
@@ -1616,7 +1617,7 @@ public class AVM2Graph extends Graph {
|
||||
if (finallyIndex > -1 && localData.finallyIndicesWithDoublePush.contains(finallyIndex)) {
|
||||
stack.push(new AnyItem());
|
||||
}
|
||||
printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, afterPart, stopPart, stopPartKind, loops, throwStates, currentRet, staticOperation, path, recursionLevel);
|
||||
printGraph(hasEmptyStackPops, foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, afterPart, stopPart, stopPartKind, loops, throwStates, currentRet, staticOperation, path, recursionLevel);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1691,34 +1692,9 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check part output.
|
||||
*
|
||||
* @param currentRet Current return
|
||||
* @param foundGotos Found gotos
|
||||
* @param partCodes Part codes
|
||||
* @param partCodePos Part code position
|
||||
* @param visited Visited
|
||||
* @param code Code
|
||||
* @param localData Local data
|
||||
* @param allParts All parts
|
||||
* @param stack Stack
|
||||
* @param parent Parent part
|
||||
* @param part Part
|
||||
* @param stopPart Stop part
|
||||
* @param stopPartKind Stop part kind
|
||||
* @param loops Loops
|
||||
* @param throwStates Throw states
|
||||
* @param currentLoop Current loop
|
||||
* @param staticOperation Unused
|
||||
* @param path Path
|
||||
* @param recursionLevel Recursion level
|
||||
* @return True to stop processing. False to continue.
|
||||
* @throws InterruptedException On interrupt
|
||||
*/
|
||||
|
||||
@Override
|
||||
protected boolean checkPartOutput(List<GraphTargetItem> currentRet, List<GotoItem> foundGotos,
|
||||
protected boolean checkPartOutput(Reference<Boolean> hasEmptyStackPops, List<GraphTargetItem> currentRet, List<GotoItem> foundGotos,
|
||||
Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos,
|
||||
Set<GraphPart> visited, GraphSource code,
|
||||
BaseLocalData localData, Set<GraphPart> allParts,
|
||||
@@ -1729,38 +1705,11 @@ public class AVM2Graph extends Graph {
|
||||
int staticOperation, String path,
|
||||
int recursionLevel) throws InterruptedException {
|
||||
AVM2LocalData aLocalData = (AVM2LocalData) localData;
|
||||
return checkTry(currentRet, foundGotos, partCodes, partCodePos, visited, aLocalData, part, stopPart, stopPartKind, loops, throwStates, allParts, stack, staticOperation, path, recursionLevel);
|
||||
return checkTry(hasEmptyStackPops, currentRet, foundGotos, partCodes, partCodePos, visited, aLocalData, part, stopPart, stopPartKind, loops, throwStates, allParts, stack, staticOperation, path, recursionLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check before decompiling next section. Override this method to provide
|
||||
* custom behavior.
|
||||
*
|
||||
* @param currentRet Current return
|
||||
* @param foundGotos Found gotos
|
||||
* @param partCodes Part codes
|
||||
* @param partCodePos Part code position
|
||||
* @param visited Visited
|
||||
* @param code Code
|
||||
* @param localData Local data
|
||||
* @param allParts All parts
|
||||
* @param stack Stack
|
||||
* @param parent Parent part
|
||||
* @param part Part
|
||||
* @param stopPart Stop part
|
||||
* @param stopPartKind Stop part kind
|
||||
* @param loops Loops
|
||||
* @param throwStates Throw states
|
||||
* @param output Output
|
||||
* @param currentLoop Current loop
|
||||
* @param staticOperation Unused
|
||||
* @param path Path
|
||||
* @return List of GraphTargetItems to replace current output and stop
|
||||
* further processing. Null to continue.
|
||||
* @throws InterruptedException On interrupt
|
||||
*/
|
||||
|
||||
@Override
|
||||
protected List<GraphTargetItem> check(List<GraphTargetItem> currentRet, List<GotoItem> foundGotos,
|
||||
protected List<GraphTargetItem> check(Reference<Boolean> hasEmptyStackPops, List<GraphTargetItem> currentRet, List<GotoItem> foundGotos,
|
||||
Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos,
|
||||
Set<GraphPart> visited, GraphSource code,
|
||||
BaseLocalData localData, Set<GraphPart> allParts,
|
||||
@@ -1963,7 +1912,7 @@ public class AVM2Graph extends Graph {
|
||||
Reference<GraphPart> nextRef = new Reference<>(null);
|
||||
Reference<GraphTargetItem> tiRef = new Reference<>(null);
|
||||
makeAllCommands(output, stack);
|
||||
SwitchItem sw = handleSwitch(switchedObject, switchStartItem, foundGotos, partCodes, partCodePos, visited, allParts, stack, stopPart, stopPartKind, loops, throwStates, localData, staticOperation, path, caseValuesMap, defaultPart, caseBodyParts, nextRef, tiRef);
|
||||
SwitchItem sw = handleSwitch(switchedObject, switchStartItem, foundGotos, partCodes, partCodePos, visited, allParts, stack, stopPart, stopPartKind, loops, throwStates, localData, staticOperation, path, caseValuesMap, defaultPart, caseBodyParts, nextRef, tiRef, hasEmptyStackPops);
|
||||
ret = new ArrayList<>();
|
||||
ret.addAll(output);
|
||||
checkSwitch(localData, sw, otherSide, ret.isEmpty() ? currentRet : ret /*hack :-(*/);
|
||||
@@ -1972,7 +1921,7 @@ public class AVM2Graph extends Graph {
|
||||
if (tiRef.getVal() != null) {
|
||||
ret.add(tiRef.getVal());
|
||||
} else {
|
||||
ret.addAll(printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, nextRef.getVal(), stopPart, stopPartKind, loops, throwStates, staticOperation, path));
|
||||
ret.addAll(printGraph(hasEmptyStackPops, foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, nextRef.getVal(), stopPart, stopPartKind, loops, throwStates, staticOperation, path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -815,6 +815,7 @@ public class ActionGraph extends Graph {
|
||||
/**
|
||||
* Check before decompiling next section.
|
||||
*
|
||||
* @param hasEmptyStackPops Has empty stack pops
|
||||
* @param currentRet Current return
|
||||
* @param foundGotos Found gotos
|
||||
* @param partCodes Part codes
|
||||
@@ -839,7 +840,7 @@ public class ActionGraph extends Graph {
|
||||
* @throws InterruptedException On interrupt
|
||||
*/
|
||||
@Override
|
||||
protected List<GraphTargetItem> check(List<GraphTargetItem> currentRet, List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, Set<GraphPart> visited, GraphSource code, BaseLocalData localData, Set<GraphPart> allParts, TranslateStack stack, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<StopPartKind> stopPartKind, List<Loop> loops, List<ThrowState> throwStates, List<GraphTargetItem> output, Loop currentLoop, int staticOperation, String path) throws InterruptedException {
|
||||
protected List<GraphTargetItem> check(Reference<Boolean> hasEmptyStackPops, List<GraphTargetItem> currentRet, List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, Set<GraphPart> visited, GraphSource code, BaseLocalData localData, Set<GraphPart> allParts, TranslateStack stack, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<StopPartKind> stopPartKind, List<Loop> loops, List<ThrowState> throwStates, List<GraphTargetItem> output, Loop currentLoop, int staticOperation, String path) throws InterruptedException {
|
||||
if (!output.isEmpty()) {
|
||||
if (output.get(output.size() - 1) instanceof StoreRegisterActionItem) {
|
||||
StoreRegisterActionItem str = (StoreRegisterActionItem) output.get(output.size() - 1);
|
||||
@@ -928,7 +929,7 @@ public class ActionGraph extends Graph {
|
||||
Reference<GraphPart> nextRef = new Reference<>(null);
|
||||
Reference<GraphTargetItem> tiRef = new Reference<>(null);
|
||||
makeAllCommands(output, stack);
|
||||
SwitchItem sw = handleSwitch(switchedObject, switchStartItem, foundGotos, partCodes, partCodePos, visited, allParts, stack, stopPart, stopPartKind, loops, throwStates, localData, staticOperation, path, caseValuesMap, defaultPart, caseBodyParts, nextRef, tiRef);
|
||||
SwitchItem sw = handleSwitch(switchedObject, switchStartItem, foundGotos, partCodes, partCodePos, visited, allParts, stack, stopPart, stopPartKind, loops, throwStates, localData, staticOperation, path, caseValuesMap, defaultPart, caseBodyParts, nextRef, tiRef, hasEmptyStackPops);
|
||||
fixSwitchEnd(sw);
|
||||
ret = new ArrayList<>();
|
||||
ret.addAll(output);
|
||||
@@ -937,7 +938,7 @@ public class ActionGraph extends Graph {
|
||||
if (tiRef.getVal() != null) {
|
||||
ret.add(tiRef.getVal());
|
||||
} else {
|
||||
ret.addAll(printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, nextRef.getVal(), stopPart, stopPartKind, loops, throwStates, staticOperation, path));
|
||||
ret.addAll(printGraph(hasEmptyStackPops, foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, nextRef.getVal(), stopPart, stopPartKind, loops, throwStates, staticOperation, path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,7 +305,7 @@ public class FunctionActionItem extends ActionItem {
|
||||
}
|
||||
writer.append(")").startBlock();
|
||||
|
||||
Graph.graphToString(actions, writer, localData);
|
||||
Graph.graphToString(actions, writer, localData);
|
||||
|
||||
writer.endBlock();
|
||||
writer.endMethod();
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.model.AndItem;
|
||||
import com.jpexs.decompiler.graph.model.BinaryOpItem;
|
||||
import com.jpexs.decompiler.graph.model.BlockItem;
|
||||
import com.jpexs.decompiler.graph.model.BranchStackResistant;
|
||||
import com.jpexs.decompiler.graph.model.BreakItem;
|
||||
import com.jpexs.decompiler.graph.model.CommaExpressionItem;
|
||||
@@ -992,7 +993,8 @@ public class Graph {
|
||||
System.err.println("</loopspre>");//*/
|
||||
List<GotoItem> gotos = new ArrayList<>();
|
||||
|
||||
List<GraphTargetItem> ret = printGraph(gotos, new HashMap<>(), new HashMap<>(), new HashSet<>(), localData, stack, allParts, null, heads.get(0), null, null, loops, throwStates, staticOperation, path);
|
||||
Reference<Boolean> hasEmptyStackPops = new Reference<>(false);
|
||||
List<GraphTargetItem> ret = printGraph(hasEmptyStackPops, gotos, new HashMap<>(), new HashMap<>(), new HashSet<>(), localData, stack, allParts, null, heads.get(0), null, null, loops, throwStates, staticOperation, path);
|
||||
|
||||
if (localData.secondPassData == null) {
|
||||
SecondPassData secondPassData = prepareSecondPass(localData, ret);
|
||||
@@ -1025,11 +1027,32 @@ public class Graph {
|
||||
propagateBreaks(ret);
|
||||
finalProcessStack(stack, ret, path);
|
||||
makeAllCommands(ret, stack);
|
||||
|
||||
if (!hasEmptyStackPops.getVal()) {
|
||||
promotePushItemsToCommands(ret);
|
||||
}
|
||||
|
||||
finalProcessAll(null, ret, 0, getFinalData(localData, loops, throwStates), path);
|
||||
//fixSwitchEnds(ret);
|
||||
handleSetTemporaryDeclarations(ret);
|
||||
handleSetTemporaryDeclarations(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private void promotePushItemsToCommands(List<GraphTargetItem> list) {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
GraphTargetItem ti = list.get(i);
|
||||
if (ti instanceof PushItem) {
|
||||
PushItem pi = (PushItem) ti;
|
||||
pi.asComment = true;
|
||||
pi.comment = "unpopped";
|
||||
}
|
||||
if (ti instanceof Block) {
|
||||
for (List<GraphTargetItem> sub : ((Block) ti).getSubs()) {
|
||||
promotePushItemsToCommands(sub);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSetTemporaryDeclarations(List<GraphTargetItem> items) {
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
@@ -2373,6 +2396,7 @@ public class Graph {
|
||||
* Check before decompiling next section. Override this method to provide
|
||||
* custom behavior.
|
||||
*
|
||||
* @param hasEmptyStackPops Has empty stack pops
|
||||
* @param currentRet Current return
|
||||
* @param foundGotos Found gotos
|
||||
* @param partCodes Part codes
|
||||
@@ -2396,7 +2420,7 @@ public class Graph {
|
||||
* further processing. Null to continue.
|
||||
* @throws InterruptedException On interrupt
|
||||
*/
|
||||
protected List<GraphTargetItem> check(List<GraphTargetItem> currentRet, List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, Set<GraphPart> visited, GraphSource code, BaseLocalData localData, Set<GraphPart> allParts, TranslateStack stack, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<StopPartKind> stopPartKind, List<Loop> loops, List<ThrowState> throwStates, List<GraphTargetItem> output, Loop currentLoop, int staticOperation, String path) throws InterruptedException {
|
||||
protected List<GraphTargetItem> check(Reference<Boolean> hasEmptyStackPops, List<GraphTargetItem> currentRet, List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, Set<GraphPart> visited, GraphSource code, BaseLocalData localData, Set<GraphPart> allParts, TranslateStack stack, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<StopPartKind> stopPartKind, List<Loop> loops, List<ThrowState> throwStates, List<GraphTargetItem> output, Loop currentLoop, int staticOperation, String path) throws InterruptedException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -3118,6 +3142,7 @@ public class Graph {
|
||||
/**
|
||||
* Check before processing with output.
|
||||
*
|
||||
* @param hasEmptyStackPops Has empty stack pops
|
||||
* @param currentRet Current return
|
||||
* @param foundGotos Found gotos
|
||||
* @param partCodes Part codes
|
||||
@@ -3140,7 +3165,7 @@ public class Graph {
|
||||
* @return True to stop processing. False to continue.
|
||||
* @throws InterruptedException On interrupt
|
||||
*/
|
||||
protected boolean checkPartOutput(List<GraphTargetItem> currentRet, List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, Set<GraphPart> visited, GraphSource code, BaseLocalData localData, Set<GraphPart> allParts, TranslateStack stack, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<StopPartKind> stopPartKind, List<Loop> loops, List<ThrowState> throwStates, Loop currentLoop, int staticOperation, String path, int recursionLevel) throws InterruptedException {
|
||||
protected boolean checkPartOutput(Reference<Boolean> hasEmptyStackPops, List<GraphTargetItem> currentRet, List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, Set<GraphPart> visited, GraphSource code, BaseLocalData localData, Set<GraphPart> allParts, TranslateStack stack, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<StopPartKind> stopPartKind, List<Loop> loops, List<ThrowState> throwStates, Loop currentLoop, int staticOperation, String path, int recursionLevel) throws InterruptedException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3227,6 +3252,7 @@ public class Graph {
|
||||
/**
|
||||
* Walks graph parts and converts them to target items.
|
||||
*
|
||||
* @param hasEmptyStackPops Has empty stack pops
|
||||
* @param foundGotos Found gotos
|
||||
* @param partCodes Part codes
|
||||
* @param partCodePos Part code position
|
||||
@@ -3245,13 +3271,14 @@ public class Graph {
|
||||
* @return List of GraphTargetItems
|
||||
* @throws InterruptedException On interrupt
|
||||
*/
|
||||
protected final List<GraphTargetItem> printGraph(List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, Set<GraphPart> visited, BaseLocalData localData, TranslateStack stack, Set<GraphPart> allParts, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<StopPartKind> stopPartKind, List<Loop> loops, List<ThrowState> throwStates, int staticOperation, String path) throws InterruptedException {
|
||||
return printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, parent, part, stopPart, stopPartKind, loops, throwStates, null, staticOperation, path, 0);
|
||||
protected final List<GraphTargetItem> printGraph(Reference<Boolean> hasEmptyStackPops, List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, Set<GraphPart> visited, BaseLocalData localData, TranslateStack stack, Set<GraphPart> allParts, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<StopPartKind> stopPartKind, List<Loop> loops, List<ThrowState> throwStates, int staticOperation, String path) throws InterruptedException {
|
||||
return printGraph(hasEmptyStackPops, foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, parent, part, stopPart, stopPartKind, loops, throwStates, null, staticOperation, path, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Walks graph parts and converts them to target items.
|
||||
*
|
||||
* @param hasEmptyStackPops Has empty stack pops
|
||||
* @param foundGotos Found gotos
|
||||
* @param partCodes Part codes
|
||||
* @param partCodePos Part code position
|
||||
@@ -3272,7 +3299,7 @@ public class Graph {
|
||||
* @return List of GraphTargetItems
|
||||
* @throws InterruptedException On interrupt
|
||||
*/
|
||||
protected final List<GraphTargetItem> printGraph(List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, Set<GraphPart> visited, BaseLocalData localData, TranslateStack stack, Set<GraphPart> allParts, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<StopPartKind> stopPartKind, List<Loop> loops, List<ThrowState> throwStates, List<GraphTargetItem> ret, int staticOperation, String path, int recursionLevel) throws InterruptedException {
|
||||
protected final List<GraphTargetItem> printGraph(Reference<Boolean> hasEmptyStackPops, List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, Set<GraphPart> visited, BaseLocalData localData, TranslateStack stack, Set<GraphPart> allParts, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<StopPartKind> stopPartKind, List<Loop> loops, List<ThrowState> throwStates, List<GraphTargetItem> ret, int staticOperation, String path, int recursionLevel) throws InterruptedException {
|
||||
|
||||
if (ret == null) {
|
||||
ret = new GraphPartMarkedArrayList<>();
|
||||
@@ -3526,7 +3553,7 @@ public class Graph {
|
||||
for (Loop el : loops) {
|
||||
loopPhases.add(el.phase);
|
||||
}
|
||||
precontinueCommands = printGraph(foundGotos, partCodes, partCodePos, subVisited, localData, new TranslateStack(path), allParts, null, backup, stopPart2, stopPartKind2, loops, throwStates, null, staticOperation, path, recursionLevel + 1);
|
||||
precontinueCommands = printGraph(hasEmptyStackPops, foundGotos, partCodes, partCodePos, subVisited, localData, new TranslateStack(path), allParts, null, backup, stopPart2, stopPartKind2, loops, throwStates, null, staticOperation, path, recursionLevel + 1);
|
||||
currentLoop.loopPreContinue = backup;
|
||||
checkContinueAtTheEnd(precontinueCommands, currentLoop);
|
||||
|
||||
@@ -3583,7 +3610,7 @@ public class Graph {
|
||||
((GraphPartMarkedArrayList) currentRet).startPart(part);
|
||||
}
|
||||
stack.setConnectedOutput(0, currentRet, localData);
|
||||
if (checkPartOutput(currentRet, foundGotos, partCodes, partCodePos, visited, code, localData, allParts, stack, parent, part, stopPart, stopPartKind, loops, throwStates, currentLoop, staticOperation, path, recursionLevel)) {
|
||||
if (checkPartOutput(hasEmptyStackPops, currentRet, foundGotos, partCodes, partCodePos, visited, code, localData, allParts, stack, parent, part, stopPart, stopPartKind, loops, throwStates, currentLoop, staticOperation, path, recursionLevel)) {
|
||||
parseNext = false;
|
||||
} else {
|
||||
boolean exHappened = false;
|
||||
@@ -3592,7 +3619,10 @@ public class Graph {
|
||||
exHappened = false;
|
||||
try {
|
||||
stack.setConnectedOutput(currentRet.size(), output, localData);
|
||||
code.translatePart(output, this, part, localData, stack, ipStart, part.end, staticOperation, path);
|
||||
code.translatePart(output, this, part, localData, stack, ipStart, part.end, staticOperation, path);
|
||||
if (stack.emptyPopCount > 0) {
|
||||
hasEmptyStackPops.setVal(true);
|
||||
}
|
||||
} catch (GraphPartChangeException ex) { //Special case for ifFrameLoaded when it's over multiple parts
|
||||
//output.addAll(ex.getOutput());
|
||||
for (GraphPart p : allParts) {
|
||||
@@ -3620,7 +3650,7 @@ public class Graph {
|
||||
}
|
||||
|
||||
if (parseNext) {
|
||||
List<GraphTargetItem> retCheck = check(currentRet, foundGotos, partCodes, partCodePos, visited, code, localData, allParts, stack, parent, part, stopPart, stopPartKind, loops, throwStates, output, currentLoop, staticOperation, path);
|
||||
List<GraphTargetItem> retCheck = check(hasEmptyStackPops, currentRet, foundGotos, partCodes, partCodePos, visited, code, localData, allParts, stack, parent, part, stopPart, stopPartKind, loops, throwStates, output, currentLoop, staticOperation, path);
|
||||
if (retCheck != null) {
|
||||
if (!retCheck.isEmpty()) {
|
||||
currentRet.addAll(retCheck);
|
||||
@@ -3817,7 +3847,7 @@ public class Graph {
|
||||
Reference<GraphTargetItem> tiRef = new Reference<>(null);
|
||||
makeAllCommands(currentRet, stack);
|
||||
SwitchItem sw = handleSwitch(switchedItem, originalSwitchedItem.getSrc(), foundGotos, partCodes, partCodePos, visited, allParts, stack, stopPart, stopPartKind, loops, throwStates, localData, staticOperation, path,
|
||||
caseValues, defaultPart, caseBodyParts, nextRef, tiRef);
|
||||
caseValues, defaultPart, caseBodyParts, nextRef, tiRef, hasEmptyStackPops);
|
||||
sw.additionalDefaultPosition = additionalDefaultPosition;
|
||||
sw.additionalDefaultValues = additionalDefaultValues;
|
||||
GraphPart next = nextRef.getVal();
|
||||
@@ -3827,7 +3857,7 @@ public class Graph {
|
||||
if (tiRef.getVal() != null) {
|
||||
ret.add(tiRef.getVal());
|
||||
} else {
|
||||
printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, part, next, stopPart, stopPartKind, loops, throwStates, currentRet, staticOperation, path, recursionLevel + 1);
|
||||
printGraph(hasEmptyStackPops, foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, part, next, stopPart, stopPartKind, loops, throwStates, currentRet, staticOperation, path, recursionLevel + 1);
|
||||
}
|
||||
}
|
||||
pos++;
|
||||
@@ -3919,7 +3949,7 @@ public class Graph {
|
||||
|
||||
if (currentLoop != null) {
|
||||
//System.err.println("handling parent loop");
|
||||
handleLoop(loopItem, li, currentLoop, loopTypeFound, doWhileCandidate, precontinueCommands, foundGotos, partCodes, partCodePos, visited, localData, allParts, null /*??*/, stopPart, stopPartKind, loops, throwStates, ret, staticOperation, path, recursionLevel, sPreLoop);
|
||||
handleLoop(hasEmptyStackPops, loopItem, li, currentLoop, loopTypeFound, doWhileCandidate, precontinueCommands, foundGotos, partCodes, partCodePos, visited, localData, allParts, null /*??*/, stopPart, stopPartKind, loops, throwStates, ret, staticOperation, path, recursionLevel, sPreLoop);
|
||||
currentLoop.phase = 1;
|
||||
}
|
||||
loopItem = newLoopItem;
|
||||
@@ -3949,7 +3979,7 @@ public class Graph {
|
||||
|
||||
TranslateStack trueStack = (TranslateStack) stack.clone();
|
||||
TranslateStack falseStack = (TranslateStack) stack.clone();
|
||||
|
||||
|
||||
//hack for as1/2 for..in to get enumeration through
|
||||
GraphTargetItem topBsr = !stack.isEmpty() && (stack.peek() instanceof BranchStackResistant) ? stack.peek() : null;
|
||||
trueStack.clear();
|
||||
@@ -3984,17 +4014,17 @@ public class Graph {
|
||||
|
||||
List<GraphTargetItem> onTrue = new ArrayList<>();
|
||||
if (!isEmpty && hasOnTrue) {
|
||||
onTrue = printGraph(foundGotos, partCodes, partCodePos, visited, prepareBranchLocalData(localData), trueStack, allParts, part, nps.get(1), stopPart2, stopPartKind2, loops, throwStates, null, staticOperation, path, recursionLevel + 1);
|
||||
onTrue = printGraph(hasEmptyStackPops, foundGotos, partCodes, partCodePos, visited, prepareBranchLocalData(localData), trueStack, allParts, part, nps.get(1), stopPart2, stopPartKind2, loops, throwStates, null, staticOperation, path, recursionLevel + 1);
|
||||
}
|
||||
List<GraphTargetItem> onFalse = new ArrayList<>();
|
||||
|
||||
if (!isEmpty && hasOnFalse) {
|
||||
onFalse = printGraph(foundGotos, partCodes, partCodePos, visited, prepareBranchLocalData(localData), falseStack, allParts, part, nps.get(0), stopPart2, stopPartKind2, loops, throwStates, null, staticOperation, path, recursionLevel + 1);
|
||||
onFalse = printGraph(hasEmptyStackPops, foundGotos, partCodes, partCodePos, visited, prepareBranchLocalData(localData), falseStack, allParts, part, nps.get(0), stopPart2, stopPartKind2, loops, throwStates, null, staticOperation, path, recursionLevel + 1);
|
||||
}
|
||||
//List<GraphTargetItem> out2 = new ArrayList<>();
|
||||
//makeAllCommands(out2, stack);
|
||||
makeAllCommands(onTrue, trueStack);
|
||||
makeAllCommands(onFalse, falseStack);
|
||||
makeAllCommands(onFalse, falseStack);
|
||||
GraphTargetItem addAfterIf = null;
|
||||
if (!onTrue.isEmpty() && !onFalse.isEmpty()
|
||||
&& (onTrue.get(onTrue.size() - 1) instanceof ContinueItem)
|
||||
@@ -4133,7 +4163,7 @@ public class Graph {
|
||||
}
|
||||
//currentRet.addAll(out2);
|
||||
if (next != null) {
|
||||
printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, part, next, stopPart, stopPartKind, loops, throwStates, currentRet, staticOperation, path, recursionLevel + 1);
|
||||
printGraph(hasEmptyStackPops, foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, part, next, stopPart, stopPartKind, loops, throwStates, currentRet, staticOperation, path, recursionLevel + 1);
|
||||
//currentRet.addAll();
|
||||
}
|
||||
}
|
||||
@@ -4147,19 +4177,19 @@ public class Graph {
|
||||
}
|
||||
|
||||
if (nextOnePart != null) {
|
||||
printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, part, getNextParts(localData, part).get(0), stopPart, stopPartKind, loops, throwStates, currentRet, staticOperation, path, recursionLevel + 1);
|
||||
printGraph(hasEmptyStackPops, foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, part, getNextParts(localData, part).get(0), stopPart, stopPartKind, loops, throwStates, currentRet, staticOperation, path, recursionLevel + 1);
|
||||
}
|
||||
|
||||
}
|
||||
if (isLoop && loopItem != null && currentLoop != null) {
|
||||
handleLoop(loopItem, li, currentLoop, loopTypeFound, doWhileCandidate, precontinueCommands, foundGotos, partCodes, partCodePos, visited, localData, allParts, part, stopPart, stopPartKind, loops, throwStates, ret, staticOperation, path, recursionLevel, sPreLoop);
|
||||
handleLoop(hasEmptyStackPops, loopItem, li, currentLoop, loopTypeFound, doWhileCandidate, precontinueCommands, foundGotos, partCodes, partCodePos, visited, localData, allParts, part, stopPart, stopPartKind, loops, throwStates, ret, staticOperation, path, recursionLevel, sPreLoop);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return originalRet;
|
||||
}
|
||||
|
||||
private void handleLoop(UniversalLoopItem loopItem, LoopItem li, Loop currentLoop, boolean loopTypeFound, boolean doWhileCandidate, List<GraphTargetItem> precontinueCommands,
|
||||
private void handleLoop(Reference<Boolean> hasEmptyStackPops, UniversalLoopItem loopItem, LoopItem li, Loop currentLoop, boolean loopTypeFound, boolean doWhileCandidate, List<GraphTargetItem> precontinueCommands,
|
||||
List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, Set<GraphPart> visited, BaseLocalData localData, Set<GraphPart> allParts, GraphPart part, List<GraphPart> stopPart, List<StopPartKind> stopPartKind, List<Loop> loops, List<ThrowState> throwStates, List<GraphTargetItem> ret, int staticOperation, String path, int recursionLevel,
|
||||
TranslateStack sPreLoop
|
||||
) throws InterruptedException {
|
||||
@@ -4388,7 +4418,7 @@ public class Graph {
|
||||
}
|
||||
|
||||
if (currentLoop.loopBreak != null) {
|
||||
printGraph(foundGotos, partCodes, partCodePos, visited, localData, sPreLoop, allParts, part, currentLoop.loopBreak, stopPart, stopPartKind, loops, throwStates, ret, staticOperation, path, recursionLevel + 1);
|
||||
printGraph(hasEmptyStackPops, foundGotos, partCodes, partCodePos, visited, localData, sPreLoop, allParts, part, currentLoop.loopBreak, stopPart, stopPartKind, loops, throwStates, ret, staticOperation, path, recursionLevel + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4677,7 +4707,7 @@ public class Graph {
|
||||
int tsize = tree.size();
|
||||
if (!tree.isEmpty() && (tree.get(tree.size() - 1) instanceof ScriptEndItem)) {
|
||||
tsize--;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < tsize; i++) {
|
||||
GraphTargetItem ti = tree.get(i);
|
||||
if (!ti.isEmpty()) {
|
||||
@@ -4686,6 +4716,9 @@ public class Graph {
|
||||
}
|
||||
ti.toStringSemicoloned(writer, localData);
|
||||
if (!ti.handlesNewLine()) {
|
||||
if (!ti.comment.isEmpty()) {
|
||||
writer.append(" //").append(ti.comment);
|
||||
}
|
||||
writer.newLine();
|
||||
}
|
||||
lastNewLine = false;
|
||||
@@ -4694,7 +4727,7 @@ public class Graph {
|
||||
lastNewLine = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return writer;
|
||||
}
|
||||
|
||||
@@ -4793,12 +4826,13 @@ public class Graph {
|
||||
* @param caseBodyParts Case body parts
|
||||
* @param nextRef Next reference
|
||||
* @param tiRef Target item reference
|
||||
* @param hasEmptyStackPops Has empty stack pops
|
||||
* @return Switch item
|
||||
* @throws InterruptedException On interrupt
|
||||
*/
|
||||
protected SwitchItem handleSwitch(GraphTargetItem switchedObject,
|
||||
GraphSourceItem switchStartItem, List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, Set<GraphPart> visited, Set<GraphPart> allParts, TranslateStack stack, List<GraphPart> stopPart, List<StopPartKind> stopPartKind, List<Loop> loops, List<ThrowState> throwStates, BaseLocalData localData, int staticOperation, String path,
|
||||
List<GraphTargetItem> caseValuesMap, GraphPart defaultPart, List<GraphPart> caseBodyParts, Reference<GraphPart> nextRef, Reference<GraphTargetItem> tiRef) throws InterruptedException {
|
||||
List<GraphTargetItem> caseValuesMap, GraphPart defaultPart, List<GraphPart> caseBodyParts, Reference<GraphPart> nextRef, Reference<GraphTargetItem> tiRef, Reference<Boolean> hasEmptyStackPops) throws InterruptedException {
|
||||
|
||||
boolean hasDefault = false;
|
||||
/*
|
||||
@@ -4950,7 +4984,7 @@ public class Graph {
|
||||
stopPartKind2x.add(StopPartKind.OTHER);
|
||||
}
|
||||
TranslateStack subStack = (TranslateStack) stack.clone();
|
||||
currentCaseCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData, subStack, allParts, null, caseBodies.get(i), stopPart2x, stopPartKind2x, loops, throwStates, staticOperation, path);
|
||||
currentCaseCommands = printGraph(hasEmptyStackPops, foundGotos, partCodes, partCodePos, visited, localData, subStack, allParts, null, caseBodies.get(i), stopPart2x, stopPartKind2x, loops, throwStates, staticOperation, path);
|
||||
if (willHaveBreak) {
|
||||
if (!currentCaseCommands.isEmpty()) {
|
||||
GraphTargetItem last = currentCaseCommands.get(currentCaseCommands.size() - 1);
|
||||
|
||||
@@ -141,6 +141,11 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
|
||||
* report bugs.
|
||||
*/
|
||||
public int line;
|
||||
|
||||
/**
|
||||
* Comment
|
||||
*/
|
||||
public String comment = "";
|
||||
|
||||
/**
|
||||
* Gets the line start item
|
||||
@@ -1060,17 +1065,30 @@ public abstract class GraphTargetItem implements Serializable, Cloneable {
|
||||
writer.startBlock();
|
||||
}
|
||||
boolean first = true;
|
||||
GraphTargetItem prevTi = null;
|
||||
for (GraphTargetItem ti : commands) {
|
||||
if (!ti.isEmpty()) {
|
||||
//Use stored line information if available to place commands on same line
|
||||
if (!ti.isEmpty()) {
|
||||
if (!first && (!useLineInfo || (ti.getLine() < 1 || prevLine < 1 || (prevLine >= 1 && prevLine != ti.getLine())))) {
|
||||
//Use stored line information if available to place commands on same line
|
||||
|
||||
if (prevTi != null && !prevTi.comment.isEmpty()) {
|
||||
writer.append(" //").append(prevTi.comment);
|
||||
}
|
||||
writer.newLine();
|
||||
} else {
|
||||
if (prevTi != null && !prevTi.comment.isEmpty()) {
|
||||
writer.append(" /*").append(prevTi.comment).append(" */ ");
|
||||
}
|
||||
}
|
||||
prevLine = ti.getLine();
|
||||
first = false;
|
||||
ti.toStringSemicoloned(writer, localData);
|
||||
prevTi = ti;
|
||||
}
|
||||
}
|
||||
if (prevTi != null && !prevTi.comment.isEmpty()) {
|
||||
writer.append(" //").append(prevTi.comment);
|
||||
}
|
||||
if (asBlock) {
|
||||
if (!first) {
|
||||
writer.newLine();
|
||||
|
||||
@@ -64,7 +64,9 @@ public class TranslateStack extends Stack<GraphTargetItem> {
|
||||
public List<GraphTargetItem> outputQueue = new ArrayList<>();
|
||||
|
||||
public BaseLocalData localData = null;
|
||||
|
||||
|
||||
public int emptyPopCount = 0;
|
||||
|
||||
@Override
|
||||
public synchronized Object clone() {
|
||||
TranslateStack st = (TranslateStack) super.clone();
|
||||
@@ -300,6 +302,7 @@ public class TranslateStack extends Stack<GraphTargetItem> {
|
||||
PopItem oldpop = getPop();
|
||||
pop = null;
|
||||
Logger.getLogger(TranslateStack.class.getName()).log(Level.FINE, "{0}: Attempt to Pop empty stack", path);
|
||||
emptyPopCount++;
|
||||
return oldpop;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ import java.util.Objects;
|
||||
*/
|
||||
public class PushItem extends GraphTargetItem {
|
||||
|
||||
public boolean asComment = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param value Value to push
|
||||
@@ -43,13 +45,16 @@ public class PushItem extends GraphTargetItem {
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
//Logger.getLogger(PushItem.class.getName()).log(Level.WARNING, "Push item left in the source code");
|
||||
if (asComment) {
|
||||
value.appendTry(writer, localData);
|
||||
return writer;
|
||||
}
|
||||
writer.append("§§push(");
|
||||
value.appendTry(writer, localData);
|
||||
writer.append(")");
|
||||
return writer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasReturnValue() {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user