Skip to content

Commit

Permalink
Adding code for Endless loop types, but it's not working right now
Browse files Browse the repository at this point in the history
  • Loading branch information
Frank Laub committed Jan 31, 2010
1 parent bcb3bbf commit eff63f2
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 27 deletions.
13 changes: 13 additions & 0 deletions src/DotWeb.Decompiler/Core/BasicBlock.cs
Expand Up @@ -22,6 +22,7 @@
using Mono.Cecil.Cil;
using Mono.Cecil;
using DotWeb.Utility.Cecil;
using System.Text;

namespace DotWeb.Decompiler.Core
{
Expand All @@ -34,6 +35,18 @@ class BasicBlock : Node
}
}

public string ToStringDetails() {
var sb = new StringBuilder(this.ToString());
sb.AppendLine();
foreach (var cil in this.Instructions) {
sb.Append("\t");
sb.Append(cil.DisplayString());
sb.AppendLine();
}
return sb.ToString();
}


public List<CodeStatement> Statements { get; private set; }

public List<Instruction> Instructions { get; private set; }
Expand Down
26 changes: 21 additions & 5 deletions src/DotWeb.Decompiler/Core/ControlFlowAnalyzer.cs
Expand Up @@ -287,9 +287,7 @@ private bool IsSuccessor(int successor, int header)
}

private void StructureLoops() {
int level = 0;
foreach (var graph in this.Cfg.Graphs) {
level++;
foreach (Interval interval in graph.Nodes) {
// Find nodes that belong to the interval (nodes from G1)
List<Node> nodes = new List<Node>();
Expand Down Expand Up @@ -350,6 +348,11 @@ private bool IsSuccessor(int successor, int header)
}
}

latchNode.LoopHead = headerNode.LoopHead;
if (latchNode != headerNode) {
loopNodes.Add(latchNode.DfsPostOrder);
}

ClassifyLoop(headerNode, latchNode, loopNodes);
}

Expand All @@ -359,7 +362,6 @@ private bool IsSuccessor(int successor, int header)
if (headerNode.Successors.Count > 1)
elseDfs = headerNode.ElseEdge.DfsPostOrder;

latchNode.LoopHead = headerNode.LoopHead;
if (latchNode.IsTwoWay) {
if ((headerNode.IsTwoWay) || (latchNode == headerNode)) {
if ((latchNode == headerNode) ||
Expand Down Expand Up @@ -407,7 +409,7 @@ private bool IsSuccessor(int successor, int header)
* loop, so it is safer to consider it an endless loop */
if (node.DfsPostOrder <= headerNode.DfsPostOrder) {
headerNode.LoopType = LoopType.Endless;
// findEndlessFollow();
FindEndlessFollow(loopNodes, headerNode);
break;
}

Expand All @@ -421,7 +423,21 @@ private bool IsSuccessor(int successor, int header)
}
else {
headerNode.LoopType = LoopType.Endless;
// findEndlessFollow();
FindEndlessFollow(loopNodes, headerNode);
}
}
}

private void FindEndlessFollow(List<int> loopNodes, BasicBlock head) {
head.LoopFollow = int.MaxValue;

foreach (var i in loopNodes) {
var node = this.Cfg.DepthFirstPostOrder[i];
foreach (var succ in node.Successors) {
if (!loopNodes.Contains(succ.DfsPostOrder) &&
(succ.DfsPostOrder < head.LoopFollow)) {
head.LoopFollow = succ.DfsPostOrder;
}
}
}
}
Expand Down
23 changes: 12 additions & 11 deletions src/DotWeb.Decompiler/Core/ControlFlowGraph.cs
Expand Up @@ -23,6 +23,7 @@
using Mono.Cecil;
using Mono.Cecil.Cil;
using DotWeb.Utility.Cecil;
using System.Diagnostics;

