From ac96c7dbb5095c5a8db064da08310ea34bece643 Mon Sep 17 00:00:00 2001 From: Honfika Date: Sun, 1 Dec 2013 08:53:04 +0100 Subject: [PATCH] Workarounds for StackOverflowExceptions --- .../com/jpexs/decompiler/flash/TagNode.java | 5 +- .../decompiler/flash/abc/avm2/AVM2Code.java | 10 ++- .../flash/abc/avm2/graph/AVM2Graph.java | 14 ++-- .../flash/abc/avm2/model/BooleanAVM2Item.java | 4 +- .../flash/abc/avm2/model/CoerceAVM2Item.java | 9 ++- .../flash/abc/avm2/model/ConvertAVM2Item.java | 9 ++- .../abc/avm2/model/DecrementAVM2Item.java | 9 ++- .../abc/avm2/model/FloatValueAVM2Item.java | 4 +- .../abc/avm2/model/IncrementAVM2Item.java | 9 ++- .../abc/avm2/model/IntegerValueAVM2Item.java | 4 +- .../abc/avm2/model/LocalRegAVM2Item.java | 3 +- .../flash/abc/avm2/model/NullAVM2Item.java | 4 +- .../flash/abc/avm2/model/StringAVM2Item.java | 4 +- .../abc/avm2/model/UndefinedAVM2Item.java | 4 +- .../avm2/model/operations/TypeOfAVM2Item.java | 9 ++- .../jpexs/decompiler/flash/action/Action.java | 16 ++-- .../decompiler/flash/action/ActionGraph.java | 8 +- .../flash/action/ActionListReader.java | 33 ++++++-- .../action/model/CallFunctionActionItem.java | 9 ++- .../action/model/CharToAsciiActionItem.java | 3 +- .../action/model/DecrementActionItem.java | 9 ++- .../action/model/DirectValueActionItem.java | 9 ++- .../action/model/FunctionActionItem.java | 9 ++- .../flash/action/model/GetTimeActionItem.java | 4 +- .../action/model/GetVariableActionItem.java | 3 +- .../action/model/IncrementActionItem.java | 9 ++- .../flash/action/model/ReturnActionItem.java | 3 +- .../action/model/SetVariableActionItem.java | 9 ++- .../action/model/StoreRegisterActionItem.java | 9 ++- .../action/model/StringLengthActionItem.java | 3 +- .../flash/action/model/TypeOfActionItem.java | 9 ++- .../action/model/operations/InActionItem.java | 4 +- .../operations/InstanceOfActionItem.java | 3 +- .../model/operations/StringAddActionItem.java | 3 +- .../model/operations/StringEqActionItem.java | 3 +- .../model/operations/StringLtActionItem.java | 3 +- .../src/com/jpexs/decompiler/graph/Graph.java | 78 ++++++++++--------- .../decompiler/graph/GraphTargetItem.java | 8 ++ .../decompiler/graph/NotCompileTimeItem.java | 3 +- .../decompiler/graph/TranslateException.java | 28 +++++++ .../decompiler/graph/model/BinaryOpItem.java | 13 +++- .../decompiler/graph/model/CommentItem.java | 23 ++++-- .../decompiler/graph/model/DuplicateItem.java | 9 ++- .../jpexs/decompiler/graph/model/IfItem.java | 9 ++- .../graph/model/IntegerValueItem.java | 3 +- .../jpexs/decompiler/graph/model/NotItem.java | 9 ++- .../decompiler/graph/model/UnaryOpItem.java | 9 ++- 47 files changed, 330 insertions(+), 124 deletions(-) create mode 100644 trunk/src/com/jpexs/decompiler/graph/TranslateException.java diff --git a/trunk/src/com/jpexs/decompiler/flash/TagNode.java b/trunk/src/com/jpexs/decompiler/flash/TagNode.java index 6ac8a1492..03cdddd66 100644 --- a/trunk/src/com/jpexs/decompiler/flash/TagNode.java +++ b/trunk/src/com/jpexs/decompiler/flash/TagNode.java @@ -49,6 +49,7 @@ import com.jpexs.decompiler.flash.tags.base.Container; import com.jpexs.decompiler.flash.tags.base.ContainerItem; import com.jpexs.decompiler.flash.tags.base.Exportable; import com.jpexs.decompiler.graph.ExportMode; +import com.jpexs.decompiler.graph.TranslateException; import com.jpexs.helpers.Helper; import java.io.File; import java.io.FileOutputStream; @@ -343,8 +344,8 @@ public class TagNode { ret.add(file); } catch (InterruptedException ex) { - } catch (IOException | OutOfMemoryError | StackOverflowError ex) { - Logger.getLogger(TagNode.class.getName()).log(Level.SEVERE, "Decompilation error", ex); + } catch (IOException | OutOfMemoryError | TranslateException | StackOverflowError ex) { + Logger.getLogger(TagNode.class.getName()).log(Level.SEVERE, "Decompilation error in file: " + name + ".as", ex); if (handler != null) { int action = handler.getNewInstance().handle(ex); switch (action) { 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 fb52d5af5..71bf77486 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java @@ -80,6 +80,7 @@ import com.jpexs.decompiler.graph.GraphPart; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.NotCompileTimeItem; +import com.jpexs.decompiler.graph.TranslateException; import com.jpexs.decompiler.graph.model.LocalData; import com.jpexs.decompiler.graph.model.ScriptEndItem; import com.jpexs.helpers.Helper; @@ -2374,10 +2375,13 @@ public class AVM2Code implements Serializable { } @SuppressWarnings("unchecked") - private static int removeTraps(HashMap> refs, boolean secondPass, boolean indeterminate, List localData, Stack stack, List output, AVM2GraphSource code, int ip, HashMap visited, HashMap> visitedStates, HashMap decisions, String path) throws InterruptedException { + private static int removeTraps(HashMap> refs, boolean secondPass, boolean indeterminate, List localData, Stack stack, List output, AVM2GraphSource code, int ip, HashMap visited, HashMap> visitedStates, HashMap decisions, String path, int recursionLevel) throws InterruptedException { if (Thread.interrupted()) { throw new InterruptedException(); } + if (recursionLevel > code.size() + 1) { + throw new TranslateException("removeTraps max recursion level reached."); + } boolean debugMode = false; int ret = 0; iploop: @@ -2614,7 +2618,7 @@ public class AVM2Code implements Serializable { for (int b : branches) { Stack brStack = (Stack) stack.clone(); if (b >= 0) { //useVisited || (!ins.isJump()) - ret += removeTraps(refs, secondPass, indeterminate, prepareBranchLocalData(localData), brStack, output, code, b, visited, visitedStates, decisions, path); + ret += removeTraps(refs, secondPass, indeterminate, prepareBranchLocalData(localData), brStack, output, code, b, visited, visitedStates, decisions, path, recursionLevel + 1); } else { if (debugMode) { System.out.println("Negative branch:" + b); @@ -2634,7 +2638,7 @@ public class AVM2Code implements Serializable { public static int removeTraps(ConstantPool constants, Trait trait, MethodInfo info, MethodBody body, List localData, AVM2GraphSource code, int addr, String path, HashMap> refs) throws InterruptedException { HashMap decisions = new HashMap<>(); - removeTraps(refs, false, false, localData, new Stack(), new ArrayList(), code, code.adr2pos(addr), new HashMap(), new HashMap>(), decisions, path); + removeTraps(refs, false, false, localData, new Stack(), new ArrayList(), code, code.adr2pos(addr), new HashMap(), new HashMap>(), decisions, path, 0); int cnt = 0; for (GraphSourceItem src : decisions.keySet()) { Decision dec = decisions.get(src); 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 823779865..e4057092a 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 @@ -286,7 +286,7 @@ public class AVM2Graph extends Graph { List oldFinallyJumps = new ArrayList<>(finallyJumps); finallyJumps.clear(); ignoredSwitches.add(swPos); - finallyCommands = printGraph(new ArrayList(), localData, stack, allParts, parent, fpart, null, loops, staticOperation, path); + finallyCommands = printGraph(localData, stack, allParts, parent, fpart, null, loops, staticOperation, path); //ignoredSwitches.remove(igs_size-1); finallyJumps.addAll(oldFinallyJumps); finallyJumps.add(finStart); @@ -339,7 +339,7 @@ public class AVM2Graph extends Graph { if (retPart != null) { stopPart2.add(retPart); } - catchedCommands.add(printGraph(new ArrayList(), localData2, stack, allParts, parent, npart, stopPart2, loops, staticOperation, path)); + catchedCommands.add(printGraph(localData2, stack, allParts, parent, npart, stopPart2, loops, staticOperation, path)); } GraphPart nepart = null; @@ -357,7 +357,7 @@ public class AVM2Graph extends Graph { if (retPart != null) { stopPart2.add(retPart); } - List tryCommands = printGraph(new ArrayList(), localData, stack, allParts, parent, part, stopPart2, loops, staticOperation, path); + List tryCommands = printGraph(localData, stack, allParts, parent, part, stopPart2, loops, staticOperation, path); output.clear(); output.add(new TryAVM2Item(tryCommands, catchedExceptions, catchedCommands, finallyCommands)); @@ -381,7 +381,7 @@ public class AVM2Graph extends Graph { ret.addAll(output); GraphTargetItem lop = checkLoop(part, stopPart, loops); if (lop == null) { - ret.addAll(printGraph(new ArrayList(), localData, stack, allParts, null, part, stopPart, loops, staticOperation, path)); + ret.addAll(printGraph(localData, stack, allParts, null, part, stopPart, loops, staticOperation, path)); } else { ret.add(lop); } @@ -572,7 +572,7 @@ public class AVM2Graph extends Graph { defaultPart = switchLoc.nextParts.get(switchLoc.nextParts.size() - 1); List stopPart2 = new ArrayList<>(stopPart); stopPart2.add(next); - defaultCommands = printGraph(new ArrayList(), localData, stack, allParts, switchLoc, defaultPart, stopPart2, loops, staticOperation, path); + defaultCommands = printGraph(localData, stack, allParts, switchLoc, defaultPart, stopPart2, loops, staticOperation, path); if (!defaultCommands.isEmpty()) { if (defaultCommands.get(defaultCommands.size() - 1) instanceof BreakItem) { if (((BreakItem) defaultCommands.get(defaultCommands.size() - 1)).loopId == currentLoop.id) { @@ -599,7 +599,7 @@ public class AVM2Graph extends Graph { stopPart2.add(defaultPart); } - cc.addAll(0, printGraph(new ArrayList(), localData, stack, allParts, switchLoc, caseBodies.get(i), stopPart2, loops, staticOperation, path)); + cc.addAll(0, printGraph(localData, stack, allParts, switchLoc, caseBodies.get(i), stopPart2, loops, staticOperation, path)); caseCommands.add(cc); } @@ -611,7 +611,7 @@ public class AVM2Graph extends Graph { ret.add(ti); } else {*/ currentLoop.phase = 2; - ret.addAll(printGraph(new ArrayList(), localData, stack, allParts, null, next, stopPart, loops, staticOperation, path)); + ret.addAll(printGraph(localData, stack, allParts, null, next, stopPart, loops, staticOperation, path)); //} } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/BooleanAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/BooleanAVM2Item.java index 7aec184c6..6ca5c512f 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/BooleanAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/BooleanAVM2Item.java @@ -18,7 +18,9 @@ package com.jpexs.decompiler.flash.abc.avm2.model; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.model.LocalData; +import java.util.Set; public class BooleanAVM2Item extends AVM2Item { @@ -40,7 +42,7 @@ public class BooleanAVM2Item extends AVM2Item { } @Override - public boolean isCompileTime() { + public boolean isCompileTime(Set dependencies) { return true; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/CoerceAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/CoerceAVM2Item.java index e6aee8e86..db6c19e79 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/CoerceAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/CoerceAVM2Item.java @@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.ecma.Undefined; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.model.LocalData; +import java.util.Set; public class CoerceAVM2Item extends AVM2Item { @@ -46,8 +47,12 @@ public class CoerceAVM2Item extends AVM2Item { } @Override - public boolean isCompileTime() { - return value.isCompileTime(); + public boolean isCompileTime(Set dependencies) { + if (dependencies.contains(value)) { + return false; + } + dependencies.add(value); + return value.isCompileTime(dependencies); } @Override diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/ConvertAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/ConvertAVM2Item.java index 76f0fdde4..365c813a2 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/ConvertAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/ConvertAVM2Item.java @@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.model.LocalData; +import java.util.Set; public class ConvertAVM2Item extends AVM2Item { @@ -64,7 +65,11 @@ public class ConvertAVM2Item extends AVM2Item { } @Override - public boolean isCompileTime() { - return value.isCompileTime(); + public boolean isCompileTime(Set dependencies) { + if (dependencies.contains(value)) { + return false; + } + dependencies.add(value); + return value.isCompileTime(dependencies); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/DecrementAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/DecrementAVM2Item.java index 7d4b4d556..ab9434c98 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/DecrementAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/DecrementAVM2Item.java @@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.model.LocalData; +import java.util.Set; public class DecrementAVM2Item extends AVM2Item { @@ -36,8 +37,12 @@ public class DecrementAVM2Item extends AVM2Item { } @Override - public boolean isCompileTime() { - return value.isCompileTime(); + public boolean isCompileTime(Set dependencies) { + if (dependencies.contains(value)) { + return false; + } + dependencies.add(value); + return value.isCompileTime(dependencies); } @Override diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/FloatValueAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/FloatValueAVM2Item.java index f936a5700..635a7e468 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/FloatValueAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/FloatValueAVM2Item.java @@ -18,7 +18,9 @@ package com.jpexs.decompiler.flash.abc.avm2.model; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.model.LocalData; +import java.util.Set; public class FloatValueAVM2Item extends NumberValueAVM2Item { @@ -40,7 +42,7 @@ public class FloatValueAVM2Item extends NumberValueAVM2Item { } @Override - public boolean isCompileTime() { + public boolean isCompileTime(Set dependencies) { return true; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/IncrementAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/IncrementAVM2Item.java index b50cec264..2ca8746c7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/IncrementAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/IncrementAVM2Item.java @@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.model.LocalData; +import java.util.Set; public class IncrementAVM2Item extends AVM2Item { @@ -36,8 +37,12 @@ public class IncrementAVM2Item extends AVM2Item { } @Override - public boolean isCompileTime() { - return value.isCompileTime(); + public boolean isCompileTime(Set dependencies) { + if (dependencies.contains(value)) { + return false; + } + dependencies.add(value); + return value.isCompileTime(dependencies); } @Override diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/IntegerValueAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/IntegerValueAVM2Item.java index 9df93394a..403f99cef 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/IntegerValueAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/IntegerValueAVM2Item.java @@ -18,7 +18,9 @@ package com.jpexs.decompiler.flash.abc.avm2.model; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.model.LocalData; +import java.util.Set; public class IntegerValueAVM2Item extends NumberValueAVM2Item { @@ -40,7 +42,7 @@ public class IntegerValueAVM2Item extends NumberValueAVM2Item { } @Override - public boolean isCompileTime() { + public boolean isCompileTime(Set dependencies) { return true; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/LocalRegAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/LocalRegAVM2Item.java index a041bf281..2163febd7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/LocalRegAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/LocalRegAVM2Item.java @@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.ecma.Undefined; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.model.LocalData; +import java.util.Set; public class LocalRegAVM2Item extends AVM2Item { @@ -72,7 +73,7 @@ public class LocalRegAVM2Item extends AVM2Item { } @Override - public boolean isCompileTime() { + public boolean isCompileTime(Set dependencies) { return isCT; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/NullAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/NullAVM2Item.java index 71e7c8f68..23f978ec4 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/NullAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/NullAVM2Item.java @@ -19,7 +19,9 @@ package com.jpexs.decompiler.flash.abc.avm2.model; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.ecma.Null; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.model.LocalData; +import java.util.Set; public class NullAVM2Item extends AVM2Item { @@ -33,7 +35,7 @@ public class NullAVM2Item extends AVM2Item { } @Override - public boolean isCompileTime() { + public boolean isCompileTime(Set dependencies) { return true; } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/StringAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/StringAVM2Item.java index 0f10eaeed..21cef43b5 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/StringAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/StringAVM2Item.java @@ -18,8 +18,10 @@ package com.jpexs.decompiler.flash.abc.avm2.model; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.model.LocalData; import com.jpexs.helpers.Helper; +import java.util.Set; public class StringAVM2Item extends AVM2Item { @@ -36,7 +38,7 @@ public class StringAVM2Item extends AVM2Item { } @Override - public boolean isCompileTime() { + public boolean isCompileTime(Set dependencies) { return true; } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/UndefinedAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/UndefinedAVM2Item.java index 4b37c7962..14159c6ab 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/UndefinedAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/UndefinedAVM2Item.java @@ -19,7 +19,9 @@ package com.jpexs.decompiler.flash.abc.avm2.model; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.ecma.Undefined; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; +import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.model.LocalData; +import java.util.Set; public class UndefinedAVM2Item extends AVM2Item { @@ -33,7 +35,7 @@ public class UndefinedAVM2Item extends AVM2Item { } @Override - public boolean isCompileTime() { + public boolean isCompileTime(Set dependencies) { return true; } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/TypeOfAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/TypeOfAVM2Item.java index bff5b8fb7..2ba0d6e62 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/TypeOfAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/TypeOfAVM2Item.java @@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.ecma.EcmaType; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.model.UnaryOpItem; +import java.util.Set; public class TypeOfAVM2Item extends UnaryOpItem { @@ -29,8 +30,12 @@ public class TypeOfAVM2Item extends UnaryOpItem { } @Override - public boolean isCompileTime() { - return value.isCompileTime(); + public boolean isCompileTime(Set dependencies) { + if (dependencies.contains(value)) { + return false; + } + dependencies.add(value); + return value.isCompileTime(dependencies); } @Override diff --git a/trunk/src/com/jpexs/decompiler/flash/action/Action.java b/trunk/src/com/jpexs/decompiler/flash/action/Action.java index dca7d9bf0..20587983e 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/Action.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/Action.java @@ -58,6 +58,7 @@ import com.jpexs.decompiler.graph.GraphSource; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphSourceItemContainer; import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.TranslateException; import com.jpexs.decompiler.graph.model.CommentItem; import com.jpexs.decompiler.graph.model.IfItem; import com.jpexs.decompiler.graph.model.LocalData; @@ -717,7 +718,7 @@ public class Action implements GraphSourceItem { return tree; } }, timeout, TimeUnit.SECONDS); - } catch (InterruptedException | TimeoutException | ExecutionException | OutOfMemoryError | StackOverflowError ex) { + } catch (InterruptedException | TimeoutException | ExecutionException | OutOfMemoryError | TranslateException | StackOverflowError ex) { Logger.getLogger(Action.class.getName()).log(Level.SEVERE, "Decompilation error", ex); convertException = ex; if (ex instanceof ExecutionException && ex.getCause() instanceof Exception) { @@ -882,13 +883,18 @@ public class Action implements GraphSourceItem { List out; try { out = ActionGraph.translateViaGraph(cnt.getRegNames(), variables2, functions, actions.subList(adr2ip(actions, endAddr, version), adr2ip(actions, endAddr + size, version)), version, staticOperation, path + (cntName == null ? "" : "/" + cntName)); - } catch (OutOfMemoryError | StackOverflowError ex2) { - Logger.getLogger(Action.class.getName()).log(Level.SEVERE, "Decompilation error", ex2); + } catch (OutOfMemoryError | TranslateException | StackOverflowError ex2) { + Logger.getLogger(Action.class.getName()).log(Level.SEVERE, "Decompilation error in: " + path, ex2); if (ex2 instanceof OutOfMemoryError) { System.gc(); } out = new ArrayList<>(); - out.add(new CommentItem("\r\n * Decompilation error\r\n * Code may be obfuscated\r\n * Error type: " + ex2.getClass().getSimpleName() + "\r\n")); + out.add(new CommentItem(new String[] { + "", + " * Decompilation error", + " * Code may be obfuscated", + " * Error type: " + ex2.getClass().getSimpleName(), + ""})); } outs.add(out); endAddr += size; @@ -1002,7 +1008,7 @@ public class Action implements GraphSourceItem { try { action.translate(localData, stack, output, staticOperation, path); } catch (EmptyStackException ese) { - Logger.getLogger(Action.class.getName()).log(Level.SEVERE, null, ese); + Logger.getLogger(Action.class.getName()).log(Level.SEVERE, "Decompilation error in: " + path, ese); output.add(new UnsupportedActionItem(action, "Empty stack")); } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/ActionGraph.java b/trunk/src/com/jpexs/decompiler/flash/action/ActionGraph.java index 99d52b1eb..0e4b9c72d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/ActionGraph.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/ActionGraph.java @@ -318,7 +318,7 @@ public class ActionGraph extends Graph { List defaultCommands = new ArrayList<>(); List stopPart2 = new ArrayList<>(stopPart); stopPart2.add(defaultPart2); - defaultCommands = printGraph(new ArrayList(), localData, stack, allParts, null, defaultPart, stopPart2, loops, staticOperation, path); + defaultCommands = printGraph(localData, stack, allParts, null, defaultPart, stopPart2, loops, staticOperation, path); List loopContinues = new ArrayList<>(); @@ -399,7 +399,7 @@ public class ActionGraph extends Graph { if ((defaultPart != null) && (defaultCommands.isEmpty())) { List stopPart2x = new ArrayList<>(stopPart); stopPart2x.add(next); - defaultCommands = printGraph(new ArrayList(), localData, stack, allParts, null, defaultPart, stopPart2x, loops, staticOperation, path); + defaultCommands = printGraph(localData, stack, allParts, null, defaultPart, stopPart2x, loops, staticOperation, path); } if (!defaultCommands.isEmpty()) { @@ -448,7 +448,7 @@ public class ActionGraph extends Graph { if (breakPart != null) { stopPart2x.add(breakPart); } - cc.addAll(0, printGraph(new ArrayList(), localData, stack, allParts, null, caseBodies.get(i), stopPart2x, loops, staticOperation, path)); + cc.addAll(0, printGraph(localData, stack, allParts, null, caseBodies.get(i), stopPart2x, loops, staticOperation, path)); 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)) { @@ -467,7 +467,7 @@ public class ActionGraph extends Graph { if (ti != null) { ret.add(ti); } else { - ret.addAll(printGraph(new ArrayList(), localData, stack, allParts, null, next, stopPart, loops, staticOperation, path)); + ret.addAll(printGraph(localData, stack, allParts, null, next, stopPart, loops, staticOperation, path)); } } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/ActionListReader.java b/trunk/src/com/jpexs/decompiler/flash/action/ActionListReader.java index c6a17f618..bd9c1228f 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/ActionListReader.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/ActionListReader.java @@ -41,6 +41,7 @@ import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphSourceItemContainer; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.NotCompileTimeItem; +import com.jpexs.decompiler.graph.TranslateException; import com.jpexs.decompiler.graph.model.LocalData; import com.jpexs.helpers.Helper; import com.jpexs.helpers.MemoryInputStream; @@ -150,12 +151,17 @@ public class ActionListReader { if (deobfuscate) { try { - actions = deobfuscateActionList(listeners, containerSWFOffset, actions, version, ip, path); - } catch (InterruptedException ex) { + try { + actions = deobfuscateActionList(listeners, containerSWFOffset, actions, version, ip, path); + } catch (InterruptedException ex) { + Logger.getLogger(ActionListReader.class.getName()).log(Level.SEVERE, null, ex); + } + updateActionLengths(actions, version); + removeZeroJumps(actions, version); + } catch (TranslateException ex) { + // keep orignal (not deobfuscated) actions Logger.getLogger(ActionListReader.class.getName()).log(Level.SEVERE, null, ex); } - updateActionLengths(actions, version); - removeZeroJumps(actions, version); } return actions; @@ -202,7 +208,14 @@ public class ActionListReader { List localData = Helper.toList(new HashMap(), new HashMap(), new HashMap()); - deobfustaceActionListAtPosRecursive(listeners, new ArrayList(), new HashMap>(), containerSWFOffset, localData, stack, cpool, actionMap, ip, ip, retdups, ip, endIp, path, new HashMap(), false, new HashMap>(), version); + int maxRecursionLevel = 0; + for (int i = 0; i < actions.size(); i++) { + Action a = actions.get(i); + if (a instanceof ActionIf || a instanceof GraphSourceItemContainer) { + maxRecursionLevel++; + } + } + deobfustaceActionListAtPosRecursive(listeners, new ArrayList(), new HashMap>(), containerSWFOffset, localData, stack, cpool, actionMap, ip, ip, retdups, ip, endIp, path, new HashMap(), false, new HashMap>(), version, 0, maxRecursionLevel); if (!retdups.isEmpty()) { for (int i = 0; i < ip; i++) { @@ -648,10 +661,14 @@ public class ActionListReader { } @SuppressWarnings("unchecked") - private static void deobfustaceActionListAtPosRecursive(List listeners, List output, HashMap> containers, long containerSWFOffset, List localData, Stack stack, ConstantPool cpool, List actions, int pos, int ip, List ret, int startIp, int endip, String path, Map visited, boolean indeterminate, Map> decisionStates, int version) throws IOException, InterruptedException { + private static void deobfustaceActionListAtPosRecursive(List listeners, List output, HashMap> containers, long containerSWFOffset, List localData, Stack stack, ConstantPool cpool, List actions, int pos, int ip, List ret, int startIp, int endip, String path, Map visited, boolean indeterminate, Map> decisionStates, int version, int recursionLevel, int maxRecursionLevel) throws IOException, InterruptedException { boolean debugMode = false; boolean decideBranch = false; + if (recursionLevel > maxRecursionLevel + 1) { + throw new TranslateException("deobfustaceActionListAtPosRecursive max recursion level reached."); + } + pos = ip; Action a; Scanner sc = new Scanner(System.in); @@ -828,7 +845,7 @@ public class ActionListReader { } else { localData2 = localData; } - deobfustaceActionListAtPosRecursive(listeners, output2, containers, containerSWFOffset, localData2, new Stack(), cpool, actions, pos, (int) endAddr, ret, startIp, (int) (endAddr + size), path + (cntName == null ? "" : "/" + cntName), visited, indeterminate, decisionStates, version); + deobfustaceActionListAtPosRecursive(listeners, output2, containers, containerSWFOffset, localData2, new Stack(), cpool, actions, pos, (int) endAddr, ret, startIp, (int) (endAddr + size), path + (cntName == null ? "" : "/" + cntName), visited, indeterminate, decisionStates, version, recursionLevel + 1, maxRecursionLevel); output2s.add(output2); endAddr += size; } @@ -896,7 +913,7 @@ public class ActionListReader { @SuppressWarnings("unchecked") Stack substack = (Stack) stack.clone(); - deobfustaceActionListAtPosRecursive(listeners, output, containers, containerSWFOffset, prepareLocalBranch(localData), substack, cpool, actions, pos, pos + aif.getJumpOffset(), ret, startIp, endip, path, visited, indeterminate, decisionStates, version); + deobfustaceActionListAtPosRecursive(listeners, output, containers, containerSWFOffset, prepareLocalBranch(localData), substack, cpool, actions, pos, pos + aif.getJumpOffset(), ret, startIp, endip, path, visited, indeterminate, decisionStates, version, recursionLevel + 1, maxRecursionLevel); } if (a.isExit()) { break; diff --git a/trunk/src/com/jpexs/decompiler/flash/action/model/CallFunctionActionItem.java b/trunk/src/com/jpexs/decompiler/flash/action/model/CallFunctionActionItem.java index 65cf52f33..55280faae 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/model/CallFunctionActionItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/model/CallFunctionActionItem.java @@ -24,6 +24,7 @@ import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.SourceGenerator; import com.jpexs.decompiler.graph.model.LocalData; import java.util.List; +import java.util.Set; public class CallFunctionActionItem extends ActionItem { @@ -67,11 +68,15 @@ public class CallFunctionActionItem extends ActionItem { } @Override - public boolean isCompileTime() { + public boolean isCompileTime(Set dependencies) { if (calculatedFunction == null) { return false; } - return calculatedFunction.isCompileTime(); + if (dependencies.contains(calculatedFunction)) { + return false; + } + dependencies.add(calculatedFunction); + return calculatedFunction.isCompileTime(dependencies); } @Override diff --git a/trunk/src/com/jpexs/decompiler/flash/action/model/CharToAsciiActionItem.java b/trunk/src/com/jpexs/decompiler/flash/action/model/CharToAsciiActionItem.java index 158e9793f..b6008deee 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/model/CharToAsciiActionItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/model/CharToAsciiActionItem.java @@ -24,6 +24,7 @@ import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.SourceGenerator; import com.jpexs.decompiler.graph.model.LocalData; import java.util.List; +import java.util.Set; public class CharToAsciiActionItem extends ActionItem { @@ -47,7 +48,7 @@ public class CharToAsciiActionItem extends ActionItem { } @Override - public boolean isCompileTime() { + public boolean isCompileTime(Set dependencies) { if (value instanceof DirectValueActionItem) { DirectValueActionItem dv = (DirectValueActionItem) value; if (dv.value instanceof String) { diff --git a/trunk/src/com/jpexs/decompiler/flash/action/model/DecrementActionItem.java b/trunk/src/com/jpexs/decompiler/flash/action/model/DecrementActionItem.java index 63262dd51..a3a082fc7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/model/DecrementActionItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/model/DecrementActionItem.java @@ -26,6 +26,7 @@ import com.jpexs.decompiler.graph.SourceGenerator; import com.jpexs.decompiler.graph.model.LocalData; import java.util.ArrayList; import java.util.List; +import java.util.Set; public class DecrementActionItem extends ActionItem { @@ -50,8 +51,12 @@ public class DecrementActionItem extends ActionItem { } @Override - public boolean isCompileTime() { - return object.isCompileTime(); + public boolean isCompileTime(Set dependencies) { + if (dependencies.contains(object)) { + return false; + } + dependencies.add(object); + return object.isCompileTime(dependencies); } @Override diff --git a/trunk/src/com/jpexs/decompiler/flash/action/model/DirectValueActionItem.java b/trunk/src/com/jpexs/decompiler/flash/action/model/DirectValueActionItem.java index 9cecfeabf..be31e2c01 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/model/DirectValueActionItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/model/DirectValueActionItem.java @@ -30,6 +30,7 @@ import com.jpexs.helpers.Helper; import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.Set; public class DirectValueActionItem extends ActionItem { @@ -173,8 +174,12 @@ public class DirectValueActionItem extends ActionItem { } @Override - public boolean isCompileTime() { - return (value instanceof Double) || (value instanceof Float) || (value instanceof Boolean) || (value instanceof Long) || (value instanceof Null) || (computedRegValue != null && computedRegValue.isCompileTime()) || (value instanceof String) || (value instanceof ConstantIndex); + public boolean isCompileTime(Set dependencies) { + if (dependencies.contains(computedRegValue)) { + return false; + } + dependencies.add(computedRegValue); + return (value instanceof Double) || (value instanceof Float) || (value instanceof Boolean) || (value instanceof Long) || (value instanceof Null) || (computedRegValue != null && computedRegValue.isCompileTime(dependencies)) || (value instanceof String) || (value instanceof ConstantIndex); } @Override diff --git a/trunk/src/com/jpexs/decompiler/flash/action/model/FunctionActionItem.java b/trunk/src/com/jpexs/decompiler/flash/action/model/FunctionActionItem.java index 1534222f0..18bd7e6cf 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/model/FunctionActionItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/model/FunctionActionItem.java @@ -35,6 +35,7 @@ import com.jpexs.helpers.Helper; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Set; import java.util.TreeSet; public class FunctionActionItem extends ActionItem { @@ -119,9 +120,13 @@ public class FunctionActionItem extends ActionItem { } @Override - public boolean isCompileTime() { + public boolean isCompileTime(Set dependencies) { for (GraphTargetItem a : actions) { - if (!a.isCompileTime()) { + if (dependencies.contains(a)) { + return false; + } + dependencies.add(a); + if (!a.isCompileTime(dependencies)) { return false; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/model/GetTimeActionItem.java b/trunk/src/com/jpexs/decompiler/flash/action/model/GetTimeActionItem.java index c3c2a993f..c765d4525 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/model/GetTimeActionItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/model/GetTimeActionItem.java @@ -19,10 +19,12 @@ package com.jpexs.decompiler.flash.action.model; import com.jpexs.decompiler.flash.action.swf4.ActionGetTime; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.GraphSourceItem; +import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.SourceGenerator; import com.jpexs.decompiler.graph.model.LocalData; import java.util.List; import java.util.Random; +import java.util.Set; public class GetTimeActionItem extends ActionItem { @@ -36,7 +38,7 @@ public class GetTimeActionItem extends ActionItem { } @Override - public boolean isCompileTime() { + public boolean isCompileTime(Set dependencies) { return true; } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/model/GetVariableActionItem.java b/trunk/src/com/jpexs/decompiler/flash/action/model/GetVariableActionItem.java index 38a7be069..841a04539 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/model/GetVariableActionItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/model/GetVariableActionItem.java @@ -26,6 +26,7 @@ import com.jpexs.decompiler.graph.SourceGenerator; import com.jpexs.decompiler.graph.model.LocalData; import java.util.ArrayList; import java.util.List; +import java.util.Set; public class GetVariableActionItem extends ActionItem { @@ -65,7 +66,7 @@ public class GetVariableActionItem extends ActionItem { } @Override - public boolean isCompileTime() { + public boolean isCompileTime(Set dependencies) { if (computedValue == null) { return false; } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/model/IncrementActionItem.java b/trunk/src/com/jpexs/decompiler/flash/action/model/IncrementActionItem.java index a3a7c995e..20b6a50f0 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/model/IncrementActionItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/model/IncrementActionItem.java @@ -26,6 +26,7 @@ import com.jpexs.decompiler.graph.SourceGenerator; import com.jpexs.decompiler.graph.model.LocalData; import java.util.ArrayList; import java.util.List; +import java.util.Set; public class IncrementActionItem extends ActionItem { @@ -50,8 +51,12 @@ public class IncrementActionItem extends ActionItem { } @Override - public boolean isCompileTime() { - return object.isCompileTime(); + public boolean isCompileTime(Set dependencies) { + if (dependencies.contains(object)) { + return false; + } + dependencies.add(object); + return object.isCompileTime(dependencies); } @Override diff --git a/trunk/src/com/jpexs/decompiler/flash/action/model/ReturnActionItem.java b/trunk/src/com/jpexs/decompiler/flash/action/model/ReturnActionItem.java index e7765f258..ff5fbd68d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/model/ReturnActionItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/model/ReturnActionItem.java @@ -35,6 +35,7 @@ import com.jpexs.decompiler.graph.model.ExitItem; import com.jpexs.decompiler.graph.model.LocalData; import java.util.ArrayList; import java.util.List; +import java.util.Set; public class ReturnActionItem extends ActionItem implements ExitItem { @@ -58,7 +59,7 @@ public class ReturnActionItem extends ActionItem implements ExitItem { } @Override - public boolean isCompileTime() { + public boolean isCompileTime(Set dependencies) { return true; } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/model/SetVariableActionItem.java b/trunk/src/com/jpexs/decompiler/flash/action/model/SetVariableActionItem.java index 22f203214..42edf1212 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/model/SetVariableActionItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/model/SetVariableActionItem.java @@ -29,6 +29,7 @@ import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.SourceGenerator; import com.jpexs.decompiler.graph.model.LocalData; import java.util.List; +import java.util.Set; public class SetVariableActionItem extends ActionItem implements SetTypeActionItem { @@ -96,8 +97,12 @@ public class SetVariableActionItem extends ActionItem implements SetTypeActionIt } @Override - public boolean isCompileTime() { - return value.isCompileTime(); + public boolean isCompileTime(Set dependencies) { + if (dependencies.contains(value)) { + return false; + } + dependencies.add(value); + return value.isCompileTime(dependencies); } @Override diff --git a/trunk/src/com/jpexs/decompiler/flash/action/model/StoreRegisterActionItem.java b/trunk/src/com/jpexs/decompiler/flash/action/model/StoreRegisterActionItem.java index d62550457..f1bcf5388 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/model/StoreRegisterActionItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/model/StoreRegisterActionItem.java @@ -26,6 +26,7 @@ import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.SourceGenerator; import com.jpexs.decompiler.graph.model.LocalData; import java.util.List; +import java.util.Set; public class StoreRegisterActionItem extends ActionItem implements SetTypeActionItem { @@ -104,8 +105,12 @@ public class StoreRegisterActionItem extends ActionItem implements SetTypeAction } @Override - public boolean isCompileTime() { - return value.isCompileTime(); + public boolean isCompileTime(Set dependencies) { + if (dependencies.contains(value)) { + return false; + } + dependencies.add(value); + return value.isCompileTime(dependencies); } @Override diff --git a/trunk/src/com/jpexs/decompiler/flash/action/model/StringLengthActionItem.java b/trunk/src/com/jpexs/decompiler/flash/action/model/StringLengthActionItem.java index f08a6b0c9..6a7c283ba 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/model/StringLengthActionItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/model/StringLengthActionItem.java @@ -23,6 +23,7 @@ import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.SourceGenerator; import com.jpexs.decompiler.graph.model.LocalData; import java.util.List; +import java.util.Set; public class StringLengthActionItem extends ActionItem { @@ -40,7 +41,7 @@ public class StringLengthActionItem extends ActionItem { } @Override - public boolean isCompileTime() { + public boolean isCompileTime(Set dependencies) { return false; } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/model/TypeOfActionItem.java b/trunk/src/com/jpexs/decompiler/flash/action/model/TypeOfActionItem.java index e6ba6bf57..51a8bd768 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/model/TypeOfActionItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/model/TypeOfActionItem.java @@ -26,6 +26,7 @@ import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.SourceGenerator; import com.jpexs.decompiler.graph.model.LocalData; import java.util.List; +import java.util.Set; public class TypeOfActionItem extends ActionItem { @@ -71,8 +72,12 @@ public class TypeOfActionItem extends ActionItem { } @Override - public boolean isCompileTime() { - return value.isCompileTime(); + public boolean isCompileTime(Set dependencies) { + if (dependencies.contains(value)) { + return false; + } + dependencies.add(value); + return value.isCompileTime(dependencies); } @Override diff --git a/trunk/src/com/jpexs/decompiler/flash/action/model/operations/InActionItem.java b/trunk/src/com/jpexs/decompiler/flash/action/model/operations/InActionItem.java index eeffd8bd9..f523c60f9 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/model/operations/InActionItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/model/operations/InActionItem.java @@ -18,7 +18,9 @@ package com.jpexs.decompiler.flash.action.model.operations; import com.jpexs.decompiler.flash.action.model.ActionItem; import com.jpexs.decompiler.graph.GraphSourceItem; +import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.model.BinaryOpItem; +import java.util.Set; public class InActionItem extends BinaryOpItem { @@ -27,7 +29,7 @@ public class InActionItem extends BinaryOpItem { } @Override - public boolean isCompileTime() { + public boolean isCompileTime(Set dependencies) { return false; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/model/operations/InstanceOfActionItem.java b/trunk/src/com/jpexs/decompiler/flash/action/model/operations/InstanceOfActionItem.java index 8653ebaa7..d978865bb 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/model/operations/InstanceOfActionItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/model/operations/InstanceOfActionItem.java @@ -22,6 +22,7 @@ import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.SourceGenerator; import com.jpexs.decompiler.graph.model.BinaryOpItem; import java.util.List; +import java.util.Set; public class InstanceOfActionItem extends BinaryOpItem { @@ -30,7 +31,7 @@ public class InstanceOfActionItem extends BinaryOpItem { } @Override - public boolean isCompileTime() { + public boolean isCompileTime(Set dependencies) { return false; } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/model/operations/StringAddActionItem.java b/trunk/src/com/jpexs/decompiler/flash/action/model/operations/StringAddActionItem.java index 15579b5be..f8c080b0e 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/model/operations/StringAddActionItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/model/operations/StringAddActionItem.java @@ -22,6 +22,7 @@ import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.SourceGenerator; import com.jpexs.decompiler.graph.model.BinaryOpItem; import java.util.List; +import java.util.Set; public class StringAddActionItem extends BinaryOpItem { @@ -30,7 +31,7 @@ public class StringAddActionItem extends BinaryOpItem { } @Override - public boolean isCompileTime() { + public boolean isCompileTime(Set dependencies) { return false; } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/model/operations/StringEqActionItem.java b/trunk/src/com/jpexs/decompiler/flash/action/model/operations/StringEqActionItem.java index e54d15cf3..c13976ce7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/model/operations/StringEqActionItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/model/operations/StringEqActionItem.java @@ -22,6 +22,7 @@ import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.SourceGenerator; import com.jpexs.decompiler.graph.model.BinaryOpItem; import java.util.List; +import java.util.Set; public class StringEqActionItem extends BinaryOpItem { @@ -30,7 +31,7 @@ public class StringEqActionItem extends BinaryOpItem { } @Override - public boolean isCompileTime() { + public boolean isCompileTime(Set dependencies) { return false; } diff --git a/trunk/src/com/jpexs/decompiler/flash/action/model/operations/StringLtActionItem.java b/trunk/src/com/jpexs/decompiler/flash/action/model/operations/StringLtActionItem.java index 256536372..b2f721cb8 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/model/operations/StringLtActionItem.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/model/operations/StringLtActionItem.java @@ -22,6 +22,7 @@ import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.SourceGenerator; import com.jpexs.decompiler.graph.model.BinaryOpItem; import java.util.List; +import java.util.Set; public class StringLtActionItem extends BinaryOpItem { @@ -30,7 +31,7 @@ public class StringLtActionItem extends BinaryOpItem { } @Override - public boolean isCompileTime() { + public boolean isCompileTime(Set dependencies) { return false; } diff --git a/trunk/src/com/jpexs/decompiler/graph/Graph.java b/trunk/src/com/jpexs/decompiler/graph/Graph.java index 7b3862289..d938af670 100644 --- a/trunk/src/com/jpexs/decompiler/graph/Graph.java +++ b/trunk/src/com/jpexs/decompiler/graph/Graph.java @@ -598,14 +598,14 @@ public class Graph { System.out.println(el); } System.out.println("");*/ - getPrecontinues(localData, null, heads.get(0), loops, null); + getPrecontinues(localData, null, heads.get(0), allParts, loops, null); /*System.err.println(""); for (Loop el : loops) { System.err.println(el); } System.err.println("");//*/ - List ret = printGraph(new ArrayList(), localData, stack, allParts, null, heads.get(0), null, loops, staticOperation, path); + List ret = printGraph(localData, stack, allParts, null, heads.get(0), null, loops, staticOperation, path); processIfs(ret); finalProcessStack(stack, ret); finalProcessAll(ret, 0, new ArrayList<>()); @@ -857,16 +857,17 @@ public class Graph { list.remove(list.size() - 1); } - protected List printGraph(List visited, List localData, Stack stack, List allParts, GraphPart parent, GraphPart part, List stopPart, List loops, int staticOperation, String path) throws InterruptedException { - return printGraph(visited, localData, stack, allParts, parent, part, stopPart, loops, null, staticOperation, path); + protected List printGraph(List localData, Stack stack, List allParts, GraphPart parent, GraphPart part, List stopPart, List loops, int staticOperation, String path) throws InterruptedException { + List visited = new ArrayList<>(); + return printGraph(visited, localData, stack, allParts, parent, part, stopPart, loops, null, staticOperation, path, 0); } protected GraphTargetItem checkLoop(LoopItem loopItem, List localData, List loops) { return loopItem; } - private void getPrecontinues(List localData, GraphPart parent, GraphPart part, List loops, List stopPart) throws InterruptedException { - markLevels(localData, part, loops); + private void getPrecontinues(List localData, GraphPart parent, GraphPart part, List allParts, List loops, List stopPart) throws InterruptedException { + markLevels(localData, part, allParts, loops); //Note: this also marks part as precontinue when there is if /* while(k<10){ @@ -917,17 +918,21 @@ public class Graph { clearLoops(loops);*/ } - private void markLevels(List localData, GraphPart part, List loops) throws InterruptedException { + private void markLevels(List localData, GraphPart part, List allParts, List loops) throws InterruptedException { clearLoops(loops); - markLevels(localData, part, loops, new ArrayList(), 1, new ArrayList()); + markLevels(localData, part, allParts, loops, new ArrayList(), 1, new ArrayList(), 0); clearLoops(loops); } - private void markLevels(List localData, GraphPart part, List loops, List stopPart, int level, List visited) throws InterruptedException { + private void markLevels(List localData, GraphPart part, List allParts, List loops, List stopPart, int level, List visited, int recursionLevel) throws InterruptedException { boolean debugMode = false; if (stopPart == null) { stopPart = new ArrayList<>(); } + if (recursionLevel > allParts.size() + 1) { + throw new TranslateException("markLevels max recursion level reached."); + } + if (debugMode) { System.err.println("markLevels " + part); } @@ -989,13 +994,13 @@ public class Graph { stopParts2.add(stopPart.get(stopPart.size() - 1)); } if (next != nextParts.get(0)) { - markLevels(localData, nextParts.get(0), loops, next == null ? stopPart : stopParts2, level + 1, visited); + markLevels(localData, nextParts.get(0), allParts, loops, next == null ? stopPart : stopParts2, level + 1, visited, recursionLevel + 1); } if (next != nextParts.get(1)) { - markLevels(localData, nextParts.get(1), loops, next == null ? stopPart : stopParts2, level + 1, visited); + markLevels(localData, nextParts.get(1), allParts, loops, next == null ? stopPart : stopParts2, level + 1, visited, recursionLevel + 1); } if (next != null) { - markLevels(localData, next, loops, stopPart, level, visited); + markLevels(localData, next, allParts, loops, stopPart, level, visited, recursionLevel + 1); } } @@ -1021,17 +1026,17 @@ public class Graph { } } if (next != p) { - markLevels(localData, p, loops, stopPart2, level + 1, visited); + markLevels(localData, p, allParts, loops, stopPart2, level + 1, visited, recursionLevel + 1); vis.add(p); } } if (next != null) { - markLevels(localData, next, loops, stopPart, level, visited); + markLevels(localData, next, allParts, loops, stopPart, level, visited, recursionLevel + 1); } } if (nextParts.size() == 1) { - markLevels(localData, nextParts.get(0), loops, stopPart, level, visited); + markLevels(localData, nextParts.get(0), allParts, loops, stopPart, level, visited, recursionLevel + 1); } for (GraphPart t : part.throwParts) { @@ -1047,14 +1052,14 @@ public class Graph { stopPart2 = stopPart; } - markLevels(localData, t, loops, stopPart2, level, visited); + markLevels(localData, t, allParts, loops, stopPart2, level, visited, recursionLevel + 1); } } if (isLoop) { if (currentLoop.loopBreak != null) { currentLoop.phase = 2; - markLevels(localData, currentLoop.loopBreak, loops, stopPart, level, visited); + markLevels(localData, currentLoop.loopBreak, allParts, loops, stopPart, level, visited, recursionLevel + 1); } } } @@ -1352,13 +1357,16 @@ public class Graph { } } - protected List printGraph(List visited, List localData, Stack stack, List allParts, GraphPart parent, GraphPart part, List stopPart, List loops, List ret, int staticOperation, String path) throws InterruptedException { + protected List printGraph(List visited, List localData, Stack stack, List allParts, GraphPart parent, GraphPart part, List stopPart, List loops, List ret, int staticOperation, String path, int recursionLevel) throws InterruptedException { if (Thread.interrupted()) { throw new InterruptedException(); } if (stopPart == null) { stopPart = new ArrayList<>(); } + if (recursionLevel > allParts.size() + 1) { + throw new TranslateException("printGraph max recursion level reached."); + } if (visited.contains(part)) { //return new ArrayList(); } else { @@ -1562,7 +1570,7 @@ public class Graph { } else { List stopPart2 = new ArrayList<>(stopPart); stopPart2.add(reversed ? sp1 : sp0); - printGraph(visited, localData, stack, allParts, parent, next, stopPart2, loops, staticOperation, path); + printGraph(visited, localData, stack, allParts, parent, next, stopPart2, loops, null, staticOperation, path, recursionLevel + 1); GraphTargetItem second = stack.pop(); GraphTargetItem first = stack.pop(); @@ -1591,7 +1599,7 @@ public class Graph { if ((ti = checkLoop(next, stopPart, loops)) != null) { currentRet.add(ti); } else { - currentRet.addAll(printGraph(visited, localData, stack, allParts, parent, next, stopPart, loops, staticOperation, path)); + currentRet.addAll(printGraph(visited, localData, stack, allParts, parent, next, stopPart, loops, null, staticOperation, path, recursionLevel + 1)); } } parseNext = false; @@ -1613,7 +1621,7 @@ public class Graph { } else { List stopPart2 = new ArrayList<>(stopPart); stopPart2.add(reversed ? sp1 : sp0); - printGraph(visited, localData, stack, allParts, parent, next, stopPart2, loops, staticOperation, path); + printGraph(visited, localData, stack, allParts, parent, next, stopPart2, loops, null, staticOperation, path, recursionLevel + 1); GraphTargetItem second = stack.pop(); GraphTargetItem first = stack.pop(); @@ -1643,7 +1651,7 @@ public class Graph { if ((ti = checkLoop(next, stopPart, loops)) != null) { currentRet.add(ti); } else { - currentRet.addAll(printGraph(visited, localData, stack, allParts, parent, next, stopPart, loops, staticOperation, path)); + currentRet.addAll(printGraph(visited, localData, stack, allParts, parent, next, stopPart, loops, null, staticOperation, path, recursionLevel + 1)); } } parseNext = false; @@ -1696,9 +1704,9 @@ public class Graph { } if (next != p) { if (first) { - defaultCommands = printGraph(visited, prepareBranchLocalData(localData), stack, allParts, part, p, stopPart2, loops, staticOperation, path); + defaultCommands = printGraph(visited, prepareBranchLocalData(localData), stack, allParts, part, p, stopPart2, loops, null, staticOperation, path, recursionLevel + 1); } else { - caseCommands.add(printGraph(visited, prepareBranchLocalData(localData), stack, allParts, part, p, stopPart2, loops, staticOperation, path)); + caseCommands.add(printGraph(visited, prepareBranchLocalData(localData), stack, allParts, part, p, stopPart2, loops, null, staticOperation, path, recursionLevel + 1)); } vis.add(p); } @@ -1708,7 +1716,7 @@ public class Graph { currentRet.add(sw); swLoop.phase = 2; if (next != null) { - currentRet.addAll(printGraph(visited, localData, stack, allParts, part, next, stopPart, loops, staticOperation, path)); + currentRet.addAll(printGraph(visited, localData, stack, allParts, part, next, stopPart, loops, null, staticOperation, path, recursionLevel + 1)); } } //else GraphPart nextOnePart = null; @@ -1762,12 +1770,12 @@ public class Graph { stopPart2.add(next); } if (!isEmpty) { - onTrue = printGraph(visited, prepareBranchLocalData(localData), trueStack, allParts, part, nps.get(1), stopPart2, loops, staticOperation, path); + onTrue = printGraph(visited, prepareBranchLocalData(localData), trueStack, allParts, part, nps.get(1), stopPart2, loops, null, staticOperation, path, recursionLevel + 1); } List onFalse = new ArrayList<>(); if (!isEmpty) { - onFalse = printGraph(visited, prepareBranchLocalData(localData), falseStack, allParts, part, nps.get(0), stopPart2, loops, staticOperation, path); + onFalse = printGraph(visited, prepareBranchLocalData(localData), falseStack, allParts, part, nps.get(0), stopPart2, loops, null, staticOperation, path, recursionLevel + 1); } if (isEmpty(onTrue) && isEmpty(onFalse) && (trueStack.size() == trueStackSizeBefore + 1) && (falseStack.size() == falseStackSizeBefore + 1)) { stack.push(new TernarOpItem(null, expr, trueStack.pop(), falseStack.pop())); @@ -1777,15 +1785,15 @@ public class Graph { if (next != null) { if (trueStack.size() != trueStackSizeBefore || falseStack.size() != falseStackSizeBefore) { // it's a hack, because duplicates all instructions in the next part, but better than EmptyStackException - onTrue = printGraph(visited, localData, trueStack, allParts, part, next, stopPart, loops, null, staticOperation, path); - onFalse = printGraph(visited, localData, falseStack, allParts, part, next, stopPart, loops, null, staticOperation, path); + onTrue = printGraph(visited, localData, trueStack, allParts, part, next, stopPart, loops, null, staticOperation, path, recursionLevel + 1); + onFalse = printGraph(visited, localData, falseStack, allParts, part, next, stopPart, loops, null, staticOperation, path, recursionLevel + 1); if (isEmpty(onTrue) && isEmpty(onFalse) && (trueStack.size() == trueStackSizeBefore + 1) && (falseStack.size() == falseStackSizeBefore + 1)) { stack.push(new TernarOpItem(null, expr, trueStack.pop(), falseStack.pop())); } else { currentRet.add(new IfItem(null, expr, onTrue, onFalse)); } } else { - printGraph(visited, localData, stack, allParts, part, next, stopPart, loops, currentRet, staticOperation, path); + printGraph(visited, localData, stack, allParts, part, next, stopPart, loops, currentRet, staticOperation, path, recursionLevel + 1); } //currentRet.addAll(); } @@ -1795,7 +1803,7 @@ public class Graph { nextOnePart = part.nextParts.get(0); } if (nextOnePart != null) { - printGraph(visited, localData, stack, allParts, part, part.nextParts.get(0), stopPart, loops, currentRet, staticOperation, path); + printGraph(visited, localData, stack, allParts, part, part.nextParts.get(0), stopPart, loops, currentRet, staticOperation, path, recursionLevel + 1); } } @@ -1820,7 +1828,7 @@ public class Graph { stopContPart.add(currentLoop.loopContinue); GraphPart precoBackup = currentLoop.loopPreContinue; currentLoop.loopPreContinue = null; - loopItem.commands.addAll(printGraph(visited, localData, new Stack(), allParts, null, precoBackup, stopContPart, loops, staticOperation, path)); + loopItem.commands.addAll(printGraph(visited, localData, new Stack(), allParts, null, precoBackup, stopContPart, loops, null, staticOperation, path, recursionLevel + 1)); } } @@ -1878,7 +1886,7 @@ public class Graph { currentLoop.loopPreContinue = null; List stopPart2 = new ArrayList<>(stopPart); stopPart2.add(currentLoop.loopContinue); - finalComm = printGraph(visited, localData, new Stack(), allParts, null, backup, stopPart2, loops, staticOperation, path); + finalComm = printGraph(visited, localData, new Stack(), allParts, null, backup, stopPart2, loops, null, staticOperation, path, recursionLevel + 1); currentLoop.loopPreContinue = backup; checkContinueAtTheEnd(finalComm, currentLoop); } @@ -1961,7 +1969,7 @@ public class Graph { currentLoop.loopPreContinue = null; List stopPart2 = new ArrayList<>(stopPart); stopPart2.add(currentLoop.loopContinue); - List finalComm = printGraph(visited, localData, new Stack(), allParts, null, backup, stopPart2, loops, staticOperation, path); + List finalComm = printGraph(visited, localData, new Stack(), allParts, null, backup, stopPart2, loops, null, staticOperation, path, recursionLevel + 1); currentLoop.loopPreContinue = backup; checkContinueAtTheEnd(finalComm, currentLoop); @@ -2015,7 +2023,7 @@ public class Graph { } if (currentLoop.loopBreak != null) { - ret.addAll(printGraph(visited, localData, stack, allParts, part, currentLoop.loopBreak, stopPart, loops, staticOperation, path)); + ret.addAll(printGraph(visited, localData, stack, allParts, part, currentLoop.loopBreak, stopPart, loops, null, staticOperation, path, recursionLevel + 1)); } } diff --git a/trunk/src/com/jpexs/decompiler/graph/GraphTargetItem.java b/trunk/src/com/jpexs/decompiler/graph/GraphTargetItem.java index 410c1736b..21c99d348 100644 --- a/trunk/src/com/jpexs/decompiler/graph/GraphTargetItem.java +++ b/trunk/src/com/jpexs/decompiler/graph/GraphTargetItem.java @@ -22,7 +22,9 @@ import com.jpexs.decompiler.graph.model.BinaryOp; import com.jpexs.decompiler.graph.model.LocalData; import java.io.Serializable; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; /** * @@ -123,6 +125,12 @@ public abstract class GraphTargetItem implements Serializable { } public boolean isCompileTime() { + Set dependencies = new HashSet<>(); + dependencies.add(this); + return isCompileTime(dependencies); + } + + public boolean isCompileTime(Set dependencies) { return false; } diff --git a/trunk/src/com/jpexs/decompiler/graph/NotCompileTimeItem.java b/trunk/src/com/jpexs/decompiler/graph/NotCompileTimeItem.java index 08cb226c6..63ae8b578 100644 --- a/trunk/src/com/jpexs/decompiler/graph/NotCompileTimeItem.java +++ b/trunk/src/com/jpexs/decompiler/graph/NotCompileTimeItem.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.graph; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.model.LocalData; +import java.util.Set; /** * @@ -33,7 +34,7 @@ public class NotCompileTimeItem extends GraphTargetItem { } @Override - public boolean isCompileTime() { + public boolean isCompileTime(Set dependencies) { return false; } diff --git a/trunk/src/com/jpexs/decompiler/graph/TranslateException.java b/trunk/src/com/jpexs/decompiler/graph/TranslateException.java new file mode 100644 index 000000000..a4da7dc4e --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/graph/TranslateException.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2010-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.graph; + +/** + * + * @author JPEXS + */ +public class TranslateException extends RuntimeException { + + public TranslateException(String s) { + super(s); + } +} diff --git a/trunk/src/com/jpexs/decompiler/graph/model/BinaryOpItem.java b/trunk/src/com/jpexs/decompiler/graph/model/BinaryOpItem.java index 61ace8ac9..3a8aa0f1b 100644 --- a/trunk/src/com/jpexs/decompiler/graph/model/BinaryOpItem.java +++ b/trunk/src/com/jpexs/decompiler/graph/model/BinaryOpItem.java @@ -23,6 +23,7 @@ import com.jpexs.decompiler.graph.GraphSourceItemPos; import com.jpexs.decompiler.graph.GraphTargetItem; import java.util.ArrayList; import java.util.List; +import java.util.Set; public abstract class BinaryOpItem extends GraphTargetItem implements BinaryOp { @@ -79,8 +80,16 @@ public abstract class BinaryOpItem extends GraphTargetItem implements BinaryOp { } @Override - public boolean isCompileTime() { - return leftSide.isCompileTime() && rightSide.isCompileTime(); + public boolean isCompileTime(Set dependencies) { + if (dependencies.contains(leftSide)) { + return false; + } + dependencies.add(leftSide); + if (dependencies.contains(rightSide)) { + return false; + } + dependencies.add(rightSide); + return leftSide.isCompileTime(dependencies) && rightSide.isCompileTime(dependencies); } @Override diff --git a/trunk/src/com/jpexs/decompiler/graph/model/CommentItem.java b/trunk/src/com/jpexs/decompiler/graph/model/CommentItem.java index 1639507c8..72bd6c021 100644 --- a/trunk/src/com/jpexs/decompiler/graph/model/CommentItem.java +++ b/trunk/src/com/jpexs/decompiler/graph/model/CommentItem.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.graph.model; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.GraphTargetItem; +import static com.jpexs.decompiler.graph.GraphTargetItem.NOPRECEDENCE; /** * @@ -25,20 +26,32 @@ import com.jpexs.decompiler.graph.GraphTargetItem; */ public class CommentItem extends GraphTargetItem { - private String comment; + private String[] commentLines; public CommentItem(String comment) { super(null, NOPRECEDENCE); - this.comment = comment; + this.commentLines = new String[] { comment }; + } + + public CommentItem(String[] commentLines) { + super(null, NOPRECEDENCE); + this.commentLines = commentLines; } @Override protected GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) { - return writer.append("/* " + comment + " */"); + writer.append("/* "); + for (int i = 0; i < commentLines.length; i++) { + writer.append(commentLines[i]); + if (i != commentLines.length - 1) { + writer.newLine(); + } + } + return writer.append(" */"); } - public String getComment() { - return comment; + public String[] getCommentLines() { + return commentLines; } @Override diff --git a/trunk/src/com/jpexs/decompiler/graph/model/DuplicateItem.java b/trunk/src/com/jpexs/decompiler/graph/model/DuplicateItem.java index a4f40c514..d8b6af98f 100644 --- a/trunk/src/com/jpexs/decompiler/graph/model/DuplicateItem.java +++ b/trunk/src/com/jpexs/decompiler/graph/model/DuplicateItem.java @@ -21,6 +21,7 @@ import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.SourceGenerator; import java.util.List; +import java.util.Set; /** * @@ -59,8 +60,12 @@ public class DuplicateItem extends GraphTargetItem { } @Override - public boolean isCompileTime() { - return value.isCompileTime(); + public boolean isCompileTime(Set dependencies) { + if (dependencies.contains(value)) { + return false; + } + dependencies.add(value); + return value.isCompileTime(dependencies); } @Override diff --git a/trunk/src/com/jpexs/decompiler/graph/model/IfItem.java b/trunk/src/com/jpexs/decompiler/graph/model/IfItem.java index bb1e6ebbe..f73df67b7 100644 --- a/trunk/src/com/jpexs/decompiler/graph/model/IfItem.java +++ b/trunk/src/com/jpexs/decompiler/graph/model/IfItem.java @@ -23,6 +23,7 @@ import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.SourceGenerator; import java.util.ArrayList; import java.util.List; +import java.util.Set; public class IfItem extends GraphTargetItem implements Block { @@ -31,8 +32,12 @@ public class IfItem extends GraphTargetItem implements Block { public List onFalse; @Override - public boolean isCompileTime() { - return expression.isCompileTime(); + public boolean isCompileTime(Set dependencies) { + if (dependencies.contains(expression)) { + return false; + } + dependencies.add(expression); + return expression.isCompileTime(dependencies); } @Override diff --git a/trunk/src/com/jpexs/decompiler/graph/model/IntegerValueItem.java b/trunk/src/com/jpexs/decompiler/graph/model/IntegerValueItem.java index ce803c004..99e40e1c1 100644 --- a/trunk/src/com/jpexs/decompiler/graph/model/IntegerValueItem.java +++ b/trunk/src/com/jpexs/decompiler/graph/model/IntegerValueItem.java @@ -19,6 +19,7 @@ package com.jpexs.decompiler.graph.model; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; +import java.util.Set; /** * @@ -39,7 +40,7 @@ public class IntegerValueItem extends GraphTargetItem { } @Override - public boolean isCompileTime() { + public boolean isCompileTime(Set dependencies) { return true; } diff --git a/trunk/src/com/jpexs/decompiler/graph/model/NotItem.java b/trunk/src/com/jpexs/decompiler/graph/model/NotItem.java index 021d5d8d8..7e9853f83 100644 --- a/trunk/src/com/jpexs/decompiler/graph/model/NotItem.java +++ b/trunk/src/com/jpexs/decompiler/graph/model/NotItem.java @@ -6,6 +6,7 @@ import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.SourceGenerator; import java.util.List; +import java.util.Set; /** * @@ -30,8 +31,12 @@ public class NotItem extends UnaryOpItem implements LogicalOpItem, Inverted { } @Override - public boolean isCompileTime() { - return value.isCompileTime(); + public boolean isCompileTime(Set dependencies) { + if (dependencies.contains(value)) { + return false; + } + dependencies.add(value); + return value.isCompileTime(dependencies); } @Override diff --git a/trunk/src/com/jpexs/decompiler/graph/model/UnaryOpItem.java b/trunk/src/com/jpexs/decompiler/graph/model/UnaryOpItem.java index 9b2651739..d6b0aefb5 100644 --- a/trunk/src/com/jpexs/decompiler/graph/model/UnaryOpItem.java +++ b/trunk/src/com/jpexs/decompiler/graph/model/UnaryOpItem.java @@ -21,6 +21,7 @@ import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphSourceItemPos; import com.jpexs.decompiler.graph.GraphTargetItem; import java.util.List; +import java.util.Set; public abstract class UnaryOpItem extends GraphTargetItem implements UnaryOp { @@ -51,8 +52,12 @@ public abstract class UnaryOpItem extends GraphTargetItem implements UnaryOp { } @Override - public boolean isCompileTime() { - return value.isCompileTime(); + public boolean isCompileTime(Set dependencies) { + if (dependencies.contains(value)) { + return false; + } + dependencies.add(value); + return value.isCompileTime(dependencies); } @Override