From 5d092a09543d4beba6130bfddc799f4c4e9d717f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=F8=EDk?= Date: Sun, 11 Aug 2013 17:21:29 +0200 Subject: [PATCH] Issues #319: AS3 - Improved try..catch..finally decompilation --- .../decompiler/flash/SWFInputStream.java | 2 +- .../decompiler/flash/abc/avm2/AVM2Code.java | 78 ++++--- .../flash/abc/avm2/graph/AVM2Graph.java | 196 ++++++++++++------ .../decompiler/flash/action/ActionGraph.java | 10 +- .../decompiler/flash/gui/GraphFrame.java | 3 +- .../flash/gui/SelectLanguageDialog.java | 6 +- .../com/jpexs/decompiler/flash/gui/View.java | 1 - .../flash/gui/abc/DecompiledEditorPane.java | 19 +- .../src/com/jpexs/decompiler/graph/Graph.java | 144 +++++++------ .../com/jpexs/decompiler/graph/GraphPart.java | 17 +- 10 files changed, 297 insertions(+), 179 deletions(-) diff --git a/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java b/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java index 301cbf427..dc1afdd1e 100644 --- a/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java +++ b/trunk/src/com/jpexs/decompiler/flash/SWFInputStream.java @@ -1089,7 +1089,7 @@ public class SWFInputStream extends InputStream { } } } - HashMap curstate = new HashMap(); + HashMap curstate = new HashMap<>(); curstate.putAll(vars); decisionStates.put(ip, curstate); diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java index 8a8b747aa..908d67b9d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java @@ -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) { diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java index 9a35a9e62..064b52d72 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java @@ -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 localRegs, Stack scopeStack, HashMap localRegNames, List fullyQualifiedNames, HashMap localRegAssigmentIps, HashMap> 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(), body); @@ -114,11 +115,7 @@ public class AVM2Graph extends Graph { public static List translateViaGraph(String path, AVM2Code code, ABC abc, MethodBody body, boolean isStatic, int scriptIndex, int classIndex, HashMap localRegs, Stack scopeStack, HashMap localRegNames, List fullyQualifiedNames, int staticOperation, HashMap localRegAssigmentIps, HashMap> refs) { AVM2Graph g = new AVM2Graph(code, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localRegNames, fullyQualifiedNames, localRegAssigmentIps, refs); - g.init(); - List allParts = new ArrayList<>(); - for (GraphPart head : g.heads) { - populateParts(head, allParts); - } + List 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()); - localData.add(new ArrayList()); + localData.add(new ArrayList()); //finallyJumps localData.add(new ArrayList()); localData.add((Integer) scriptIndex); localData.add(new HashMap()); //localRegAssignmentIps localData.add(Integer.valueOf(0)); localData.add(refs); localData.add(code); + g.init(localData); + List allParts = new ArrayList<>(); + for (GraphPart head : g.heads) { + populateParts(head, allParts); + } return g.translate(localData, staticOperation, path); } @Override protected void checkGraph(List 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 ignoredSwitches = (List) 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 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> 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() { @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 stopPart2 = new ArrayList<>(stopPart); stopPart2.add(fepart); - finallyCommands = printGraph(new ArrayList(), localData, stack, allParts, parent, fpart, stopPart2, loops, staticOperation, path); + //finallyCommands = printGraph(new ArrayList(), 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(), localData, stack, allParts, parent, fpart, null, loops, staticOperation, path); - } + //ignoredSwitches.add(-1); + //int igs_size=ignoredSwitches.size(); + List oldFinallyJumps = new ArrayList<>(finallyJumps); + finallyJumps.clear(); + ignoredSwitches.add(swPos); + finallyCommands = printGraph(new ArrayList(), 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 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()); List stopPart2 = new ArrayList<>(stopPart); stopPart2.add(nepart); + if (retPart != null) { + stopPart2.add(retPart); + } catchedCommands.add(printGraph(new ArrayList(), localData2, stack, allParts, parent, npart, stopPart2, loops, staticOperation, path)); } @@ -332,6 +353,10 @@ public class AVM2Graph extends Graph { List stopPart2 = new ArrayList<>(stopPart); stopPart2.add(nepart); stopPart2.addAll(catchParts); + + if (retPart != null) { + stopPart2.add(retPart); + } List tryCommands = printGraph(new ArrayList(), 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 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 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> 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 localData, GraphPart next) { + protected GraphPart checkPart(Stack stack, List localData, GraphPart next, List allParts) { @SuppressWarnings("unchecked") List finallyJumps = (List) localData.get(DATA_FINALLYJUMPS); - for (int f : finallyJumps) { - if (next.start == f) { - return null; + @SuppressWarnings("unchecked") + List ignoredSwitches = (List) 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 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 ret = code.clearTemporaryRegisters(list); + List 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; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/ActionGraph.java b/trunk/src/com/jpexs/decompiler/flash/action/ActionGraph.java index 25600886c..422a369b4 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/ActionGraph.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/ActionGraph.java @@ -74,7 +74,7 @@ public class ActionGraph extends Graph { ActionGraph g = new ActionGraph(code, registerNames, variables, functions, version); List 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 defaultCommands = new ArrayList<>(); List 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; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/GraphFrame.java b/trunk/src/com/jpexs/decompiler/flash/gui/GraphFrame.java index 66642183e..748a7f640 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/GraphFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/GraphFrame.java @@ -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()) * (BLOCK_WIDTH + SPACE_HORIZONTAL) / 2 - SPACE_HORIZONTAL, partPos, true); backLinksLeft = 1; backLinksRight = 1; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/SelectLanguageDialog.java b/trunk/src/com/jpexs/decompiler/flash/gui/SelectLanguageDialog.java index 4c9659e17..86deb236c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/SelectLanguageDialog.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/SelectLanguageDialog.java @@ -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()); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/View.java b/trunk/src/com/jpexs/decompiler/flash/gui/View.java index 39b2deeaf..36d5d2c58 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/View.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/View.java @@ -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; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java b/trunk/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java index 14cbd57f9..2cc6246d7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java @@ -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; } diff --git a/trunk/src/com/jpexs/decompiler/graph/Graph.java b/trunk/src/com/jpexs/decompiler/graph/Graph.java index 93c4bfc6d..883d16d3f 100644 --- a/trunk/src/com/jpexs/decompiler/graph/Graph.java +++ b/trunk/src/com/jpexs/decompiler/graph/Graph.java @@ -64,7 +64,7 @@ public class Graph { } - public void init() { + public void init(List localData) { if (heads != null) { return; } @@ -74,7 +74,7 @@ public class Graph { List visited = new ArrayList<>(); for (GraphPart head : heads) { time = head.setTime(time, ordered, visited); - fixGraph(head); + fixGraph(localData, head); makeMulti(head, new ArrayList()); } } @@ -89,17 +89,17 @@ public class Graph { } } - private void fixGraph(GraphPart part) { + private void fixGraph(List localData, GraphPart part) { //if(true) return; try { - while (fixGraphOnce(part, new ArrayList(), false)) { + while (fixGraphOnce(localData, part, new ArrayList(), false)) { } } catch (Exception | Error ex) { //ignore } } - private boolean fixGraphOnce(GraphPart part, List visited, boolean doChildren) { + private boolean fixGraphOnce(List localData, GraphPart part, List 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())) { + if (part.leadsTo(localData, this, code, r, new ArrayList())) { modify = false; continue; } @@ -166,7 +166,7 @@ public class Graph { p.path = newpath; } - fixGraphOnce(part, new ArrayList(), true); + fixGraphOnce(localData, part, new ArrayList(), 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() /*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() /*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 loops) { return getNextCommonPart(part, new ArrayList(),loops); }*/ - public GraphPart getNextCommonPart(GraphPart part, List loops) { - return getCommonPart(part.nextParts, loops); + public GraphPart getNextCommonPart(List localData, GraphPart part, List loops) { + return getCommonPart(localData, part.nextParts, loops); } - public GraphPart getCommonPart(List parts, List loops) { + public GraphPart getCommonPart(List localData, List parts, List 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 r : reachable) { if (!r.contains(p)) { @@ -431,7 +435,7 @@ public class Graph { return null; } - public GraphPart getMostCommonPart(List parts, List loops) { + public GraphPart getMostCommonPart(List localData, List parts, List 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 translateViaGraph(List localData, String path, GraphSource code, List 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 stack = new Stack<>(); List loops = new ArrayList<>(); - getLoops(heads.get(0), loops, null); + getLoops(localData, heads.get(0), loops, null); /*System.out.println(""); for (Loop el : loops) { System.out.println(el); } System.out.println("");*/ - getPrecontinues(null, heads.get(0), loops, null); + getPrecontinues(localData, null, heads.get(0), loops, null); /*System.err.println(""); for (Loop el : loops) { System.err.println(el); @@ -755,7 +759,7 @@ public class Graph { return null; } - protected GraphPart checkPart(List localData, GraphPart part) { + protected GraphPart checkPart(Stack stack, List localData, GraphPart part, List allParts) { return part; } @@ -835,8 +839,8 @@ public class Graph { return loopItem; } - private void getPrecontinues(GraphPart parent, GraphPart part, List loops, List stopPart) { - markLevels(part, loops); + private void getPrecontinues(List localData, GraphPart parent, GraphPart part, List loops, List 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 loops) { + private void markLevels(List localData, GraphPart part, List loops) { clearLoops(loops); - markLevels(part, loops, new ArrayList(), 1, new ArrayList()); + markLevels(localData, part, loops, new ArrayList(), 1, new ArrayList()); clearLoops(loops); } - private void markLevels(GraphPart part, List loops, List stopPart, int level, List visited) { + private void markLevels(List localData, GraphPart part, List loops, List stopPart, int level, List 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 next = getCommonPart(localData, nextParts, loops);//part.getNextPartPath(new ArrayList()); List 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 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 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 loops, List stopPart) { + private void getLoops(List localData, GraphPart part, List loops, List stopPart) { clearLoops(loops); - getLoops(part, loops, stopPart, true, 1, new ArrayList()); + getLoops(localData, part, loops, stopPart, true, 1, new ArrayList()); clearLoops(loops); } - private void getLoops(GraphPart part, List loops, List stopPart, boolean first, int level, List visited) { + private void getLoops(List localData, GraphPart part, List loops, List stopPart, boolean first, int level, List 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 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 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 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 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 vis = new ArrayList<>(); GraphTargetItem switchedItem = stack.pop(); List 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 trueStack = (Stack) stack.clone(); diff --git a/trunk/src/com/jpexs/decompiler/graph/GraphPart.java b/trunk/src/com/jpexs/decompiler/graph/GraphPart.java index 6013fc433..ed04b0955 100644 --- a/trunk/src/com/jpexs/decompiler/graph/GraphPart.java +++ b/trunk/src/com/jpexs/decompiler/graph/GraphPart.java @@ -60,7 +60,14 @@ public class GraphPart implements Serializable { return time; } - private boolean leadsTo(GraphSource code, GraphPart part, List visited, List loops) { + private boolean leadsTo(List localData, Graph gr, GraphSource code, GraphPart part, List visited, List 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 loops) { + public boolean leadsTo(List localData, Graph gr, GraphSource code, GraphPart part, List loops) { for (Loop l : loops) { l.leadsToMark = 0; } - return leadsTo(code, part, new ArrayList(), loops); + return leadsTo(localData, gr, code, part, new ArrayList(), loops); } public GraphPart(int start, int end) {