mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-27 06:40:46 +00:00
try to improve try..catch vs loops
This commit is contained in:
@@ -59,6 +59,7 @@ public class AVM2LocalData extends BaseLocalData {
|
||||
public List<DottedChain> fullyQualifiedNames;
|
||||
|
||||
public List<ABCException> parsedExceptions = new ArrayList<>();
|
||||
public List<Integer> parsedExceptionIds = new ArrayList<>();
|
||||
|
||||
//public Map<Integer, List<Integer>> finallyJumps;
|
||||
/**
|
||||
@@ -154,6 +155,7 @@ public class AVM2LocalData extends BaseLocalData {
|
||||
defaultParts = localData.defaultParts;
|
||||
finallyThrowParts = localData.finallyThrowParts;
|
||||
inGetLoops = localData.inGetLoops;
|
||||
parsedExceptionIds = localData.parsedExceptionIds;
|
||||
}
|
||||
|
||||
public AVM2ConstantPool getConstants() {
|
||||
|
||||
@@ -84,6 +84,7 @@ import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.Loop;
|
||||
import com.jpexs.decompiler.graph.ScopeStack;
|
||||
import com.jpexs.decompiler.graph.ThrowState;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import com.jpexs.decompiler.graph.model.AnyItem;
|
||||
import com.jpexs.decompiler.graph.model.BreakItem;
|
||||
@@ -160,7 +161,7 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeGetLoops(BaseLocalData localData, String path, Set<GraphPart> allParts) throws InterruptedException {
|
||||
protected void beforeGetLoops(BaseLocalData localData, String path, Set<GraphPart> allParts, List<ThrowState> throwStates) throws InterruptedException {
|
||||
AVM2LocalData avm2LocalData = ((AVM2LocalData) localData);
|
||||
avm2LocalData.codeStats = avm2LocalData.code.getStats(avm2LocalData.abc, avm2LocalData.methodBody, avm2LocalData.methodBody.init_scope_depth, false);
|
||||
getIgnoredSwitches((AVM2LocalData) localData, allParts);
|
||||
@@ -171,10 +172,13 @@ public class AVM2Graph extends Graph {
|
||||
|
||||
for (GraphPart finallySwitchTarget : avm2LocalData.finallyJumps.values()) {
|
||||
if (!avm2LocalData.defaultParts.values().contains(finallySwitchTarget)) {
|
||||
finallySwitchTarget.throwParts.clear(); // having throwparts in these causes problems
|
||||
for (ThrowState ts : throwStates) {
|
||||
ts.throwingParts.remove(finallySwitchTarget);
|
||||
}
|
||||
//finallySwitchTarget.throwParts.clear(); // having throwparts in these causes problems
|
||||
}
|
||||
}
|
||||
Map<Integer, Set<Integer>> setLocalPosToGetLocalPos = calculateLocalRegsUsage(avm2LocalData, integerSwitchesIps, path, allParts);
|
||||
Map<Integer, Set<Integer>> setLocalPosToGetLocalPos = calculateLocalRegsUsage(throwStates, avm2LocalData, integerSwitchesIps, path, allParts);
|
||||
avm2LocalData.setLocalPosToGetLocalPos = setLocalPosToGetLocalPos;
|
||||
avm2LocalData.inGetLoops = true;
|
||||
}
|
||||
@@ -440,7 +444,7 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
}
|
||||
|
||||
private void walkLocalRegsUsage(AVM2LocalData localData, Set<Integer> getLocalPos, GraphPart startPart, GraphPart part, Set<GraphPart> visited, int ip, int searchRegId) {
|
||||
private void walkLocalRegsUsage(List<ThrowState> throwStates, AVM2LocalData localData, Set<Integer> getLocalPos, GraphPart startPart, GraphPart part, Set<GraphPart> visited, int ip, int searchRegId) {
|
||||
if (visited.contains(part) && part != startPart) {
|
||||
return;
|
||||
}
|
||||
@@ -510,24 +514,28 @@ public class AVM2Graph extends Graph {
|
||||
//okay, proceed to finally block
|
||||
} else if (targetPart.nextParts.size() == 1) {
|
||||
//continue or break, definitely not a return, there won't be a register usage
|
||||
walkLocalRegsUsage(localData, getLocalPos, startPart, targetPart.nextParts.get(0), visited, ip, searchRegId);
|
||||
walkLocalRegsUsage(throwStates, localData, getLocalPos, startPart, targetPart.nextParts.get(0), visited, ip, searchRegId);
|
||||
return;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (GraphPart p : part.nextParts) {
|
||||
walkLocalRegsUsage(localData, getLocalPos, startPart, p, visited, p.start, searchRegId);
|
||||
walkLocalRegsUsage(throwStates, localData, getLocalPos, startPart, p, visited, p.start, searchRegId);
|
||||
}
|
||||
} finally {
|
||||
for (GraphPart p : part.throwParts) {
|
||||
walkLocalRegsUsage(localData, getLocalPos, startPart, p, visited, p.start, searchRegId);
|
||||
for (ThrowState ts : throwStates) {
|
||||
if (ts.throwingParts.contains(part)) {
|
||||
GraphPart p = ts.targetPart;
|
||||
walkLocalRegsUsage(throwStates, localData, getLocalPos, startPart, p, visited, p.start, searchRegId);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: optimize this to make it faster!!!
|
||||
public Map<Integer, Set<Integer>> calculateLocalRegsUsage(AVM2LocalData localData, Set<Integer> ignoredSwitches, String path, Set<GraphPart> allParts) {
|
||||
public Map<Integer, Set<Integer>> calculateLocalRegsUsage(List<ThrowState> throwStates, AVM2LocalData localData, Set<Integer> ignoredSwitches, String path, Set<GraphPart> allParts) {
|
||||
logger.log(Level.FINE, "--- {0} ---", path);
|
||||
Map<Integer, Set<Integer>> setLocalPosToGetLocalPos = new TreeMap<>();
|
||||
Map<GraphPart, GraphPart> reverseFinallyJumps = new HashMap<>();
|
||||
@@ -557,7 +565,7 @@ public class AVM2Graph extends Graph {
|
||||
if (part == null) { //might be last part of script (?)
|
||||
continue;
|
||||
}
|
||||
walkLocalRegsUsage(localData, setLocalPosToGetLocalPos.get(ip), part, part, new HashSet<>(), ip + 1, setLocalPosToRegisterId.get(ip));
|
||||
walkLocalRegsUsage(throwStates, localData, setLocalPosToGetLocalPos.get(ip), part, part, new HashSet<>(), ip + 1, setLocalPosToRegisterId.get(ip));
|
||||
}
|
||||
|
||||
/*for (int ip : setLocalPosToGetLocalPos.keySet()) {
|
||||
@@ -601,7 +609,7 @@ public class AVM2Graph extends Graph {
|
||||
for (GraphPart p : allBlocks) {
|
||||
if (avm2code.pos2adr(p.start) >= ex.start && avm2code.pos2adr(p.end) <= ex.end && targetPart != null) {
|
||||
//Logger.getLogger(Graph.class.getName()).fine("ADDING throwpart " + target + " to " + p);
|
||||
p.throwParts.add(targetPart);
|
||||
//p.throwParts.add(targetPart);
|
||||
//target.refs.add(p);
|
||||
}
|
||||
}
|
||||
@@ -705,6 +713,31 @@ public class AVM2Graph extends Graph {
|
||||
return ret;
|
||||
}
|
||||
|
||||
private GraphPart firstPartOutsideWalk(GraphPart part, int startIp, int endIp, Set<GraphPart> visited) {
|
||||
if (visited.contains(part)) {
|
||||
return null;
|
||||
}
|
||||
visited.add(part);
|
||||
if (part.start < startIp || part.start >= endIp) {
|
||||
return part;
|
||||
}
|
||||
for (GraphPart n : part.nextParts) {
|
||||
GraphPart r = firstPartOutsideWalk(n, startIp, endIp, visited);
|
||||
if (r != null) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private GraphPart searchFirstPartOutSideTryCatchSimple(ABCException ex, Collection<? extends GraphPart> allParts) {
|
||||
int startIp = code.adr2pos(ex.start, true);
|
||||
int endIp = code.adr2pos(ex.end, true);
|
||||
|
||||
GraphPart startPart = searchPart(startIp, allParts);
|
||||
return firstPartOutsideWalk(startPart, startIp, endIp, new HashSet<>());
|
||||
}
|
||||
|
||||
private GraphPart searchFirstPartOutSideTryCatch(AVM2LocalData localData, ABCException ex, List<Loop> loops, Collection<? extends GraphPart> allParts) {
|
||||
LinkedHashSet<GraphPart> reachable = new LinkedHashSet<>();
|
||||
int startIp = localData.code.adr2pos(ex.start, true);
|
||||
@@ -722,7 +755,7 @@ public class AVM2Graph extends Graph {
|
||||
subLocalData.finallyJumpsToFinallyIndex = new HashMap<>();
|
||||
subLocalData.finallyThrowParts = new HashMap<>();
|
||||
subLocalData.ignoredSwitches = new HashMap<>();
|
||||
getReachableParts(subLocalData, startPart, reachable, loops);
|
||||
getReachableParts(subLocalData, startPart, reachable, loops, new ArrayList<>() /*??*/);
|
||||
|
||||
for (GraphPart r : reachable) {
|
||||
if (r.start < startIp || r.start >= endIp) {
|
||||
@@ -739,43 +772,36 @@ public class AVM2Graph extends Graph {
|
||||
return part;
|
||||
}
|
||||
|
||||
private boolean checkTry(List<GraphTargetItem> currentRet, List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, AVM2LocalData localData, GraphPart part, List<GraphPart> stopPart, List<Loop> loops, Set<GraphPart> allParts, TranslateStack stack, int staticOperation, String path) throws InterruptedException {
|
||||
if (localData.parsedExceptions == null) {
|
||||
localData.parsedExceptions = new ArrayList<>();
|
||||
}
|
||||
List<ABCException> parsedExceptions = localData.parsedExceptions;
|
||||
if (localData.finallyJumps == null) {
|
||||
localData.finallyJumps = new HashMap<>();
|
||||
}
|
||||
if (localData.ignoredSwitches == null) {
|
||||
localData.ignoredSwitches = new HashMap<>();
|
||||
}
|
||||
long addr = avm2code.pos2adr(part.start); //avm2code.getAddrThroughJumpAndDebugLine(avm2code.pos2adr(part.start));
|
||||
long maxEndAddr = -1;
|
||||
List<ABCException> catchedExceptions = new ArrayList<>();
|
||||
private void getCatchedExceptionIds(GraphPart part, List<Integer> previouslyCatchedExceptionIds, List<Integer> catchedExceptionIds, Reference<Integer> finallyIndex, Collection<? extends GraphPart> allParts,
|
||||
List<Loop> loops, AVM2LocalData localData) {
|
||||
|
||||
long addr = avm2code.pos2adr(part.start);
|
||||
long maxEndAddr = -1;
|
||||
finallyIndex.setVal(-1);
|
||||
|
||||
int endIp = -1;
|
||||
List<Integer> finnalysIndicesToBe = new ArrayList<>();
|
||||
int realEndIp = -1;
|
||||
maxEndAddr = -1;
|
||||
for (int e = 0; e < body.exceptions.length; e++) {
|
||||
long fixedExStart = avm2code.pos2adr(avm2code.adr2pos(body.exceptions[e].start, true));
|
||||
long fixedExEnd = avm2code.pos2adr(avm2code.adr2pos(body.exceptions[e].end, true));
|
||||
if (!previouslyCatchedExceptionIds.contains(e)) {
|
||||
if (addr == fixedExStart) { //avm2code.getAddrThroughJumpAndDebugLine(fixedExStart)) {
|
||||
ABCException ex = body.exceptions[e];
|
||||
|
||||
if (addr == fixedExStart) { //avm2code.getAddrThroughJumpAndDebugLine(fixedExStart)) {
|
||||
ABCException ex = body.exceptions[e];
|
||||
if (!parsedExceptions.contains(ex)) {
|
||||
if (ex.isFinally()) {
|
||||
finnalysIndicesToBe.add(e);
|
||||
} else {
|
||||
long endAddr = avm2code.getAddrThroughJumpAndDebugLine(fixedExEnd);
|
||||
if (endAddr > maxEndAddr) {
|
||||
catchedExceptions.clear();
|
||||
catchedExceptionIds.clear();
|
||||
maxEndAddr = avm2code.getAddrThroughJumpAndDebugLine(fixedExEnd);
|
||||
endIp = avm2code.adr2pos(maxEndAddr);
|
||||
realEndIp = avm2code.adr2pos(fixedExEnd);
|
||||
catchedExceptions.add(body.exceptions[e]);
|
||||
/*endIp = avm2code.adr2pos(maxEndAddr);
|
||||
realEndIp = avm2code.adr2pos(fixedExEnd);*/
|
||||
|
||||
catchedExceptionIds.add(e);
|
||||
|
||||
} else if (endAddr == maxEndAddr) {
|
||||
catchedExceptions.add(body.exceptions[e]);
|
||||
catchedExceptionIds.add(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -783,8 +809,7 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
|
||||
//GraphPart endPart = searchPart(endIp, allParts);
|
||||
int finallyIndex = -1;
|
||||
ABCException finallyException = null;
|
||||
//finallyIndex.setVal(-1);
|
||||
|
||||
Collections.sort(finnalysIndicesToBe, new Comparator<Integer>() {
|
||||
@Override
|
||||
@@ -793,48 +818,63 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
});
|
||||
|
||||
/*if (catchedExceptions.isEmpty() && !finnalysIndicesToBe.isEmpty()) {
|
||||
for (int i = 0; i < finnalysIndicesToBe.size(); i++) {
|
||||
int e = finnalysIndicesToBe.get(i);
|
||||
if (!localData.ignoredSwitches.containsKey(e)) {
|
||||
catchedExceptions.add(body.exceptions[e]);
|
||||
finnalysIndicesToBe.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
GraphPart outSideExceptionPart = null;
|
||||
if (!catchedExceptions.isEmpty()) {
|
||||
outSideExceptionPart = searchFirstPartOutSideTryCatch(localData, catchedExceptions.get(0), loops, allParts);
|
||||
if (!catchedExceptionIds.isEmpty()) {
|
||||
outSideExceptionPart = searchFirstPartOutSideTryCatch(localData, body.exceptions[catchedExceptionIds.get(0)], loops, allParts);
|
||||
}
|
||||
|
||||
for (int e : finnalysIndicesToBe) {
|
||||
ABCException finallyExceptionToBe = body.exceptions[e];
|
||||
if (catchedExceptions.isEmpty() || outSideExceptionPart == null) {
|
||||
if (catchedExceptionIds.isEmpty() || outSideExceptionPart == null) {
|
||||
//there's no exception, finally only
|
||||
finallyIndex = e;
|
||||
finallyException = finallyExceptionToBe;
|
||||
finallyIndex.setVal(e);
|
||||
break;
|
||||
}
|
||||
GraphPart outSideExceptionNonEmptyPart = nearestNonEmptyPart(outSideExceptionPart);
|
||||
|
||||
GraphPart outSideFinallyPart = searchFirstPartOutSideTryCatch(localData, finallyExceptionToBe, loops, allParts);
|
||||
if (outSideExceptionNonEmptyPart == outSideFinallyPart) {
|
||||
finallyIndex = e;
|
||||
finallyException = finallyExceptionToBe;
|
||||
finallyIndex.setVal(e);
|
||||
break;
|
||||
}
|
||||
if (outSideExceptionNonEmptyPart.nextParts.size() == 1 && outSideExceptionNonEmptyPart.nextParts.get(0) == outSideFinallyPart) {
|
||||
if (outSideExceptionNonEmptyPart.getHeight() == 1) {
|
||||
if (avm2code.code.get(outSideExceptionNonEmptyPart.start).definition instanceof PushByteIns) {
|
||||
finallyIndex = e;
|
||||
finallyException = finallyExceptionToBe;
|
||||
finallyIndex.setVal(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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<Loop> loops, List<ThrowState> throwStates, Set<GraphPart> allParts, TranslateStack stack, int staticOperation, String path) throws InterruptedException {
|
||||
if (localData.parsedExceptions == null) {
|
||||
localData.parsedExceptions = new ArrayList<>();
|
||||
}
|
||||
if (localData.finallyJumps == null) {
|
||||
localData.finallyJumps = new HashMap<>();
|
||||
}
|
||||
if (localData.ignoredSwitches == null) {
|
||||
localData.ignoredSwitches = new HashMap<>();
|
||||
}
|
||||
|
||||
List<ABCException> parsedExceptions = localData.parsedExceptions;
|
||||
List<Integer> parsedExceptionIds = localData.parsedExceptionIds;
|
||||
|
||||
List<Integer> catchedExceptionIds = new ArrayList<>();
|
||||
Reference<Integer> finallyIndexRef = new Reference<>(-1);
|
||||
|
||||
getCatchedExceptionIds(part, parsedExceptionIds, catchedExceptionIds, finallyIndexRef, allParts, loops, localData);
|
||||
List<ABCException> catchedExceptions = new ArrayList<>();
|
||||
for (int e : catchedExceptionIds) {
|
||||
catchedExceptions.add(body.exceptions[e]);
|
||||
}
|
||||
ABCException finallyException = null;
|
||||
int finallyIndex = finallyIndexRef.getVal();
|
||||
if (finallyIndex > -1) {
|
||||
finallyException = body.exceptions[finallyIndex];
|
||||
}
|
||||
|
||||
if (finallyException != null) {
|
||||
catchedExceptions.add(finallyException);
|
||||
@@ -846,10 +886,24 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
|
||||
if (catchedExceptions.size() > 0) {
|
||||
|
||||
for (ThrowState ts : throwStates) {
|
||||
if (catchedExceptionIds.contains(ts.exceptionId)) {
|
||||
ts.state = 1;
|
||||
}
|
||||
if (ts.exceptionId == finallyIndex) {
|
||||
ts.state = 1;
|
||||
}
|
||||
}
|
||||
|
||||
parsedExceptions.addAll(catchedExceptions);
|
||||
parsedExceptionIds.addAll(catchedExceptionIds);
|
||||
if (finallyException != null) {
|
||||
catchedExceptions.remove(finallyException);
|
||||
}
|
||||
if (finallyIndex > -1) {
|
||||
parsedExceptionIds.add(finallyIndex);
|
||||
}
|
||||
List<GraphTargetItem> tryCommands = new ArrayList<>();
|
||||
List<List<GraphTargetItem>> catchCommands = new ArrayList<>();
|
||||
List<GraphTargetItem> finallyCommands = new ArrayList<>();
|
||||
@@ -863,13 +917,20 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
|
||||
if (partsToCalCommon.size() > 1) {
|
||||
afterPart = getMostCommonPart(localData, partsToCalCommon, loops);
|
||||
/*System.err.println("getting common part of");
|
||||
for (GraphPart p : partsToCalCommon) {
|
||||
System.err.println("- " + p);
|
||||
}*/
|
||||
|
||||
afterPart = getMostCommonPart(localData, partsToCalCommon, loops, throwStates);
|
||||
//System.err.println("result: " + afterPart);
|
||||
}
|
||||
|
||||
if (catchedExceptions.size() > 0 && afterPart == null) {
|
||||
//in all catches is probably continue/return/break or something
|
||||
//we need to search a part which is first outside the try..block
|
||||
afterPart = searchFirstPartOutSideTryCatch(localData, catchedExceptions.get(0), loops, allParts);
|
||||
//System.err.println("oursidetrycatch: " + afterPart);
|
||||
}
|
||||
|
||||
GraphPart exAfterPart = afterPart;
|
||||
@@ -877,7 +938,7 @@ public class AVM2Graph extends Graph {
|
||||
if (finallyException == null) {
|
||||
List<GraphPart> stopPart2 = new ArrayList<>(stopPart);
|
||||
stopPart2.add(afterPart);
|
||||
tryCommands = printGraph(foundGotos, partCodes, partCodePos, localData, stack, allParts, null, part, stopPart2, loops, staticOperation, path);
|
||||
tryCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, part, stopPart2, loops, throwStates, staticOperation, path);
|
||||
}
|
||||
|
||||
boolean inlinedFinally = false;
|
||||
@@ -899,12 +960,15 @@ public class AVM2Graph extends Graph {
|
||||
int targetPos = avm2code.adr2pos(finallyException.target);
|
||||
finallyTryTargetPart = searchPart(targetPos, allParts);
|
||||
|
||||
//Is it wrong to assume try target is only single part before finally?
|
||||
finallyPart = finallyTryTargetPart.nextParts.isEmpty() ? null : finallyTryTargetPart.nextParts.get(0);
|
||||
|
||||
List<GraphPart> finallyTargetStopPart = new ArrayList<>(stopPart);
|
||||
|
||||
//List<GraphPart> finallyTargetStopPart = new ArrayList<>(stopPart);
|
||||
if (finallyPart != null) {
|
||||
//finallyTargetStopPart
|
||||
}
|
||||
if (afterPart != null) {
|
||||
finallyTargetStopPart.add(afterPart);
|
||||
//finallyTargetStopPart.add(afterPart);
|
||||
}
|
||||
|
||||
TranslateStack st2 = (TranslateStack) stack.clone();
|
||||
@@ -912,8 +976,10 @@ public class AVM2Graph extends Graph {
|
||||
st2.add(new ExceptionAVM2Item(finallyException));
|
||||
AVM2LocalData localData2 = new AVM2LocalData(localData);
|
||||
localData2.scopeStack = new ScopeStack();
|
||||
finallyTargetItems = printGraph(foundGotos, partCodes, partCodePos, localData2, st2, allParts, null, finallyTryTargetPart, finallyTargetStopPart, loops, 0, path);
|
||||
boolean targetHasThrow = false;
|
||||
|
||||
//We are assuming Finally target has only 1 part
|
||||
finallyTargetItems = translatePart(localData, finallyTryTargetPart, st2, staticOperation, path);//printGraph(foundGotos, partCodes, partCodePos, visited, localData2, st2, allParts, null, finallyTryTargetPart, finallyTargetStopPart, loops, throwStates, 0, path);
|
||||
//boolean targetHasThrow = false;
|
||||
if (!finallyTargetItems.isEmpty() && (finallyTargetItems.get(finallyTargetItems.size() - 1) instanceof ThrowAVM2Item)) {
|
||||
|
||||
//ignore some usual commands at the beginning - these are ignored in ffdec later, but we need to check it's empty
|
||||
@@ -940,7 +1006,7 @@ public class AVM2Graph extends Graph {
|
||||
if (!isEmpty) { //there must be at least single command before Throw
|
||||
inlinedFinally = true;
|
||||
}
|
||||
targetHasThrow = true;
|
||||
//targetHasThrow = true;
|
||||
}
|
||||
|
||||
List<GraphPart> tryStopPart = new ArrayList<>(stopPart);
|
||||
@@ -948,23 +1014,27 @@ public class AVM2Graph extends Graph {
|
||||
tryStopPart.add(finallyPart);
|
||||
}
|
||||
|
||||
if (finallyPart == null && afterPart != null) {
|
||||
tryStopPart.add(afterPart);
|
||||
}
|
||||
|
||||
if (defaultPart != null) {
|
||||
tryStopPart.add(defaultPart);
|
||||
}
|
||||
|
||||
if (switchPart == null && inlinedFinally && afterPart == null) {
|
||||
//switchPart == null && inlinedFinally &&
|
||||
if (afterPart == null) {
|
||||
afterPart = searchFirstPartOutSideTryCatch(localData, finallyException, loops, allParts);
|
||||
if (afterPart != null) {
|
||||
tryStopPart.add(afterPart);
|
||||
}
|
||||
|
||||
if (afterPart != null) {
|
||||
tryStopPart.add(afterPart);
|
||||
}
|
||||
|
||||
if (switchPart != null) {
|
||||
afterPart = defaultPart;
|
||||
} else {
|
||||
if (!inlinedFinally) {
|
||||
afterPart = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tryCommands = printGraph(foundGotos, partCodes, partCodePos, localData, stack, allParts, null, part, tryStopPart, loops, staticOperation, path);
|
||||
tryCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, part, tryStopPart, loops, throwStates, staticOperation, path);
|
||||
makeAllCommands(tryCommands, stack);
|
||||
processIfs(tryCommands);
|
||||
|
||||
@@ -980,17 +1050,11 @@ public class AVM2Graph extends Graph {
|
||||
finallyStopPart.add(switchPart);
|
||||
}
|
||||
if (finallyPart != null) {
|
||||
finallyCommands = printGraph(foundGotos, partCodes, partCodePos, localData, stack, allParts, null, finallyPart, finallyStopPart, loops, staticOperation, path);
|
||||
finallyCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, finallyPart, finallyStopPart, loops, throwStates, staticOperation, path);
|
||||
}
|
||||
if (switchPart != null) {
|
||||
finallyCommands.addAll(translatePart(localData, switchPart, stack, staticOperation, path));
|
||||
stack.pop(); //value switched by lookupswitch
|
||||
afterPart = defaultPart;
|
||||
exAfterPart = afterPart;
|
||||
} else {
|
||||
if (!inlinedFinally) {
|
||||
afterPart = null;
|
||||
}
|
||||
stack.pop(); //value switched by lookupswitch
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1016,7 +1080,7 @@ public class AVM2Graph extends Graph {
|
||||
stopPart2.add(defaultPart);
|
||||
}
|
||||
|
||||
List<GraphTargetItem> currentCatchCommands = printGraph(foundGotos, partCodes, partCodePos, localData2, st2, allParts, null, catchPart, stopPart2, loops, staticOperation, path);
|
||||
List<GraphTargetItem> currentCatchCommands = printGraph(foundGotos, partCodes, partCodePos, visited, localData2, st2, allParts, null, catchPart, stopPart2, loops, throwStates, staticOperation, path);
|
||||
/*if (!currentCatchCommands.isEmpty() && (currentCatchCommands.get(0) instanceof SetLocalAVM2Item)) {
|
||||
if (currentCatchCommands.get(0).value.getNotCoerced() instanceof ExceptionAVM2Item) {
|
||||
currentCatchCommands.remove(0);
|
||||
@@ -1031,6 +1095,15 @@ public class AVM2Graph extends Graph {
|
||||
catchCommands.add(currentCatchCommands);
|
||||
}
|
||||
|
||||
for (ThrowState ts : throwStates) {
|
||||
if (catchedExceptionIds.contains(ts.exceptionId)) {
|
||||
ts.state = 2;
|
||||
}
|
||||
if (ts.exceptionId == finallyIndex) {
|
||||
ts.state = 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (!inlinedFinally && catchCommands.isEmpty() && finallyCommands.isEmpty() && tryCommands.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
@@ -1047,7 +1120,6 @@ public class AVM2Graph extends Graph {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
TryAVM2Item tryItem = new TryAVM2Item(tryCommands, catchedExceptions, catchCommands, finallyCommands, "");
|
||||
if (inlinedFinally) {
|
||||
List<List<GraphTargetItem>> parentCatchCommands = new ArrayList<>();
|
||||
@@ -1079,7 +1151,7 @@ public class AVM2Graph extends Graph {
|
||||
if (finallyIndex > -1 && localData.finallyIndicesWithDoublePush.contains(finallyIndex)) {
|
||||
stack.push(new AnyItem());
|
||||
}
|
||||
currentRet.addAll(printGraph(foundGotos, partCodes, partCodePos, localData, stack, allParts, null, afterPart, stopPart, loops, staticOperation, path));
|
||||
currentRet.addAll(printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, afterPart, stopPart, loops, throwStates, staticOperation, path));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1087,7 +1159,22 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canHandleLoop(BaseLocalData localData, GraphPart part, List<Loop> loops) {
|
||||
protected boolean canHandleVisited(BaseLocalData localData, GraphPart part) {
|
||||
AVM2LocalData aLocalData = (AVM2LocalData) localData;
|
||||
for (ABCException ex : body.exceptions) {
|
||||
if (aLocalData.parsedExceptions.contains(ex)) {
|
||||
continue;
|
||||
}
|
||||
int fixStart = avm2code.adr2pos(ex.start, true);
|
||||
if (part.start == fixStart) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canHandleLoop(BaseLocalData localData, GraphPart part, List<Loop> loops, List<ThrowState> throwStates) {
|
||||
Loop toBeLoop = null;
|
||||
for (Loop el : loops) {
|
||||
if ((el.loopContinue == part) && (el.phase == 0)) {
|
||||
@@ -1124,15 +1211,14 @@ public class AVM2Graph extends Graph {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean checkPartOutput(List<GraphTargetItem> currentRet, List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, GraphSource code, BaseLocalData localData, Set<GraphPart> allParts, TranslateStack stack, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<Loop> loops, Loop currentLoop, int staticOperation, String path) throws InterruptedException {
|
||||
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<Loop> loops, List<ThrowState> throwStates, Loop currentLoop, int staticOperation, String path) throws InterruptedException {
|
||||
AVM2LocalData aLocalData = (AVM2LocalData) localData;
|
||||
return checkTry(currentRet, foundGotos, partCodes, partCodePos, aLocalData, part, stopPart, loops, allParts, stack, staticOperation, path);
|
||||
return checkTry(currentRet, foundGotos, partCodes, partCodePos, visited, aLocalData, part, stopPart, loops, throwStates, allParts, stack, staticOperation, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<GraphTargetItem> check(List<GraphTargetItem> currentRet, List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, GraphSource code, BaseLocalData localData, Set<GraphPart> allParts, TranslateStack stack, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<Loop> loops, List<GraphTargetItem> output, Loop currentLoop, int staticOperation, String path) throws InterruptedException {
|
||||
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<Loop> loops, List<ThrowState> throwStates, List<GraphTargetItem> output, Loop currentLoop, int staticOperation, String path) throws InterruptedException {
|
||||
List<GraphTargetItem> ret = null;
|
||||
|
||||
/*if (ret != null) {
|
||||
@@ -1218,13 +1304,15 @@ public class AVM2Graph extends Graph {
|
||||
} else {
|
||||
part = part.nextParts.get(1);
|
||||
GraphPart defaultPart = part;
|
||||
if (code.size() > defaultPart.start && ((AVM2Instruction) code.get(defaultPart.start)).definition instanceof JumpIns) {
|
||||
if (code.size() > defaultPart.start && ((AVM2Instruction) code.get(defaultPart.start)).definition instanceof JumpIns
|
||||
&& defaultPart.refs.size() == 1
|
||||
&& !partIsLoopContBrePre(defaultPart, loops, throwStates)) {
|
||||
defaultPart = defaultPart.nextParts.get(0);
|
||||
}
|
||||
|
||||
Reference<GraphPart> nextRef = new Reference<>(null);
|
||||
Reference<GraphTargetItem> tiRef = new Reference<>(null);
|
||||
SwitchItem sw = handleSwitch(switchedObject, switchStartItem, foundGotos, partCodes, partCodePos, allParts, stack, stopPart, loops, localData, staticOperation, path, caseValuesMap, defaultPart, caseBodyParts, nextRef, tiRef);
|
||||
SwitchItem sw = handleSwitch(switchedObject, switchStartItem, foundGotos, partCodes, partCodePos, visited, allParts, stack, stopPart, loops, throwStates, localData, staticOperation, path, caseValuesMap, defaultPart, caseBodyParts, nextRef, tiRef);
|
||||
ret = new ArrayList<>();
|
||||
ret.addAll(output);
|
||||
checkSwitch(localData, sw, otherSide, ret.isEmpty() ? currentRet : ret /*hack :-(*/);
|
||||
@@ -1233,7 +1321,7 @@ public class AVM2Graph extends Graph {
|
||||
if (tiRef.getVal() != null) {
|
||||
ret.add(tiRef.getVal());
|
||||
} else {
|
||||
ret.addAll(printGraph(foundGotos, partCodes, partCodePos, localData, stack, allParts, null, nextRef.getVal(), stopPart, loops, staticOperation, path));
|
||||
ret.addAll(printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, nextRef.getVal(), stopPart, loops, throwStates, staticOperation, path));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1348,7 +1436,7 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GraphTargetItem checkLoop(List<GraphTargetItem> output, LoopItem loopItem, BaseLocalData localData, List<Loop> loops) {
|
||||
protected GraphTargetItem checkLoop(List<GraphTargetItem> output, LoopItem loopItem, BaseLocalData localData, List<Loop> loops, List<ThrowState> throwStates) {
|
||||
AVM2LocalData aLocalData = (AVM2LocalData) localData;
|
||||
if (loopItem instanceof WhileItem) {
|
||||
WhileItem w = (WhileItem) loopItem;
|
||||
@@ -1812,8 +1900,8 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FinalProcessLocalData getFinalData(BaseLocalData localData, List<Loop> loops) {
|
||||
FinalProcessLocalData finalProcess = super.getFinalData(localData, loops);
|
||||
protected FinalProcessLocalData getFinalData(BaseLocalData localData, List<Loop> loops, List<ThrowState> throwStates) {
|
||||
FinalProcessLocalData finalProcess = super.getFinalData(localData, loops, throwStates);
|
||||
finalProcess.registerUsage = ((AVM2LocalData) localData).setLocalPosToGetLocalPos;
|
||||
return finalProcess;
|
||||
}
|
||||
@@ -1868,4 +1956,25 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
return avm2code.code.get(part.end).definition instanceof LookupSwitchIns;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ThrowState> getThrowStates(Set<GraphPart> allParts) {
|
||||
List<ThrowState> ret = new ArrayList<>();
|
||||
for (int e = 0; e < body.exceptions.length; e++) {
|
||||
ThrowState ts = new ThrowState();
|
||||
ts.exceptionId = e;
|
||||
ts.state = 0;
|
||||
ts.targetPart = searchPart(code.adr2pos(body.exceptions[e].target), allParts);
|
||||
int startIp = code.adr2pos(body.exceptions[e].start, true);
|
||||
int endIp = code.adr2pos(body.exceptions[e].end, true);
|
||||
for (GraphPart p : allParts) {
|
||||
if (p.start >= startIp && p.start < endIp) {
|
||||
ts.throwingParts.add(p);
|
||||
}
|
||||
}
|
||||
ret.add(ts);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItemContainer;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.Loop;
|
||||
import com.jpexs.decompiler.graph.ThrowState;
|
||||
import com.jpexs.decompiler.graph.TranslateStack;
|
||||
import com.jpexs.decompiler.graph.model.BreakItem;
|
||||
import com.jpexs.decompiler.graph.model.ContinueItem;
|
||||
@@ -58,6 +59,7 @@ import com.jpexs.decompiler.graph.model.ScriptEndItem;
|
||||
import com.jpexs.decompiler.graph.model.SwitchItem;
|
||||
import com.jpexs.decompiler.graph.model.WhileItem;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.Reference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -288,7 +290,7 @@ public class ActionGraph extends Graph {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<GraphTargetItem> check(List<GraphTargetItem> currentRet, List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, GraphSource code, BaseLocalData localData, Set<GraphPart> allParts, TranslateStack stack, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<Loop> loops, List<GraphTargetItem> output, Loop currentLoop, int staticOperation, String path) throws InterruptedException {
|
||||
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<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);
|
||||
@@ -312,13 +314,11 @@ public class ActionGraph extends Graph {
|
||||
}
|
||||
List<GraphTargetItem> caseValuesMap = new ArrayList<>();
|
||||
|
||||
//int pos = 0;
|
||||
StrictEqActionItem set = (StrictEqActionItem) stack.pop();
|
||||
caseValuesMap.add(set.rightSide);
|
||||
if (set.leftSide instanceof StoreRegisterActionItem) {
|
||||
switchedObject = ((StoreRegisterActionItem) set.leftSide).value;
|
||||
}
|
||||
//GraphPart switchLoc = part.nextParts.get(1).nextParts.get(0);
|
||||
List<GraphPart> caseBodyParts = new ArrayList<>();
|
||||
caseBodyParts.add(part.nextParts.get(0));
|
||||
GraphTargetItem top = null;
|
||||
@@ -339,185 +339,23 @@ public class ActionGraph extends Graph {
|
||||
} else {
|
||||
part = part.nextParts.get(1);
|
||||
GraphPart defaultPart = part;
|
||||
if (code.size() > defaultPart.start && code.get(defaultPart.start) instanceof ActionJump) {
|
||||
if (code.size() > defaultPart.start && code.get(defaultPart.start) instanceof ActionJump
|
||||
&& defaultPart.refs.size() == 1
|
||||
&& !partIsLoopContBrePre(defaultPart, loops, throwStates)) {
|
||||
defaultPart = defaultPart.nextParts.get(0);
|
||||
}
|
||||
|
||||
boolean hasDefault = false;
|
||||
/*
|
||||
case 4:
|
||||
case 5:
|
||||
default:
|
||||
trace("5 & def");
|
||||
...
|
||||
case 6:
|
||||
|
||||
*/
|
||||
//must go backwards to hit case 5, not case 4
|
||||
for (int i = caseBodyParts.size() - 1; i >= 0; i--) {
|
||||
if (caseBodyParts.get(i) == defaultPart) {
|
||||
DefaultItem di = new DefaultItem();
|
||||
caseValuesMap.add(i + 1, di);
|
||||
caseBodyParts.add(i + 1, defaultPart);
|
||||
hasDefault = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasDefault) {
|
||||
/*
|
||||
case 1:
|
||||
trace("1");
|
||||
case 2:
|
||||
trace("2"); //no break
|
||||
default:
|
||||
trace("def");
|
||||
...
|
||||
case 3:
|
||||
*/
|
||||
//must go backwards to hit case 2, not case 1
|
||||
for (int i = caseBodyParts.size() - 1; i >= 0; i--) {
|
||||
if (caseBodyParts.get(i).leadsTo(localData, this, code, defaultPart, loops, false)) {
|
||||
DefaultItem di = new DefaultItem();
|
||||
caseValuesMap.add(i + 1, di);
|
||||
caseBodyParts.add(i + 1, defaultPart);
|
||||
hasDefault = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasDefault) {
|
||||
/*
|
||||
case 1:
|
||||
trace("1");
|
||||
break;
|
||||
default:
|
||||
trace("def"); //no break
|
||||
case 2:
|
||||
trace("2");
|
||||
*/
|
||||
for (int i = 0; i < caseBodyParts.size(); i++) {
|
||||
if (defaultPart.leadsTo(localData, this, code, caseBodyParts.get(i), loops, false)) {
|
||||
DefaultItem di = new DefaultItem();
|
||||
caseValuesMap.add(i, di);
|
||||
caseBodyParts.add(i, defaultPart);
|
||||
hasDefault = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasDefault) {
|
||||
/*
|
||||
case 1:
|
||||
...
|
||||
case 2:
|
||||
...
|
||||
default:
|
||||
trace("def");
|
||||
*/
|
||||
caseValuesMap.add(new DefaultItem());
|
||||
caseBodyParts.add(defaultPart);
|
||||
}
|
||||
|
||||
GraphPart breakPart = getMostCommonPart(localData, caseBodyParts, loops);
|
||||
//removeEdgeToFromList(gotoTargets, breakPart);
|
||||
List<List<GraphTargetItem>> caseCommands = new ArrayList<>();
|
||||
GraphPart next = breakPart;
|
||||
|
||||
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);
|
||||
currentLoop.phase = 1;
|
||||
loops.add(currentLoop);
|
||||
List<Integer> valuesMapping = new ArrayList<>();
|
||||
List<GraphPart> caseBodies = new ArrayList<>();
|
||||
for (int i = 0; i < caseValuesMap.size(); i++) {
|
||||
GraphPart cur = caseBodyParts.get(i);
|
||||
if (!caseBodies.contains(cur)) {
|
||||
//removeEdgeToFromList(gotoTargets, cur);
|
||||
caseBodies.add(cur);
|
||||
}
|
||||
valuesMapping.add(caseBodies.indexOf(cur));
|
||||
}
|
||||
|
||||
for (int i = 0; i < caseBodies.size(); i++) {
|
||||
List<GraphTargetItem> currentCaseCommands = new ArrayList<>();
|
||||
GraphPart nextCase = next;
|
||||
if (next != null) {
|
||||
if (i < caseBodies.size() - 1) {
|
||||
if (!caseBodies.get(i).leadsTo(localData, this, code, caseBodies.get(i + 1), loops, false)) {
|
||||
currentCaseCommands.add(new BreakItem(null, localData.lineStartInstruction, currentLoop.id));
|
||||
} else {
|
||||
nextCase = caseBodies.get(i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
List<GraphPart> stopPart2x = new ArrayList<>(stopPart);
|
||||
for (GraphPart b : caseBodies) {
|
||||
if (b != caseBodies.get(i)) {
|
||||
stopPart2x.add(b);
|
||||
}
|
||||
}
|
||||
if (breakPart != null) {
|
||||
stopPart2x.add(breakPart);
|
||||
}
|
||||
currentCaseCommands.addAll(0, printGraph(foundGotos, partCodes, partCodePos, localData, stack, allParts, null, caseBodies.get(i), stopPart2x, loops, staticOperation, path));
|
||||
if (currentCaseCommands.size() >= 2) {
|
||||
if (currentCaseCommands.get(currentCaseCommands.size() - 1) instanceof BreakItem) {
|
||||
if ((currentCaseCommands.get(currentCaseCommands.size() - 2) instanceof ContinueItem) || (currentCaseCommands.get(currentCaseCommands.size() - 2) instanceof BreakItem)) {
|
||||
currentCaseCommands.remove(currentCaseCommands.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
caseCommands.add(currentCaseCommands);
|
||||
}
|
||||
|
||||
//If the lastone is default empty and alone, remove it
|
||||
if (!caseCommands.isEmpty()) {
|
||||
List<GraphTargetItem> lastc = caseCommands.get(caseCommands.size() - 1);
|
||||
if (!lastc.isEmpty() && (lastc.get(lastc.size() - 1) instanceof BreakItem)) {
|
||||
BreakItem bi = (BreakItem) lastc.get(lastc.size() - 1);
|
||||
lastc.remove(lastc.size() - 1);
|
||||
}
|
||||
if (lastc.isEmpty()) {
|
||||
int cnt2 = 0;
|
||||
if (caseValuesMap.get(caseValuesMap.size() - 1) instanceof DefaultItem) {
|
||||
for (int i = valuesMapping.size() - 1; i >= 0; i--) {
|
||||
if (valuesMapping.get(i) == caseCommands.size() - 1) {
|
||||
cnt2++;
|
||||
}
|
||||
}
|
||||
|
||||
caseValuesMap.remove(caseValuesMap.size() - 1);
|
||||
valuesMapping.remove(valuesMapping.size() - 1);
|
||||
if (cnt2 == 1) {
|
||||
caseCommands.remove(lastc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//remove last break from last section
|
||||
if (!caseCommands.isEmpty()) {
|
||||
List<GraphTargetItem> lastc = caseCommands.get(caseCommands.size() - 1);
|
||||
if (!lastc.isEmpty() && (lastc.get(lastc.size() - 1) instanceof BreakItem)) {
|
||||
BreakItem bi = (BreakItem) lastc.get(lastc.size() - 1);
|
||||
lastc.remove(lastc.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
Reference<GraphPart> nextRef = new Reference<>(null);
|
||||
Reference<GraphTargetItem> tiRef = new Reference<>(null);
|
||||
SwitchItem sw = handleSwitch(switchedObject, switchStartItem, foundGotos, partCodes, partCodePos, visited, allParts, stack, stopPart, loops, throwStates, localData, staticOperation, path, caseValuesMap, defaultPart, caseBodyParts, nextRef, tiRef);
|
||||
ret = new ArrayList<>();
|
||||
ret.addAll(output);
|
||||
SwitchItem sti = new SwitchItem(null, switchStartItem, currentLoop, switchedObject, caseValuesMap, caseCommands, valuesMapping);
|
||||
ret.add(sti);
|
||||
currentLoop.phase = 2;
|
||||
if (next != null) {
|
||||
if (ti != null) {
|
||||
ret.add(ti);
|
||||
ret.add(sw);
|
||||
if (nextRef.getVal() != null) {
|
||||
if (tiRef.getVal() != null) {
|
||||
ret.add(tiRef.getVal());
|
||||
} else {
|
||||
ret.addAll(printGraph(foundGotos, partCodes, partCodePos, localData, stack, allParts, null, next, stopPart, loops, staticOperation, path));
|
||||
ret.addAll(printGraph(foundGotos, partCodes, partCodePos, visited, localData, stack, allParts, null, nextRef.getVal(), stopPart, loops, throwStates, staticOperation, path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user