diff --git a/Decompiler.csproj b/Decompiler.csproj index 83db650ab..dec6cf25a 100644 --- a/Decompiler.csproj +++ b/Decompiler.csproj @@ -36,6 +36,7 @@ + @@ -44,13 +45,14 @@ + + - MainForm.cs diff --git a/Decompiler.sln b/Decompiler.sln index 281cd4d99..ae4af9b72 100644 --- a/Decompiler.sln +++ b/Decompiler.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 -# SharpDevelop 3.0.0.2707 +# SharpDevelop 3.0.0.2909 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Decompiler", "Decompiler.csproj", "{EE3A3C1A-F9C3-4C75-853D-A9476E518C3A}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil", "lib\cecil-0.6\src\Mono.Cecil\Mono.Cecil.csproj", "{D8F63DFF-5230-43E4-9AB2-DA6E721A1FAE}" diff --git a/src/AstMetodBodyBuilder.cs b/src/AstMetodBodyBuilder.cs index 49c53fb65..7e4ea70ed 100644 --- a/src/AstMetodBodyBuilder.cs +++ b/src/AstMetodBodyBuilder.cs @@ -25,7 +25,7 @@ namespace Decompiler StackExpressionCollection exprCollection = new StackExpressionCollection(body); exprCollection.Optimize(); - BasicBlockSet basicBlockSet = new BasicBlockSet(exprCollection); + ControlFlow.MethodBodyGraph bodyGraph = new ControlFlow.MethodBodyGraph(exprCollection); foreach(VariableDefinition varDef in methodDef.Body.Variables) { localVarTypes[varDef.Name] = varDef.VariableType; @@ -37,11 +37,11 @@ namespace Decompiler // astBlock.Children.Add(astLocalVar); } - for(int b = 0; b < basicBlockSet.Childs.Count; b++) { - BasicBlock basicBlock = (BasicBlock)basicBlockSet.Childs[b]; - astBlock.Children.Add(MakeComment(basicBlock.ToString())); - for(int i = 0; i < basicBlock.Body.Count; i++) { - StackExpression expr = basicBlock.Body[i]; + for(int b = 0; b < bodyGraph.Childs.Count; b++) { + ControlFlow.BasicBlock node = (ControlFlow.BasicBlock)bodyGraph.Childs[b]; + astBlock.Children.Add(MakeComment(node.ToString())); + for(int i = 0; i < node.Body.Count; i++) { + StackExpression expr = node.Body[i]; Ast.Statement astStatement = null; try { List args = new List(); diff --git a/src/ControlFlow.cs b/src/ControlFlow/Node.cs similarity index 52% rename from src/ControlFlow.cs rename to src/ControlFlow/Node.cs index 8fa08ec08..926840b48 100644 --- a/src/ControlFlow.cs +++ b/src/ControlFlow/Node.cs @@ -2,7 +2,7 @@ using System; using System.Collections; using System.Collections.Generic; -namespace Decompiler +namespace Decompiler.ControlFlow { public class Set: System.Collections.ObjectModel.Collection { @@ -54,75 +54,6 @@ namespace Decompiler { this.parent = parent; } - } - - public class BasicBlock: Node - { - int id; - List body = new List(); - - public int Id { - get { return id; } - } - - public List Body { - get { return body; } - } - - public BasicBlock(Node parent, int id): base(parent) - { - this.id = id; - } - - public override string ToString() - { - return string.Format("BasicBlock {0}", id, body.Count); - } - } - - public enum BasicBlockSetType { - MethodBody, - Acyclic, - Loop, - } - - // TODO: Split into two classes? - public class BasicBlockSet: Node - { - BasicBlockSetType type; - - public BasicBlockSetType Type { - get { return type; } - } - - BasicBlockSet(Node parent): base(parent) - { - - } - - // TODO: Add links between the generated BasicBlocks - public BasicBlockSet(StackExpressionCollection exprs): base(null) - { - if (exprs.Count == 0) throw new ArgumentException("Count == 0", "exprs"); - - this.type = BasicBlockSetType.MethodBody; - - BasicBlock basicBlock = null; - int basicBlockId = 1; - for(int i = 0; i < exprs.Count; i++) { - // Start new basic block if - // - this is first expression - // - last expression was branch - // - this expression is branch target - if (i == 0 || exprs[i - 1].BranchTarget != null || exprs[i].BranchesHere.Count > 0){ - basicBlock = new BasicBlock(this, basicBlockId++); - this.Childs.Add(basicBlock); - } - basicBlock.Body.Add(exprs[i]); - } - - this.HeadChild = this.Childs[0]; - } public void Optimize() { @@ -132,7 +63,7 @@ namespace Decompiler foreach(Node child in this.Childs) { if (child.Predecessors.Count == 1) { Node predecessor = child.Predecessors[0]; - MergeNodes(predecessor, child); + MergeChilds(predecessor, child); optimized = true; break; // Collection was modified; restart } @@ -140,48 +71,44 @@ namespace Decompiler } while (optimized); } - static void MergeNodes(Node head, Node tail) + static void MergeChilds(Node head, Node tail) { if (head == null) throw new ArgumentNullException("head"); if (tail == null) throw new ArgumentNullException("tail"); if (head.Parent != tail.Parent) throw new ArgumentException("different parents"); Node container = head.Parent; - BasicBlockSet mergedNode = new BasicBlockSet(container); - + Node mergedNode; // Get type if (tail.Successors.Contains(head)) { - mergedNode.type = BasicBlockSetType.Loop; + mergedNode = new Loop(container); } else { - mergedNode.type = BasicBlockSetType.Acyclic; + mergedNode = new AcyclicGraph(container); } - BasicBlockSet headAsSet = head as BasicBlockSet; - BasicBlockSet tailAsSet = tail as BasicBlockSet; - // Add head if (head is BasicBlock) { mergedNode.HeadChild = head; mergedNode.Childs.Add(head); - } else if (headAsSet != null && headAsSet.type == BasicBlockSetType.Acyclic) { - mergedNode.HeadChild = headAsSet.HeadChild; - mergedNode.Childs.AddRange(headAsSet.Childs); - } else if (headAsSet != null && headAsSet.type == BasicBlockSetType.Loop) { - mergedNode.HeadChild = headAsSet; - mergedNode.Childs.Add(headAsSet); + } else if (head is AcyclicGraph) { + mergedNode.HeadChild = ((AcyclicGraph)head).HeadChild; + mergedNode.Childs.AddRange(((AcyclicGraph)head).Childs); + } else if (head is Loop) { + mergedNode.HeadChild = head; + mergedNode.Childs.Add(head); } else { - throw new Exception("Invalid head"); + throw new Exception("Invalid head type"); } // Add tail if (tail is BasicBlock) { mergedNode.Childs.Add(tail); - } else if (tailAsSet != null && tailAsSet.type == BasicBlockSetType.Acyclic) { - mergedNode.Childs.AddRange(tailAsSet.Childs); - } else if (tailAsSet != null && tailAsSet.type == BasicBlockSetType.Loop) { - mergedNode.Childs.Add(tailAsSet); + } else if (tail is AcyclicGraph) { + mergedNode.Childs.AddRange(((AcyclicGraph)tail).Childs); + } else if (tail is Loop) { + mergedNode.Childs.Add(tail); } else { - throw new Exception("Invalid tail"); + throw new Exception("Invalid tail type"); } // Remove links between the head and tail diff --git a/src/ControlFlow/Nodes.cs b/src/ControlFlow/Nodes.cs new file mode 100644 index 000000000..8d93c41cd --- /dev/null +++ b/src/ControlFlow/Nodes.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; + +namespace Decompiler.ControlFlow +{ + public class MethodBodyGraph: Node + { + // TODO: Add links between the generated BasicBlocks + public MethodBodyGraph(StackExpressionCollection exprs): base(null) + { + if (exprs.Count == 0) throw new ArgumentException("Count == 0", "exprs"); + + BasicBlock basicBlock = null; + int basicBlockId = 1; + for(int i = 0; i < exprs.Count; i++) { + // Start new basic block if + // - this is first expression + // - last expression was branch + // - this expression is branch target + if (i == 0 || exprs[i - 1].BranchTarget != null || exprs[i].BranchesHere.Count > 0){ + basicBlock = new BasicBlock(this, basicBlockId++); + this.Childs.Add(basicBlock); + } + basicBlock.Body.Add(exprs[i]); + } + + this.HeadChild = this.Childs[0]; + } + } + + public class AcyclicGraph: Node + { + public AcyclicGraph(Node parent): base(parent){ + + } + } + + public class Loop: Node + { + public Loop(Node parent): base(parent){ + + } + } + + public class BasicBlock: Node + { + int id; + List body = new List(); + + public int Id { + get { return id; } + } + + public List Body { + get { return body; } + } + + public BasicBlock(Node parent, int id): base(parent) + { + this.id = id; + } + + public override string ToString() + { + return string.Format("BasicBlock {0}", id, body.Count); + } + } +}