Issues #319: AS3 - Improved try..catch..finally decompilation

This commit is contained in:
Jindra Petk
2013-08-11 17:21:29 +02:00
parent 1cc46522e7
commit 5d092a0954
10 changed files with 297 additions and 179 deletions

View File

@@ -1089,7 +1089,7 @@ public class SWFInputStream extends InputStream {
}
}
}
HashMap<String, GraphTargetItem> curstate = new HashMap<String, GraphTargetItem>();
HashMap<String, GraphTargetItem> curstate = new HashMap<>();
curstate.putAll(vars);
decisionStates.put(ip, curstate);

View File

@@ -893,6 +893,18 @@ public class AVM2Code implements Serializable {
for (int i = 0; i < output.size(); i++) {
if (output.get(i) instanceof SetLocalAVM2Item) {
if (isKilled(((SetLocalAVM2Item) output.get(i)).regIndex, 0, code.size() - 1)) {
SetLocalAVM2Item lsi = (SetLocalAVM2Item) output.get(i);
if (i + 1 < output.size()) {
if (output.get(i + 1) instanceof ReturnValueAVM2Item) {
ReturnValueAVM2Item rv = (ReturnValueAVM2Item) output.get(i + 1);
if (rv.value instanceof LocalRegAVM2Item) {
LocalRegAVM2Item lr = (LocalRegAVM2Item) rv.value;
if (lr.regIndex == lsi.regIndex) {
rv.value = lsi.value;
}
}
}
}
output.remove(i);
i--;
}
@@ -907,8 +919,8 @@ public class AVM2Code implements Serializable {
if (ip >= code.size()) {
return code.size() - 1;
}
if (code.get(ip).definition instanceof DebugLineIns) {
return ip + 1;
while (code.get(ip).definition instanceof DebugLineIns) {
ip++;
}
return ip;
}
@@ -975,37 +987,37 @@ public class AVM2Code implements Serializable {
}
}
}
if ((ip + 8 < code.size())) { //return in finally clause
if (ins.definition instanceof SetLocalTypeIns) {
if (code.get(ip + 1).definition instanceof PushByteIns) {
AVM2Instruction jmp = code.get(ip + 2);
if (jmp.definition instanceof JumpIns) {
if (jmp.operands[0] == 0) {
if (code.get(ip + 3).definition instanceof LabelIns) {
if (code.get(ip + 4).definition instanceof PopIns) {
if (code.get(ip + 5).definition instanceof LabelIns) {
AVM2Instruction gl = code.get(ip + 6);
if (gl.definition instanceof GetLocalTypeIns) {
if (((GetLocalTypeIns) gl.definition).getRegisterId(gl) == ((SetLocalTypeIns) ins.definition).getRegisterId(ins)) {
AVM2Instruction ki = code.get(ip + 7);
if (ki.definition instanceof KillIns) {
if (ki.operands[0] == ((SetLocalTypeIns) ins.definition).getRegisterId(ins)) {
if (code.get(ip + 8).definition instanceof ReturnValueIns) {
ip = ip + 8;
continue;
}
}
}
}
}
}
}
}
}
}
}
}
}
/*if ((ip + 8 < code.size())) { //return in finally clause
if (ins.definition instanceof SetLocalTypeIns) {
if (code.get(ip + 1).definition instanceof PushByteIns) {
AVM2Instruction jmp = code.get(ip + 2);
if (jmp.definition instanceof JumpIns) {
if (jmp.operands[0] == 0) {
if (code.get(ip + 3).definition instanceof LabelIns) {
if (code.get(ip + 4).definition instanceof PopIns) {
if (code.get(ip + 5).definition instanceof LabelIns) {
AVM2Instruction gl = code.get(ip + 6);
if (gl.definition instanceof GetLocalTypeIns) {
if (((GetLocalTypeIns) gl.definition).getRegisterId(gl) == ((SetLocalTypeIns) ins.definition).getRegisterId(ins)) {
AVM2Instruction ki = code.get(ip + 7);
if (ki.definition instanceof KillIns) {
if (ki.operands[0] == ((SetLocalTypeIns) ins.definition).getRegisterId(ins)) {
if (code.get(ip + 8).definition instanceof ReturnValueIns) {
ip = ip + 8;
continue;
}
}
}
}
}
}
}
}
}
}
}
}
}//*/
/*if ((ip + 2 < code.size()) && (ins.definition instanceof NewCatchIns)) { //Filling local register in catch clause
if (code.get(ip + 1).definition instanceof DupIns) {

View File

@@ -50,6 +50,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictEqAVM2Item;
import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictNeqAVM2Item;
import com.jpexs.decompiler.flash.abc.types.ABCException;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
import com.jpexs.decompiler.graph.Graph;
import com.jpexs.decompiler.graph.GraphPart;
import com.jpexs.decompiler.graph.GraphPartMulti;
@@ -75,17 +76,17 @@ import java.util.Stack;
*/
public class AVM2Graph extends Graph {
private AVM2Code code;
private AVM2Code avm2code;
private ABC abc;
private MethodBody body;
public AVM2Code getCode() {
return code;
return avm2code;
}
public AVM2Graph(AVM2Code code, ABC abc, MethodBody body, boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, Stack<GraphTargetItem> scopeStack, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames, HashMap<Integer, Integer> localRegAssigmentIps, HashMap<Integer, List<Integer>> refs) {
super(new AVM2GraphSource(code, isStatic, scriptIndex, classIndex, localRegs, scopeStack, abc, body, localRegNames, fullyQualifiedNames, localRegAssigmentIps, refs), body.getExceptionEntries());
this.code = code;
this.avm2code = code;
this.abc = abc;
this.body = body;
/*heads = makeGraph(code, new ArrayList<GraphPart>(), body);
@@ -114,11 +115,7 @@ public class AVM2Graph extends Graph {
public static List<GraphTargetItem> translateViaGraph(String path, AVM2Code code, ABC abc, MethodBody body, boolean isStatic, int scriptIndex, int classIndex, HashMap<Integer, GraphTargetItem> localRegs, Stack<GraphTargetItem> scopeStack, HashMap<Integer, String> localRegNames, List<String> fullyQualifiedNames, int staticOperation, HashMap<Integer, Integer> localRegAssigmentIps, HashMap<Integer, List<Integer>> refs) {
AVM2Graph g = new AVM2Graph(code, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localRegNames, fullyQualifiedNames, localRegAssigmentIps, refs);
g.init();
List<GraphPart> allParts = new ArrayList<>();
for (GraphPart head : g.heads) {
populateParts(head, allParts);
}
List<Object> localData = new ArrayList<>();
localData.add((Boolean) isStatic);
localData.add((Integer) classIndex);
@@ -131,22 +128,27 @@ public class AVM2Graph extends Graph {
localData.add(localRegNames);
localData.add(fullyQualifiedNames);
localData.add(new ArrayList<ABCException>());
localData.add(new ArrayList<Integer>());
localData.add(new ArrayList<Integer>()); //finallyJumps
localData.add(new ArrayList<Integer>());
localData.add((Integer) scriptIndex);
localData.add(new HashMap<Integer, Integer>()); //localRegAssignmentIps
localData.add(Integer.valueOf(0));
localData.add(refs);
localData.add(code);
g.init(localData);
List<GraphPart> allParts = new ArrayList<>();
for (GraphPart head : g.heads) {
populateParts(head, allParts);
}
return g.translate(localData, staticOperation, path);
}
@Override
protected void checkGraph(List<GraphPart> allBlocks) {
for (ABCException ex : body.exceptions) {
int startIp = code.adr2pos(ex.start);
int endIp = code.adr2pos(ex.end);
int targetIp = code.adr2pos(ex.target);
int startIp = avm2code.adr2pos(ex.start);
int endIp = avm2code.adr2pos(ex.end);
int targetIp = avm2code.adr2pos(ex.target);
GraphPart target = null;
for (GraphPart p : allBlocks) {
if (p.start == targetIp) {
@@ -194,17 +196,17 @@ public class AVM2Graph extends Graph {
@SuppressWarnings("unchecked")
List<Integer> ignoredSwitches = (List<Integer>) localData.get(DATA_IGNOREDSWITCHES);
int ip = part.start;
int addr = this.code.fixAddrAfterDebugLine(this.code.pos2adr(part.start));
int addr = this.avm2code.fixAddrAfterDebugLine(this.avm2code.pos2adr(part.start));
int maxend = -1;
List<ABCException> catchedExceptions = new ArrayList<>();
for (int e = 0; e < body.exceptions.length; e++) {
if (addr == this.code.fixAddrAfterDebugLine(body.exceptions[e].start)) {
if (addr == this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].start)) {
if (!body.exceptions[e].isFinally()) {
if (((body.exceptions[e].end) > maxend) && (!parsedExceptions.contains(body.exceptions[e]))) {
catchedExceptions.clear();
maxend = this.code.fixAddrAfterDebugLine(body.exceptions[e].end);
maxend = this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].end);
catchedExceptions.add(body.exceptions[e]);
} else if (this.code.fixAddrAfterDebugLine(body.exceptions[e].end) == maxend) {
} else if (this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].end) == maxend) {
catchedExceptions.add(body.exceptions[e]);
}
}
@@ -215,19 +217,19 @@ public class AVM2Graph extends Graph {
//currentLoop.phase=0;
}*/
parsedExceptions.addAll(catchedExceptions);
int endpos = code.adr2pos(this.code.fixAddrAfterDebugLine(catchedExceptions.get(0).end));
int endpos = code.adr2pos(this.avm2code.fixAddrAfterDebugLine(catchedExceptions.get(0).end));
int endposStartBlock = code.adr2pos(catchedExceptions.get(0).end);
List<List<GraphTargetItem>> catchedCommands = new ArrayList<>();
if (this.code.code.get(endpos).definition instanceof JumpIns) {
int afterCatchAddr = this.code.pos2adr(endpos + 1) + this.code.code.get(endpos).operands[0];
int afterCatchPos = this.code.adr2pos(afterCatchAddr);
if (this.avm2code.code.get(endpos).definition instanceof JumpIns) {
int afterCatchAddr = this.avm2code.pos2adr(endpos + 1) + this.avm2code.code.get(endpos).operands[0];
int afterCatchPos = this.avm2code.adr2pos(afterCatchAddr);
final AVM2Graph t = this;
Collections.sort(catchedExceptions, new Comparator<ABCException>() {
@Override
public int compare(ABCException o1, ABCException o2) {
return t.code.fixAddrAfterDebugLine(o1.target) - t.code.fixAddrAfterDebugLine(o2.target);
return t.avm2code.fixAddrAfterDebugLine(o1.target) - t.avm2code.fixAddrAfterDebugLine(o2.target);
}
});
@@ -236,13 +238,13 @@ public class AVM2Graph extends Graph {
int returnPos = afterCatchPos;
for (int e = 0; e < body.exceptions.length; e++) {
if (body.exceptions[e].isFinally()) {
if (addr == this.code.fixAddrAfterDebugLine(body.exceptions[e].start)) {
if (afterCatchPos + 1 == code.adr2pos(this.code.fixAddrAfterDebugLine(body.exceptions[e].end))) {
AVM2Instruction jmpIns = this.code.code.get(code.adr2pos(this.code.fixAddrAfterDebugLine(body.exceptions[e].end)));
if (jmpIns.definition instanceof JumpIns) {
int finStart = code.adr2pos(this.code.fixAddrAfterDebugLine(body.exceptions[e].end) + jmpIns.getBytes().length + jmpIns.operands[0]);
if (addr == this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].start)) {
if (afterCatchPos + 1 == code.adr2pos(this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].end))) {
AVM2Instruction jmpIns = this.avm2code.code.get(code.adr2pos(this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].end)));
if (jmpIns.definition instanceof JumpIns) {
int finStart = code.adr2pos(this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].end) + jmpIns.getBytes().length + jmpIns.operands[0]);
boolean switchFound = false;
GraphPart fpart = null;
for (GraphPart p : allParts) {
if (p.start == finStart) {
@@ -250,9 +252,10 @@ public class AVM2Graph extends Graph {
break;
}
}
for (int f = finStart; f < this.code.code.size(); f++) {
if (this.code.code.get(f).definition instanceof LookupSwitchIns) {
AVM2Instruction swins = this.code.code.get(f);
int swPos = -1;
for (int f = finStart; f < this.avm2code.code.size(); f++) {
if (this.avm2code.code.get(f).definition instanceof LookupSwitchIns) {
AVM2Instruction swins = this.avm2code.code.get(f);
if (swins.operands.length >= 3) {
if (swins.operands[0] == swins.getBytes().length) {
if (code.adr2pos(code.pos2adr(f) + swins.operands[2]) < finStart) {
@@ -265,10 +268,12 @@ public class AVM2Graph extends Graph {
}
}
//this.code.code.get(f).ignored = true;
ignoredSwitches.add(f);
//ignoredSwitches.add(f);
swPos = f;
List<GraphPart> stopPart2 = new ArrayList<>(stopPart);
stopPart2.add(fepart);
finallyCommands = printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, parent, fpart, stopPart2, loops, staticOperation, path);
//finallyCommands = printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, parent, fpart, stopPart2, loops, staticOperation, path);
returnPos = f + 1;
break;
}
@@ -276,9 +281,14 @@ public class AVM2Graph extends Graph {
}
}
}
if (!switchFound) {
finallyCommands = printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, parent, fpart, null, loops, staticOperation, path);
}
//ignoredSwitches.add(-1);
//int igs_size=ignoredSwitches.size();
List<Integer> oldFinallyJumps = new ArrayList<>(finallyJumps);
finallyJumps.clear();
ignoredSwitches.add(swPos);
finallyCommands = printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, parent, fpart, null, loops, staticOperation, path);
//ignoredSwitches.remove(igs_size-1);
finallyJumps.addAll(oldFinallyJumps);
finallyJumps.add(finStart);
break;
}
@@ -286,11 +296,19 @@ public class AVM2Graph extends Graph {
}
}
}
GraphPart retPart = null;
for (GraphPart p : allParts) {
if (p.start == returnPos) {
retPart = p;
break;
}
}
List<GraphPart> catchParts = new ArrayList<>();
for (int e = 0; e < catchedExceptions.size(); e++) {
int eendpos;
if (e < catchedExceptions.size() - 1) {
eendpos = code.adr2pos(this.code.fixAddrAfterDebugLine(catchedExceptions.get(e + 1).target)) - 2;
eendpos = code.adr2pos(this.avm2code.fixAddrAfterDebugLine(catchedExceptions.get(e + 1).target)) - 2;
} else {
eendpos = afterCatchPos - 1;
}
@@ -318,6 +336,9 @@ public class AVM2Graph extends Graph {
localData2.set(DATA_SCOPESTACK, new Stack<GraphTargetItem>());
List<GraphPart> stopPart2 = new ArrayList<>(stopPart);
stopPart2.add(nepart);
if (retPart != null) {
stopPart2.add(retPart);
}
catchedCommands.add(printGraph(new ArrayList<GraphPart>(), localData2, stack, allParts, parent, npart, stopPart2, loops, staticOperation, path));
}
@@ -332,6 +353,10 @@ public class AVM2Graph extends Graph {
List<GraphPart> stopPart2 = new ArrayList<>(stopPart);
stopPart2.add(nepart);
stopPart2.addAll(catchParts);
if (retPart != null) {
stopPart2.add(retPart);
}
List<GraphTargetItem> tryCommands = printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, parent, part, stopPart2, loops, staticOperation, path);
output.clear();
@@ -364,16 +389,16 @@ public class AVM2Graph extends Graph {
}
if (part.nextParts.isEmpty()) {
if (this.code.code.get(part.end).definition instanceof ReturnValueIns) { //returns in finally clause
if (this.avm2code.code.get(part.end).definition instanceof ReturnValueIns) { //returns in finally clause
if (part.getHeight() >= 3) {
if (this.code.code.get(part.getPosAt(part.getHeight() - 2)).definition instanceof KillIns) {
if (this.code.code.get(part.getPosAt(part.getHeight() - 3)).definition instanceof GetLocalTypeIns) {
if (this.avm2code.code.get(part.getPosAt(part.getHeight() - 2)).definition instanceof KillIns) {
if (this.avm2code.code.get(part.getPosAt(part.getHeight() - 3)).definition instanceof GetLocalTypeIns) {
if (output.size() >= 2) {
if (output.get(output.size() - 2) instanceof SetLocalAVM2Item) {
ret = new ArrayList<>();
ret.addAll(output);
ret.remove(ret.size() - 1);
ret.add(new ReturnValueAVM2Item(this.code.code.get(part.end), ((SetLocalAVM2Item) output.get(output.size() - 2)).value));
ret.add(new ReturnValueAVM2Item(this.avm2code.code.get(part.end), ((SetLocalAVM2Item) output.get(output.size() - 2)).value));
return ret;
}
}
@@ -382,7 +407,7 @@ public class AVM2Graph extends Graph {
}
}
}
if ((this.code.code.get(part.end).definition instanceof LookupSwitchIns) && ignoredSwitches.contains(part.end)) {
if ((this.avm2code.code.get(part.end).definition instanceof LookupSwitchIns) && ignoredSwitches.contains(part.end)) {
ret = new ArrayList<>();
ret.addAll(output);
return ret;
@@ -391,16 +416,16 @@ public class AVM2Graph extends Graph {
&& (!stack.isEmpty())
&& (stack.peek() instanceof StrictEqAVM2Item)
&& (part.nextParts.get(0).getHeight() >= 2)
&& (this.code.code.get(this.code.fixIPAfterDebugLine(part.nextParts.get(0).start)).definition instanceof PushIntegerTypeIns)
&& (this.avm2code.code.get(this.avm2code.fixIPAfterDebugLine(part.nextParts.get(0).start)).definition instanceof PushIntegerTypeIns)
&& (!part.nextParts.get(0).nextParts.isEmpty())
&& (this.code.code.get(part.nextParts.get(0).nextParts.get(0).end).definition instanceof LookupSwitchIns))
&& (this.avm2code.code.get(part.nextParts.get(0).nextParts.get(0).end).definition instanceof LookupSwitchIns))
|| ((part.nextParts.size() == 2)
&& (!stack.isEmpty())
&& (stack.peek() instanceof StrictNeqAVM2Item)
&& (part.nextParts.get(1).getHeight() >= 2)
&& (this.code.code.get(this.code.fixIPAfterDebugLine(part.nextParts.get(1).start)).definition instanceof PushIntegerTypeIns)
&& (this.avm2code.code.get(this.avm2code.fixIPAfterDebugLine(part.nextParts.get(1).start)).definition instanceof PushIntegerTypeIns)
&& (!part.nextParts.get(1).nextParts.isEmpty())
&& (this.code.code.get(part.nextParts.get(1).nextParts.get(0).end).definition instanceof LookupSwitchIns))) {
&& (this.avm2code.code.get(part.nextParts.get(1).nextParts.get(0).end).definition instanceof LookupSwitchIns))) {
if (stack.peek() instanceof StrictEqAVM2Item) {
ignoredSwitches.add(part.nextParts.get(0).nextParts.get(0).end);
@@ -431,13 +456,13 @@ public class AVM2Graph extends Graph {
if (tar instanceof StrictNeqAVM2Item) {
tar = ((StrictNeqAVM2Item) tar).leftSide;
}
caseValuesMap.put(this.code.code.get(part.nextParts.get(reversed ? 0 : 1).start).operands[0], tar);
caseValuesMap.put(this.avm2code.code.get(part.nextParts.get(reversed ? 0 : 1).start).operands[0], tar);
GraphPart switchLoc = part.nextParts.get(reversed ? 0 : 1).nextParts.get(0);
while ((this.code.code.get(part.nextParts.get(reversed ? 1 : 0).end).definition instanceof IfStrictNeIns)
|| (this.code.code.get(part.nextParts.get(reversed ? 1 : 0).end).definition instanceof IfStrictEqIns)) {
while ((this.avm2code.code.get(part.nextParts.get(reversed ? 1 : 0).end).definition instanceof IfStrictNeIns)
|| (this.avm2code.code.get(part.nextParts.get(reversed ? 1 : 0).end).definition instanceof IfStrictEqIns)) {
part = part.nextParts.get(reversed ? 1 : 0);
translatePart(localData, part, stack, staticOperation, null);
tar = stack.pop();
@@ -447,7 +472,7 @@ public class AVM2Graph extends Graph {
if (tar instanceof StrictNeqAVM2Item) {
tar = ((StrictNeqAVM2Item) tar).leftSide;
}
if (this.code.code.get(part.end).definition instanceof IfStrictNeIns) {
if (this.avm2code.code.get(part.end).definition instanceof IfStrictNeIns) {
reversed = false;
} else {
reversed = true;
@@ -457,7 +482,7 @@ public class AVM2Graph extends Graph {
Stack<GraphTargetItem> sstack = new Stack<>();
do {
for (int n = 0; n < numPart.getHeight(); n++) {
ins = this.code.code.get(numPart.getPosAt(n));
ins = this.avm2code.code.get(numPart.getPosAt(n));
if (ins.definition instanceof LookupSwitchIns) {
break;
}
@@ -468,7 +493,7 @@ public class AVM2Graph extends Graph {
} else {
numPart = numPart.nextParts.get(0);
}
} while (!(this.code.code.get(numPart.end).definition instanceof LookupSwitchIns));
} while (!(this.avm2code.code.get(numPart.end).definition instanceof LookupSwitchIns));
GraphTargetItem nt = sstack.peek();
if (!(nt instanceof IntegerValueAVM2Item)) {
@@ -476,7 +501,7 @@ public class AVM2Graph extends Graph {
}
IntegerValueAVM2Item iv = (IntegerValueAVM2Item) nt;
caseValuesMap.put((int) (long) iv.value, tar);
while (this.code.code.get(part.nextParts.get(reversed ? 1 : 0).start).definition instanceof JumpIns) {
while (this.avm2code.code.get(part.nextParts.get(reversed ? 1 : 0).start).definition instanceof JumpIns) {
reversed = false;
part = part.nextParts.get(reversed ? 1 : 0);
if (part instanceof GraphPartMulti) {
@@ -486,7 +511,7 @@ public class AVM2Graph extends Graph {
}
boolean hasDefault = false;
GraphPart dp = part.nextParts.get(reversed ? 1 : 0);
while (this.code.code.get(dp.start).definition instanceof JumpIns) {
while (this.avm2code.code.get(dp.start).definition instanceof JumpIns) {
if (dp instanceof GraphPartMulti) {
dp = ((GraphPartMulti) dp).parts.get(0);
}
@@ -498,7 +523,7 @@ public class AVM2Graph extends Graph {
Stack<GraphTargetItem> sstack = new Stack<>();
do {
for (int n = 0; n < numPart.getHeight(); n++) {
ins = this.code.code.get(numPart.getPosAt(n));
ins = this.avm2code.code.get(numPart.getPosAt(n));
if (ins.definition instanceof LookupSwitchIns) {
break;
}
@@ -509,7 +534,7 @@ public class AVM2Graph extends Graph {
} else {
numPart = numPart.nextParts.get(0);
}
} while (!(this.code.code.get(numPart.end).definition instanceof LookupSwitchIns));
} while (!(this.avm2code.code.get(numPart.end).definition instanceof LookupSwitchIns));
GraphTargetItem nt = sstack.peek();
if (nt instanceof IntegerValueAVM2Item) {
hasDefault = true;
@@ -526,7 +551,7 @@ public class AVM2Graph extends Graph {
List<List<GraphTargetItem>> caseCommands = new ArrayList<>();
GraphPart next = null;
next = getMostCommonPart(switchLoc.nextParts, loops);//getNextPartPath(loopContinues);
next = getMostCommonPart(localData, switchLoc.nextParts, loops);//getNextPartPath(loopContinues);
currentLoop = new Loop(loops.size(), null, next);
currentLoop.phase = 1;
loops.add(currentLoop);
@@ -594,14 +619,61 @@ public class AVM2Graph extends Graph {
}
@Override
protected GraphPart checkPart(List<Object> localData, GraphPart next) {
protected GraphPart checkPart(Stack<GraphTargetItem> stack, List<Object> localData, GraphPart next, List<GraphPart> allParts) {
@SuppressWarnings("unchecked")
List<Integer> finallyJumps = (List<Integer>) localData.get(DATA_FINALLYJUMPS);
for (int f : finallyJumps) {
if (next.start == f) {
return null;
@SuppressWarnings("unchecked")
List<Integer> ignoredSwitches = (List<Integer>) localData.get(DATA_IGNOREDSWITCHES);
GraphPart ret = next;
for (int f = 0; f < finallyJumps.size(); f++) {
int fip = finallyJumps.get(f);
int swip = ignoredSwitches.get(f);
if (next.start == fip) {
if (stack != null && swip != -1) {
AVM2Instruction swIns = avm2code.code.get(swip);
GraphTargetItem t = stack.pop();
Double dval = EcmaScript.toNumber(t.getResult());
int val = (int) (double) dval;
if (swIns.definition instanceof LookupSwitchIns) {
List<Integer> branches = swIns.getBranches(code);
int nip = branches.get(0);
if (val >= 0 && val < branches.size() - 1) {
nip = branches.get(1 + val);
}
for (GraphPart p : allParts) {
if (p.start == nip) {
return p;
}
}
ret = null;
}
}
ret = null;
}
}
if (ret != next) {
return ret;
}
int pos = next.start;
int addr = this.avm2code.fixAddrAfterDebugLine(avm2code.pos2adr(pos));
for (int e = 0; e < body.exceptions.length; e++) {
if (body.exceptions[e].isFinally()) {
if (addr == this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].start)) {
if (true) { //afterCatchPos + 1 == code.adr2pos(this.code.fixAddrAfterDebugLine(body.exceptions[e].end))) {
AVM2Instruction jmpIns = this.avm2code.code.get(avm2code.adr2pos(this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].end)));
if (jmpIns.definition instanceof JumpIns) {
int finStart = avm2code.adr2pos(this.avm2code.fixAddrAfterDebugLine(body.exceptions[e].end) + jmpIns.getBytes().length + jmpIns.operands[0]);
finallyJumps.add(finStart);
ignoredSwitches.add(-1);
break;
}
}
}
}
}
return next;
}
@@ -677,7 +749,7 @@ public class AVM2Graph extends Graph {
}*/
List<GraphTargetItem> ret = code.clearTemporaryRegisters(list);
List<GraphTargetItem> ret = avm2code.clearTemporaryRegisters(list);
if (ret != list) {
list.clear();
list.addAll(ret);
@@ -740,7 +812,7 @@ public class AVM2Graph extends Graph {
}
for (GraphTargetItem i : output) {
if (i instanceof SetLocalAVM2Item) {
if (code.isKilled(((SetLocalAVM2Item) i).regIndex, 0, code.code.size() - 1)) {
if (avm2code.isKilled(((SetLocalAVM2Item) i).regIndex, 0, avm2code.code.size() - 1)) {
continue;
}
}

View File

@@ -74,7 +74,7 @@ public class ActionGraph extends Graph {
ActionGraph g = new ActionGraph(code, registerNames, variables, functions, version);
List<Object> localData = new ArrayList<>();
localData.add(registerNames);
g.init();
g.init(localData);
return g.translate(localData, staticOperation, path);
}
@@ -313,7 +313,7 @@ public class ActionGraph extends Graph {
defaultAndLastPart.add(defaultPart);
defaultAndLastPart.add(caseBodyParts.get(caseBodyParts.size() - 1));
GraphPart defaultPart2 = getCommonPart(defaultAndLastPart, loops);//34-37
GraphPart defaultPart2 = getCommonPart(localData, defaultAndLastPart, loops);//34-37
List<GraphTargetItem> defaultCommands = new ArrayList<>();
List<GraphPart> stopPart2 = new ArrayList<>(stopPart);
@@ -353,7 +353,7 @@ public class ActionGraph extends Graph {
if (defaultPart2 != null) {
mcp.add(defaultPart2);
}
GraphPart breakPart = getMostCommonPart(mcp, loops);
GraphPart breakPart = getMostCommonPart(localData, mcp, loops);
if ((defaultPart2 != breakPart) && (defaultCommands.isEmpty())) {
defaultPart = defaultPart2;
}
@@ -422,13 +422,13 @@ public class ActionGraph extends Graph {
nextCase = next;
if (next != null) {
if (i < caseBodies.size() - 1) {
if (!caseBodies.get(i).leadsTo(code, caseBodies.get(i + 1), loops)) {
if (!caseBodies.get(i).leadsTo(localData, this, code, caseBodies.get(i + 1), loops)) {
cc.add(new BreakItem(null, currentLoop.id));
} else {
nextCase = caseBodies.get(i + 1);
}
} else if (!defaultCommands.isEmpty()) {
if (!caseBodies.get(i).leadsTo(code, defaultPart, loops)) {
if (!caseBodies.get(i).leadsTo(localData, this, code, defaultPart, loops)) {
cc.add(new BreakItem(null, currentLoop.id));
} else {
nextCase = defaultPart;

View File

@@ -21,6 +21,7 @@ import com.jpexs.decompiler.graph.GraphPart;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -47,7 +48,7 @@ public class GraphFrame extends AppFrame {
private GraphPart head;
public GraphPanel(Graph graph) {
graph.init();
graph.init(new ArrayList<>());
size = getPartPositions(head = graph.heads.get(0), SPACE_VERTICAL + SPACE_VERTICAL + BLOCK_HEIGHT / 2, getPartWidth(graph.heads.get(0), new HashSet<GraphPart>()) * (BLOCK_WIDTH + SPACE_HORIZONTAL) / 2 - SPACE_HORIZONTAL, partPos, true);
backLinksLeft = 1;
backLinksRight = 1;

View File

@@ -22,10 +22,8 @@ import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashSet;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Set;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
@@ -96,8 +94,8 @@ public class SelectLanguageDialog extends AppDialog implements ActionListener {
View.centerScreen(this);
setTitle(translate("dialog.title"));
pack();
if(getWidth()<350){
setSize(350, getHeight());
if (getWidth() < 350) {
setSize(350, getHeight());
}
}

View File

@@ -37,7 +37,6 @@ import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.plaf.basic.BasicProgressBarUI;
import org.pushingpixels.flamingo.api.common.icon.ImageWrapperResizableIcon;
import org.pushingpixels.substance.api.SubstanceConstants;
import org.pushingpixels.substance.api.SubstanceLookAndFeel;

View File

@@ -33,10 +33,9 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.SwingUtilities;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.Document;
import jsyntaxpane.SyntaxDocument;
public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretListener {
@@ -99,6 +98,11 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL
if (bi == -1) {
return false;
}
View.execInEventDispatch(new Runnable() {
@Override
public void run() {
}
});
abcPanel.detailPanel.showCard(DetailPanel.METHOD_TRAIT_CARD, trait);
if (reset || (abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex() != bi)) {
abcPanel.detailPanel.methodTraitPanel.methodCodePanel.setBodyIndex(bi, abc, name);
@@ -163,7 +167,16 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL
}
@Override
public void caretUpdate(CaretEvent e) {
public void caretUpdate(final CaretEvent e) {
if (!SwingUtilities.isEventDispatchThread()) {
View.execInEventDispatch(new Runnable() {
@Override
public void run() {
caretUpdate(e);
}
});
return;
}
if (abc == null) {
return;
}

View File

@@ -64,7 +64,7 @@ public class Graph {
}
public void init() {
public void init(List<Object> localData) {
if (heads != null) {
return;
}
@@ -74,7 +74,7 @@ public class Graph {
List<GraphPart> visited = new ArrayList<>();
for (GraphPart head : heads) {
time = head.setTime(time, ordered, visited);
fixGraph(head);
fixGraph(localData, head);
makeMulti(head, new ArrayList<GraphPart>());
}
}
@@ -89,17 +89,17 @@ public class Graph {
}
}
private void fixGraph(GraphPart part) {
private void fixGraph(List<Object> localData, GraphPart part) {
//if(true) return;
try {
while (fixGraphOnce(part, new ArrayList<GraphPart>(), false)) {
while (fixGraphOnce(localData, part, new ArrayList<GraphPart>(), false)) {
}
} catch (Exception | Error ex) {
//ignore
}
}
private boolean fixGraphOnce(GraphPart part, List<GraphPart> visited, boolean doChildren) {
private boolean fixGraphOnce(List<Object> localData, GraphPart part, List<GraphPart> visited, boolean doChildren) {
if (visited.contains(part)) {
return false;
}
@@ -127,7 +127,7 @@ public class Graph {
if (r.path.rootName.equals("e") && !part.path.rootName.equals("e")) {
continue;
}
if (part.leadsTo(code, r, new ArrayList<Loop>())) {
if (part.leadsTo(localData, this, code, r, new ArrayList<Loop>())) {
modify = false;
continue;
}
@@ -166,7 +166,7 @@ public class Graph {
p.path = newpath;
}
fixGraphOnce(part, new ArrayList<GraphPart>(), true);
fixGraphOnce(localData, part, new ArrayList<GraphPart>(), true);
fixed = true;
}
}
@@ -196,17 +196,17 @@ public class Graph {
}
if (part.nextParts.size() == 2) {
if (part.nextParts.get(1).leadsTo(code, part.nextParts.get(0), new ArrayList<Loop>() /*visited*/)) {
fixGraphOnce(part.nextParts.get(1), visited, doChildren);
fixGraphOnce(part.nextParts.get(0), visited, doChildren);
if (part.nextParts.get(1).leadsTo(localData, this, code, part.nextParts.get(0), new ArrayList<Loop>() /*visited*/)) {
fixGraphOnce(localData, part.nextParts.get(1), visited, doChildren);
fixGraphOnce(localData, part.nextParts.get(0), visited, doChildren);
} else {
fixGraphOnce(part.nextParts.get(0), visited, doChildren);
fixGraphOnce(part.nextParts.get(1), visited, doChildren);
fixGraphOnce(localData, part.nextParts.get(0), visited, doChildren);
fixGraphOnce(localData, part.nextParts.get(1), visited, doChildren);
}
} else {
for (int j = part.nextParts.size() - 1; j >= 0; j--) {
GraphPart p = part.nextParts.get(j);
fixGraphOnce(p, visited, doChildren);
fixGraphOnce(localData, p, visited, doChildren);
}
}
return fixed;
@@ -371,11 +371,11 @@ public class Graph {
/* public GraphPart getNextCommonPart(GraphPart part, List<Loop> loops) {
return getNextCommonPart(part, new ArrayList<GraphPart>(),loops);
}*/
public GraphPart getNextCommonPart(GraphPart part, List<Loop> loops) {
return getCommonPart(part.nextParts, loops);
public GraphPart getNextCommonPart(List<Object> localData, GraphPart part, List<Loop> loops) {
return getCommonPart(localData, part.nextParts, loops);
}
public GraphPart getCommonPart(List<GraphPart> parts, List<Loop> loops) {
public GraphPart getCommonPart(List<Object> localData, List<GraphPart> parts, List<Loop> loops) {
if (parts.isEmpty()) {
return null;
}
@@ -396,7 +396,7 @@ public class Graph {
if (q == p) {
continue;
}
if (!q.leadsTo(code, p, loops)) {
if (!q.leadsTo(localData, this, code, p, loops)) {
common = false;
break;
}
@@ -417,6 +417,10 @@ public class Graph {
/*if (ignored.contains(p)) {
continue;
}*/
p = checkPart(null, localData, p, null);
if (p == null) {
continue;
}
boolean common = true;
for (List<GraphPart> r : reachable) {
if (!r.contains(p)) {
@@ -431,7 +435,7 @@ public class Graph {
return null;
}
public GraphPart getMostCommonPart(List<GraphPart> parts, List<Loop> loops) {
public GraphPart getMostCommonPart(List<Object> localData, List<GraphPart> parts, List<Loop> loops) {
if (parts.isEmpty()) {
return null;
}
@@ -458,7 +462,7 @@ public class Graph {
if (q == p) {
continue;
}
if (!q.leadsTo(code, p, loops)) {
if (!q.leadsTo(localData, this, code, p, loops)) {
common = false;
break;
}
@@ -474,7 +478,7 @@ public class Graph {
if (j == i) {
continue;
}
if (parts.get(i).leadsTo(code, parts.get(j), loops)) {
if (parts.get(i).leadsTo(localData, this, code, parts.get(j), loops)) {
parts.remove(i);
i--;
continue loopi;
@@ -551,7 +555,7 @@ public class Graph {
public static List<GraphTargetItem> translateViaGraph(List<Object> localData, String path, GraphSource code, List<Integer> alternateEntries, int staticOperation) {
Graph g = new Graph(code, alternateEntries);
g.init();
g.init(localData);
return g.translate(localData, staticOperation, path);
}
@@ -562,13 +566,13 @@ public class Graph {
}
Stack<GraphTargetItem> stack = new Stack<>();
List<Loop> loops = new ArrayList<>();
getLoops(heads.get(0), loops, null);
getLoops(localData, heads.get(0), loops, null);
/*System.out.println("<loops>");
for (Loop el : loops) {
System.out.println(el);
}
System.out.println("</loops>");*/
getPrecontinues(null, heads.get(0), loops, null);
getPrecontinues(localData, null, heads.get(0), loops, null);
/*System.err.println("<loopspre>");
for (Loop el : loops) {
System.err.println(el);
@@ -755,7 +759,7 @@ public class Graph {
return null;
}
protected GraphPart checkPart(List<Object> localData, GraphPart part) {
protected GraphPart checkPart(Stack<GraphTargetItem> stack, List<Object> localData, GraphPart part, List<GraphPart> allParts) {
return part;
}
@@ -835,8 +839,8 @@ public class Graph {
return loopItem;
}
private void getPrecontinues(GraphPart parent, GraphPart part, List<Loop> loops, List<GraphPart> stopPart) {
markLevels(part, loops);
private void getPrecontinues(List<Object> localData, GraphPart parent, GraphPart part, List<Loop> loops, List<GraphPart> stopPart) {
markLevels(localData, part, loops);
//Note: this also marks part as precontinue when there is if
/*
while(k<10){
@@ -887,13 +891,13 @@ public class Graph {
clearLoops(loops);*/
}
private void markLevels(GraphPart part, List<Loop> loops) {
private void markLevels(List<Object> localData, GraphPart part, List<Loop> loops) {
clearLoops(loops);
markLevels(part, loops, new ArrayList<GraphPart>(), 1, new ArrayList<GraphPart>());
markLevels(localData, part, loops, new ArrayList<GraphPart>(), 1, new ArrayList<GraphPart>());
clearLoops(loops);
}
private void markLevels(GraphPart part, List<Loop> loops, List<GraphPart> stopPart, int level, List<GraphPart> visited) {
private void markLevels(List<Object> localData, GraphPart part, List<Loop> loops, List<GraphPart> stopPart, int level, List<GraphPart> visited) {
boolean debugMode = false;
if (stopPart == null) {
stopPart = new ArrayList<>();
@@ -951,7 +955,7 @@ public class Graph {
}
if (nextParts.size() == 2) {
GraphPart next = getCommonPart(nextParts, loops);//part.getNextPartPath(new ArrayList<GraphPart>());
GraphPart next = getCommonPart(localData, nextParts, loops);//part.getNextPartPath(new ArrayList<GraphPart>());
List<GraphPart> stopParts2 = new ArrayList<>(); //stopPart);
if (next != null) {
stopParts2.add(next);
@@ -959,18 +963,18 @@ public class Graph {
stopParts2.add(stopPart.get(stopPart.size() - 1));
}
if (next != nextParts.get(0)) {
markLevels(nextParts.get(0), loops, next == null ? stopPart : stopParts2, level + 1, visited);
markLevels(localData, nextParts.get(0), loops, next == null ? stopPart : stopParts2, level + 1, visited);
}
if (next != nextParts.get(1)) {
markLevels(nextParts.get(1), loops, next == null ? stopPart : stopParts2, level + 1, visited);
markLevels(localData, nextParts.get(1), loops, next == null ? stopPart : stopParts2, level + 1, visited);
}
if (next != null) {
markLevels(next, loops, stopPart, level, visited);
markLevels(localData, next, loops, stopPart, level, visited);
}
}
if (nextParts.size() > 2) {
GraphPart next = getMostCommonPart(nextParts, loops);
GraphPart next = getMostCommonPart(localData, nextParts, loops);
List<GraphPart> vis = new ArrayList<>();
for (GraphPart p : nextParts) {
if (vis.contains(p)) {
@@ -991,17 +995,17 @@ public class Graph {
}
}
if (next != p) {
markLevels(p, loops, stopPart2, level + 1, visited);
markLevels(localData, p, loops, stopPart2, level + 1, visited);
vis.add(p);
}
}
if (next != null) {
markLevels(next, loops, stopPart, level, visited);
markLevels(localData, next, loops, stopPart, level, visited);
}
}
if (nextParts.size() == 1) {
markLevels(nextParts.get(0), loops, stopPart, level, visited);
markLevels(localData, nextParts.get(0), loops, stopPart, level, visited);
}
for (GraphPart t : part.throwParts) {
@@ -1010,21 +1014,21 @@ public class Graph {
List<GraphPart> cmn = new ArrayList<>();
cmn.add(part);
cmn.add(t);
GraphPart next = getCommonPart(cmn, loops);
GraphPart next = getCommonPart(localData, cmn, loops);
if (next != null) {
stopPart2.add(next);
} else {
stopPart2 = stopPart;
}
markLevels(t, loops, stopPart2, level, visited);
markLevels(localData, t, loops, stopPart2, level, visited);
}
}
if (isLoop) {
if (currentLoop.loopBreak != null) {
currentLoop.phase = 2;
markLevels(currentLoop.loopBreak, loops, stopPart, level, visited);
markLevels(localData, currentLoop.loopBreak, loops, stopPart, level, visited);
}
}
}
@@ -1035,13 +1039,13 @@ public class Graph {
}
}
private void getLoops(GraphPart part, List<Loop> loops, List<GraphPart> stopPart) {
private void getLoops(List<Object> localData, GraphPart part, List<Loop> loops, List<GraphPart> stopPart) {
clearLoops(loops);
getLoops(part, loops, stopPart, true, 1, new ArrayList<GraphPart>());
getLoops(localData, part, loops, stopPart, true, 1, new ArrayList<GraphPart>());
clearLoops(loops);
}
private void getLoops(GraphPart part, List<Loop> loops, List<GraphPart> stopPart, boolean first, int level, List<GraphPart> visited) {
private void getLoops(List<Object> localData, GraphPart part, List<Loop> loops, List<GraphPart> stopPart, boolean first, int level, List<GraphPart> visited) {
boolean debugMode = false;
if (stopPart == null) {
@@ -1050,6 +1054,11 @@ public class Graph {
if (part == null) {
return;
}
part = checkPart(null, localData, part, null);
if (part == null) {
return;
}
if (!visited.contains(part)) {
visited.add(part);
}
@@ -1080,7 +1089,7 @@ public class Graph {
loopContinues2.remove(lastP1.loopContinue);
List<Loop> loops2 = new ArrayList<>(loops);
loops2.remove(lastP1);
if (!part.leadsTo(code, lastP1.loopContinue, loops2)) {
if (!part.leadsTo(localData, this, code, lastP1.loopContinue, loops2)) {
if (lastP1.breakCandidatesLocked == 0) {
if (debugMode) {
System.err.println("added breakCandidate " + part + " to " + lastP1);
@@ -1105,7 +1114,7 @@ public class Graph {
}
part.level = level;
boolean isLoop = part.leadsTo(code, part, loops);
boolean isLoop = part.leadsTo(localData, this, code, part, loops);
Loop currentLoop = null;
if (isLoop) {
currentLoop = new Loop(loops.size(), part, null);
@@ -1115,23 +1124,23 @@ public class Graph {
}
if (part.nextParts.size() == 2) {
GraphPart next = getNextCommonPart(part, loops);//part.getNextPartPath(loopContinues);
GraphPart next = getNextCommonPart(localData, part, loops);//part.getNextPartPath(loopContinues);
List<GraphPart> stopPart2 = new ArrayList<>(stopPart);
if (next != null) {
stopPart2.add(next);
}
if (next != part.nextParts.get(0)) {
getLoops(part.nextParts.get(0), loops, stopPart2, false, level + 1, visited);
getLoops(localData, part.nextParts.get(0), loops, stopPart2, false, level + 1, visited);
}
if (next != part.nextParts.get(1)) {
getLoops(part.nextParts.get(1), loops, stopPart2, false, level + 1, visited);
getLoops(localData, part.nextParts.get(1), loops, stopPart2, false, level + 1, visited);
}
if (next != null) {
getLoops(next, loops, stopPart, false, level, visited);
getLoops(localData, next, loops, stopPart, false, level, visited);
}
}
if (part.nextParts.size() > 2) {
GraphPart next = getNextCommonPart(part, loops);
GraphPart next = getNextCommonPart(localData, part, loops);
for (GraphPart p : part.nextParts) {
@@ -1148,15 +1157,15 @@ public class Graph {
}
}
if (next != p) {
getLoops(p, loops, stopPart2, false, level + 1, visited);
getLoops(localData, p, loops, stopPart2, false, level + 1, visited);
}
}
if (next != null) {
getLoops(next, loops, stopPart, false, level, visited);
getLoops(localData, next, loops, stopPart, false, level, visited);
}
}
if (part.nextParts.size() == 1) {
getLoops(part.nextParts.get(0), loops, stopPart, false, level, visited);
getLoops(localData, part.nextParts.get(0), loops, stopPart, false, level, visited);
}
List<Loop> loops2 = new ArrayList<>(loops);
@@ -1165,7 +1174,7 @@ public class Graph {
}
for (GraphPart t : part.throwParts) {
if (!visited.contains(t)) {
getLoops(t, loops, stopPart, false, level, visited);
getLoops(localData, t, loops, stopPart, false, level, visited);
}
}
for (Loop l : loops2) {
@@ -1177,13 +1186,20 @@ public class Graph {
Map<GraphPart, Integer> removed = new HashMap<>();
do {
found = null;
for (int i = 0; i < currentLoop.breakCandidates.size(); i++) {
GraphPart ch = checkPart(null, localData, currentLoop.breakCandidates.get(i), null);
if (ch == null) {
currentLoop.breakCandidates.remove(i);
i--;
}
}
loopcand:
for (GraphPart cand : currentLoop.breakCandidates) {
for (GraphPart cand2 : currentLoop.breakCandidates) {
if (cand == cand2) {
continue;
}
if (cand.leadsTo(code, cand2, loops)) {
if (cand.leadsTo(localData, this, code, cand2, loops)) {
int lev1 = Integer.MAX_VALUE;
int lev2 = Integer.MAX_VALUE;
for (int i = 0; i < currentLoop.breakCandidates.size(); i++) {
@@ -1284,7 +1300,7 @@ public class Graph {
if (removedVisited.contains(r)) {
continue;
}
getLoops(r, loops, stopPart, false, removed.get(r), visited);
getLoops(localData, r, loops, stopPart, false, removed.get(r), visited);
removedVisited.add(r);
}
start = false;
@@ -1297,7 +1313,7 @@ public class Graph {
el.phase = 2;
}
}
getLoops(currentLoop.loopBreak, loops, stopPart, false, level, visited);
getLoops(localData, currentLoop.loopBreak, loops, stopPart, false, level, visited);
}
}
@@ -1341,7 +1357,7 @@ public class Graph {
if (part == null) {
return ret;
}
part = checkPart(localData, part);
part = checkPart(stack, localData, part, allParts);
if (part == null) {
return ret;
}
@@ -1497,8 +1513,8 @@ public class Graph {
boolean reversed = false;
loopContinues = getLoopsContinues(loops);
loopContinues.add(part);//???
if (sp1.leadsTo(code, sp0, loops)) {
} else if (sp0.leadsTo(code, sp1, loops)) {
if (sp1.leadsTo(localData, this, code, sp0, loops)) {
} else if (sp0.leadsTo(localData, this, code, sp1, loops)) {
reversed = true;
}
GraphPart next = reversed ? sp0 : sp1;
@@ -1548,8 +1564,8 @@ public class Graph {
boolean reversed = false;
loopContinues = getLoopsContinues(loops);
loopContinues.add(part);//???
if (sp1.leadsTo(code, sp0, loops)) {
} else if (sp0.leadsTo(code, sp1, loops)) {
if (sp1.leadsTo(localData, this, code, sp0, loops)) {
} else if (sp0.leadsTo(localData, this, code, sp1, loops)) {
reversed = true;
}
GraphPart next = reversed ? sp0 : sp1;
@@ -1603,7 +1619,7 @@ public class Graph {
if (part.nextParts.size() > 2) {//alchemy direct switch
GraphPart next = getMostCommonPart(part.nextParts, loops);
GraphPart next = getMostCommonPart(localData, part.nextParts, loops);
List<GraphPart> vis = new ArrayList<>();
GraphTargetItem switchedItem = stack.pop();
List<GraphTargetItem> caseValues = new ArrayList<>();
@@ -1679,7 +1695,7 @@ public class Graph {
}
}
if (nextOnePart == null) {
GraphPart next = getNextCommonPart(part, loops);
GraphPart next = getNextCommonPart(localData, part, loops);
@SuppressWarnings("unchecked")
Stack<GraphTargetItem> trueStack = (Stack<GraphTargetItem>) stack.clone();

View File

@@ -60,7 +60,14 @@ public class GraphPart implements Serializable {
return time;
}
private boolean leadsTo(GraphSource code, GraphPart part, List<GraphPart> visited, List<Loop> loops) {
private boolean leadsTo(List<Object> localData, Graph gr, GraphSource code, GraphPart part, List<GraphPart> visited, List<Loop> loops) {
GraphPart tpart = gr.checkPart(null, localData, this, null);
if (tpart == null) {
return false;
}
if (tpart != this) {
return tpart.leadsTo(localData, gr, code, part, visited, loops);
}
Loop currentLoop = null;
for (Loop l : loops) {
/*if(l.phase==0){
@@ -97,7 +104,7 @@ public class GraphPart implements Serializable {
if (p == part) {
return true;
} else {
if (p.leadsTo(code, part, visited, loops)) {
if (p.leadsTo(localData, gr, code, part, visited, loops)) {
return true;
}
}
@@ -106,7 +113,7 @@ public class GraphPart implements Serializable {
if (p == part) {
return true;
} else {
if (p.leadsTo(code, part, visited, loops)) {
if (p.leadsTo(localData, gr, code, part, visited, loops)) {
return true;
}
}
@@ -114,11 +121,11 @@ public class GraphPart implements Serializable {
return false;
}
public boolean leadsTo(GraphSource code, GraphPart part, List<Loop> loops) {
public boolean leadsTo(List<Object> localData, Graph gr, GraphSource code, GraphPart part, List<Loop> loops) {
for (Loop l : loops) {
l.leadsToMark = 0;
}
return leadsTo(code, part, new ArrayList<GraphPart>(), loops);
return leadsTo(localData, gr, code, part, new ArrayList<GraphPart>(), loops);
}
public GraphPart(int start, int end) {