Workarounds for StackOverflowExceptions

This commit is contained in:
Honfika
2013-12-01 08:53:04 +01:00
parent ab569f1dd2
commit ac96c7dbb5
47 changed files with 330 additions and 124 deletions

View File

@@ -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) {

View File

@@ -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<Integer, List<Integer>> refs, boolean secondPass, boolean indeterminate, List<Object> localData, Stack<GraphTargetItem> stack, List<GraphTargetItem> output, AVM2GraphSource code, int ip, HashMap<Integer, Integer> visited, HashMap<Integer, HashMap<Integer, GraphTargetItem>> visitedStates, HashMap<GraphSourceItem, Decision> decisions, String path) throws InterruptedException {
private static int removeTraps(HashMap<Integer, List<Integer>> refs, boolean secondPass, boolean indeterminate, List<Object> localData, Stack<GraphTargetItem> stack, List<GraphTargetItem> output, AVM2GraphSource code, int ip, HashMap<Integer, Integer> visited, HashMap<Integer, HashMap<Integer, GraphTargetItem>> visitedStates, HashMap<GraphSourceItem, Decision> 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<GraphTargetItem> brStack = (Stack<GraphTargetItem>) 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<Object> localData, AVM2GraphSource code, int addr, String path, HashMap<Integer, List<Integer>> refs) throws InterruptedException {
HashMap<GraphSourceItem, AVM2Code.Decision> decisions = new HashMap<>();
removeTraps(refs, false, false, localData, new Stack<GraphTargetItem>(), new ArrayList<GraphTargetItem>(), code, code.adr2pos(addr), new HashMap<Integer, Integer>(), new HashMap<Integer, HashMap<Integer, GraphTargetItem>>(), decisions, path);
removeTraps(refs, false, false, localData, new Stack<GraphTargetItem>(), new ArrayList<GraphTargetItem>(), code, code.adr2pos(addr), new HashMap<Integer, Integer>(), new HashMap<Integer, HashMap<Integer, GraphTargetItem>>(), decisions, path, 0);
int cnt = 0;
for (GraphSourceItem src : decisions.keySet()) {
Decision dec = decisions.get(src);

View File

@@ -286,7 +286,7 @@ public class AVM2Graph extends Graph {
List<Integer> oldFinallyJumps = new ArrayList<>(finallyJumps);
finallyJumps.clear();
ignoredSwitches.add(swPos);
finallyCommands = printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, parent, fpart, null, loops, staticOperation, path);
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<GraphPart>(), 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<GraphTargetItem> tryCommands = printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, parent, part, stopPart2, loops, staticOperation, path);
List<GraphTargetItem> 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<GraphPart>(), 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<GraphPart> stopPart2 = new ArrayList<>(stopPart);
stopPart2.add(next);
defaultCommands = printGraph(new ArrayList<GraphPart>(), 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<GraphPart>(), 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<GraphPart>(), localData, stack, allParts, null, next, stopPart, loops, staticOperation, path));
ret.addAll(printGraph(localData, stack, allParts, null, next, stopPart, loops, staticOperation, path));
//}
}
}

View File

@@ -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<GraphTargetItem> dependencies) {
return true;
}
}

View File

@@ -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<GraphTargetItem> dependencies) {
if (dependencies.contains(value)) {
return false;
}
dependencies.add(value);
return value.isCompileTime(dependencies);
}
@Override

View File

@@ -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<GraphTargetItem> dependencies) {
if (dependencies.contains(value)) {
return false;
}
dependencies.add(value);
return value.isCompileTime(dependencies);
}
}

View File

@@ -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<GraphTargetItem> dependencies) {
if (dependencies.contains(value)) {
return false;
}
dependencies.add(value);
return value.isCompileTime(dependencies);
}
@Override

View File

@@ -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<GraphTargetItem> dependencies) {
return true;
}
}

View File

@@ -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<GraphTargetItem> dependencies) {
if (dependencies.contains(value)) {
return false;
}
dependencies.add(value);
return value.isCompileTime(dependencies);
}
@Override

View File

@@ -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<GraphTargetItem> dependencies) {
return true;
}
}

View File

