diff --git a/src/Libraries/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs b/src/Libraries/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs index 36066b1a43..fae41f6860 100644 --- a/src/Libraries/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs +++ b/src/Libraries/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs @@ -147,7 +147,7 @@ namespace ICSharpCode.Decompiler.Ast if (node is ILLabel) { yield return new Ast.LabelStatement { Label = ((ILLabel)node).Name }; } else if (node is ILExpression) { - List ilRanges = ILRange.OrderAndJoint(node.GetSelfAndChildrenRecursive().SelectMany(e => e.ILRanges)); + List ilRanges = ILRange.OrderAndJoin(node.GetSelfAndChildrenRecursive().SelectMany(e => e.ILRanges)); AstNode codeExpr = TransformExpression((ILExpression)node); if (codeExpr != null) { codeExpr = codeExpr.WithAnnotation(ilRanges); @@ -253,7 +253,7 @@ namespace ICSharpCode.Decompiler.Ast Expression astExpr = node as Expression; // get IL ranges - used in debugger - List ilRanges = ILRange.OrderAndJoint(expr.GetSelfAndChildrenRecursive().SelectMany(e => e.ILRanges)); + List ilRanges = ILRange.OrderAndJoin(expr.GetSelfAndChildrenRecursive().SelectMany(e => e.ILRanges)); AstNode result; if (astExpr != null) diff --git a/src/Libraries/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs b/src/Libraries/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs index 6fa539280a..7155a67b9e 100644 --- a/src/Libraries/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs +++ b/src/Libraries/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs @@ -307,7 +307,7 @@ namespace ICSharpCode.Decompiler.Ast if (symbolsStack.Count > 0 && ranges != null && ranges.Count > 0) { symbolsStack.Peek().SequencePoints.Add( new SequencePoint() { - ILRanges = ranges, + ILRanges = ILRange.OrderAndJoin(ranges).ToArray(), StartLocation = startLocation, EndLocation = output.Location }); diff --git a/src/Libraries/ICSharpCode.Decompiler/CodeMappings.cs b/src/Libraries/ICSharpCode.Decompiler/CodeMappings.cs index c6c0f06571..b2dcab8621 100644 --- a/src/Libraries/ICSharpCode.Decompiler/CodeMappings.cs +++ b/src/Libraries/ICSharpCode.Decompiler/CodeMappings.cs @@ -44,8 +44,14 @@ namespace ICSharpCode.Decompiler public class SequencePoint { - public List ILRanges { get; set; } + public ILRange[] ILRanges { get; set; } public TextLocation StartLocation { 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; + } } } diff --git a/src/Libraries/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs b/src/Libraries/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs index 52c2772271..a45a718207 100644 --- a/src/Libraries/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs +++ b/src/Libraries/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs @@ -94,7 +94,7 @@ namespace ICSharpCode.Decompiler.Disassembler new SequencePoint() { StartLocation = output.Location, EndLocation = output.Location, - ILRanges = new List() { 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() { StartLocation = startLocation, EndLocation = output.Location, - ILRanges = new List() { 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) } }); } diff --git a/src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs b/src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs index cbdc5d771f..da8c6c6beb 100644 --- a/src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs +++ b/src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs @@ -743,7 +743,7 @@ namespace ICSharpCode.Decompiler.ILAst // Convert stack-based IL code to ILAst tree 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) { // Unreachable code diff --git a/src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstTypes.cs b/src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstTypes.cs index 4f3930fcdd..9cd42a14fc 100644 --- a/src/Libraries/ICSharpCode.Decompiler/ILAst/ILAstTypes.cs +++ b/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 int To; // Exlusive + public readonly int From; + public readonly int To; // Exlusive + + public ILRange(int @from, int to) + { + this.From = @from; + this.To = to; + } 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 OrderAndJoint(IEnumerable input) + public static List OrderAndJoin(IEnumerable input) { if (input == null) throw new ArgumentNullException("Input is null!"); - List ranges = input.Where(r => r != null).OrderBy(r => r.From).ToList(); - for (int i = 0; i < ranges.Count - 1;) { - ILRange curr = ranges[i]; - ILRange next = ranges[i + 1]; - // Merge consequtive ranges if they intersect - if (curr.From <= next.From && next.From <= curr.To) { - curr.To = Math.Max(curr.To, next.To); - ranges.RemoveAt(i + 1); - } else { - i++; + List result = new List(); + foreach(ILRange curr in input.OrderBy(r => r.From)) { + if (result.Count > 0) { + // Merge consequtive ranges if possible + ILRange last = result[result.Count - 1]; + if (curr.From <= last.To) { + result[result.Count - 1] = new ILRange(last.From, Math.Max(last.To, curr.To)); + continue; + } } + result.Add(curr); } - return ranges; + return result; } - public static IEnumerable Invert(IEnumerable input, int codeSize) + public static List Invert(IEnumerable input, int codeSize) { if (input == null) throw new ArgumentNullException("Input is null!"); @@ -259,23 +265,25 @@ namespace ICSharpCode.Decompiler.ILAst if (codeSize <= 0) throw new ArgumentException("Code size must be grater than 0"); - var ordered = OrderAndJoint(input); + List ordered = OrderAndJoin(input); + List result = new List(ordered.Count + 1); if (ordered.Count == 0) { - yield return new ILRange() { From = 0, To = codeSize }; + result.Add(new ILRange(0, codeSize)); } else { // Gap before the first element 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 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 Debug.Assert(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; } }