Browse Source

Improve stepping.

pull/191/merge
Eusebiu Marcu 15 years ago
parent
commit
73d50fbbb4
  1. 13
      Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs
  2. 59
      ICSharpCode.Decompiler/CodeMappings.cs
  3. 11
      ICSharpCode.Decompiler/ILAst/ILAstTypes.cs

13
Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs

@ -287,21 +287,22 @@ namespace ILSpy.Debugger.Services
// Stepping: // Stepping:
SourceCodeMapping GetCurrentCodeMapping() SourceCodeMapping GetCurrentCodeMapping(out bool isMatch)
{ {
isMatch = false;
if (CurrentLineBookmark.Instance == null) if (CurrentLineBookmark.Instance == null)
return null; return null;
var frame = debuggedProcess.SelectedThread.MostRecentStackFrame;
// get the mapped instruction from the current line marker or the next one // get the mapped instruction from the current line marker or the next one
uint token;
return CodeMappingsStorage.GetInstructionByTypeAndLine( return CodeMappingsStorage.GetInstructionByTypeAndLine(
CurrentLineBookmark.Instance.Type.FullName, CurrentLineBookmark.Instance.Type.FullName, (uint)frame.MethodInfo.MetadataToken, frame.IP, out isMatch);
CurrentLineBookmark.Instance.LineNumber, out token);
} }
StackFrame GetStackFrame() StackFrame GetStackFrame()
{ {
var map = GetCurrentCodeMapping(); bool isMatch;
var map = GetCurrentCodeMapping(out isMatch);
if (map == null) { if (map == null) {
CurrentLineBookmark.Remove(); CurrentLineBookmark.Remove();
Continue(); Continue();
@ -309,7 +310,7 @@ namespace ILSpy.Debugger.Services
} else { } else {
var frame = debuggedProcess.SelectedThread.MostRecentStackFrame; var frame = debuggedProcess.SelectedThread.MostRecentStackFrame;
frame.SourceCodeLine = map.SourceCodeLine; frame.SourceCodeLine = map.SourceCodeLine;
frame.ILRanges = map.ToArray(); frame.ILRanges = map.ToArray(isMatch);
return frame; return frame;
} }
} }

59
ICSharpCode.Decompiler/CodeMappings.cs

@ -42,17 +42,26 @@ namespace ICSharpCode.Decompiler
/// <summary> /// <summary>
/// Retrieves the array that contains the IL range and the missing gaps between ranges. /// Retrieves the array that contains the IL range and the missing gaps between ranges.
/// </summary> /// </summary>
/// <returns></returns> /// <returns>The array representation of the step aranges.</returns>
public int[] ToArray() public int[] ToArray(bool isMatch)
{ {
var currentList = new List<ILRange>();
// add list for the current source code line // add list for the current source code line
var currentList = MemberMapping.MemberCodeMappings currentList.AddRange(ILRange.OrderAndJoint(MemberMapping.MemberCodeMappings
.FindAll(m => m.SourceCodeLine == this.SourceCodeLine) .FindAll(m => m.SourceCodeLine == this.SourceCodeLine)
.ConvertAll<ILRange>(m => m.ILInstructionOffset); .ConvertAll<ILRange>(m => m.ILInstructionOffset)));
// add inverted if (!isMatch) {
currentList.AddRange(MemberMapping.InvertedList); // add inverted
currentList.AddRange(MemberMapping.InvertedList);
} else {
// if the current list contains the last mapping, add also the last gap
if (currentList.Count == 1)
currentList.Add(MemberMapping.InvertedList.LastOrDefault());
}
// set the output
var resultList = new List<int>(); var resultList = new List<int>();
foreach (var element in ILRange.OrderAndJoint(currentList)) { foreach (var element in ILRange.OrderAndJoint(currentList)) {
resultList.Add(element.From); resultList.Add(element.From);
@ -101,7 +110,7 @@ namespace ICSharpCode.Decompiler
if (invertedList == null) { if (invertedList == null) {
var list = MemberCodeMappings.ConvertAll<ILRange>( var list = MemberCodeMappings.ConvertAll<ILRange>(
s => new ILRange { From = s.ILInstructionOffset.From, To = s.ILInstructionOffset.To }); s => new ILRange { From = s.ILInstructionOffset.From, To = s.ILInstructionOffset.To });
invertedList = ILRange.Invert(list, CodeSize); invertedList = ILRange.OrderAndJoint(ILRange.Invert(list, CodeSize));
} }
return invertedList; return invertedList;
} }
@ -201,6 +210,40 @@ namespace ICSharpCode.Decompiler
return null; return null;
} }
public static SourceCodeMapping GetInstructionByTypeAndLine(
this ConcurrentDictionary<string, List<MemberMapping>> codeMappings,
string typeName,
uint token,
int ilOffset, out bool isMatch)
{
isMatch = false;
if (codeMappings == null)
throw new ArgumentNullException("CodeMappings storage must be valid!");
if (!codeMappings.ContainsKey(typeName)) {
return null;
}
var methodMappings = codeMappings[typeName];
var maping = methodMappings.Find(m => m.MetadataToken == token);
// try find an exact match
var map = maping.MemberCodeMappings.Find(m => m.ILInstructionOffset.From <= ilOffset && ilOffset < m.ILInstructionOffset.To);
if (map == null) {
// get the immediate next one
map = maping.MemberCodeMappings.Find(m => m.ILInstructionOffset.From >= ilOffset);
isMatch = false;
if (map == null)
map = maping.MemberCodeMappings.LastOrDefault(); // get the last
return map;
}
isMatch = true;
return map;
}
/// <summary> /// <summary>
/// Gets the source code and type name from metadata token and offset. /// Gets the source code and type name from metadata token and offset.
/// </summary> /// </summary>

11
ICSharpCode.Decompiler/ILAst/ILAstTypes.cs

@ -224,7 +224,10 @@ namespace ICSharpCode.Decompiler.ILAst
public static List<ILRange> OrderAndJoint(IEnumerable<ILRange> input) public static List<ILRange> OrderAndJoint(IEnumerable<ILRange> input)
{ {
List<ILRange> ranges = input.OrderBy(r => r.From).ToList(); if (input == null)
throw new ArgumentNullException("Input is null!");
List<ILRange> ranges = input.Where(r => r != null).OrderBy(r => r.From).ToList();
for (int i = 0; i < ranges.Count - 1;) { for (int i = 0; i < ranges.Count - 1;) {
ILRange curr = ranges[i]; ILRange curr = ranges[i];
ILRange next = ranges[i + 1]; ILRange next = ranges[i + 1];
@ -241,6 +244,12 @@ namespace ICSharpCode.Decompiler.ILAst
public static IEnumerable<ILRange> Invert(IEnumerable<ILRange> input, int codeSize) public static IEnumerable<ILRange> Invert(IEnumerable<ILRange> input, int codeSize)
{ {
if (input == null)
throw new ArgumentNullException("Input is null!");
if (codeSize <= 0)
throw new ArgumentException("Code size must be grater than 0");
var ordered = OrderAndJoint(input); var ordered = OrderAndJoint(input);
if (ordered.Count == 0) { if (ordered.Count == 0) {
yield return new ILRange() { From = 0, To = codeSize }; yield return new ILRange() { From = 0, To = codeSize };

Loading…
Cancel
Save