Skip to content

Commit

Permalink
Setup document right.
Browse files Browse the repository at this point in the history
  • Loading branch information
wasabii committed Feb 6, 2024
1 parent cfb0aaf commit 02881c8
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 12 deletions.
37 changes: 25 additions & 12 deletions src/IKVM.Reflection/Diagnostics/PortablePdbSymbolWriter.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Diagnostics;
using System.Diagnostics.SymbolStore;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;

Expand Down Expand Up @@ -106,7 +106,7 @@ public void SetSource(byte[] source)
/// <summary>
/// Track local variable information.
/// </summary>
protected sealed class LocalVar
protected readonly struct LocalVar
{

readonly System.Reflection.FieldAttributes attributes;
Expand Down Expand Up @@ -279,15 +279,15 @@ internal Method(int token, StandaloneSignatureHandle localSignatureHandle)
/// <summary>
/// Describes a sequence point on a method.
/// </summary>
protected class SequencePoint
protected readonly struct SequencePoint
{

Document document;
int[] offsets;
int[] lines;
int[] columns;
int[] endLines;
int[] endColumns;
readonly Document document;
readonly int[] offsets;
readonly int[] lines;
readonly int[] columns;
readonly int[] endLines;
readonly int[] endColumns;

/// <summary>
/// Initializes a new instance.
Expand Down Expand Up @@ -520,7 +520,7 @@ public virtual void WriteTo(MetadataBuilder metadata, out int userEntryPoint)
void WriteMethod(MetadataBuilder metadata, Method method, Dictionary<Document, DocumentHandle> documentCache)
{
// find first document and set as initial, as it will be directly on method debug information
var initialDocument = method.SequencePoints.Select(i => i.Document).FirstOrDefault(i => i != null);
var initialDocument = GetSingleDocument(method.SequencePoints);
var initialDocumentHandle = initialDocument != null ? GetOrWriteDocument(metadata, initialDocument, documentCache) : default;
var currentDocumentHandle = initialDocumentHandle;

Expand All @@ -533,6 +533,17 @@ void WriteMethod(MetadataBuilder metadata, Method method, Dictionary<Document, D
Debug.Assert(MetadataTokens.GetRowNumber(methodDebugHandle) == MetadataTokens.GetRowNumber(MetadataTokens.EntityHandle(method.Token)));
}

/// <summary>
/// Returns the single unique <see cref="Document"/> in a set of sequence points, or <c>null</c> if there is no single unique document.
/// </summary>
/// <param name="sequencePoints"></param>
/// <returns></returns>
Document GetSingleDocument(IEnumerable<SequencePoint> sequencePoints)
{
var s = sequencePoints.Select(i => i.Document).Distinct().Take(2).ToList();
return s.Count == 1 ? s[0] : null;
}

/// <summary>
/// Writes the sequence points for the method.
/// </summary>
Expand All @@ -556,8 +567,10 @@ void WriteSequencePoints(MetadataBuilder metadata, Method method, Dictionary<Doc
if (method.LocalSignatureHandle.IsNil)
throw new InvalidOperationException("MethodBuilder missing local signature.");

// sequence points begin with local signature and initial document
enc.Header(method.LocalSignatureHandle, default, ref previousDocument);
// add the header, optionally with the first encountered document
var firstDocument = method.SequencePoints.Select(i => i.Document).FirstOrDefault();
var firstDocumentHandle = firstDocument != null ? GetOrWriteDocument(metadata, firstDocument, documentCache) : default;
enc.Header(method.LocalSignatureHandle, firstDocumentHandle, ref previousDocument);

// add the sequence points recorded on the method
foreach (var sequencePoint in method.SequencePoints)
Expand Down
2 changes: 2 additions & 0 deletions src/IKVM.Reflection/Emit/SequencePointEncoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public SequencePointEncoder(BlobBuilder writer)
/// Encodes the local signature.
/// </summary>
/// <param name="localSignature"></param>
/// <param name="initialDocument"></param>
/// <param name="previousDocument".
public void Header(StandaloneSignatureHandle localSignature, DocumentHandle initialDocument, ref DocumentHandle previousDocument)
{
if (headerEncoded)
Expand Down

0 comments on commit 02881c8

Please sign in to comment.