namespace DotWeb.Decompiler.Core
{
Expand Down Expand Up @@ -62,6 +63,8 @@ class ControlFlowGraph
private void CreateBlocks(Dictionary<int, BasicBlock> blocksByOffset) {
BasicBlock lastBlock = null;
foreach (Instruction cil in Method.Body.Instructions) {
Debug.Assert(cil.OpCode.FlowControl != FlowControl.Break);

if (cil.OpCode.OperandType == OperandType.InlineSwitch)
this.HasCases = true;

Expand All @@ -85,6 +88,7 @@ class ControlFlowGraph

private void Merge(BasicBlock bb) {
while (bb.FlowControl != FlowControl.Cond_Branch &&
bb.FlowControl != FlowControl.Branch &&
bb.FlowControl != FlowControl.Return &&
bb.FlowControl != FlowControl.Throw) {
BasicBlock next = (BasicBlock)bb.Successors.First();
Expand Down Expand Up @@ -132,18 +136,15 @@ class ControlFlowGraph

public override string ToString() {
StringBuilder sb = new StringBuilder();
if (Graphs != null) {
foreach (BasicBlock block in this.BasicGraph.Nodes) {
sb.AppendLine(block.ToString());
}
foreach (BasicBlock block in this.BasicGraph.Nodes) {
sb.AppendLine(block.ToStringDetails());
}
else {
int i = 0;
foreach (var graph in Graphs) {
sb.AppendFormat("Level: {0}\n", i++);
foreach (var interval in graph.Nodes) {
sb.AppendLine(interval.ToString());
}

int i = 0;
foreach (var graph in Graphs) {
sb.AppendFormat("Level: {0}\n", i++);
foreach (var interval in graph.Nodes) {
sb.AppendLine(interval.ToString());
}
}
return sb.ToString();
Expand Down
5 changes: 3 additions & 2 deletions src/DotWeb.Decompiler/MethodDecompiler.cs
Expand Up @@ -28,10 +28,11 @@ namespace DotWeb.Decompiler
public static class MethodDecompiler
{
public static CodeMethodMember Parse(TypeSystem typeHierarchy, MethodDefinition method) {
Console.WriteLine(method);

var cfg = new ControlFlowGraph(typeHierarchy, method);
#if DEBUG
Console.WriteLine(method);
Console.WriteLine(cfg);
#endif

var cfa = new ControlFlowAnalyzer(cfg);
cfa.Structure();
Expand Down
14 changes: 14 additions & 0 deletions test/DotWeb.Translator.Test/IntervalTests.cs
Expand Up @@ -171,6 +171,20 @@ class GraphBuilder
builder.Test("L1, i1, n1, n2, n3");
}

[Test]
public void WhileBreak() {
var builder = new GraphBuilder(4);
builder.Connect(1, 2);
builder.Connect(2, 3);
builder.Connect(3, 2);
builder.Connect(2, 4);
builder.Test(
"L1, i1, n1",
"L1, i2, n2, n3, n4",
"L2, i1, n1, n2, n3, n4"
);
}

[Test]
public void DragonBook() {
// Taken from the Dragon book, Page 661, Example 10.30, Fig. 10.45
Expand Down
20 changes: 11 additions & 9 deletions test/DotWeb.Translator.Test/Script/Loops.cs
Expand Up @@ -42,11 +42,12 @@ class Loops
public void BreakInWhile(int a) {
while (a < 100) {
if (a == 12) {
Console.WriteLine(a);
Console.WriteLine("break");
break;
}
else
Console.WriteLine(a);
else {
Console.WriteLine("else");
}

a--;
}
Expand All @@ -56,27 +57,28 @@ class Loops
public void WhileBreak() {
int i = 0;
while (true) {
i = 20;
if (i == 10) {
Console.WriteLine(i);
Console.WriteLine("break");
break;
}
Console.WriteLine(i);
Console.WriteLine("loop");
i++;
}
Console.WriteLine(i);
Console.WriteLine("exit");
}

public void WhileCondBreak() {
int i = 0;
while (i < 9) {
if (i == 10) {
Console.WriteLine(i);
Console.WriteLine("break");
break;
}
Console.WriteLine(i);
Console.WriteLine("loop");
i++;
}
Console.WriteLine(i);
Console.WriteLine("exit");
}
}
}

0 comments on commit eff63f2

Please sign in to comment.