mirror of https://github.com/icsharpcode/ILSpy.git
6 changed files with 278 additions and 51 deletions
@ -0,0 +1,187 @@
@@ -0,0 +1,187 @@
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace Decompiler |
||||
{ |
||||
public class Set<T>: List<T> |
||||
{ |
||||
|
||||
} |
||||
|
||||
|
||||
public class BasicBlock |
||||
{ |
||||
int id; |
||||
BasicBlockSet owner; |
||||
Set<BasicBlock> predecessors; |
||||
public Set<BasicBlock> successors; |
||||
BasicBlock fallThroughSuccessor; |
||||
BasicBlock branchSuccessor; |
||||
List<StackExpression> body = new List<StackExpression>(); |
||||
|
||||
#region Peoperties
|
||||
|
||||
public int Id { |
||||
get { return id; } |
||||
set { id = value; } |
||||
} |
||||
|
||||
public BasicBlockSet Owner { |
||||
get { return owner; } |
||||
set { owner = value; } |
||||
} |
||||
|
||||
public Set<BasicBlock> Predecessors { |
||||
get { return predecessors; } |
||||
set { predecessors = value; } |
||||
} |
||||
|
||||
public Set<BasicBlock> 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<StackExpression> 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<object> elements = new Set<object>(); |
||||
|
||||
Set<BasicBlock> BasicBlockSuccessors; |
||||
|
||||
BasicBlock headBasicBlock { |
||||
get { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public BasicBlockSet Owner { |
||||
get { return owner; } |
||||
} |
||||
|
||||
public BasicBlockSetType Type { |
||||
get { return type; } |
||||
} |
||||
|
||||
public object Head { |
||||
get { return head; } |
||||
} |
||||
|
||||
public Set<object> Elements { |
||||
get { return elements; } |
||||
} |
||||
|
||||
|
||||
BasicBlockSet() |
||||
{ |
||||
|
||||
} |
||||
|
||||
public BasicBlockSet(object head, object tail) |
||||
{ |
||||
if (head == null) throw new ArgumentNullException("head"); |
||||
if (tail == null) throw new ArgumentNullException("tail"); |
||||
|
||||
BasicBlockSet headAsSet = head as BasicBlockSet; |
||||
BasicBlockSet tailAsSet = tail as BasicBlockSet; |
||||
|
||||
// Add head
|
||||
if (head is BasicBlock) { |
||||
this.head = head; |
||||
this.elements.Add(head); |
||||
} else if (headAsSet != null && headAsSet.type == BasicBlockSetType.Acyclic) { |
||||
this.head = headAsSet.head; |
||||
this.elements.AddRange(headAsSet.elements); |
||||
} else if (headAsSet != null && headAsSet.type == BasicBlockSetType.Loop) { |
||||
this.head = headAsSet; |
||||
this.elements.Add(headAsSet); |
||||
} else { |
||||
throw new Exception("Invalid head"); |
||||
} |
||||
|
||||
// Add tail
|
||||
if (tail is BasicBlock) { |
||||
this.elements.Add(tail); |
||||
} else if (tailAsSet != null && tailAsSet.type == BasicBlockSetType.Acyclic) { |
||||
this.elements.AddRange(tailAsSet.elements); |
||||
} else if (tailAsSet != null && tailAsSet.type == BasicBlockSetType.Loop) { |
||||
this.elements.Add(tailAsSet); |
||||
} else { |
||||
throw new Exception("Invalid tail"); |
||||
} |
||||
|
||||
// Get type
|
||||
if (tail is BasicBlock) { |
||||
if (((BasicBlock)tail).successors.Contains(this.headBasicBlock)) { |
||||
this.type = BasicBlockSetType.Loop; |
||||
} else { |
||||
this.type = BasicBlockSetType.Acyclic; |
||||
} |
||||
} else if (tailAsSet != null) { |
||||
if (tailAsSet.BasicBlockSuccessors.Contains(this.headBasicBlock)) { |
||||
|
||||
} |
||||
} else { |
||||
throw new Exception("Invalid tail"); |
||||
} |
||||
} |
||||
|
||||
public BasicBlockSet(StackExpressionCollection exprs) |
||||
{ |
||||
if (exprs.Count == 0) throw new ArgumentException("Count == 0", "exprs"); |
||||
|
||||
this.owner = null; |
||||
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.elements.Add(basicBlock); |
||||
basicBlock.Id = basicBlockId++; |
||||
} |
||||
basicBlock.Body.Add(exprs[i]); |
||||
} |
||||
|
||||
this.head = this.elements[0]; |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue