diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/AVM2Code.java b/trunk/src/com/jpexs/asdec/abc/avm2/AVM2Code.java
index 3f6428766..cdd385731 100644
--- a/trunk/src/com/jpexs/asdec/abc/avm2/AVM2Code.java
+++ b/trunk/src/com/jpexs/asdec/abc/avm2/AVM2Code.java
@@ -20,7 +20,7 @@ import com.jpexs.asdec.Main;
import com.jpexs.asdec.abc.ABC;
import com.jpexs.asdec.abc.ABCInputStream;
import com.jpexs.asdec.abc.CopyOutputStream;
-import com.jpexs.asdec.abc.avm2.flowgraph.Graph;
+import com.jpexs.asdec.abc.avm2.graph.AVM2Graph;
import com.jpexs.asdec.abc.avm2.instructions.AVM2Instruction;
import com.jpexs.asdec.abc.avm2.instructions.IfTypeIns;
import com.jpexs.asdec.abc.avm2.instructions.InstructionDefinition;
@@ -1901,7 +1901,7 @@ public class AVM2Code implements Serializable {
//try {
try{
- list = Graph.translateViaGraph(path,this, abc, body);
+ list = AVM2Graph.translateViaGraph(path,this, abc, body);
}catch(Exception ex2){
Logger.getLogger(AVM2Code.class.getName()).log(Level.SEVERE, "Decompilation error in "+path,ex2);
return "/*\r\n * Decompilation error\r\n * Code may be obfuscated\r\n * Error Message: " + ex2.getMessage() + "\r\n */";
diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/flowgraph/Graph.java b/trunk/src/com/jpexs/asdec/abc/avm2/graph/AVM2Graph.java
similarity index 84%
rename from trunk/src/com/jpexs/asdec/abc/avm2/flowgraph/Graph.java
rename to trunk/src/com/jpexs/asdec/abc/avm2/graph/AVM2Graph.java
index ffab8f10f..9d21407df 100644
--- a/trunk/src/com/jpexs/asdec/abc/avm2/flowgraph/Graph.java
+++ b/trunk/src/com/jpexs/asdec/abc/avm2/graph/AVM2Graph.java
@@ -14,8 +14,12 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package com.jpexs.asdec.abc.avm2.flowgraph;
+package com.jpexs.asdec.abc.avm2.graph;
+import com.jpexs.asdec.graph.Graph;
+import com.jpexs.asdec.graph.GraphPart;
+import com.jpexs.asdec.graph.Loop;
+import com.jpexs.asdec.graph.GraphPartMulti;
import com.jpexs.asdec.abc.ABC;
import com.jpexs.asdec.abc.avm2.AVM2Code;
import com.jpexs.asdec.abc.avm2.ConvertException;
@@ -85,69 +89,26 @@ import java.util.logging.Logger;
*
* @author JPEXS
*/
-public class Graph {
+public class AVM2Graph extends Graph{
- public List heads;
private AVM2Code code;
private ABC abc;
private MethodBody body;
- public Graph(AVM2Code code, ABC abc, MethodBody body) {
+ public AVM2Graph(AVM2Code code, ABC abc, MethodBody body) {
heads = makeGraph(code, new ArrayList(), body);
this.code = code;
this.abc = abc;
this.body = body;
for (GraphPart head : heads) {
- fixGraph(head);
- //makeMulti(head, new ArrayList());
+ fixGraph(head);
}
}
- private void makeMulti(GraphPart part, List visited) {
- if (visited.contains(part)) {
- return;
- }
- visited.add(part);
- GraphPart p = part;
- List multiList = new ArrayList();
- multiList.add(p);
- while ((p.nextParts.size() == 1) && (p.nextParts.get(0).refs.size() == 1)) {
- p = p.nextParts.get(0);
- multiList.add(p);
- }
- if (multiList.size() > 1) {
- GraphPartMulti gpm = new GraphPartMulti(multiList);
- gpm.refs = part.refs;
- GraphPart lastPart = multiList.get(multiList.size() - 1);
- gpm.nextParts = lastPart.nextParts;
- for (GraphPart next : gpm.nextParts) {
- int index = next.refs.indexOf(lastPart);
- if (index == -1) {
-
- continue;
- }
- next.refs.remove(lastPart);
- next.refs.add(index, gpm);
- }
- for (GraphPart parent : part.refs) {
- if (parent.start == -1) {
- continue;
- }
- int index = parent.nextParts.indexOf(part);
- if (index == -1) {
- continue;
- }
- parent.nextParts.remove(part);
- parent.nextParts.add(index, gpm);
- }
- }
- for (int i = 0; i < part.nextParts.size(); i++) {
- makeMulti(part.nextParts.get(i), visited);
- }
- }
+
public static List translateViaGraph(String path, AVM2Code code, ABC abc, MethodBody body) {
- Graph g = new Graph(code, abc, body);
+ AVM2Graph g = new AVM2Graph(code, abc, body);
List allParts = new ArrayList();
for (GraphPart head : g.heads) {
populateParts(head, allParts);
@@ -155,37 +116,7 @@ public class Graph {
return g.printGraph(path, new Stack(), new Stack(), allParts, new ArrayList(), new ArrayList(), 0, null, g.heads.get(0), null, new ArrayList(), new HashMap(), body, new ArrayList());
}
- private static void populateParts(GraphPart part, List allParts) {
- if (allParts.contains(part)) {
- return;
- }
- allParts.add(part);
- for (GraphPart p : part.nextParts) {
- populateParts(p, allParts);
- }
- }
-
- private String strOfChars(int len, String chars) {
- String ret = "";
- for (int i = 0; i < len; i++) {
- ret += chars;
- }
- return ret;
- }
- private static final String TAB = " ";
-
- private String printOutput(int level, List output, List fqn, HashMap lrn) {
- String s = Highlighting.stripHilights(code.listToString(output, abc.constants, lrn, fqn));
- String parts[] = s.split("\n");
- String ret = "";
- for (String p : parts) {
- if (p.trim().equals("")) {
- continue;
- }
- ret += (strOfChars(level, TAB) + p.trim()) + "\r\n";
- }
- return ret;
- }
+
private TreeItem checkLoop(GraphPart part, GraphPart stopPart, List loops) {
if (part == stopPart) {
@@ -394,7 +325,7 @@ public class Graph {
//((IfTypeIns)ins.definition).translateInverted(new HashMap(), co.stack, ins);
}
} catch (ConvertException ex) {
- Logger.getLogger(Graph.class.getName()).log(Level.SEVERE, null, ex);
+ Logger.getLogger(AVM2Graph.class.getName()).log(Level.SEVERE, null, ex);
}
int ip = part.start;
@@ -615,8 +546,11 @@ public class Graph {
}
finalPart = fex.continuePart;
isFor = true;
- for (ContinueTreeItem cti : finalPart.forContinues) {
- cti.loopPos = breakIp;
+ for (Object o : finalPart.forContinues) {
+ if(o instanceof ContinueTreeItem)
+ {
+ ((ContinueTreeItem)o).loopPos = breakIp;
+ }
}
}
if (isFor) {
@@ -867,135 +801,7 @@ public class Graph {
return ret;
}
- private void fixGraph(GraphPart part) {
- while (fixGraphOnce(part, new ArrayList(), false)) {
- }
- }
-
- private boolean fixGraphOnce(GraphPart part, List visited, boolean doChildren) {
- if (visited.contains(part)) {
- return false;
- }
- visited.add(part);
- boolean fixed = false;
- /*System.out.print("Part " + part.start + "-" + part.end + " refs:");
- for (GraphPart gp : part.refs) {
- System.out.print(gp.path + " ");
- }
- System.out.println("");*/
- int i = 1;
- String lastpref = null;
- boolean modify = true;
- int prvni = -1;
-
- if (!doChildren) {
-
- List uniqueRefs = new ArrayList();
- for (GraphPart r : part.refs) {
- if (!uniqueRefs.contains(r)) {
- uniqueRefs.add(r);
- }
- }
- loopi:
- for (; i <= part.path.length(); i++) {
- lastpref = null;
- int pos = -1;
- for (GraphPart r : uniqueRefs) {
- pos++;
- if (r.path.startsWith("e")) {
- continue;
- }
- if (part.leadsTo(r, new ArrayList())) {
- //modify=false;
- //continue;
- }
-
- prvni = pos;
- if (i > r.path.length()) {
- i--;
- break loopi;
- }
- if (lastpref == null) {
- lastpref = r.path.substring(0, i);
- } else {
- if (!r.path.startsWith(lastpref)) {
- i--;
- break loopi;
- }
- }
- }
- }
- if (i > part.path.length()) {
- i = part.path.length();
- }
- if (modify && ((uniqueRefs.size() > 1) && (prvni >= 0))) {
- String newpath = uniqueRefs.get(prvni).path.substring(0, i);
- if (!part.path.equals(newpath)) {
- if (part.path.startsWith(newpath)) {
- String origPath = part.path;
- GraphPart p = part;
- part.path = newpath;
- while (p.nextParts.size() == 1) {
- p = p.nextParts.get(0);
- if (!p.path.equals(origPath)) {
- break;
- }
- p.path = newpath;
- }
- fixGraphOnce(part, new ArrayList(), true);
- fixed = true;
- }
- }
- }
- } else {
-
- if (!fixed) {
- if (part.nextParts.size() == 1) {
- if (!(part.path.startsWith("e") && (!part.nextParts.get(0).path.startsWith("e")))) {
- if (part.nextParts.get(0).path.length() > part.path.length()) {
- part.nextParts.get(0).path = part.path;
- fixed = true;
- }
- }
- }
- if (part.nextParts.size() > 1) {
- for (int j = 0; j < part.nextParts.size(); j++) {
- GraphPart npart = part.nextParts.get(j);
-
- if (npart.path.length() > part.path.length() + 1) {
- npart.path = part.path + "" + j;
- fixed = true;
- }
- }
- }
- }
-
- }
- /* if (part.nextParts.size() == 2) {
- GraphPart left = part.nextParts.get(0);
- GraphPart right = part.nextParts.get(1);
- if ((left.nextParts.size() == 1) && (right.nextParts.size() == 1)) {
- if (left.nextParts.get(0) == right.nextParts.get(0)) {
- if (!left.nextParts.get(0).path.equals(part.path)) {
- String origPath = left.nextParts.get(0).path;
- GraphPart p = left;
- while (p.nextParts.size() == 1) {
- p = p.nextParts.get(0);
- if (!p.path.equals(origPath)) {
- break;
- }
- p.path = part.path;
- }
- fixed = true;
- }
- }
- }
- }*/
- for (GraphPart p : part.nextParts) {
- fixGraphOnce(p, visited, doChildren);
- }
- return fixed;
- }
+
private List makeGraph(AVM2Code code, List allBlocks, MethodBody body) {
HashMap> refs = code.visitCode(body);
diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/flowgraph/ForException.java b/trunk/src/com/jpexs/asdec/abc/avm2/graph/ForException.java
similarity index 82%
rename from trunk/src/com/jpexs/asdec/abc/avm2/flowgraph/ForException.java
rename to trunk/src/com/jpexs/asdec/abc/avm2/graph/ForException.java
index 89acd134b..2059ca970 100644
--- a/trunk/src/com/jpexs/asdec/abc/avm2/flowgraph/ForException.java
+++ b/trunk/src/com/jpexs/asdec/abc/avm2/graph/ForException.java
@@ -1,5 +1,6 @@
-package com.jpexs.asdec.abc.avm2.flowgraph;
+package com.jpexs.asdec.abc.avm2.graph;
+import com.jpexs.asdec.graph.GraphPart;
import com.jpexs.asdec.abc.avm2.treemodel.TreeItem;
import java.util.List;
diff --git a/trunk/src/com/jpexs/asdec/abc/gui/ASMSourceEditorPane.java b/trunk/src/com/jpexs/asdec/abc/gui/ASMSourceEditorPane.java
index ed933e755..278e8a547 100644
--- a/trunk/src/com/jpexs/asdec/abc/gui/ASMSourceEditorPane.java
+++ b/trunk/src/com/jpexs/asdec/abc/gui/ASMSourceEditorPane.java
@@ -19,7 +19,7 @@ package com.jpexs.asdec.abc.gui;
import com.jpexs.asdec.abc.ABC;
import com.jpexs.asdec.abc.avm2.AVM2Code;
import com.jpexs.asdec.abc.avm2.ConstantPool;
-import com.jpexs.asdec.abc.avm2.flowgraph.Graph;
+import com.jpexs.asdec.abc.avm2.graph.AVM2Graph;
import com.jpexs.asdec.abc.avm2.parser.ASM3Parser;
import com.jpexs.asdec.abc.avm2.parser.ParseException;
import com.jpexs.asdec.helpers.Highlighting;
@@ -73,7 +73,7 @@ public class ASMSourceEditorPane extends LineMarkedEditorPane implements CaretLi
}
public void graph() {
- Graph gr = new Graph(abc.bodies[bodyIndex].code,abc,abc.bodies[bodyIndex]);
+ AVM2Graph gr = new AVM2Graph(abc.bodies[bodyIndex].code,abc,abc.bodies[bodyIndex]);
(new GraphFrame(gr, "")).setVisible(true);
}
diff --git a/trunk/src/com/jpexs/asdec/abc/gui/GraphFrame.java b/trunk/src/com/jpexs/asdec/abc/gui/GraphFrame.java
index 1d8f70e9b..c36fa6b83 100644
--- a/trunk/src/com/jpexs/asdec/abc/gui/GraphFrame.java
+++ b/trunk/src/com/jpexs/asdec/abc/gui/GraphFrame.java
@@ -16,8 +16,8 @@
*/
package com.jpexs.asdec.abc.gui;
-import com.jpexs.asdec.abc.avm2.flowgraph.Graph;
-import com.jpexs.asdec.abc.avm2.flowgraph.GraphPart;
+import com.jpexs.asdec.abc.avm2.graph.AVM2Graph;
+import com.jpexs.asdec.graph.GraphPart;
import com.jpexs.asdec.gui.View;
import java.awt.*;
import java.util.ArrayList;
@@ -41,9 +41,9 @@ public class GraphFrame extends JFrame {
private static final int SPACE_HORIZONTAL = 10;
private static final int BLOCK_WIDTH = 200;
private static final int BLOCK_HEIGHT = 20;
- private Graph graph;
+ private AVM2Graph graph;
- public GraphPanel(Graph graph) {
+ public GraphPanel(AVM2Graph graph) {
this.graph = graph;
setPreferredSize(new Dimension((BLOCK_WIDTH + SPACE_HORIZONTAL) * getPartWidth(graph.heads.get(0), new HashSet()), (BLOCK_HEIGHT + SPACE_VERTICAL) * getPartHeight(graph.heads.get(0), new ArrayList())));
}
@@ -121,7 +121,7 @@ public class GraphFrame extends JFrame {
}
}
- public GraphFrame(Graph graph, String name) {
+ public GraphFrame(AVM2Graph graph, String name) {
setSize(500, 500);
Container cnt = getContentPane();
cnt.setLayout(new BorderLayout());
diff --git a/trunk/src/com/jpexs/asdec/abc/gui/GraphTreeFrame.java b/trunk/src/com/jpexs/asdec/abc/gui/GraphTreeFrame.java
index 568af4eb7..d1776a490 100644
--- a/trunk/src/com/jpexs/asdec/abc/gui/GraphTreeFrame.java
+++ b/trunk/src/com/jpexs/asdec/abc/gui/GraphTreeFrame.java
@@ -16,8 +16,8 @@
*/
package com.jpexs.asdec.abc.gui;
-import com.jpexs.asdec.abc.avm2.flowgraph.Graph;
-import com.jpexs.asdec.abc.avm2.flowgraph.GraphPart;
+import com.jpexs.asdec.abc.avm2.graph.AVM2Graph;
+import com.jpexs.asdec.graph.GraphPart;
import java.awt.BorderLayout;
import java.awt.Container;
import javax.swing.JFrame;
@@ -34,7 +34,7 @@ public class GraphTreeFrame extends JFrame {
public JTree graphTree;
- public GraphTreeFrame(final Graph graph) {
+ public GraphTreeFrame(final AVM2Graph graph) {
setSize(400, 400);
graphTree = new JTree(new TreeModel() {
public Object getRoot() {
diff --git a/trunk/src/com/jpexs/asdec/abc/types/traits/TraitMethodGetterSetter.java b/trunk/src/com/jpexs/asdec/abc/types/traits/TraitMethodGetterSetter.java
index 3717909fd..e378119d6 100644
--- a/trunk/src/com/jpexs/asdec/abc/types/traits/TraitMethodGetterSetter.java
+++ b/trunk/src/com/jpexs/asdec/abc/types/traits/TraitMethodGetterSetter.java
@@ -17,7 +17,7 @@
package com.jpexs.asdec.abc.types.traits;
import com.jpexs.asdec.abc.ABC;
-import com.jpexs.asdec.abc.avm2.flowgraph.Graph;
+import com.jpexs.asdec.abc.avm2.graph.AVM2Graph;
import com.jpexs.asdec.abc.avm2.treemodel.TreeItem;
import com.jpexs.asdec.abc.types.MethodBody;
import com.jpexs.asdec.helpers.Helper;
diff --git a/trunk/src/com/jpexs/asdec/graph/Graph.java b/trunk/src/com/jpexs/asdec/graph/Graph.java
new file mode 100644
index 000000000..34d85685f
--- /dev/null
+++ b/trunk/src/com/jpexs/asdec/graph/Graph.java
@@ -0,0 +1,170 @@
+package com.jpexs.asdec.graph;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author JPEXS
+ */
+public abstract class Graph {
+ public List heads;
+
+ protected static void populateParts(GraphPart part, List allParts) {
+ if (allParts.contains(part)) {
+ return;
+ }
+ allParts.add(part);
+ for (GraphPart p : part.nextParts) {
+ populateParts(p, allParts);
+ }
+ }
+
+ protected void fixGraph(GraphPart part) {
+ while (fixGraphOnce(part, new ArrayList(), false)) {
+ }
+ }
+
+ private boolean fixGraphOnce(GraphPart part, List visited, boolean doChildren) {
+ if (visited.contains(part)) {
+ return false;
+ }
+ visited.add(part);
+ boolean fixed = false;
+ int i = 1;
+ String lastpref = null;
+ boolean modify = true;
+ int prvni = -1;
+
+ if (!doChildren) {
+
+ List uniqueRefs = new ArrayList();
+ for (GraphPart r : part.refs) {
+ if (!uniqueRefs.contains(r)) {
+ uniqueRefs.add(r);
+ }
+ }
+ loopi:
+ for (; i <= part.path.length(); i++) {
+ lastpref = null;
+ int pos = -1;
+ for (GraphPart r : uniqueRefs) {
+ pos++;
+ if (r.path.startsWith("e")) {
+ continue;
+ }
+ if (part.leadsTo(r, new ArrayList())) {
+ //modify=false;
+ //continue;
+ }
+
+ prvni = pos;
+ if (i > r.path.length()) {
+ i--;
+ break loopi;
+ }
+ if (lastpref == null) {
+ lastpref = r.path.substring(0, i);
+ } else {
+ if (!r.path.startsWith(lastpref)) {
+ i--;
+ break loopi;
+ }
+ }
+ }
+ }
+ if (i > part.path.length()) {
+ i = part.path.length();
+ }
+ if (modify && ((uniqueRefs.size() > 1) && (prvni >= 0))) {
+ String newpath = uniqueRefs.get(prvni).path.substring(0, i);
+ if (!part.path.equals(newpath)) {
+ if (part.path.startsWith(newpath)) {
+ String origPath = part.path;
+ GraphPart p = part;
+ part.path = newpath;
+ while (p.nextParts.size() == 1) {
+ p = p.nextParts.get(0);
+ if (!p.path.equals(origPath)) {
+ break;
+ }
+ p.path = newpath;
+ }
+ fixGraphOnce(part, new ArrayList(), true);
+ fixed = true;
+ }
+ }
+ }
+ } else {
+
+ if (!fixed) {
+ if (part.nextParts.size() == 1) {
+ if (!(part.path.startsWith("e") && (!part.nextParts.get(0).path.startsWith("e")))) {
+ if (part.nextParts.get(0).path.length() > part.path.length()) {
+ part.nextParts.get(0).path = part.path;
+ fixed = true;
+ }
+ }
+ }
+ if (part.nextParts.size() > 1) {
+ for (int j = 0; j < part.nextParts.size(); j++) {
+ GraphPart npart = part.nextParts.get(j);
+
+ if (npart.path.length() > part.path.length() + 1) {
+ npart.path = part.path + "" + j;
+ fixed = true;
+ }
+ }
+ }
+ }
+
+ }
+ for (GraphPart p : part.nextParts) {
+ fixGraphOnce(p, visited, doChildren);
+ }
+ return fixed;
+ }
+
+ protected void makeMulti(GraphPart part, List visited) {
+ if (visited.contains(part)) {
+ return;
+ }
+ visited.add(part);
+ GraphPart p = part;
+ List multiList = new ArrayList();
+ multiList.add(p);
+ while ((p.nextParts.size() == 1) && (p.nextParts.get(0).refs.size() == 1)) {
+ p = p.nextParts.get(0);
+ multiList.add(p);
+ }
+ if (multiList.size() > 1) {
+ GraphPartMulti gpm = new GraphPartMulti(multiList);
+ gpm.refs = part.refs;
+ GraphPart lastPart = multiList.get(multiList.size() - 1);
+ gpm.nextParts = lastPart.nextParts;
+ for (GraphPart next : gpm.nextParts) {
+ int index = next.refs.indexOf(lastPart);
+ if (index == -1) {
+
+ continue;
+ }
+ next.refs.remove(lastPart);
+ next.refs.add(index, gpm);
+ }
+ for (GraphPart parent : part.refs) {
+ if (parent.start == -1) {
+ continue;
+ }
+ int index = parent.nextParts.indexOf(part);
+ if (index == -1) {
+ continue;
+ }
+ parent.nextParts.remove(part);
+ parent.nextParts.add(index, gpm);
+ }
+ }
+ for (int i = 0; i < part.nextParts.size(); i++) {
+ makeMulti(part.nextParts.get(i), visited);
+ }
+ }
+}
diff --git a/trunk/src/com/jpexs/asdec/abc/avm2/flowgraph/GraphPart.java b/trunk/src/com/jpexs/asdec/graph/GraphPart.java
similarity index 93%
rename from trunk/src/com/jpexs/asdec/abc/avm2/flowgraph/GraphPart.java
rename to trunk/src/com/jpexs/asdec/graph/GraphPart.java
index 87ffd547b..90853466b 100644
--- a/trunk/src/com/jpexs/asdec/abc/avm2/flowgraph/GraphPart.java
+++ b/trunk/src/com/jpexs/asdec/graph/GraphPart.java
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package com.jpexs.asdec.abc.avm2.flowgraph;
+package com.jpexs.asdec.graph;
import com.jpexs.asdec.abc.avm2.treemodel.ContinueTreeItem;
import java.util.ArrayList;
@@ -37,7 +37,7 @@ public class GraphPart {
public String path="";
public List refs=new ArrayList();
public boolean ignored=false;
- public List forContinues=new ArrayList();
+ public List