From 38019ad5bf52dfa702ef3e8afd0487ac64bd60d6 Mon Sep 17 00:00:00 2001 From: ElektroKill Date: Thu, 14 Dec 2023 18:36:57 +0100 Subject: [PATCH] Introduce `PdbExtraTypeInfo` struct and adjusted `IDebugInfoProvider` --- .../DebugInfo/IDebugInfoProvider.cs | 8 +++++++- .../IL/ApplyPdbLocalTypeInfoTypeVisitor.cs | 10 +++++++++- ICSharpCode.Decompiler/IL/ILReader.cs | 5 ++--- .../PdbProvider/MonoCecilDebugInfoProvider.cs | 6 ++---- .../PdbProvider/PortableDebugInfoProvider.cs | 19 +++++++++---------- 5 files changed, 29 insertions(+), 19 deletions(-) diff --git a/ICSharpCode.Decompiler/DebugInfo/IDebugInfoProvider.cs b/ICSharpCode.Decompiler/DebugInfo/IDebugInfoProvider.cs index bab259b26..810919e56 100644 --- a/ICSharpCode.Decompiler/DebugInfo/IDebugInfoProvider.cs +++ b/ICSharpCode.Decompiler/DebugInfo/IDebugInfoProvider.cs @@ -17,13 +17,19 @@ namespace ICSharpCode.Decompiler.DebugInfo public string Name { get; } } + public struct PdbExtraTypeInfo + { + public string[] TupleElementNames; + public bool[] DynamicFlags; + } + public interface IDebugInfoProvider { string Description { get; } IList GetSequencePoints(MethodDefinitionHandle method); IList GetVariables(MethodDefinitionHandle method); bool TryGetName(MethodDefinitionHandle method, int index, out string name); - bool TryGetExtraTypeInfo(MethodDefinitionHandle method, int index, out string[] tupleElementNames, out bool[] dynamicFlags); + bool TryGetExtraTypeInfo(MethodDefinitionHandle method, int index, out PdbExtraTypeInfo extraTypeInfo); string SourceFileName { get; } } } diff --git a/ICSharpCode.Decompiler/IL/ApplyPdbLocalTypeInfoTypeVisitor.cs b/ICSharpCode.Decompiler/IL/ApplyPdbLocalTypeInfoTypeVisitor.cs index a6b629f87..1d8796c1e 100644 --- a/ICSharpCode.Decompiler/IL/ApplyPdbLocalTypeInfoTypeVisitor.cs +++ b/ICSharpCode.Decompiler/IL/ApplyPdbLocalTypeInfoTypeVisitor.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Immutable; +using ICSharpCode.Decompiler.DebugInfo; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem.Implementation; @@ -16,12 +17,19 @@ namespace ICSharpCode.Decompiler.IL private int dynamicTypeIndex = 0; private int tupleTypeIndex = 0; - public ApplyPdbLocalTypeInfoTypeVisitor(bool[] dynamicData, string[] tupleElementNames) + private ApplyPdbLocalTypeInfoTypeVisitor(bool[] dynamicData, string[] tupleElementNames) { this.dynamicData = dynamicData; this.tupleElementNames = tupleElementNames; } + public static IType Apply(IType type, PdbExtraTypeInfo pdbExtraTypeInfo) + { + if (pdbExtraTypeInfo.DynamicFlags is null && pdbExtraTypeInfo.TupleElementNames is null) + return type; + return type.AcceptVisitor(new ApplyPdbLocalTypeInfoTypeVisitor(pdbExtraTypeInfo.DynamicFlags, pdbExtraTypeInfo.TupleElementNames)); + } + public override IType VisitModOpt(ModifiedType type) { dynamicTypeIndex++; diff --git a/ICSharpCode.Decompiler/IL/ILReader.cs b/ICSharpCode.Decompiler/IL/ILReader.cs index ae85ec79c..4aaa4a739 100644 --- a/ICSharpCode.Decompiler/IL/ILReader.cs +++ b/ICSharpCode.Decompiler/IL/ILReader.cs @@ -306,10 +306,9 @@ namespace ICSharpCode.Decompiler.IL } if (UseDebugSymbols && DebugInfo is not null && - DebugInfo.TryGetExtraTypeInfo((MethodDefinitionHandle)method.MetadataToken, index, - out string[] tupleElementNames, out bool[] dynamicFlags)) + DebugInfo.TryGetExtraTypeInfo((MethodDefinitionHandle)method.MetadataToken, index, out var pdbExtraTypeInfo)) { - type = type.AcceptVisitor(new ApplyPdbLocalTypeInfoTypeVisitor(dynamicFlags, tupleElementNames)); + type = ApplyPdbLocalTypeInfoTypeVisitor.Apply(type, pdbExtraTypeInfo); } ILVariable ilVar = new ILVariable(kind, type, index); diff --git a/ICSharpCode.ILSpyX/PdbProvider/MonoCecilDebugInfoProvider.cs b/ICSharpCode.ILSpyX/PdbProvider/MonoCecilDebugInfoProvider.cs index 78f468a7e..6fe3021bb 100644 --- a/ICSharpCode.ILSpyX/PdbProvider/MonoCecilDebugInfoProvider.cs +++ b/ICSharpCode.ILSpyX/PdbProvider/MonoCecilDebugInfoProvider.cs @@ -136,13 +136,11 @@ namespace ICSharpCode.ILSpyX.PdbProvider return name != null; } - public bool TryGetExtraTypeInfo(SRM.MethodDefinitionHandle method, int index, - [NotNullWhen(true)] out string[]? tupleElementNames, [NotNullWhen(true)] out bool[]? dynamicFlags) + public bool TryGetExtraTypeInfo(SRM.MethodDefinitionHandle method, int index, out PdbExtraTypeInfo extraTypeInfo) { // Mono.Cecil's WindowsPDB reader is unable to read tuple element names // and dynamic flags custom debug information. - tupleElementNames = null; - dynamicFlags = null; + extraTypeInfo = default; return false; } } diff --git a/ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs b/ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs index e4df859d7..0ad89015d 100644 --- a/ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs +++ b/ICSharpCode.ILSpyX/PdbProvider/PortableDebugInfoProvider.cs @@ -162,12 +162,10 @@ namespace ICSharpCode.ILSpyX.PdbProvider return false; } - public bool TryGetExtraTypeInfo(MethodDefinitionHandle method, int index, - [NotNullWhen(true)] out string?[]? tupleElementNames, [NotNullWhen(true)] out bool[]? dynamicFlags) + public bool TryGetExtraTypeInfo(MethodDefinitionHandle method, int index, out PdbExtraTypeInfo extraTypeInfo) { var metadata = GetMetadataReader(); - tupleElementNames = null; - dynamicFlags = null; + extraTypeInfo = default; if (metadata == null) return false; @@ -200,7 +198,7 @@ namespace ICSharpCode.ILSpyX.PdbProvider if (cdi.Value.IsNil || cdi.Kind.IsNil) continue; var kind = metadata.GetGuid(cdi.Kind); - if (kind == KnownGuids.TupleElementNames && tupleElementNames is null) + if (kind == KnownGuids.TupleElementNames && extraTypeInfo.TupleElementNames is null) { var reader = metadata.GetBlobReader(cdi.Value); var list = new List(); @@ -212,25 +210,26 @@ namespace ICSharpCode.ILSpyX.PdbProvider list.Add(string.IsNullOrWhiteSpace(s) ? null : s); } - tupleElementNames = list.ToArray(); + extraTypeInfo.TupleElementNames = list.ToArray(); } - else if (kind == KnownGuids.DynamicLocalVariables && dynamicFlags is null) + else if (kind == KnownGuids.DynamicLocalVariables && extraTypeInfo.DynamicFlags is null) { var reader = metadata.GetBlobReader(cdi.Value); + extraTypeInfo.DynamicFlags = new bool[reader.Length * 8]; int j = 0; while (reader.RemainingBytes > 0) { int b = reader.ReadByte(); for (int i = 1; i < 0x100; i <<= 1) - dynamicFlags[j++] = (b & i) != 0; + extraTypeInfo.DynamicFlags[j++] = (b & i) != 0; } } - if (tupleElementNames != null && dynamicFlags != null) + if (extraTypeInfo.TupleElementNames != null && extraTypeInfo.DynamicFlags != null) break; } - return tupleElementNames != null || dynamicFlags != null; + return extraTypeInfo.TupleElementNames != null || extraTypeInfo.DynamicFlags != null; } } }