Browse Source

Create class for each node type

pull/1/head^2
David Srbecký 18 years ago
parent
commit
0bff44d922
  1. 4
      Decompiler.csproj
  2. 2
      Decompiler.sln
  3. 12
      src/AstMetodBodyBuilder.cs
  4. 109
      src/ControlFlow/Node.cs
  5. 68
      src/ControlFlow/Nodes.cs

4
Decompiler.csproj

@ -36,6 +36,7 @@ @@ -36,6 +36,7 @@
</ItemGroup>
<ItemGroup>
<Folder Include="src" />
<Folder Include="src\ControlFlow" />
<Compile Include="src\AssemblyInfo.cs" />
<Compile Include="src\AstBuilder.cs" />
<Compile Include="src\AstMetodBodyBuilder.cs" />
@ -44,13 +45,14 @@ @@ -44,13 +45,14 @@
<Compile Include="src\ByteCode.Type.cs" />
<Compile Include="src\ByteCodeCollection.cs" />
<Compile Include="src\CilStack.cs" />
<Compile Include="src\ControlFlow\Nodes.cs" />
<Compile Include="src\ControlFlow\Node.cs" />
<Compile Include="src\MainForm.cs" />
<Compile Include="src\MainForm.Designer.cs" />
<Compile Include="src\Program.cs" />
<Compile Include="src\ByteCode.StackAnalysis.cs" />
<Compile Include="src\StackExpression.cs" />
<Compile Include="src\StackExpressionCollection.cs" />
<Compile Include="src\ControlFlow.cs" />
<Compile Include="src\Util.cs" />
<EmbeddedResource Include="src\MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>

2
Decompiler.sln

@ -1,7 +1,7 @@ @@ -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}"

12
src/AstMetodBodyBuilder.cs

@ -25,7 +25,7 @@ namespace Decompiler @@ -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 @@ -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<Ast.Expression> args = new List<Ast.Expression>();

109
src/ControlFlow.cs → src/ControlFlow/Node.cs

@ -2,7 +2,7 @@ using System; @@ -2,7 +2,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
namespace Decompiler
namespace Decompiler.ControlFlow
{
public class Set<T>: System.Collections.ObjectModel.Collection<T>
{
@ -54,75 +54,6 @@ namespace Decompiler @@ -54,75 +54,6 @@ namespace Decompiler
{
this.parent = parent;
}
}
public class BasicBlock: Node
{
int id;
List<StackExpression> body = new List<StackExpression>();
public int Id {
get { return id; }
}
public List<StackExpression> 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 @@ -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 @@ -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

68
src/ControlFlow/Nodes.cs

@ -0,0 +1,68 @@ @@ -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<StackExpression> body = new List<StackExpression>();
public int Id {
get { return id; }
}
public List<StackExpression> 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);
}
}
}
Loading…
Cancel
Save