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 4e60d2a1b..9260fcfd9 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 @@ -1224,7 +1224,7 @@ public class AVM2Graph extends Graph { } //code.code.get(f).ignored = true; ignoredSwitches.add(f); - finallyCommands = printGraph(localData, stack, allParts, parent, fpart, fepart, loops, forFinalCommands); + finallyCommands = printGraph(new ArrayList(), localData, stack, allParts, parent, fpart, fepart, loops, forFinalCommands); returnPos = f + 1; break; } @@ -1233,7 +1233,7 @@ public class AVM2Graph extends Graph { } } if (!switchFound) { - finallyCommands = printGraph(localData, stack, allParts, parent, fpart, null, loops, forFinalCommands); + finallyCommands = printGraph(new ArrayList(), localData, stack, allParts, parent, fpart, null, loops, forFinalCommands); } finallyJumps.add(finStart); break; @@ -1271,7 +1271,7 @@ public class AVM2Graph extends Graph { List localData2 = new ArrayList(); localData2.addAll(localData); localData2.set(DATA_SCOPESTACK, new Stack()); - catchedCommands.add(printGraph(localData2, stack, allParts, parent, npart, nepart, loops, forFinalCommands)); + catchedCommands.add(printGraph(new ArrayList(), localData2, stack, allParts, parent, npart, nepart, loops, forFinalCommands)); } GraphPart nepart = null; @@ -1282,7 +1282,7 @@ public class AVM2Graph extends Graph { break; } } - List tryCommands = printGraph(localData, stack, allParts, parent, part, nepart, loops, forFinalCommands); + List tryCommands = printGraph(new ArrayList(), localData, stack, allParts, parent, part, nepart, loops, forFinalCommands); output.clear(); output.add(new TryTreeItem(tryCommands, catchedExceptions, catchedCommands, finallyCommands)); @@ -1306,7 +1306,7 @@ public class AVM2Graph extends Graph { ret.addAll(output); GraphTargetItem lop = checkLoop(part, stopPart, loops); if (lop == null) { - ret.addAll(printGraph(localData, stack, allParts, null, part, stopPart, loops, forFinalCommands)); + ret.addAll(printGraph(new ArrayList(), localData, stack, allParts, null, part, stopPart, loops, forFinalCommands)); } else { ret.add(lop); } @@ -1446,7 +1446,7 @@ public class AVM2Graph extends Graph { GraphPart defaultPart = null; if (hasDefault) { defaultPart = switchLoc.nextParts.get(switchLoc.nextParts.size() - 1); - defaultCommands = printGraph(localData, stack, allParts, switchLoc, defaultPart, next, loops, forFinalCommands); + defaultCommands = printGraph(new ArrayList(), localData, stack, allParts, switchLoc, defaultPart, next, loops, forFinalCommands); } List ignored = new ArrayList(); @@ -1473,7 +1473,7 @@ public class AVM2Graph extends Graph { } } } - cc.addAll(0, printGraph(localData, stack, allParts, switchLoc, caseBodies.get(i), nextCase, loops, forFinalCommands)); + cc.addAll(0, printGraph(new ArrayList(), localData, stack, allParts, switchLoc, caseBodies.get(i), nextCase, loops, forFinalCommands)); caseCommands.add(cc); } @@ -1484,7 +1484,7 @@ public class AVM2Graph extends Graph { if (ti != null) { ret.add(ti); } else { - ret.addAll(printGraph(localData, stack, allParts, null, next, stopPart, loops, forFinalCommands)); + ret.addAll(printGraph(new ArrayList(), localData, stack, allParts, null, next, stopPart, loops, forFinalCommands)); } } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/ActionGraph.java b/trunk/src/com/jpexs/decompiler/flash/action/ActionGraph.java index 5ddbc9c34..dc2cd7e2c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/ActionGraph.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/ActionGraph.java @@ -188,7 +188,7 @@ public class ActionGraph extends Graph { List defaultCommands = new ArrayList(); - defaultCommands = printGraph(localData, stack, allParts, null, defaultPart, defaultPart2, loops, forFinalCommands); + defaultCommands = printGraph(new ArrayList(), localData, stack, allParts, null, defaultPart, defaultPart2, loops, forFinalCommands); List loopContinues = new ArrayList(); @@ -260,7 +260,7 @@ public class ActionGraph extends Graph { defaultPart = null; } if ((defaultPart != null) && (defaultCommands.isEmpty())) { - defaultCommands = printGraph(localData, stack, allParts, null, defaultPart, next, loops, forFinalCommands); + defaultCommands = printGraph(new ArrayList(), localData, stack, allParts, null, defaultPart, next, loops, forFinalCommands); } List ignored = new ArrayList(); @@ -287,7 +287,7 @@ public class ActionGraph extends Graph { } } } - cc.addAll(0, printGraph(localData, stack, allParts, null, caseBodies.get(i), nextCase, loops, forFinalCommands)); + cc.addAll(0, printGraph(new ArrayList(), localData, stack, allParts, null, caseBodies.get(i), nextCase, loops, forFinalCommands)); if (cc.size() >= 2) { if (cc.get(cc.size() - 1) instanceof BreakItem) { if ((cc.get(cc.size() - 2) instanceof ContinueItem) || (cc.get(cc.size() - 2) instanceof BreakItem)) { @@ -311,7 +311,7 @@ public class ActionGraph extends Graph { if (ti != null) { ret.add(ti); } else { - ret.addAll(printGraph(localData, stack, allParts, null, next, stopPart, loops, forFinalCommands)); + ret.addAll(printGraph(new ArrayList(), localData, stack, allParts, null, next, stopPart, loops, forFinalCommands)); } } } diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/AndItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/AndItem.java index bf8878e66..3de98b6ef 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/AndItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/AndItem.java @@ -22,6 +22,16 @@ public class AndItem extends BinaryOpItem { public GraphPart firstPart; + public GraphPart getFirstPart() { + if (leftSide instanceof AndItem) { + return ((AndItem) leftSide).getFirstPart(); + } + if (leftSide instanceof OrItem) { + return ((OrItem) leftSide).getFirstPart(); + } + return firstPart; + } + @Override public List getNeededSources() { List ret = super.getNeededSources(); diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/Graph.java b/trunk/src/com/jpexs/decompiler/flash/graph/Graph.java index 3dce80c15..5b46cb73b 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/Graph.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/Graph.java @@ -61,12 +61,19 @@ public class Graph { } private boolean fixGraphOnce(GraphPart part, List visited, boolean doChildren) { + if ((part.start == 1743) && (!doChildren)) { + //p/1/0 + System.out.println("dfewf"); + } + if ((part.start == 1740) && (!doChildren)) { + System.out.println("efewf"); + } if (visited.contains(part)) { return false; } visited.add(part); boolean fixed = false; - int i = 1; + int i = 0; GraphPath lastpref = null; boolean modify = true; int prvni = -1; @@ -154,8 +161,19 @@ public class Graph { } } - for (GraphPart p : part.nextParts) { - fixGraphOnce(p, visited, doChildren); + if (part.nextParts.size() == 2) { + if (part.nextParts.get(1).leadsTo(code, part.nextParts.get(0), visited)) { + fixGraphOnce(part.nextParts.get(1), visited, doChildren); + fixGraphOnce(part.nextParts.get(0), visited, doChildren); + } else { + fixGraphOnce(part.nextParts.get(0), visited, doChildren); + fixGraphOnce(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); + } } return fixed; } @@ -295,7 +313,7 @@ public class Graph { populateParts(head, allParts); } Stack stack = new Stack(); - List ret = printGraph(localData, stack, allParts, null, heads.get(0), null, new ArrayList(), new HashMap>()); + List ret = printGraph(new ArrayList(), localData, stack, allParts, null, heads.get(0), null, new ArrayList(), new HashMap>()); processIfs(ret); finalProcessStack(stack, ret); finalProcessAll(ret, 0); @@ -450,9 +468,12 @@ public class Graph { return ret; } - protected List printGraph(List localData, Stack stack, List allParts, GraphPart parent, GraphPart part, GraphPart stopPart, List loops, HashMap> forFinalCommands) { - //String methodPath, Stack stack, Stack scopeStack, List allParts, List parsedExceptions, List finallyJumps, int level, GraphPart parent, GraphPart part, GraphPart stopPart, List loops, HashMap localRegs, MethodBody body, List ignoredSwitches - + protected List printGraph(List visited, List localData, Stack stack, List allParts, GraphPart parent, GraphPart part, GraphPart stopPart, List loops, HashMap> forFinalCommands) { + if (visited.contains(part)) { + //return new ArrayList(); + } else { + visited.add(part); + } List ret = new ArrayList(); try { boolean debugMode = false; @@ -462,6 +483,10 @@ public class Graph { } while (((part != null) && (part.getHeight() == 1)) && (code.size() > part.start) && (code.get(part.start).isJump())) { //Parts with only jump in it gets ignored + + if (part == stopPart) { + return ret; + } GraphTargetItem lop = checkLoop(part.nextParts.get(0), stopPart, loops); if (lop == null) { part = part.nextParts.get(0); @@ -470,7 +495,7 @@ public class Graph { } } - if (code.size() <= part.start) { + if ((part != null) && (code.size() <= part.start)) { return ret; } @@ -524,11 +549,11 @@ public class Graph { stack.pop(); if (top.toBoolean()) { ret.addAll(output); - ret.addAll(printGraph(localData, stack, allParts, parent, part.nextParts.get(0), stopPart, loops, forFinalCommands)); + ret.addAll(printGraph(visited, localData, stack, allParts, parent, part.nextParts.get(0), stopPart, loops, forFinalCommands)); return ret; } else { ret.addAll(output); - ret.addAll(printGraph(localData, stack, allParts, parent, part.nextParts.get(1), stopPart, loops, forFinalCommands)); + ret.addAll(printGraph(visited, localData, stack, allParts, parent, part.nextParts.get(1), stopPart, loops, forFinalCommands)); return ret; } } else { @@ -570,7 +595,7 @@ public class Graph { if ((ti = checkLoop(next, stopPart, loops)) != null) { ret.add(ti); } else { - printGraph(localData, stack, allParts, parent, next, reversed ? sp1 : sp0, loops, forFinalCommands); + printGraph(visited, localData, stack, allParts, parent, next, reversed ? sp1 : sp0, loops, forFinalCommands); GraphTargetItem second = stack.pop(); GraphTargetItem first = stack.pop(); if (!reversed) { @@ -598,7 +623,7 @@ public class Graph { if ((ti = checkLoop(next, stopPart, loops)) != null) { ret.add(ti); } else { - ret.addAll(printGraph(localData, stack, allParts, parent, next, stopPart, loops, forFinalCommands)); + ret.addAll(printGraph(visited, localData, stack, allParts, parent, next, stopPart, loops, forFinalCommands)); } } return ret; @@ -618,7 +643,7 @@ public class Graph { if ((ti = checkLoop(next, stopPart, loops)) != null) { ret.add(ti); } else { - printGraph(localData, stack, allParts, parent, next, reversed ? sp1 : sp0, loops, forFinalCommands); + printGraph(visited, localData, stack, allParts, parent, next, reversed ? sp1 : sp0, loops, forFinalCommands); GraphTargetItem second = stack.pop(); GraphTargetItem first = stack.pop(); @@ -649,7 +674,7 @@ public class Graph { if ((ti = checkLoop(next, stopPart, loops)) != null) { ret.add(ti); } else { - ret.addAll(printGraph(localData, stack, allParts, parent, next, stopPart, loops, forFinalCommands)); + ret.addAll(printGraph(visited, localData, stack, allParts, parent, next, stopPart, loops, forFinalCommands)); } } @@ -754,7 +779,7 @@ public class Graph { loops.add(l); List wtbody=new ArrayList(); wtbody.addAll(output); - wtbody.addAll(printGraph(localData, stack, allParts, parent, part, stopPart, loops, forFinalCommands)); + wtbody.addAll(printGraph(visited, localData, stack, allParts, parent, part, stopPart, loops, forFinalCommands)); ret.add(new WhileItem(null, l, trueExp, wtbody)); return ret; }*/ @@ -770,12 +795,7 @@ public class Graph { loops.add(currentLoop); } - loopContinues = new ArrayList(); - for (Loop l : loops) { - if (l.loopContinue != null) { - loopContinues.add(l.loopContinue); - } - } + if ((!whileTrue) && loop && (part.nextParts.size() > 1) && (!doWhile)) { currentLoop.loopBreak = part.nextParts.get(reversed ? 0 : 1); @@ -791,24 +811,26 @@ public class Graph { expr = stack.pop(); } } - if (loop) { - GraphTargetItem expr2 = expr; - if (expr2 instanceof NotItem) { - expr2 = ((NotItem) expr2).getOriginal(); - } - if (expr2 instanceof AndItem) { - currentLoop.loopContinue = ((AndItem) expr2).firstPart; - } - if (expr2 instanceof OrItem) { - currentLoop.loopContinue = ((OrItem) expr2).firstPart; - } - } + /*if (loop) { + GraphTargetItem expr2 = expr; + if (expr2 instanceof NotItem) { + expr2 = ((NotItem) expr2).getOriginal(); + } + }*/ if (doWhile) { //ret.add(new DoWhileTreeItem(null, currentLoop.id, part.start, output, expr)); } else { ret.addAll(output); } + if (loop) { + if (expr instanceof AndItem) { + currentLoop.loopContinue = ((AndItem) expr).getFirstPart(); + } + if (expr instanceof OrItem) { + currentLoop.loopContinue = ((OrItem) expr).getFirstPart(); + } + } GraphPart loopBodyStart = null; if ((reversed == loop) || doWhile) { if (expr instanceof LogicalOpItem) { @@ -818,6 +840,8 @@ public class Graph { } } + loopContinues = getLoopsContinues(loops); + GraphPart next = part.getNextPartPath(loopContinues); List retx = ret; if ((!loop) || (doWhile && (part.nextParts.size() > 1))) { @@ -840,7 +864,7 @@ public class Graph { if (debugMode) { System.err.println("ONTRUE: (inside " + part + ")"); } - onTrue = printGraph(prepareBranchLocalData(localData), trueStack, allParts, part, part.nextParts.get(1), next == null ? stopPart : next, loops, forFinalCommands); + onTrue = printGraph(visited, prepareBranchLocalData(localData), trueStack, allParts, part, part.nextParts.get(1), next == null ? stopPart : next, loops, forFinalCommands); if (debugMode) { System.err.println("/ONTRUE (inside " + part + ")"); } @@ -858,7 +882,7 @@ public class Graph { if ((next == part.nextParts.get(0)) || (part.nextParts.get(0).path.equals(part.path) || part.nextParts.get(0).path.length() < part.path.length())) { onFalse = new ArrayList(); } else { - onFalse = (printGraph(prepareBranchLocalData(localData), falseStack, allParts, part, part.nextParts.get(0), next == null ? stopPart : next, loops, forFinalCommands)); + onFalse = (printGraph(visited, prepareBranchLocalData(localData), falseStack, allParts, part, part.nextParts.get(0), next == null ? stopPart : next, loops, forFinalCommands)); } if (debugMode) { System.err.println("/ONFALSE (inside " + part + ")"); @@ -875,7 +899,7 @@ public class Graph { List body = new ArrayList(); if (next != null) { - body = printGraph(prepareBranchLocalData(localData), stack, allParts, part, next, stopPart, loops, forFinalCommands); + body = printGraph(visited, prepareBranchLocalData(localData), stack, allParts, part, next, stopPart, loops, forFinalCommands); } retw.addAll(body); @@ -944,7 +968,7 @@ public class Graph { loopBody.add(ti); } else { if (!(doWhile && (loopBodyStart == null))) { - loopBody = printGraph(prepareBranchLocalData(localData), stack, allParts, part, loopBodyStart != null ? loopBodyStart : part.nextParts.get(reversed ? 1 : 0), stopPart, loops, forFinalCommands); + loopBody = printGraph(visited, prepareBranchLocalData(localData), stack, allParts, part, loopBodyStart != null ? loopBodyStart : part.nextParts.get(reversed ? 1 : 0), stopPart, loops, forFinalCommands); } } checkContinueAtTheEnd(loopBody, currentLoop); @@ -960,7 +984,7 @@ public class Graph { } loopBody.addAll(0, output); if (part.nextParts.size() == 1) { - loopBody.addAll(printGraph(prepareBranchLocalData(localData), stack, allParts, part, part.nextParts.get(0), stopPart, loops, forFinalCommands)); + loopBody.addAll(printGraph(visited, prepareBranchLocalData(localData), stack, allParts, part, part.nextParts.get(0), stopPart, loops, forFinalCommands)); } checkContinueAtTheEnd(loopBody, currentLoop); @@ -1034,7 +1058,7 @@ public class Graph { if (debugMode) { System.err.println("NEXT: (inside " + part + ")"); } - ret.addAll(printGraph(localData, stack, allParts, part, next, stopPart, loops, forFinalCommands)); + ret.addAll(printGraph(visited, localData, stack, allParts, part, next, stopPart, loops, forFinalCommands)); if (debugMode) { System.err.println("/NEXT: (inside " + part + ")"); } @@ -1097,7 +1121,7 @@ public class Graph { GraphTargetItem lop = checkLoop(p, stopPart, loops); if (lop == null) { if (p.path.length() >= part.path.length()) { - ret.addAll(printGraph(localData, stack, allParts, part, p, stopPart, loops, forFinalCommands)); + ret.addAll(printGraph(visited, localData, stack, allParts, part, p, stopPart, loops, forFinalCommands)); } else { if ((p != stopPart) && (p.refs.size() > 1)) { List nextList = new ArrayList(); @@ -1113,7 +1137,7 @@ public class Graph { } } if ((nearestLoop != null)) {// && (nearestLoop.loopBreak != null)) { - List finalCommands = printGraph(localData, stack, allParts, part, p, nearestLoop.loopContinue, loops, forFinalCommands); + List finalCommands = printGraph(visited, localData, stack, allParts, part, p, nearestLoop.loopContinue, loops, forFinalCommands); nearestLoop.loopContinue = p; forFinalCommands.put(nearestLoop, finalCommands); ContinueItem cti = new ContinueItem(null, nearestLoop.id); diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/OrItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/OrItem.java index fde0fd8ec..e127d20bf 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/OrItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/OrItem.java @@ -22,6 +22,16 @@ public class OrItem extends BinaryOpItem { public GraphPart firstPart; + public GraphPart getFirstPart() { + if (leftSide instanceof AndItem) { + return ((AndItem) leftSide).getFirstPart(); + } + if (leftSide instanceof OrItem) { + return ((OrItem) leftSide).getFirstPart(); + } + return firstPart; + } + public OrItem(GraphSourceItem src, GraphTargetItem leftSide, GraphTargetItem rightSide) { super(src, PRECEDENCE_LOGICALOR, leftSide, rightSide, "||"); this.leftSide = leftSide;