diff --git a/trunk/src/com/jpexs/decompiler/flash/action/Action.java b/trunk/src/com/jpexs/decompiler/flash/action/Action.java index 0782c3757..13a9c7ff0 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/Action.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/Action.java @@ -36,6 +36,7 @@ import com.jpexs.decompiler.flash.graph.GraphSourceItemContainer; import com.jpexs.decompiler.flash.graph.GraphTargetItem; import com.jpexs.decompiler.flash.graph.IfItem; import com.jpexs.decompiler.flash.graph.NotItem; +import com.jpexs.decompiler.flash.graph.ScriptEndItem; import com.jpexs.decompiler.flash.helpers.Helper; import com.jpexs.decompiler.flash.helpers.Highlighting; import java.io.ByteArrayInputStream; @@ -766,6 +767,7 @@ public class Action implements GraphSourceItem { break; } if (ip >= actions.size()) { + output.add(new ScriptEndItem()); break; } Action action = actions.get(ip); diff --git a/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java b/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java index 4a017a31a..f28079610 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/swf4/ActionPush.java @@ -22,13 +22,7 @@ import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.parser.ParseException; import com.jpexs.decompiler.flash.action.parser.pcode.ASMParsedSymbol; import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer; -import com.jpexs.decompiler.flash.action.treemodel.DecrementTreeItem; import com.jpexs.decompiler.flash.action.treemodel.DirectValueTreeItem; -import com.jpexs.decompiler.flash.action.treemodel.IncrementTreeItem; -import com.jpexs.decompiler.flash.action.treemodel.SetTypeTreeItem; -import com.jpexs.decompiler.flash.action.treemodel.StoreRegisterTreeItem; -import com.jpexs.decompiler.flash.action.treemodel.operations.PreDecrementTreeItem; -import com.jpexs.decompiler.flash.action.treemodel.operations.PreIncrementTreeItem; import com.jpexs.decompiler.flash.graph.GraphSourceItem; import com.jpexs.decompiler.flash.graph.GraphTargetItem; import com.jpexs.decompiler.flash.helpers.Helper; diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/DoWhileItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/DoWhileItem.java index fad04a3f7..5c0b96e46 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/DoWhileItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/DoWhileItem.java @@ -22,7 +22,7 @@ import java.util.List; public class DoWhileItem extends LoopItem implements Block { public List commands; - public GraphTargetItem expression; + public List expression; @Override public boolean needsSemicolon() { @@ -36,7 +36,7 @@ public class DoWhileItem extends LoopItem implements Block { return ret; } - public DoWhileItem(GraphSourceItem src, Loop loop, List commands, GraphTargetItem expression) { + public DoWhileItem(GraphSourceItem src, Loop loop, List commands, List expression) { super(src, loop); this.expression = expression; this.commands = commands; @@ -52,7 +52,17 @@ public class DoWhileItem extends LoopItem implements Block { ret += ti.toStringSemicoloned(localData) + "\r\n"; } } - ret += hilight("}\r\nwhile(") + expression.toString(localData) + hilight(");") + "\r\n"; + String expStr = ""; + for (int i = 0; i < expression.size(); i++) { + if (expression.get(i).isEmpty()) { + continue; + } + if (i > 0) { + expStr += ", "; + } + expStr += expression.get(i).toString(localData); + } + ret += hilight("}\r\nwhile(") + expStr + hilight(");") + "\r\n"; ret += ":loop" + loop.id; return ret; diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/Graph.java b/trunk/src/com/jpexs/decompiler/flash/graph/Graph.java index bdf49eb61..7457eb438 100644 --- a/trunk/src/com/jpexs/decompiler/flash/graph/Graph.java +++ b/trunk/src/com/jpexs/decompiler/flash/graph/Graph.java @@ -399,7 +399,6 @@ public class Graph { List ret = new ArrayList(); boolean debugMode = false; - if (debugMode) { System.err.println("PART " + part); } @@ -1014,10 +1013,51 @@ public class Graph { body = printGraph(prepareBranchLocalData(localData), stack, allParts, part, next, stopPart, loops, forFinalCommands); } retw.addAll(body); - List tr = new ArrayList(); - tr.add(new TrueItem(null)); - retx.add(new WhileItem(null, whileTrueLoop, tr, retw)); - next = null; + + + if (!retw.isEmpty()) { + checkContinueAtTheEnd(retw, whileTrueLoop); + List finalCommands = forFinalCommands.get(whileTrueLoop); + IfItem ifi = null; + if (!finalCommands.isEmpty()) { + if (finalCommands.get(finalCommands.size() - 1) instanceof IfItem) { + ifi = (IfItem) finalCommands.get(finalCommands.size() - 1); + finalCommands.remove(finalCommands.size() - 1); + } + } else if (retw.get(retw.size() - 1) instanceof IfItem) { + ifi = (IfItem) retw.get(retw.size() - 1); + retw.remove(retw.size() - 1); + } + if (ifi != null) { + if (ifi.onFalse.isEmpty()) { + if (!ifi.onTrue.isEmpty()) { + if (ifi.onTrue.get(ifi.onTrue.size() - 1) instanceof ExitItem) { + whileTrue = false; + List tr = new ArrayList(); + GraphTargetItem ex = ifi.expression; + if (ex instanceof LogicalOpItem) { + ex = ((LogicalOpItem) ex).invert(); + } else { + ex = new NotItem(null, ex); + } + if (!finalCommands.isEmpty()) { + tr.addAll(finalCommands); + } + tr.add(ex); + retx.add(new DoWhileItem(null, whileTrueLoop, retw, tr)); + retx.addAll(ifi.onTrue); + next = null; + } + } + } + } + } + if (whileTrue) { + List tr = new ArrayList(); + tr.add(new TrueItem(null)); + retx.add(new WhileItem(null, whileTrueLoop, tr, retw)); + next = null; + } } else { retx.add(new IfItem(null, expr, onTrue, onFalse)); } @@ -1091,9 +1131,10 @@ public class Graph { checkContinueAtTheEnd(loopBody, currentLoop); List addIf = new ArrayList(); + List nextcmds = new ArrayList(); if ((!loopBody.isEmpty()) && (loopBody.get(loopBody.size() - 1) instanceof IfItem)) { IfItem ift = (IfItem) loopBody.get(loopBody.size() - 1); - if (ift.onFalse.isEmpty() || ((ift.onFalse.size() == 1) && (ift.onFalse.get(0) instanceof ContinueItem) && (((ContinueItem) ift.onFalse.get(0)).loopId == currentLoop.id))) { + if ((ift.onFalse.isEmpty() || (ift.onFalse.get(ift.onFalse.size() - 1) instanceof ExitItem)) || ((ift.onFalse.size() == 1) && (ift.onFalse.get(0) instanceof ContinueItem) && (((ContinueItem) ift.onFalse.get(0)).loopId == currentLoop.id))) { if (ift.expression != null) { expr = ift.expression; if (expr instanceof LogicalOpItem) { @@ -1103,15 +1144,19 @@ public class Graph { } } addIf = ift.onTrue; + nextcmds = ift.onFalse; loopBody.remove(loopBody.size() - 1); } } - if ((!addIf.isEmpty()) && (addIf.get(addIf.size() - 1) instanceof ContinueItem) && (((ContinueItem) addIf.get(addIf.size() - 1)).loopId == currentLoop.id)) { + if ((!addIf.isEmpty())) { // && (addIf.get(addIf.size() - 1) instanceof ContinueItem) && (((ContinueItem) addIf.get(addIf.size() - 1)).loopId == currentLoop.id)) { loopBody.add(expr); checkContinueAtTheEnd(addIf, currentLoop); ret.add(new WhileItem(null, currentLoop, loopBody, addIf)); + ret.addAll(nextcmds); } else { - ret.add(new DoWhileItem(null, currentLoop, loopBody, expr)); + List ex = new ArrayList(); + ex.add(expr); + ret.add(new DoWhileItem(null, currentLoop, loopBody, ex)); ret.addAll(addIf); } @@ -1216,7 +1261,7 @@ public class Graph { } } } - if ((nearestLoop != null) && (nearestLoop.loopBreak != null)) { + if ((nearestLoop != null)) {// && (nearestLoop.loopBreak != null)) { List finalCommands = printGraph(localData, stack, allParts, part, p, nearestLoop.loopContinue, loops, forFinalCommands); nearestLoop.loopContinue = p; forFinalCommands.put(nearestLoop, finalCommands); diff --git a/trunk/src/com/jpexs/decompiler/flash/graph/ScriptEndItem.java b/trunk/src/com/jpexs/decompiler/flash/graph/ScriptEndItem.java new file mode 100644 index 000000000..a316d875b --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/graph/ScriptEndItem.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2013 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.graph; + +import java.util.List; + +/** + * + * @author JPEXS + */ +public class ScriptEndItem extends GraphTargetItem implements ExitItem { + + public ScriptEndItem() { + super(null, NOPRECEDENCE); + } + + @Override + public String toString(List localData) { + return ""; + } + + @Override + public boolean needsSemicolon() { + return false; + } + + @Override + public boolean isEmpty() { + return true; + } +}