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

2
Decompiler.sln

@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 9.00 Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005 # 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}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Decompiler", "Decompiler.csproj", "{EE3A3C1A-F9C3-4C75-853D-A9476E518C3A}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil", "lib\cecil-0.6\src\Mono.Cecil\Mono.Cecil.csproj", "{D8F63DFF-5230-43E4-9AB2-DA6E721A1FAE}" 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
StackExpressionCollection exprCollection = new StackExpressionCollection(body); StackExpressionCollection exprCollection = new StackExpressionCollection(body);
exprCollection.Optimize(); exprCollection.Optimize();
BasicBlockSet basicBlockSet = new BasicBlockSet(exprCollection); ControlFlow.MethodBodyGraph bodyGraph = new ControlFlow.MethodBodyGraph(exprCollection);
foreach(VariableDefinition varDef in methodDef.Body.Variables) { foreach(VariableDefinition varDef in methodDef.Body.Variables) {
localVarTypes[varDef.Name] = varDef.VariableType; localVarTypes[varDef.Name] = varDef.VariableType;
@ -37,11 +37,11 @@ namespace Decompiler
// astBlock.Children.Add(astLocalVar); // astBlock.Children.Add(astLocalVar);
} }
for(int b = 0; b < basicBlockSet.Childs.Count; b++) { for(int b = 0; b < bodyGraph.Childs.Count; b++) {
BasicBlock basicBlock = (BasicBlock)basicBlockSet.Childs[b]; ControlFlow.BasicBlock node = (ControlFlow.BasicBlock)bodyGraph.Childs[b];
astBlock.Children.Add(MakeComment(basicBlock.ToString())); astBlock.Children.Add(MakeComment(node.ToString()));
for(int i = 0; i < basicBlock.Body.Count; i++) { for(int i = 0; i < node.Body.Count; i++) {
StackExpression expr = basicBlock.Body[i]; StackExpression expr = node.Body[i];
Ast.Statement astStatement = null; Ast.Statement astStatement = null;
try { try {
List<Ast.Expression> args = new List<Ast.Expression>(); List<Ast.Expression> args = new List<Ast.Expression>();

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

@ -2,7 +2,7 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
namespace Decompiler namespace Decompiler.ControlFlow
{ {
public class Set<T>: System.Collections.ObjectModel.Collection<T> public class Set<T>: System.Collections.ObjectModel.Collection<T>
{ {
@ -54,75 +54,6 @@ namespace Decompiler
{ {
this.parent = parent; 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() public void Optimize()
{ {
@ -132,7 +63,7 @@ namespace Decompiler
foreach(Node child in this.Childs) { foreach(Node child in this.Childs) {
if (child.Predecessors.Count == 1) { if (child.Predecessors.Count == 1) {
Node predecessor = child.Predecessors[0]; Node predecessor = child.Predecessors[0];
MergeNodes(predecessor, child); MergeChilds(predecessor, child);
optimized = true; optimized = true;
break; // Collection was modified; restart break; // Collection was modified; restart
} }
@ -140,48 +71,44 @@ namespace Decompiler
} while (optimized); } while (optimized);
} }
static void MergeNodes(Node head, Node tail) static void MergeChilds(Node head, Node tail)
{ {
if (head == null) throw new ArgumentNullException("head"); if (head == null) throw new ArgumentNullException("head");
if (tail == null) throw new ArgumentNullException("tail"); if (tail == null) throw new ArgumentNullException("tail");
if (head.Parent != tail.Parent) throw new ArgumentException("different parents"); if (head.Parent != tail.Parent) throw new ArgumentException("different parents");
Node container = head.Parent; Node container = head.Parent;
BasicBlockSet mergedNode = new BasicBlockSet(container); Node mergedNode;
// Get type // Get type
if (tail.Successors.Contains(head)) { if (tail.Successors.Contains(head)) {
mergedNode.type = BasicBlockSetType.Loop; mergedNode = new Loop(container);
} else { } else {
mergedNode.type = BasicBlockSetType.Acyclic; mergedNode = new AcyclicGraph(container);
} }
BasicBlockSet headAsSet = head as BasicBlockSet;
BasicBlockSet tailAsSet = tail as BasicBlockSet;
// Add head // Add head
if (head is BasicBlock) { if (head is BasicBlock) {
mergedNode.HeadChild = head; mergedNode.HeadChild = head;
mergedNode.Childs.Add(head); mergedNode.Childs.Add(head);
} else if (headAsSet != null && headAsSet.type == BasicBlockSetType.Acyclic) { } else if (head is AcyclicGraph) {
mergedNode.HeadChild = headAsSet.HeadChild; mergedNode.HeadChild = ((AcyclicGraph)head).HeadChild;
mergedNode.Childs.AddRange(headAsSet.Childs); mergedNode.Childs.AddRange(((AcyclicGraph)head).Childs);
} else if (headAsSet != null && headAsSet.type == BasicBlockSetType.Loop) { } else if (head is Loop) {
mergedNode.HeadChild = headAsSet; mergedNode.HeadChild = head;
mergedNode.Childs.Add(headAsSet); mergedNode.Childs.Add(head);
} else { } else {
throw new Exception("Invalid head"); throw new Exception("Invalid head type");
} }
// Add tail // Add tail
if (tail is BasicBlock) { if (tail is BasicBlock) {
mergedNode.Childs.Add(tail); mergedNode.Childs.Add(tail);
} else if (tailAsSet != null && tailAsSet.type == BasicBlockSetType.Acyclic) { } else if (tail is AcyclicGraph) {
mergedNode.Childs.AddRange(tailAsSet.Childs); mergedNode.Childs.AddRange(((AcyclicGraph)tail).Childs);
} else if (tailAsSet != null && tailAsSet.type == BasicBlockSetType.Loop) { } else if (tail is Loop) {
mergedNode.Childs.Add(tailAsSet); mergedNode.Childs.Add(tail);
} else { } else {
throw new Exception("Invalid tail"); throw new Exception("Invalid tail type");
} }
// Remove links between the head and tail // Remove links between the head and tail

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