mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-17 11:58:51 +00:00
New loop detection algorithm
This commit is contained in:
@@ -2144,9 +2144,10 @@ public class AVM2Code implements Serializable {
|
||||
oos.writeObject(this);
|
||||
oos.flush();
|
||||
}
|
||||
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
|
||||
AVM2Code copy = (AVM2Code) ois.readObject();
|
||||
ois.close();
|
||||
AVM2Code copy;
|
||||
try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) {
|
||||
copy = (AVM2Code) ois.readObject();
|
||||
}
|
||||
return copy;
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
|
||||
@@ -27,16 +27,21 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocalTypeIn
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.KillIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnValueIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushIntegerTypeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.FilteredCheckTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.HasNextTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.InTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.LocalRegTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.NextNameTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.NextValueTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.NullTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.ReturnValueTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.ReturnVoidTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.SetLocalTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.SetPropertyTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.SetTypeTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.WithTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.clauses.ExceptionTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.clauses.FilterTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.clauses.ForEachInTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.clauses.ForInTreeItem;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.treemodel.clauses.TryTreeItem;
|
||||
@@ -50,7 +55,9 @@ import com.jpexs.decompiler.flash.graph.GraphPart;
|
||||
import com.jpexs.decompiler.flash.graph.GraphPartMulti;
|
||||
import com.jpexs.decompiler.flash.graph.GraphSource;
|
||||
import com.jpexs.decompiler.flash.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.flash.graph.IfItem;
|
||||
import com.jpexs.decompiler.flash.graph.Loop;
|
||||
import com.jpexs.decompiler.flash.graph.LoopItem;
|
||||
import com.jpexs.decompiler.flash.graph.SwitchItem;
|
||||
import com.jpexs.decompiler.flash.graph.WhileItem;
|
||||
import java.util.ArrayList;
|
||||
@@ -1147,7 +1154,7 @@ public class AVM2Graph extends Graph {
|
||||
}*/
|
||||
|
||||
@Override
|
||||
protected List<GraphTargetItem> check(GraphSource srcCode, List<Object> localData, List<GraphPart> allParts, Stack<GraphTargetItem> stack, GraphPart parent, GraphPart part, GraphPart stopPart, List<Loop> loops, List<GraphTargetItem> output, HashMap<Loop, List<GraphTargetItem>> forFinalCommands) {
|
||||
protected List<GraphTargetItem> check(GraphSource srcCode, List<Object> localData, List<GraphPart> allParts, Stack<GraphTargetItem> stack, GraphPart parent, GraphPart part, GraphPart stopPart, List<Loop> loops, List<GraphTargetItem> output) {
|
||||
List<GraphTargetItem> ret = null;
|
||||
|
||||
|
||||
@@ -1227,7 +1234,7 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
//code.code.get(f).ignored = true;
|
||||
ignoredSwitches.add(f);
|
||||
finallyCommands = printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, parent, fpart, fepart, loops, forFinalCommands);
|
||||
finallyCommands = printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, parent, fpart, fepart, loops);
|
||||
returnPos = f + 1;
|
||||
break;
|
||||
}
|
||||
@@ -1236,7 +1243,7 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
}
|
||||
if (!switchFound) {
|
||||
finallyCommands = printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, parent, fpart, null, loops, forFinalCommands);
|
||||
finallyCommands = printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, parent, fpart, null, loops);
|
||||
}
|
||||
finallyJumps.add(finStart);
|
||||
break;
|
||||
@@ -1274,7 +1281,7 @@ public class AVM2Graph extends Graph {
|
||||
List<Object> localData2 = new ArrayList<>();
|
||||
localData2.addAll(localData);
|
||||
localData2.set(DATA_SCOPESTACK, new Stack<GraphTargetItem>());
|
||||
catchedCommands.add(printGraph(new ArrayList<GraphPart>(), localData2, stack, allParts, parent, npart, nepart, loops, forFinalCommands));
|
||||
catchedCommands.add(printGraph(new ArrayList<GraphPart>(), localData2, stack, allParts, parent, npart, nepart, loops));
|
||||
}
|
||||
|
||||
GraphPart nepart = null;
|
||||
@@ -1285,7 +1292,7 @@ public class AVM2Graph extends Graph {
|
||||
break;
|
||||
}
|
||||
}
|
||||
List<GraphTargetItem> tryCommands = printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, parent, part, nepart, loops, forFinalCommands);
|
||||
List<GraphTargetItem> tryCommands = printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, parent, part, nepart, loops);
|
||||
|
||||
output.clear();
|
||||
output.add(new TryTreeItem(tryCommands, catchedExceptions, catchedCommands, finallyCommands));
|
||||
@@ -1309,7 +1316,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, forFinalCommands));
|
||||
ret.addAll(printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, null, part, stopPart, loops));
|
||||
} else {
|
||||
ret.add(lop);
|
||||
}
|
||||
@@ -1433,6 +1440,7 @@ public class AVM2Graph extends Graph {
|
||||
|
||||
GraphTargetItem ti = checkLoop(next, stopPart, loops);
|
||||
Loop currentLoop = new Loop(loops.size(), null, next);
|
||||
currentLoop.used = true;
|
||||
loops.add(currentLoop);
|
||||
//switchLoc.getNextPartPath(new ArrayList<GraphPart>());
|
||||
List<Integer> valuesMapping = new ArrayList<>();
|
||||
@@ -1449,7 +1457,14 @@ public class AVM2Graph extends Graph {
|
||||
GraphPart defaultPart = null;
|
||||
if (hasDefault) {
|
||||
defaultPart = switchLoc.nextParts.get(switchLoc.nextParts.size() - 1);
|
||||
defaultCommands = printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, switchLoc, defaultPart, next, loops, forFinalCommands);
|
||||
defaultCommands = printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, switchLoc, defaultPart, next, loops);
|
||||
if (!defaultCommands.isEmpty()) {
|
||||
if (defaultCommands.get(defaultCommands.size() - 1) instanceof BreakItem) {
|
||||
if (((BreakItem) defaultCommands.get(defaultCommands.size() - 1)).loopId == currentLoop.id) {
|
||||
defaultCommands.remove(defaultCommands.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<GraphPart> ignored = new ArrayList<>();
|
||||
@@ -1464,19 +1479,19 @@ public class AVM2Graph extends Graph {
|
||||
if (next != null) {
|
||||
if (i < caseBodies.size() - 1) {
|
||||
if (!caseBodies.get(i).leadsTo(srcCode, caseBodies.get(i + 1), ignored)) {
|
||||
cc.add(new BreakItem(null, currentLoop.id));
|
||||
//cc.add(new BreakItem(null, currentLoop.id));
|
||||
} else {
|
||||
nextCase = caseBodies.get(i + 1);
|
||||
}
|
||||
} else if (hasDefault) {
|
||||
if (!caseBodies.get(i).leadsTo(srcCode, defaultPart, ignored)) {
|
||||
cc.add(new BreakItem(null, currentLoop.id));
|
||||
//cc.add(new BreakItem(null, currentLoop.id));
|
||||
} else {
|
||||
nextCase = defaultPart;
|
||||
}
|
||||
}
|
||||
}
|
||||
cc.addAll(0, printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, switchLoc, caseBodies.get(i), nextCase, loops, forFinalCommands));
|
||||
cc.addAll(0, printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, switchLoc, caseBodies.get(i), nextCase, loops));
|
||||
caseCommands.add(cc);
|
||||
}
|
||||
|
||||
@@ -1487,7 +1502,7 @@ public class AVM2Graph extends Graph {
|
||||
if (ti != null) {
|
||||
ret.add(ti);
|
||||
} else {
|
||||
ret.addAll(printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, null, next, stopPart, loops, forFinalCommands));
|
||||
ret.addAll(printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, null, next, stopPart, loops));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1506,6 +1521,57 @@ public class AVM2Graph extends Graph {
|
||||
return next;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GraphTargetItem checkLoop(LoopItem loopItem, List<Object> localData, List<Loop> loops) {
|
||||
if (loopItem instanceof WhileItem) {
|
||||
WhileItem w = (WhileItem) loopItem;
|
||||
|
||||
if ((!w.expression.isEmpty()) && (w.expression.get(w.expression.size() - 1) instanceof HasNextTreeItem)) {
|
||||
if (((HasNextTreeItem) w.expression.get(w.expression.size() - 1)).collection.getNotCoerced().getThroughRegister() instanceof FilteredCheckTreeItem) {
|
||||
GraphTargetItem gti = ((HasNextTreeItem) ((HasNextTreeItem) w.expression.get(w.expression.size() - 1))).collection.getNotCoerced().getThroughRegister();
|
||||
if (w.commands.size() >= 3) { //((w.commands.size() == 3) || (w.commands.size() == 4)) {
|
||||
int pos = 0;
|
||||
while (w.commands.get(pos) instanceof SetLocalTreeItem) {
|
||||
pos++;
|
||||
}
|
||||
GraphTargetItem ft = w.commands.get(pos);
|
||||
if (ft instanceof WithTreeItem) {
|
||||
ft = w.commands.get(pos + 1);
|
||||
if (ft instanceof IfItem) {
|
||||
IfItem ift = (IfItem) ft;
|
||||
if (ift.onTrue.size() > 0) {
|
||||
ft = ift.onTrue.get(0);
|
||||
if (ft instanceof SetPropertyTreeItem) {
|
||||
SetPropertyTreeItem spt = (SetPropertyTreeItem) ft;
|
||||
if (spt.object instanceof LocalRegTreeItem) {
|
||||
int regIndex = ((LocalRegTreeItem) spt.object).regIndex;
|
||||
HasNextTreeItem iti = (HasNextTreeItem) w.expression.get(w.expression.size() - 1);
|
||||
@SuppressWarnings("unchecked")
|
||||
HashMap<Integer, GraphTargetItem> localRegs = (HashMap<Integer, GraphTargetItem>) localData.get(DATA_LOCALREGS);
|
||||
localRegs.put(regIndex, new FilterTreeItem(null, iti.collection.getThroughRegister(), ift.expression));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!w.commands.isEmpty()) {
|
||||
if (w.commands.get(0) instanceof SetTypeTreeItem) {
|
||||
SetTypeTreeItem sti = (SetTypeTreeItem) w.commands.remove(0);
|
||||
GraphTargetItem gti = sti.getValue().getNotCoerced();
|
||||
if (gti instanceof NextValueTreeItem) {
|
||||
return new ForEachInTreeItem(w.src, w.loop, new InTreeItem(null, sti.getObject(), ((HasNextTreeItem) w.expression.get(w.expression.size() - 1)).collection), w.commands);
|
||||
} else if (gti instanceof NextNameTreeItem) {
|
||||
return new ForInTreeItem(w.src, w.loop, new InTreeItem(null, sti.getObject(), ((HasNextTreeItem) w.expression.get(w.expression.size() - 1)).collection), w.commands);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return loopItem;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalProcess(List<GraphTargetItem> list, int level) {
|
||||
if (level == 0) {
|
||||
@@ -1515,24 +1581,14 @@ public class AVM2Graph extends Graph {
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (list.get(i) instanceof WhileItem) {
|
||||
WhileItem w = (WhileItem) list.get(i);
|
||||
if ((!w.expression.isEmpty()) && (w.expression.get(w.expression.size() - 1) instanceof HasNextTreeItem)) {
|
||||
if (!w.commands.isEmpty()) {
|
||||
if (w.commands.get(0) instanceof SetTypeTreeItem) {
|
||||
SetTypeTreeItem sti = (SetTypeTreeItem) w.commands.remove(0);
|
||||
GraphTargetItem gti = sti.getValue().getNotCoerced();
|
||||
if (gti instanceof NextValueTreeItem) {
|
||||
list.set(i, new ForEachInTreeItem(w.src, w.loop, new InTreeItem(null, sti.getObject(), ((HasNextTreeItem) w.expression.get(w.expression.size() - 1)).collection), w.commands));
|
||||
} else if (gti instanceof NextNameTreeItem) {
|
||||
list.set(i, new ForInTreeItem(w.src, w.loop, new InTreeItem(null, sti.getObject(), ((HasNextTreeItem) w.expression.get(w.expression.size() - 1)).collection), w.commands));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*for (int i = 0; i < list.size(); i++) {
|
||||
|
||||
if (list.get(i) instanceof WhileItem) {
|
||||
WhileItem w = (WhileItem) list.get(i);
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
List<GraphTargetItem> ret = code.clearTemporaryRegisters(list);
|
||||
|
||||
@@ -30,7 +30,7 @@ import java.util.List;
|
||||
|
||||
public abstract class Trait implements Serializable {
|
||||
|
||||
public boolean debugMode = false;
|
||||
public static boolean debugMode = false;
|
||||
public int name_index;
|
||||
public int kindType;
|
||||
public int kindFlags;
|
||||
|
||||
@@ -55,9 +55,7 @@ public class TraitMethodGetterSetter extends Trait {
|
||||
|
||||
@Override
|
||||
public String convert(String path, List<ABCContainerTag> abcTags, ABC abc, boolean isStatic, boolean pcode, int scriptIndex, int classIndex, boolean highlight, List<String> fullyQualifiedNames) {
|
||||
if (!Configuration.DO_DECOMPILE) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (debugMode) {
|
||||
System.err.println("Decompiling " + path + "." + getName(abc).getName(abc.constants, fullyQualifiedNames));
|
||||
}
|
||||
@@ -65,7 +63,7 @@ public class TraitMethodGetterSetter extends Trait {
|
||||
|
||||
String bodyStr = "";
|
||||
int bodyIndex = abc.findBodyIndex(method_info);
|
||||
if (bodyIndex != -1) {
|
||||
if ((bodyIndex != -1) && Configuration.DO_DECOMPILE) {
|
||||
bodyStr = ABC.addTabs(abc.bodies[bodyIndex].toString(path + "." + getName(abc).getName(abc.constants, fullyQualifiedNames), pcode, isStatic, scriptIndex, classIndex, abc, abc.constants, abc.method_info, new Stack<GraphTargetItem>(), false, highlight, fullyQualifiedNames, null), 3);
|
||||
}
|
||||
return ABC.IDENT_STRING + ABC.IDENT_STRING + header + ((classIndex != -1 && abc.instance_info[classIndex].isInterface()) ? ";" : " {\r\n" + bodyStr + "\r\n" + ABC.IDENT_STRING + ABC.IDENT_STRING + "}");
|
||||
|
||||
@@ -122,7 +122,7 @@ public class Traits implements Serializable {
|
||||
|
||||
public String convert(String path, List<ABCContainerTag> abcTags, ABC abc, boolean isStatic, boolean pcode, boolean makePackages, int scriptIndex, int classIndex, boolean highlighting, List<String> fullyQualifiedNames) {
|
||||
String s = "";
|
||||
ExecutorService executor = Executors.newFixedThreadPool(20);
|
||||
ExecutorService executor = Executors.newFixedThreadPool(Trait.debugMode ? 1 : 20);
|
||||
List<Future<String>> futureResults = new ArrayList<>();
|
||||
for (int t = 0; t < traits.length; t++) {
|
||||
Future<String> future = executor.submit(new TraitConvertTask(traits[t], makePackages, path, abcTags, abc, isStatic, pcode, scriptIndex, classIndex, highlighting, fullyQualifiedNames, t));
|
||||
|
||||
@@ -124,7 +124,7 @@ public class ActionGraph extends Graph {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<GraphTargetItem> check(GraphSource code, List<Object> localData, List<GraphPart> allParts, Stack<GraphTargetItem> stack, GraphPart parent, GraphPart part, GraphPart stopPart, List<Loop> loops, List<GraphTargetItem> output, HashMap<Loop, List<GraphTargetItem>> forFinalCommands) {
|
||||
protected List<GraphTargetItem> check(GraphSource code, List<Object> localData, List<GraphPart> allParts, Stack<GraphTargetItem> stack, GraphPart parent, GraphPart part, GraphPart stopPart, List<Loop> loops, List<GraphTargetItem> output) {
|
||||
if (!output.isEmpty()) {
|
||||
if (output.get(output.size() - 1) instanceof StoreRegisterTreeItem) {
|
||||
StoreRegisterTreeItem str = (StoreRegisterTreeItem) output.get(output.size() - 1);
|
||||
@@ -188,7 +188,7 @@ public class ActionGraph extends Graph {
|
||||
|
||||
List<GraphTargetItem> defaultCommands = new ArrayList<>();
|
||||
|
||||
defaultCommands = printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, null, defaultPart, defaultPart2, loops, forFinalCommands);
|
||||
defaultCommands = printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, null, defaultPart, defaultPart2, loops);
|
||||
|
||||
|
||||
List<GraphPart> loopContinues = new ArrayList<>();
|
||||
@@ -260,7 +260,7 @@ public class ActionGraph extends Graph {
|
||||
defaultPart = null;
|
||||
}
|
||||
if ((defaultPart != null) && (defaultCommands.isEmpty())) {
|
||||
defaultCommands = printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, null, defaultPart, next, loops, forFinalCommands);
|
||||
defaultCommands = printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, null, defaultPart, next, loops);
|
||||
}
|
||||
|
||||
List<GraphPart> ignored = new ArrayList<>();
|
||||
@@ -287,7 +287,7 @@ public class ActionGraph extends Graph {
|
||||
}
|
||||
}
|
||||
}
|
||||
cc.addAll(0, printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, null, caseBodies.get(i), nextCase, loops, forFinalCommands));
|
||||
cc.addAll(0, printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, null, caseBodies.get(i), nextCase, loops));
|
||||
if (cc.size() >= 2) {
|
||||
if (cc.get(cc.size() - 1) instanceof BreakItem) {
|
||||
if ((cc.get(cc.size() - 2) instanceof ContinueItem) || (cc.get(cc.size() - 2) instanceof BreakItem)) {
|
||||
@@ -311,7 +311,7 @@ public class ActionGraph extends Graph {
|
||||
if (ti != null) {
|
||||
ret.add(ti);
|
||||
} else {
|
||||
ret.addAll(printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, null, next, stopPart, loops, forFinalCommands));
|
||||
ret.addAll(printGraph(new ArrayList<GraphPart>(), localData, stack, allParts, null, next, stopPart, loops));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
52
trunk/src/com/jpexs/decompiler/flash/graph/CommentItem.java
Normal file
52
trunk/src/com/jpexs/decompiler/flash/graph/CommentItem.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.graph;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class CommentItem extends GraphTargetItem {
|
||||
|
||||
private String comment;
|
||||
|
||||
public CommentItem(String comment) {
|
||||
super(null, NOPRECEDENCE);
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(List<Object> localData) {
|
||||
return "/* " + comment + " */";
|
||||
}
|
||||
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsSemicolon() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,6 +16,9 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.graph;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
@@ -24,7 +27,12 @@ public class Loop {
|
||||
|
||||
public GraphPart loopContinue;
|
||||
public GraphPart loopBreak;
|
||||
public GraphPart loopPreContinue;
|
||||
public int precoPhase;
|
||||
public List<GraphPart> breakCandidates = new ArrayList<>();
|
||||
public long id;
|
||||
public boolean used = false;
|
||||
public boolean finished = false;
|
||||
|
||||
public Loop(long id, GraphPart loopContinue, GraphPart loopBreak) {
|
||||
this.loopContinue = loopContinue;
|
||||
@@ -34,6 +42,6 @@ public class Loop {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "loop(id:" + id + ",continue:" + loopContinue + ", break:" + loopBreak + ")";
|
||||
return "loop(id:" + id + (loopPreContinue != null ? ",precontinue:" + loopPreContinue : "") + ",continue:" + loopContinue + ", break:" + loopBreak + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class SwitchItem extends LoopItem implements Block {
|
||||
@Override
|
||||
public String toString(List<Object> localData) {
|
||||
String ret = "";
|
||||
ret += "loopswitch" + loop.id + ":\r\n";
|
||||
ret += "loop" + loop.id + ":\r\n";
|
||||
ret += hilight("switch(") + switchedObject.toString(localData) + hilight(")") + "\r\n{\r\n";
|
||||
for (int i = 0; i < caseCommands.size(); i++) {
|
||||
for (int k = 0; k < valuesMapping.size(); k++) {
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.graph;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class UniversalLoopItem extends LoopItem implements Block {
|
||||
|
||||
public List<GraphTargetItem> commands;
|
||||
|
||||
public UniversalLoopItem(GraphSourceItem src, Loop loop) {
|
||||
super(src, loop);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(List<Object> localData) {
|
||||
String ret = "";
|
||||
ret += "loop" + loop.id + ":\r\n";
|
||||
ret += hilight("while(true)");
|
||||
ret += "\r\n{\r\n";
|
||||
for (GraphTargetItem ti : commands) {
|
||||
if (!ti.isEmpty()) {
|
||||
ret += ti.toStringSemicoloned(localData) + "\r\n";
|
||||
}
|
||||
}
|
||||
ret += hilight("}") + "\r\n";
|
||||
ret += ":loop" + loop.id;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ContinueItem> getContinues() {
|
||||
List<ContinueItem> ret = new ArrayList<>();
|
||||
for (GraphTargetItem ti : commands) {
|
||||
if (ti instanceof ContinueItem) {
|
||||
ret.add((ContinueItem) ti);
|
||||
}
|
||||
if (ti instanceof Block) {
|
||||
ret.addAll(((Block) ti).getContinues());
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<List<GraphTargetItem>> getSubs() {
|
||||
List<List<GraphTargetItem>> ret = new ArrayList<>();
|
||||
ret.add(commands);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -270,9 +270,10 @@ public class Helper {
|
||||
oos.writeObject(o);
|
||||
oos.flush();
|
||||
}
|
||||
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
|
||||
Object copy = ois.readObject();
|
||||
ois.close();
|
||||
Object copy;
|
||||
try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) {
|
||||
copy = ois.readObject();
|
||||
}
|
||||
return copy;
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
|
||||
@@ -143,12 +143,13 @@ public class ActionScript3Test {
|
||||
+ "}\r\n"
|
||||
+ "if(a==9)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "return;\r\n"
|
||||
+ "break;\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"hello 1\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"hello2\");\r\n"
|
||||
+ "}\r\n", false);
|
||||
+ "}\r\n"
|
||||
+ "return;\r\n", false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -179,6 +180,7 @@ public class ActionScript3Test {
|
||||
+ "var d:* = undefined;\r\n"
|
||||
+ "var e:* = undefined;\r\n"
|
||||
+ "var a:* = 5;\r\n"
|
||||
+ "loop3:\r\n"
|
||||
+ "switch(a)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "case 57*a:\r\n"
|
||||
@@ -192,12 +194,9 @@ public class ActionScript3Test {
|
||||
+ "}\r\n"
|
||||
+ "if(b==15)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "break loop3;\r\n"
|
||||
+ "}\r\n"
|
||||
+ "else\r\n"
|
||||
+ "{\r\n"
|
||||
+ "b=b+1;\r\n"
|
||||
+ "continue;\r\n"
|
||||
+ "}\r\n"
|
||||
+ "}\r\n"
|
||||
+ "break;\r\n"
|
||||
+ "case 13:\r\n"
|
||||
|
||||
@@ -33,9 +33,9 @@ public class SWFStreamTest {
|
||||
sos.writeFB(20, f);
|
||||
}
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
||||
SWFInputStream sis = new SWFInputStream(bais, 10);
|
||||
assertTrue(Double.compare(f, sis.readFB(20)) == 0);
|
||||
sis.close();
|
||||
try (SWFInputStream sis = new SWFInputStream(bais, 10)) {
|
||||
assertTrue(Double.compare(f, sis.readFB(20)) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -49,13 +49,13 @@ public class SWFStreamTest {
|
||||
sos.writeUB(9, 5);
|
||||
}
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
||||
SWFInputStream sis = new SWFInputStream(bais, 10);
|
||||
assertEquals(1, sis.readUB(5));
|
||||
assertEquals(2, sis.readUB(6));
|
||||
assertEquals(3, sis.readUB(7));
|
||||
assertEquals(4, sis.readUB(8));
|
||||
assertEquals(5, sis.readUB(9));
|
||||
sis.close();
|
||||
try (SWFInputStream sis = new SWFInputStream(bais, 10)) {
|
||||
assertEquals(1, sis.readUB(5));
|
||||
assertEquals(2, sis.readUB(6));
|
||||
assertEquals(3, sis.readUB(7));
|
||||
assertEquals(4, sis.readUB(8));
|
||||
assertEquals(5, sis.readUB(9));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -69,13 +69,13 @@ public class SWFStreamTest {
|
||||
sos.writeSB(9, -5);
|
||||
}
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
||||
SWFInputStream sis = new SWFInputStream(bais, 10);
|
||||
assertEquals(-1, sis.readSB(5));
|
||||
assertEquals(2, sis.readSB(6));
|
||||
assertEquals(-3, sis.readSB(7));
|
||||
assertEquals(4, sis.readSB(8));
|
||||
assertEquals(-5, sis.readSB(9));
|
||||
sis.close();
|
||||
try (SWFInputStream sis = new SWFInputStream(bais, 10)) {
|
||||
assertEquals(-1, sis.readSB(5));
|
||||
assertEquals(2, sis.readSB(6));
|
||||
assertEquals(-3, sis.readSB(7));
|
||||
assertEquals(4, sis.readSB(8));
|
||||
assertEquals(-5, sis.readSB(9));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user