mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-02 09:14:53 +00:00
Issues #319: AS3 - Improved try..catch..finally decompilation
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user