diff --git a/Decompiler.csproj b/Decompiler.csproj
index 9a315da95..83db650ab 100644
--- a/Decompiler.csproj
+++ b/Decompiler.csproj
@@ -50,6 +50,7 @@
+
MainForm.cs
diff --git a/src/AstMetodBodyBuilder.cs b/src/AstMetodBodyBuilder.cs
index b95868e66..d539825c8 100644
--- a/src/AstMetodBodyBuilder.cs
+++ b/src/AstMetodBodyBuilder.cs
@@ -22,8 +22,10 @@ namespace Decompiler
methodDef.Body.Simplify();
ByteCodeCollection body = new ByteCodeCollection(methodDef);
- StackExpressionCollection exprCol = new StackExpressionCollection(body);
- exprCol.Optimize();
+ StackExpressionCollection exprCollection = new StackExpressionCollection(body);
+ exprCollection.Optimize();
+
+ BasicBlockSet basicBlockSet = new BasicBlockSet(exprCollection);
foreach(VariableDefinition varDef in methodDef.Body.Variables) {
localVarTypes[varDef.Name] = varDef.VariableType;
@@ -35,43 +37,47 @@ namespace Decompiler
// astBlock.Children.Add(astLocalVar);
}
- for(int i = 0; i < exprCol.Count; i++) {
- StackExpression expr = exprCol[i];
- Ast.Statement astStatement = null;
- try {
- List args = new List();
- foreach(CilStackSlot stackSlot in expr.StackBefore.PeekCount(expr.PopCount)) {
- string name = string.Format("expr{0:X2}", stackSlot.AllocadedBy.Offset);
- args.Add(new Ast.IdentifierExpression(name));
- }
- object codeExpr = MakeCodeDomExpression(methodDef, expr, args.ToArray());
- if (codeExpr is Ast.Expression) {
- if (expr.PushCount == 1) {
- string type = expr.ExpressionByteCode.Type.FullName;
- string name = string.Format("expr{0:X2}", expr.ExpressionByteCode.Offset);
- Ast.LocalVariableDeclaration astLocal = new Ast.LocalVariableDeclaration(new Ast.TypeReference(type.ToString()));
- astLocal.Variables.Add(new Ast.VariableDeclaration(name, (Ast.Expression)codeExpr));
- astStatement = astLocal;
- } else {
- astStatement = new ExpressionStatement((Ast.Expression)codeExpr);
+ for(int b = 0; b < basicBlockSet.Elements.Count; b++) {
+ BasicBlock basicBlock = (BasicBlock)basicBlockSet.Elements[b];
+ astBlock.Children.Add(MakeComment(basicBlock.ToString()));
+ for(int i = 0; i < basicBlock.Body.Count; i++) {
+ StackExpression expr = basicBlock.Body[i];
+ Ast.Statement astStatement = null;
+ try {
+ List args = new List();
+ foreach(CilStackSlot stackSlot in expr.StackBefore.PeekCount(expr.PopCount)) {
+ string name = string.Format("expr{0:X2}", stackSlot.AllocadedBy.Offset);
+ args.Add(new Ast.IdentifierExpression(name));
+ }
+ object codeExpr = MakeCodeDomExpression(methodDef, expr, args.ToArray());
+ if (codeExpr is Ast.Expression) {
+ if (expr.PushCount == 1) {
+ string type = expr.LastByteCode.Type.FullName;
+ string name = string.Format("expr{0:X2}", expr.LastByteCode.Offset);
+ Ast.LocalVariableDeclaration astLocal = new Ast.LocalVariableDeclaration(new Ast.TypeReference(type.ToString()));
+ astLocal.Variables.Add(new Ast.VariableDeclaration(name, (Ast.Expression)codeExpr));
+ astStatement = astLocal;
+ } else {
+ astStatement = new ExpressionStatement((Ast.Expression)codeExpr);
+ }
+ } else if (codeExpr is Ast.Statement) {
+ astStatement = (Ast.Statement)codeExpr;
}
- } else if (codeExpr is Ast.Statement) {
- astStatement = (Ast.Statement)codeExpr;
+ } catch (NotImplementedException) {
+ astStatement = MakeComment(expr.LastByteCode.Description);
}
- } catch (NotImplementedException) {
- astStatement = MakeComment(expr.ExpressionByteCode.Description);
- }
- if (expr.IsBranchTarget) {
- astBlock.Children.Add(new Ast.LabelStatement(string.Format("IL_{0:X2}", expr.FirstByteCode.Offset)));
- }
- // Skip last return statement
- if (i == exprCol.Count - 1 &&
- expr.ExpressionByteCode.OpCode.Code == Code.Ret &&
- expr.ExpressionByteCode.PopCount == 0 &&
- !expr.IsBranchTarget) {
- continue;
+ if (expr.IsBranchTarget) {
+ astBlock.Children.Add(new Ast.LabelStatement(string.Format("IL_{0:X2}", expr.FirstByteCode.Offset)));
+ }
+ // Skip last return statement
+// if (i == exprCol.Count - 1 &&
+// expr.LastByteCode.OpCode.Code == Code.Ret &&
+// expr.LastByteCode.PopCount == 0 &&
+// !expr.IsBranchTarget) {
+// continue;
+// }
+ astBlock.Children.Add(astStatement);
}
- astBlock.Children.Add(astStatement);
}
return astBlock;
@@ -79,7 +85,7 @@ namespace Decompiler
static Ast.ExpressionStatement MakeComment(string text)
{
- text = "/*" + text + "*/";
+ text = "/* " + text + "*/";
return new Ast.ExpressionStatement(new PrimitiveExpression(text, text));
}
@@ -97,7 +103,7 @@ namespace Decompiler
allArgs.Add(astExpr);
}
}
- return MakeCodeDomExpression(methodDef, expr.ExpressionByteCode, allArgs.ToArray());
+ return MakeCodeDomExpression(methodDef, expr.LastByteCode, allArgs.ToArray());
}
static object MakeCodeDomExpression(MethodDefinition methodDef, ByteCode byteCode, params Ast.Expression[] args)
diff --git a/src/ByteCode.cs b/src/ByteCode.cs
index 470305ffe..c73e7908a 100644
--- a/src/ByteCode.cs
+++ b/src/ByteCode.cs
@@ -9,6 +9,7 @@ namespace Decompiler
{
public partial class ByteCode
{
+ StackExpression owner;
ByteCode previous;
ByteCode next;
@@ -17,6 +18,11 @@ namespace Decompiler
OpCode opCode;
object operand;
+ public StackExpression Owner {
+ get { return owner; }
+ set { owner = value; }
+ }
+
public ByteCode Previous {
get { return previous; }
set { previous = value; }
@@ -44,7 +50,7 @@ namespace Decompiler
public ByteCode BranchTarget {
get {
- return (ByteCode)operand;
+ return operand as ByteCode;
}
}
@@ -66,7 +72,7 @@ namespace Decompiler
public string Description {
get {
return string.Format(
- " {1, -22} # {2}->{3} {4} {5}",
+ "{1, -22} # {2}->{3} {4} {5}",
this.Offset,
this.OpCode + " " + FormatByteCodeOperand(this.Operand),
this.OpCode.StackBehaviourPop,
diff --git a/src/ControlFlow.cs b/src/ControlFlow.cs
new file mode 100644
index 000000000..291399b82
--- /dev/null
+++ b/src/ControlFlow.cs
@@ -0,0 +1,187 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Decompiler
+{
+ public class Set: List
+ {
+
+ }
+
+
+ public class BasicBlock
+ {
+ int id;
+ BasicBlockSet owner;
+ Set predecessors;
+ public Set successors;
+ BasicBlock fallThroughSuccessor;
+ BasicBlock branchSuccessor;
+ List body = new List();
+
+ #region Peoperties
+
+ public int Id {
+ get { return id; }
+ set { id = value; }
+ }
+
+ public BasicBlockSet Owner {
+ get { return owner; }
+ set { owner = value; }
+ }
+
+ public Set Predecessors {
+ get { return predecessors; }
+ set { predecessors = value; }
+ }
+
+ public Set Successors {
+ get { return successors; }
+ set { successors = value; }
+ }
+
+ public BasicBlock FallThroughSuccessor {
+ get { return fallThroughSuccessor; }
+ set { fallThroughSuccessor = value; }
+ }
+
+ public BasicBlock BranchSuccessor {
+ get { return branchSuccessor; }
+ set { branchSuccessor = value; }
+ }
+
+ public List Body {
+ get { return body; }
+ set { body = value; }
+ }
+
+ #endregion
+
+ public override string ToString()
+ {
+ //return string.Format("BackBlock {0} ({1} expressions)", id, body.Count);
+ return string.Format("BackBlock {0}", id, body.Count);
+ }
+ }
+
+ public enum BasicBlockSetType {
+ MethodBody,
+ Acyclic,
+ Loop,
+ }
+
+ public class BasicBlockSet
+ {
+ BasicBlockSet owner;
+ BasicBlockSetType type;
+
+ object head;
+ Set