Browse Source

Make ILRange immutable struct

pull/32/merge
David Srbecký 13 years ago
parent
commit
052ea0565f
  1. 4
      src/Libraries/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs
  2. 2
      src/Libraries/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs
  3. 8
      src/Libraries/ICSharpCode.Decompiler/CodeMappings.cs
  4. 4
      src/Libraries/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs
  5. 2
      src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs
  6. 52
      src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstTypes.cs

4
src/Libraries/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs

@ -147,7 +147,7 @@ namespace ICSharpCode.Decompiler.Ast
if (node is ILLabel) { if (node is ILLabel) {
yield return new Ast.LabelStatement { Label = ((ILLabel)node).Name }; yield return new Ast.LabelStatement { Label = ((ILLabel)node).Name };
} else if (node is ILExpression) { } else if (node is ILExpression) {
List<ILRange> ilRanges = ILRange.OrderAndJoint(node.GetSelfAndChildrenRecursive<ILExpression>().SelectMany(e => e.ILRanges)); List<ILRange> ilRanges = ILRange.OrderAndJoin(node.GetSelfAndChildrenRecursive<ILExpression>().SelectMany(e => e.ILRanges));
AstNode codeExpr = TransformExpression((ILExpression)node); AstNode codeExpr = TransformExpression((ILExpression)node);
if (codeExpr != null) { if (codeExpr != null) {
codeExpr = codeExpr.WithAnnotation(ilRanges); codeExpr = codeExpr.WithAnnotation(ilRanges);
@ -253,7 +253,7 @@ namespace ICSharpCode.Decompiler.Ast
Expression astExpr = node as Expression; Expression astExpr = node as Expression;
// get IL ranges - used in debugger // get IL ranges - used in debugger
List<ILRange> ilRanges = ILRange.OrderAndJoint(expr.GetSelfAndChildrenRecursive<ILExpression>().SelectMany(e => e.ILRanges)); List<ILRange> ilRanges = ILRange.OrderAndJoin(expr.GetSelfAndChildrenRecursive<ILExpression>().SelectMany(e => e.ILRanges));
AstNode result; AstNode result;
if (astExpr != null) if (astExpr != null)

2
src/Libraries/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs

@ -307,7 +307,7 @@ namespace ICSharpCode.Decompiler.Ast
if (symbolsStack.Count > 0 && ranges != null && ranges.Count > 0) { if (symbolsStack.Count > 0 && ranges != null && ranges.Count > 0) {
symbolsStack.Peek().SequencePoints.Add( symbolsStack.Peek().SequencePoints.Add(
new SequencePoint() { new SequencePoint() {
ILRanges = ranges, ILRanges = ILRange.OrderAndJoin(ranges).ToArray(),
StartLocation = startLocation, StartLocation = startLocation,
EndLocation = output.Location EndLocation = output.Location
}); });

8
src/Libraries/ICSharpCode.Decompiler/CodeMappings.cs

@ -44,8 +44,14 @@ namespace ICSharpCode.Decompiler
public class SequencePoint public class SequencePoint
{ {
public List<ILRange> ILRanges { get; set; } public ILRange[] ILRanges { get; set; }
public TextLocation StartLocation { get; set; } public TextLocation StartLocation { get; set; }
public TextLocation EndLocation { get; set; } public TextLocation EndLocation { get; set; }
public int ILOffset { get { return this.ILRanges[0].From; } }
public override string ToString()
{
return string.Join(" ", this.ILRanges) + " " + this.StartLocation + "-" + this.EndLocation;
}
} }
} }

4
src/Libraries/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs

@ -94,7 +94,7 @@ namespace ICSharpCode.Decompiler.Disassembler
new SequencePoint() { new SequencePoint() {
StartLocation = output.Location, StartLocation = output.Location,
EndLocation = output.Location, EndLocation = output.Location,
ILRanges = new List<ILRange>() { new ILRange { From = inst.Offset, To = inst.Next == null ? method.Body.CodeSize : inst.Next.Offset } } ILRanges = new ILRange[] { new ILRange(inst.Offset, inst.Next == null ? method.Body.CodeSize : inst.Next.Offset) }
}); });
} }
@ -198,7 +198,7 @@ namespace ICSharpCode.Decompiler.Disassembler
new SequencePoint() { new SequencePoint() {
StartLocation = startLocation, StartLocation = startLocation,
EndLocation = output.Location, EndLocation = output.Location,
ILRanges = new List<ILRange>() { new ILRange { From = inst.Offset, To = inst.Next == null ? codeSize : inst.Next.Offset } } ILRanges = new ILRange[] { new ILRange(inst.Offset, inst.Next == null ? codeSize : inst.Next.Offset) }
}); });
} }