@@ -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<GraphTargetItem> dependencies) {
return isCT;
}
}

View File

@@ -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<GraphTargetItem> dependencies) {
return true;
}

View File

@@ -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<GraphTargetItem> dependencies) {
return true;
}

View File

@@ -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<GraphTargetItem> dependencies) {
return true;
}

View File

@@ -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<GraphTargetItem> dependencies) {
if (dependencies.contains(value)) {
return false;
}
dependencies.add(value);
return value.isCompileTime(dependencies);
}
@Override

View File

@@ -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<GraphTargetItem> 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"));
}

View File

@@ -318,7 +318,7 @@ public class ActionGraph extends Graph {
List<GraphTargetItem> defaultCommands = new ArrayList<>();
List<GraphPart> stopPart2 = new ArrayList<>(stopPart);
stopPart2.add(defaultPart2);
defaultCommands = printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, null, defaultPart, stopPart2, loops, staticOperation, path);
defaultCommands = printGraph(localData, stack, allParts, null, defaultPart, stopPart2, loops, staticOperation, path);
List<GraphPart> loopContinues = new ArrayList<>();
@@ -399,7 +399,7 @@ public class ActionGraph extends Graph {
if ((defaultPart != null) && (defaultCommands.isEmpty())) {
List<GraphPart> stopPart2x = new ArrayList<>(stopPart);
stopPart2x.add(next);
defaultCommands = printGraph(new ArrayList<GraphPart>(), 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<GraphPart>(), 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<GraphPart>(), localData, stack, allParts, null, next, stopPart, loops, staticOperation, path));
ret.addAll(printGraph(localData, stack, allParts, null, next, stopPart, loops, staticOperation, path));
}
}
}

View File

@@ -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<Object> localData = Helper.toList(new HashMap<Integer, String>(), new HashMap<String, GraphTargetItem>(), new HashMap<String, GraphTargetItem>());
deobfustaceActionListAtPosRecursive(listeners, new ArrayList<GraphTargetItem>(), new HashMap<Long, List<GraphSourceItemContainer>>(), containerSWFOffset, localData, stack, cpool, actionMap, ip, ip, retdups, ip, endIp, path, new HashMap<Integer, Integer>(), false, new HashMap<Integer, HashMap<String, GraphTargetItem>>(), 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<GraphTargetItem>(), new HashMap<Long, List<GraphSourceItemContainer>>(), containerSWFOffset, localData, stack, cpool, actionMap, ip, ip, retdups, ip, endIp, path, new HashMap<Integer, Integer>(), false, new HashMap<Integer, HashMap<String, GraphTargetItem>>(), 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<DisassemblyListener> listeners, List<GraphTargetItem> output, HashMap<Long, List<GraphSourceItemContainer>> containers, long containerSWFOffset, List<Object> localData, Stack<GraphTargetItem> stack, ConstantPool cpool, List<Action> actions, int pos, int ip, List<Action> ret, int startIp, int endip, String path, Map<Integer, Integer> visited, boolean indeterminate, Map<Integer, HashMap<String, GraphTargetItem>> decisionStates, int version) throws IOException, InterruptedException {
private static void deobfustaceActionListAtPosRecursive(List<DisassemblyListener> listeners, List<GraphTargetItem> output, HashMap<Long, List<GraphSourceItemContainer>> containers, long containerSWFOffset, List<Object> localData, Stack<GraphTargetItem> stack, ConstantPool cpool, List<Action> actions, int pos, int ip, List<Action> ret, int startIp, int endip, String path, Map<Integer, Integer> visited, boolean indeterminate, Map<Integer, HashMap<String, GraphTargetItem>> 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<GraphTargetItem>(), 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<GraphTargetItem>(), 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<GraphTargetItem> substack = (Stack<GraphTargetItem>) 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;

View File

@@ -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<GraphTargetItem> dependencies) {
if (calculatedFunction == null) {
return false;
}
return calculatedFunction.isCompileTime();
if (dependencies.contains(calculatedFunction)) {
return false;
}
dependencies.add(calculatedFunction);
return calculatedFunction.isCompileTime(dependencies);
}
@Override

View File

@@ -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<GraphTargetItem> dependencies) {
if (value instanceof DirectValueActionItem) {
DirectValueActionItem dv = (DirectValueActionItem) value;
if (dv.value instanceof String) {

View File

@@ -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<GraphTargetItem> dependencies) {
if (dependencies.contains(object)) {
return false;
}
dependencies.add(object);
return object.isCompileTime(dependencies);
}
@Override

View File

@@ -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<GraphTargetItem> 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

View File

@@ -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<GraphTargetItem> dependencies) {
for (GraphTargetItem a : actions) {
if (!a.isCompileTime()) {
if (dependencies.contains(a)) {
return false;
}
dependencies.add(a);
if (!a.isCompileTime(dependencies)) {
return false;
}
}

View File

@@ -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<GraphTargetItem> dependencies) {
return true;
}

View File

@@ -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<GraphTargetItem> dependencies) {
if (computedValue == null) {
return false;
}

View File

@@ -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<GraphTargetItem> dependencies) {
if (dependencies.contains(object)) {
return false;
}
dependencies.add(object);
return object.isCompileTime(dependencies);
}
@Override

View File

@@ -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<GraphTargetItem> dependencies) {
return true;
}

View File

@@ -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<GraphTargetItem> dependencies) {
if (dependencies.contains(value)) {
return false;
}
dependencies.add(value);
return value.isCompileTime(dependencies);
}
@Override

View File

@@ -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<GraphTargetItem> dependencies) {
if (dependencies.contains(value)) {
return false;
}
dependencies.add(value);
return value.isCompileTime(dependencies);
}
@Override

View File

@@ -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<GraphTargetItem> dependencies) {
return false;
}

View File

@@ -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<GraphTargetItem> dependencies) {
if (dependencies.contains(value)) {
return false;
}
dependencies.add(value);
return value.isCompileTime(dependencies);
}
@Override

View File

@@ -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<GraphTargetItem> dependencies) {
return false;
}
}

View File

@@ -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<GraphTargetItem> dependencies) {
return false;
}

View File

@@ -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<GraphTargetItem> dependencies) {
return false;
}

View File

@@ -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<GraphTargetItem> dependencies) {
return false;
}

View File

@@ -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<GraphTargetItem> dependencies) {
return false;
}

View File

@@ -598,14 +598,14 @@ public class Graph {
System.out.println(el);
}
System.out.println("</loops>");*/
getPrecontinues(localData, null, heads.get(0), loops, null);
getPrecontinues(localData, null, heads.get(0), allParts, loops, null);
/*System.err.println("<loopspre>");
for (Loop el : loops) {
System.err.println(el);
}
System.err.println("</loopspre>");//*/
List<GraphTargetItem> ret = printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, null, heads.get(0), null, loops, staticOperation, path);
List<GraphTargetItem> 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<GraphTargetItem> printGraph(List<GraphPart> visited, List<Object> localData, Stack<GraphTargetItem> stack, List<GraphPart> allParts, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<Loop> loops, int staticOperation, String path) throws InterruptedException {
return printGraph(visited, localData, stack, allParts, parent, part, stopPart, loops, null, staticOperation, path);
protected List<GraphTargetItem> printGraph(List<Object> localData, Stack<GraphTargetItem> stack, List<GraphPart> allParts, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<Loop> loops, int staticOperation, String path) throws InterruptedException {
List<GraphPart> visited = new ArrayList<>();
return printGraph(visited, localData, stack, allParts, parent, part, stopPart, loops, null, staticOperation, path, 0);
}
protected GraphTargetItem checkLoop(LoopItem loopItem, List<Object> localData, List<Loop> loops) {
return loopItem;
}
private void getPrecontinues(List<Object> localData, GraphPart parent, GraphPart part, List<Loop> loops, List<GraphPart> stopPart) throws InterruptedException {
markLevels(localData, part, loops);
private void getPrecontinues(List<Object> localData, GraphPart parent, GraphPart part, List<GraphPart> allParts, List<Loop> loops, List<GraphPart> 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<Object> localData, GraphPart part, List<Loop> loops) throws InterruptedException {
private void markLevels(List<Object> localData, GraphPart part, List<GraphPart> allParts, List<Loop> loops) throws InterruptedException {
clearLoops(loops);
markLevels(localData, part, loops, new ArrayList<GraphPart>(), 1, new ArrayList<GraphPart>());
markLevels(localData, part, allParts, loops, new ArrayList<GraphPart>(), 1, new ArrayList<GraphPart>(), 0);
clearLoops(loops);
}
private void markLevels(List<Object> localData, GraphPart part, List<Loop> loops, List<GraphPart> stopPart, int level, List<GraphPart> visited) throws InterruptedException {
private void markLevels(List<Object> localData, GraphPart part, List<GraphPart> allParts, List<Loop> loops, List<GraphPart> stopPart, int level, List<GraphPart> 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<GraphTargetItem> printGraph(List<GraphPart> visited, List<Object> localData, Stack<GraphTargetItem> stack, List<GraphPart> allParts, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<Loop> loops, List<GraphTargetItem> ret, int staticOperation, String path) throws InterruptedException {
protected List<GraphTargetItem> printGraph(List<GraphPart> visited, List<Object> localData, Stack<GraphTargetItem> stack, List<GraphPart> allParts, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<Loop> loops, List<GraphTargetItem> 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<GraphTargetItem>();
} else {
@@ -1562,7 +1570,7 @@ public class Graph {
} else {
List<GraphPart> 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<GraphPart> 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<GraphTargetItem> 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<GraphTargetItem>(), allParts, null, precoBackup, stopContPart, loops, staticOperation, path));
loopItem.commands.addAll(printGraph(visited, localData, new Stack<GraphTargetItem>(), allParts, null, precoBackup, stopContPart, loops, null, staticOperation, path, recursionLevel + 1));
}
}
@@ -1878,7 +1886,7 @@ public class Graph {
currentLoop.loopPreContinue = null;
List<GraphPart> stopPart2 = new ArrayList<>(stopPart);
stopPart2.add(currentLoop.loopContinue);
finalComm = printGraph(visited, localData, new Stack<GraphTargetItem>(), allParts, null, backup, stopPart2, loops, staticOperation, path);
finalComm = printGraph(visited, localData, new Stack<GraphTargetItem>(), 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<GraphPart> stopPart2 = new ArrayList<>(stopPart);
stopPart2.add(currentLoop.loopContinue);
List<GraphTargetItem> finalComm = printGraph(visited, localData, new Stack<GraphTargetItem>(), allParts, null, backup, stopPart2, loops, staticOperation, path);
List<GraphTargetItem> finalComm = printGraph(visited, localData, new Stack<GraphTargetItem>(), 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));
}
}

View File

@@ -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<GraphTargetItem> dependencies = new HashSet<>();
dependencies.add(this);
return isCompileTime(dependencies);
}
public boolean isCompileTime(Set<GraphTargetItem> dependencies) {
return false;
}

View File

@@ -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<GraphTargetItem> dependencies) {
return false;
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.graph;
/**
*
* @author JPEXS
*/
public class TranslateException extends RuntimeException {
public TranslateException(String s) {
super(s);
}
}

View File

@@ -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<GraphTargetItem> 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

View File

@@ -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

View File

@@ -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<GraphTargetItem> dependencies) {
if (dependencies.contains(value)) {
return false;
}
dependencies.add(value);
return value.isCompileTime(dependencies);
}
@Override

View File

@@ -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<GraphTargetItem> onFalse;
@Override
public boolean isCompileTime() {
return expression.isCompileTime();
public boolean isCompileTime(Set<GraphTargetItem> dependencies) {
if (dependencies.contains(expression)) {
return false;
}
dependencies.add(expression);
return expression.isCompileTime(dependencies);
}
@Override

View File

@@ -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<GraphTargetItem> dependencies) {
return true;
}

View File

@@ -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<GraphTargetItem> dependencies) {
if (dependencies.contains(value)) {
return false;
}
dependencies.add(value);
return value.isCompileTime(dependencies);
}
@Override

View File

@@ -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<GraphTargetItem> dependencies) {
if (dependencies.contains(value)) {
return false;
}
dependencies.add(value);
return value.isCompileTime(dependencies);
}
@Override