2
src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs

@ -743,7 +743,7 @@ namespace ICSharpCode.Decompiler.ILAst
// Convert stack-based IL code to ILAst tree // Convert stack-based IL code to ILAst tree
foreach(ByteCode byteCode in body) { foreach(ByteCode byteCode in body) {
ILRange ilRange = new ILRange() { From = byteCode.Offset, To = byteCode.EndOffset }; ILRange ilRange = new ILRange(byteCode.Offset, byteCode.EndOffset);
if (byteCode.StackBefore == null) { if (byteCode.StackBefore == null) {
// Unreachable code // Unreachable code

52
src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstTypes.cs

@ -221,37 +221,43 @@ namespace ICSharpCode.Decompiler.ILAst
} }
} }
public class ILRange public struct ILRange
{ {
public int From; public readonly int From;
public int To; // Exlusive public readonly int To; // Exlusive
public ILRange(int @from, int to)
{
this.From = @from;
this.To = to;
}
public override string ToString() public override string ToString()
{ {
return string.Format("{0}-{1}", From.ToString("X"), To.ToString("X")); return string.Format("{0:X2}-{1:X2}", From, To);
} }
public static List<ILRange> OrderAndJoint(IEnumerable<ILRange> input) public static List<ILRange> OrderAndJoin(IEnumerable<ILRange> input)
{ {
if (input == null) if (input == null)
throw new ArgumentNullException("Input is null!"); throw new ArgumentNullException("Input is null!");
List<ILRange> ranges = input.Where(r => r != null).OrderBy(r => r.From).ToList(); List<ILRange> result = new List<ILRange>();
for (int i = 0; i < ranges.Count - 1;) { foreach(ILRange curr in input.OrderBy(r => r.From)) {
ILRange curr = ranges[i]; if (result.Count > 0) {
ILRange next = ranges[i + 1]; // Merge consequtive ranges if possible
// Merge consequtive ranges if they intersect ILRange last = result[result.Count - 1];
if (curr.From <= next.From && next.From <= curr.To) { if (curr.From <= last.To) {
curr.To = Math.Max(curr.To, next.To); result[result.Count - 1] = new ILRange(last.From, Math.Max(last.To, curr.To));
ranges.RemoveAt(i + 1); continue;
} else { }
i++;
} }
result.Add(curr);
} }
return ranges; return result;
} }
public static IEnumerable<ILRange> Invert(IEnumerable<ILRange> input, int codeSize) public static List<ILRange> Invert(IEnumerable<ILRange> input, int codeSize)
{ {
if (input == null) if (input == null)
throw new ArgumentNullException("Input is null!"); throw new ArgumentNullException("Input is null!");
@ -259,23 +265,25 @@ namespace ICSharpCode.Decompiler.ILAst
if (codeSize <= 0) if (codeSize <= 0)
throw new ArgumentException("Code size must be grater than 0"); throw new ArgumentException("Code size must be grater than 0");
var ordered = OrderAndJoint(input); List<ILRange> ordered = OrderAndJoin(input);
List<ILRange> result = new List<ILRange>(ordered.Count + 1);
if (ordered.Count == 0) { if (ordered.Count == 0) {
yield return new ILRange() { From = 0, To = codeSize }; result.Add(new ILRange(0, codeSize));
} else { } else {
// Gap before the first element // Gap before the first element
if (ordered.First().From != 0) if (ordered.First().From != 0)
yield return new ILRange() { From = 0, To = ordered.First().From }; result.Add(new ILRange(0, ordered.First().From));
// Gaps between elements // Gaps between elements
for (int i = 0; i < ordered.Count - 1; i++) for (int i = 0; i < ordered.Count - 1; i++)
yield return new ILRange() { From = ordered[i].To, To = ordered[i + 1].From }; result.Add(new ILRange(ordered[i].To, ordered[i + 1].From));
// Gap after the last element // Gap after the last element
Debug.Assert(ordered.Last().To <= codeSize); Debug.Assert(ordered.Last().To <= codeSize);
if (ordered.Last().To != codeSize) if (ordered.Last().To != codeSize)
yield return new ILRange() { From = ordered.Last().To, To = codeSize }; result.Add(new ILRange(ordered.Last().To, codeSize));
} }
return result;
} }
} }

Loading…
Cancel
Save