Browse Source

Reduce "unsafe" by replacing byte* pointer usage with ReadOnlySpan<byte> (#3106)

pull/3111/head
James May 2 years ago committed by GitHub
parent
commit
0bab8a01ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 40
      ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs
  2. 20
      ILSpy/Metadata/CorTables/ClassLayoutTableTreeNode.cs
  3. 17
      ILSpy/Metadata/CorTables/EventMapTableTreeNode.cs
  4. 18
      ILSpy/Metadata/CorTables/FieldLayoutTableTreeNode.cs
  5. 17
      ILSpy/Metadata/CorTables/FieldMarshalTableTreeNode.cs
  6. 18
      ILSpy/Metadata/CorTables/FieldRVATableTreeNode.cs
  7. 26
      ILSpy/Metadata/CorTables/ImplMapTableTreeNode.cs
  8. 17
      ILSpy/Metadata/CorTables/InterfaceImplTableTreeNode.cs
  9. 17
      ILSpy/Metadata/CorTables/NestedClassTableTreeNode.cs
  10. 17
      ILSpy/Metadata/CorTables/PropertyMapTableTreeNode.cs
  11. 4
      ILSpy/Metadata/DebugTables/StateMachineMethodTableTreeNode.cs
  12. 11
      ILSpy/Metadata/Helpers.cs

40
ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
@ -384,11 +385,13 @@ namespace ICSharpCode.Decompiler.Metadata @@ -384,11 +385,13 @@ namespace ICSharpCode.Decompiler.Metadata
yield return Read(row);
}
unsafe (Handle Handle, MethodSemanticsAttributes Semantics, MethodDefinitionHandle Method, EntityHandle Association) Read(int row)
(Handle Handle, MethodSemanticsAttributes Semantics, MethodDefinitionHandle Method, EntityHandle Association) Read(int row)
{
byte* ptr = metadata.MetadataPointer + offset + rowSize * row;
int methodDef = methodSmall ? *(ushort*)(ptr + 2) : (int)*(uint*)(ptr + 2);
int assocDef = assocSmall ? *(ushort*)(ptr + assocOffset) : (int)*(uint*)(ptr + assocOffset);
var span = metadata.AsReadOnlySpan();
var methodDefSpan = span.Slice(offset + rowSize * row + 2);
int methodDef = methodSmall ? BinaryPrimitives.ReadUInt16LittleEndian(methodDefSpan) : (int)BinaryPrimitives.ReadUInt32LittleEndian(methodDefSpan);
var assocSpan = span.Slice(assocOffset);
int assocDef = assocSmall ? BinaryPrimitives.ReadUInt16LittleEndian(assocSpan) : (int)BinaryPrimitives.ReadUInt32LittleEndian(assocSpan);
EntityHandle propOrEvent;
if ((assocDef & 0x1) == 1)
{
@ -398,7 +401,7 @@ namespace ICSharpCode.Decompiler.Metadata @@ -398,7 +401,7 @@ namespace ICSharpCode.Decompiler.Metadata
{
propOrEvent = MetadataTokens.EventDefinitionHandle(assocDef >> 1);
}
return (MetadataTokens.Handle(0x18000000 | (row + 1)), (MethodSemanticsAttributes)(*(ushort*)ptr), MetadataTokens.MethodDefinitionHandle(methodDef), propOrEvent);
return (MetadataTokens.Handle(0x18000000 | (row + 1)), (MethodSemanticsAttributes)(BinaryPrimitives.ReadUInt16LittleEndian(span)), MetadataTokens.MethodDefinitionHandle(methodDef), propOrEvent);
}
}
@ -411,9 +414,9 @@ namespace ICSharpCode.Decompiler.Metadata @@ -411,9 +414,9 @@ namespace ICSharpCode.Decompiler.Metadata
}
}
public unsafe static (int Offset, FieldDefinitionHandle FieldDef) GetFieldLayout(this MetadataReader metadata, EntityHandle fieldLayoutHandle)
public static (int Offset, FieldDefinitionHandle FieldDef) GetFieldLayout(this MetadataReader metadata, EntityHandle fieldLayoutHandle)
{
byte* startPointer = metadata.MetadataPointer;
var startPointer = metadata.AsReadOnlySpan();
int offset = metadata.GetTableMetadataOffset(TableIndex.FieldLayout);
int rowSize = metadata.GetTableRowSize(TableIndex.FieldLayout);
int rowCount = metadata.GetTableRowCount(TableIndex.FieldLayout);
@ -422,14 +425,31 @@ namespace ICSharpCode.Decompiler.Metadata @@ -422,14 +425,31 @@ namespace ICSharpCode.Decompiler.Metadata
bool small = metadata.GetTableRowCount(TableIndex.Field) <= ushort.MaxValue;
for (int row = rowCount - 1; row >= 0; row--)
{
byte* ptr = startPointer + offset + rowSize * row;
uint rowNo = small ? *(ushort*)(ptr + 4) : *(uint*)(ptr + 4);
ReadOnlySpan<byte> ptr = startPointer.Slice(offset + rowSize * row);
var rowNoSpan = ptr.Slice(4);
uint rowNo = small ? BinaryPrimitives.ReadUInt16LittleEndian(rowNoSpan) : BinaryPrimitives.ReadUInt32LittleEndian(rowNoSpan);
if (fieldRowNo == rowNo)
{
return (*(int*)ptr, MetadataTokens.FieldDefinitionHandle(fieldRowNo));
return (BinaryPrimitives.ReadInt32LittleEndian(ptr), MetadataTokens.FieldDefinitionHandle(fieldRowNo));
}
}
return (0, default);
}
public static ReadOnlySpan<byte> AsReadOnlySpan(this MetadataReader metadataReader)
{
unsafe
{
return new(metadataReader.MetadataPointer, metadataReader.MetadataLength);
}
}
public static BlobReader AsBlobReader(this MetadataReader metadataReader)
{
unsafe
{
return new(metadataReader.MetadataPointer, metadataReader.MetadataLength);
}
}
}
}

20
ILSpy/Metadata/CorTables/ClassLayoutTableTreeNode.cs

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
@ -38,7 +40,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -38,7 +40,7 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Icon => Images.Literal;
public unsafe override bool View(ViewModels.TabPageModel tabPage)
public override bool View(ViewModels.TabPageModel tabPage)
{
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
@ -49,7 +51,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -49,7 +51,7 @@ namespace ICSharpCode.ILSpy.Metadata
var list = new List<ClassLayoutEntry>();
var length = metadata.GetTableRowCount(TableIndex.ClassLayout);
byte* ptr = metadata.MetadataPointer;
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset;
ClassLayoutEntry scrollTargetEntry = default;
@ -80,15 +82,15 @@ namespace ICSharpCode.ILSpy.Metadata @@ -80,15 +82,15 @@ namespace ICSharpCode.ILSpy.Metadata
public readonly EntityHandle Parent;
public readonly uint ClassSize;
public unsafe ClassLayout(byte* ptr, int typeDefSize)
public ClassLayout(ReadOnlySpan<byte> ptr, int typeDefSize)
{
PackingSize = (ushort)Helpers.GetValue(ptr, 2);
ClassSize = (uint)Helpers.GetValue(ptr + 2, 4);
Parent = MetadataTokens.TypeDefinitionHandle(Helpers.GetValue(ptr + 6, typeDefSize));
PackingSize = BinaryPrimitives.ReadUInt16LittleEndian(ptr);
ClassSize = BinaryPrimitives.ReadUInt32LittleEndian(ptr.Slice(2, 4));
Parent = MetadataTokens.TypeDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(6, typeDefSize)));
}
}
unsafe struct ClassLayoutEntry
struct ClassLayoutEntry
{
readonly PEFile module;
readonly MetadataReader metadata;
@ -117,7 +119,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -117,7 +119,7 @@ namespace ICSharpCode.ILSpy.Metadata
[ColumnInfo("X8", Kind = ColumnKind.Other)]
public uint ClassSize => classLayout.ClassSize;
public ClassLayoutEntry(PEFile module, byte* ptr, int metadataOffset, int row)
public ClassLayoutEntry(PEFile module, ReadOnlySpan<byte> ptr, int metadataOffset, int row)
{
this.module = module;
this.metadata = module.Metadata;
@ -125,7 +127,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -125,7 +127,7 @@ namespace ICSharpCode.ILSpy.Metadata
var rowOffset = metadata.GetTableMetadataOffset(TableIndex.ClassLayout)
+ metadata.GetTableRowSize(TableIndex.ClassLayout) * (row - 1);
this.Offset = metadataOffset + rowOffset;
this.classLayout = new ClassLayout(ptr + rowOffset, metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4);
this.classLayout = new ClassLayout(ptr.Slice(rowOffset), metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4);
this.parentTooltip = null;
}
}

17
ILSpy/Metadata/CorTables/EventMapTableTreeNode.cs

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
@ -38,7 +39,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -38,7 +39,7 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Icon => Images.Literal;
public unsafe override bool View(ViewModels.TabPageModel tabPage)
public override bool View(ViewModels.TabPageModel tabPage)
{
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
@ -50,7 +51,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -50,7 +51,7 @@ namespace ICSharpCode.ILSpy.Metadata
EventMapEntry scrollTargetEntry = default;
var length = metadata.GetTableRowCount(TableIndex.EventMap);
byte* ptr = metadata.MetadataPointer;
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset;
for (int rid = 1; rid <= length; rid++)
{
@ -79,14 +80,14 @@ namespace ICSharpCode.ILSpy.Metadata @@ -79,14 +80,14 @@ namespace ICSharpCode.ILSpy.Metadata
public readonly TypeDefinitionHandle Parent;
public readonly EventDefinitionHandle EventList;
public unsafe EventMap(byte* ptr, int typeDefSize, int eventDefSize)
public EventMap(ReadOnlySpan<byte> ptr, int typeDefSize, int eventDefSize)
{
Parent = MetadataTokens.TypeDefinitionHandle(Helpers.GetValue(ptr, typeDefSize));
EventList = MetadataTokens.EventDefinitionHandle(Helpers.GetValue(ptr + typeDefSize, eventDefSize));
Parent = MetadataTokens.TypeDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(0, typeDefSize)));
EventList = MetadataTokens.EventDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(typeDefSize, eventDefSize)));
}
}
unsafe struct EventMapEntry
struct EventMapEntry
{
readonly PEFile module;
readonly MetadataReader metadata;
@ -120,7 +121,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -120,7 +121,7 @@ namespace ICSharpCode.ILSpy.Metadata
string eventListTooltip;
public string EventListTooltip => GenerateTooltip(ref eventListTooltip, module, eventMap.EventList);
public EventMapEntry(PEFile module, byte* ptr, int metadataOffset, int row)
public EventMapEntry(PEFile module, ReadOnlySpan<byte> ptr, int metadataOffset, int row)
{
this.module = module;
this.metadata = module.Metadata;
@ -130,7 +131,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -130,7 +131,7 @@ namespace ICSharpCode.ILSpy.Metadata
this.Offset = metadataOffset + rowOffset;
int typeDefSize = metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4;
int eventDefSize = metadata.GetTableRowCount(TableIndex.Event) < ushort.MaxValue ? 2 : 4;
this.eventMap = new EventMap(ptr + rowOffset, typeDefSize, eventDefSize);
this.eventMap = new EventMap(ptr.Slice(rowOffset), typeDefSize, eventDefSize);
this.parentTooltip = null;
this.eventListTooltip = null;
}

18
ILSpy/Metadata/CorTables/FieldLayoutTableTreeNode.cs

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
@ -38,7 +40,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -38,7 +40,7 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Icon => Images.Literal;
public unsafe override bool View(ViewModels.TabPageModel tabPage)
public override bool View(ViewModels.TabPageModel tabPage)
{
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
@ -50,7 +52,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -50,7 +52,7 @@ namespace ICSharpCode.ILSpy.Metadata
FieldLayoutEntry scrollTargetEntry = default;
var length = metadata.GetTableRowCount(TableIndex.FieldLayout);
byte* ptr = metadata.MetadataPointer;
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset;
for (int rid = 1; rid <= length; rid++)
{
@ -79,14 +81,14 @@ namespace ICSharpCode.ILSpy.Metadata @@ -79,14 +81,14 @@ namespace ICSharpCode.ILSpy.Metadata
public readonly int Offset;
public readonly FieldDefinitionHandle Field;
public unsafe FieldLayout(byte* ptr, int fieldDefSize)
public FieldLayout(ReadOnlySpan<byte> ptr, int fieldDefSize)
{
Offset = Helpers.GetValue(ptr, 4);
Field = MetadataTokens.FieldDefinitionHandle(Helpers.GetValue(ptr + 4, fieldDefSize));
Offset = BinaryPrimitives.ReadInt32LittleEndian(ptr);
Field = MetadataTokens.FieldDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(4, fieldDefSize)));
}
}
unsafe struct FieldLayoutEntry
struct FieldLayoutEntry
{
readonly PEFile module;
readonly MetadataReader metadata;
@ -112,7 +114,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -112,7 +114,7 @@ namespace ICSharpCode.ILSpy.Metadata
[ColumnInfo("X8", Kind = ColumnKind.Other)]
public int FieldOffset => fieldLayout.Offset;
public FieldLayoutEntry(PEFile module, byte* ptr, int metadataOffset, int row)
public FieldLayoutEntry(PEFile module, ReadOnlySpan<byte> ptr, int metadataOffset, int row)
{
this.module = module;
this.metadata = module.Metadata;
@ -121,7 +123,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -121,7 +123,7 @@ namespace ICSharpCode.ILSpy.Metadata
+ metadata.GetTableRowSize(TableIndex.FieldLayout) * (row - 1);
this.Offset = metadataOffset + rowOffset;
int fieldDefSize = metadata.GetTableRowCount(TableIndex.Field) < ushort.MaxValue ? 2 : 4;
this.fieldLayout = new FieldLayout(ptr + rowOffset, fieldDefSize);
this.fieldLayout = new FieldLayout(ptr.Slice(rowOffset), fieldDefSize);
this.fieldTooltip = null;
}
}

17
ILSpy/Metadata/CorTables/FieldMarshalTableTreeNode.cs

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
@ -38,7 +39,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -38,7 +39,7 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Icon => Images.Literal;
public unsafe override bool View(ViewModels.TabPageModel tabPage)
public override bool View(ViewModels.TabPageModel tabPage)
{
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
@ -50,7 +51,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -50,7 +51,7 @@ namespace ICSharpCode.ILSpy.Metadata
FieldMarshalEntry scrollTargetEntry = default;
var length = metadata.GetTableRowCount(TableIndex.FieldMarshal);
byte* ptr = metadata.MetadataPointer;
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset;
for (int rid = 1; rid <= length; rid++)
{
@ -79,14 +80,14 @@ namespace ICSharpCode.ILSpy.Metadata @@ -79,14 +80,14 @@ namespace ICSharpCode.ILSpy.Metadata
public readonly BlobHandle NativeType;
public readonly EntityHandle Parent;
public unsafe FieldMarshal(byte* ptr, int blobHeapSize, int hasFieldMarshalRefSize)
public FieldMarshal(ReadOnlySpan<byte> ptr, int blobHeapSize, int hasFieldMarshalRefSize)
{
Parent = Helpers.FromHasFieldMarshalTag((uint)Helpers.GetValue(ptr, hasFieldMarshalRefSize));
NativeType = MetadataTokens.BlobHandle(Helpers.GetValue(ptr + hasFieldMarshalRefSize, blobHeapSize));
Parent = Helpers.FromHasFieldMarshalTag((uint)Helpers.GetValueLittleEndian(ptr, hasFieldMarshalRefSize));
NativeType = MetadataTokens.BlobHandle(Helpers.GetValueLittleEndian(ptr.Slice(hasFieldMarshalRefSize, blobHeapSize)));
}
}
unsafe struct FieldMarshalEntry
struct FieldMarshalEntry
{
readonly PEFile module;
readonly MetadataReader metadata;
@ -112,7 +113,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -112,7 +113,7 @@ namespace ICSharpCode.ILSpy.Metadata
[ColumnInfo("X8", Kind = ColumnKind.HeapOffset)]
public int NativeType => MetadataTokens.GetHeapOffset(fieldMarshal.NativeType);
public FieldMarshalEntry(PEFile module, byte* ptr, int metadataOffset, int row)
public FieldMarshalEntry(PEFile module, ReadOnlySpan<byte> ptr, int metadataOffset, int row)
{
this.module = module;
this.metadata = module.Metadata;
@ -122,7 +123,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -122,7 +123,7 @@ namespace ICSharpCode.ILSpy.Metadata
this.Offset = metadataOffset + rowOffset;
int hasFieldMarshalRefSize = metadata.ComputeCodedTokenSize(32768, TableMask.Field | TableMask.Param);
int blobHeapSize = metadata.GetHeapSize(HeapIndex.Blob) < ushort.MaxValue ? 2 : 4;
this.fieldMarshal = new FieldMarshal(ptr + rowOffset, blobHeapSize, hasFieldMarshalRefSize);
this.fieldMarshal = new FieldMarshal(ptr.Slice(rowOffset), blobHeapSize, hasFieldMarshalRefSize);
this.parentTooltip = null;
}
}

18
ILSpy/Metadata/CorTables/FieldRVATableTreeNode.cs

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
@ -38,7 +40,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -38,7 +40,7 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Icon => Images.Literal;
public unsafe override bool View(ViewModels.TabPageModel tabPage)
public override bool View(ViewModels.TabPageModel tabPage)
{
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
@ -50,7 +52,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -50,7 +52,7 @@ namespace ICSharpCode.ILSpy.Metadata
FieldRVAEntry scrollTargetEntry = default;
var length = metadata.GetTableRowCount(TableIndex.FieldRva);
byte* ptr = metadata.MetadataPointer;
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset;
for (int rid = 1; rid <= length; rid++)
{
@ -79,14 +81,14 @@ namespace ICSharpCode.ILSpy.Metadata @@ -79,14 +81,14 @@ namespace ICSharpCode.ILSpy.Metadata
public readonly int Offset;
public readonly FieldDefinitionHandle Field;
public unsafe FieldRVA(byte* ptr, int fieldDefSize)
public FieldRVA(ReadOnlySpan<byte> ptr, int fieldDefSize)
{
Offset = Helpers.GetValue(ptr, 4);
Field = MetadataTokens.FieldDefinitionHandle(Helpers.GetValue(ptr + 4, fieldDefSize));
Offset = BinaryPrimitives.ReadInt32LittleEndian(ptr);
Field = MetadataTokens.FieldDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(4, fieldDefSize)));
}
}
unsafe struct FieldRVAEntry
struct FieldRVAEntry
{
readonly PEFile module;
readonly MetadataReader metadata;
@ -112,7 +114,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -112,7 +114,7 @@ namespace ICSharpCode.ILSpy.Metadata
[ColumnInfo("X8", Kind = ColumnKind.Other)]
public int FieldOffset => fieldRVA.Offset;
public FieldRVAEntry(PEFile module, byte* ptr, int metadataOffset, int row)
public FieldRVAEntry(PEFile module, ReadOnlySpan<byte> ptr, int metadataOffset, int row)
{
this.module = module;
this.metadata = module.Metadata;
@ -121,7 +123,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -121,7 +123,7 @@ namespace ICSharpCode.ILSpy.Metadata
+ metadata.GetTableRowSize(TableIndex.FieldRva) * (row - 1);
this.Offset = metadataOffset + rowOffset;
int fieldDefSize = metadata.GetTableRowCount(TableIndex.Field) < ushort.MaxValue ? 2 : 4;
this.fieldRVA = new FieldRVA(ptr + rowOffset, fieldDefSize);
this.fieldRVA = new FieldRVA(ptr.Slice(rowOffset), fieldDefSize);
this.fieldTooltip = null;
}
}

26
ILSpy/Metadata/CorTables/ImplMapTableTreeNode.cs

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
@ -40,7 +42,9 @@ namespace ICSharpCode.ILSpy.Metadata @@ -40,7 +42,9 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Icon => Images.Literal;
public unsafe override bool View(ViewModels.TabPageModel tabPage)
public override bool View(ViewModels.TabPageModel tabPage)
{
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
@ -52,11 +56,11 @@ namespace ICSharpCode.ILSpy.Metadata @@ -52,11 +56,11 @@ namespace ICSharpCode.ILSpy.Metadata
ImplMapEntry scrollTargetEntry = default;
var length = metadata.GetTableRowCount(TableIndex.ImplMap);
byte* ptr = metadata.MetadataPointer;
var span = metadata.AsReadOnlySpan();
int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset;
for (int rid = 1; rid <= length; rid++)
{
ImplMapEntry entry = new ImplMapEntry(module, ptr, metadataOffset, rid);
ImplMapEntry entry = new ImplMapEntry(module, span, metadataOffset, rid);
if (entry.RID == this.scrollTarget)
{
scrollTargetEntry = entry;
@ -83,16 +87,16 @@ namespace ICSharpCode.ILSpy.Metadata @@ -83,16 +87,16 @@ namespace ICSharpCode.ILSpy.Metadata
public readonly StringHandle ImportName;
public readonly ModuleReferenceHandle ImportScope;
public unsafe ImplMap(byte* ptr, int moduleRefSize, int memberForwardedTagRefSize, int stringHandleSize)
public ImplMap(ReadOnlySpan<byte> span, int moduleRefSize, int memberForwardedTagRefSize, int stringHandleSize)
{
MappingFlags = (PInvokeAttributes)Helpers.GetValue(ptr, 2);
MemberForwarded = Helpers.FromMemberForwardedTag((uint)Helpers.GetValue(ptr + 2, memberForwardedTagRefSize));
ImportName = MetadataTokens.StringHandle(Helpers.GetValue(ptr + 2 + memberForwardedTagRefSize, stringHandleSize));
ImportScope = MetadataTokens.ModuleReferenceHandle(Helpers.GetValue(ptr + 2 + memberForwardedTagRefSize + stringHandleSize, moduleRefSize));
MappingFlags = (PInvokeAttributes)BinaryPrimitives.ReadUInt16LittleEndian(span);
MemberForwarded = Helpers.FromMemberForwardedTag((uint)Helpers.GetValueLittleEndian(span.Slice(2, memberForwardedTagRefSize)));
ImportName = MetadataTokens.StringHandle(Helpers.GetValueLittleEndian(span.Slice(2 + memberForwardedTagRefSize, stringHandleSize)));
ImportScope = MetadataTokens.ModuleReferenceHandle(Helpers.GetValueLittleEndian(span.Slice(2 + memberForwardedTagRefSize + stringHandleSize, moduleRefSize)));
}
}
unsafe struct ImplMapEntry
struct ImplMapEntry
{
readonly PEFile module;
readonly MetadataReader metadata;
@ -141,7 +145,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -141,7 +145,7 @@ namespace ICSharpCode.ILSpy.Metadata
public string ImportNameTooltip => $"{MetadataTokens.GetHeapOffset(implMap.ImportName):X} \"{ImportName}\"";
public unsafe ImplMapEntry(PEFile module, byte* ptr, int metadataOffset, int row)
public ImplMapEntry(PEFile module, ReadOnlySpan<byte> span, int metadataOffset, int row)
{
this.module = module;
this.metadata = module.Metadata;
@ -152,7 +156,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -152,7 +156,7 @@ namespace ICSharpCode.ILSpy.Metadata
int moduleRefSize = metadata.GetTableRowCount(TableIndex.ModuleRef) < ushort.MaxValue ? 2 : 4;
int memberForwardedTagRefSize = metadata.ComputeCodedTokenSize(32768, TableMask.MethodDef | TableMask.Field);
int stringHandleSize = metadata.GetHeapSize(HeapIndex.String) < ushort.MaxValue ? 2 : 4;
this.implMap = new ImplMap(ptr + rowOffset, moduleRefSize, memberForwardedTagRefSize, stringHandleSize);
this.implMap = new ImplMap(span.Slice(rowOffset), moduleRefSize, memberForwardedTagRefSize, stringHandleSize);
this.importScopeTooltip = null;
this.memberForwardedTooltip = null;
}

17
ILSpy/Metadata/CorTables/InterfaceImplTableTreeNode.cs

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
@ -38,7 +39,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -38,7 +39,7 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Icon => Images.Literal;
public unsafe override bool View(ViewModels.TabPageModel tabPage)
public override bool View(ViewModels.TabPageModel tabPage)
{
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
@ -50,7 +51,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -50,7 +51,7 @@ namespace ICSharpCode.ILSpy.Metadata
InterfaceImplEntry scrollTargetEntry = default;
var length = metadata.GetTableRowCount(TableIndex.InterfaceImpl);
byte* ptr = metadata.MetadataPointer;
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset;
for (int rid = 1; rid <= length; rid++)
{
@ -79,14 +80,14 @@ namespace ICSharpCode.ILSpy.Metadata @@ -79,14 +80,14 @@ namespace ICSharpCode.ILSpy.Metadata
public readonly EntityHandle Class;
public readonly EntityHandle Interface;
public unsafe InterfaceImpl(byte* ptr, int classSize, int interfaceSize)
public InterfaceImpl(ReadOnlySpan<byte> ptr, int classSize, int interfaceSize)
{
Class = MetadataTokens.TypeDefinitionHandle(Helpers.GetValue(ptr, classSize));
Interface = Helpers.FromTypeDefOrRefTag((uint)Helpers.GetValue(ptr + classSize, interfaceSize));
Class = MetadataTokens.TypeDefinitionHandle(Helpers.GetValueLittleEndian(ptr, classSize));
Interface = Helpers.FromTypeDefOrRefTag((uint)Helpers.GetValueLittleEndian(ptr.Slice(classSize, interfaceSize)));
}
}
unsafe struct InterfaceImplEntry
struct InterfaceImplEntry
{
readonly PEFile module;
readonly MetadataReader metadata;
@ -120,7 +121,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -120,7 +121,7 @@ namespace ICSharpCode.ILSpy.Metadata
string interfaceTooltip;
public string InterfaceTooltip => GenerateTooltip(ref interfaceTooltip, module, interfaceImpl.Interface);
public InterfaceImplEntry(PEFile module, byte* ptr, int metadataOffset, int row)
public InterfaceImplEntry(PEFile module, ReadOnlySpan<byte> ptr, int metadataOffset, int row)
{
this.module = module;
this.metadata = module.Metadata;
@ -128,7 +129,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -128,7 +129,7 @@ namespace ICSharpCode.ILSpy.Metadata
var rowOffset = metadata.GetTableMetadataOffset(TableIndex.InterfaceImpl)
+ metadata.GetTableRowSize(TableIndex.InterfaceImpl) * (row - 1);
this.Offset = metadataOffset + rowOffset;
this.interfaceImpl = new InterfaceImpl(ptr + rowOffset, metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4, metadata.ComputeCodedTokenSize(16384, TableMask.TypeDef | TableMask.TypeRef | TableMask.TypeSpec));
this.interfaceImpl = new InterfaceImpl(ptr.Slice(rowOffset), metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4, metadata.ComputeCodedTokenSize(16384, TableMask.TypeDef | TableMask.TypeRef | TableMask.TypeSpec));
this.interfaceTooltip = null;
this.classTooltip = null;
}

17
ILSpy/Metadata/CorTables/NestedClassTableTreeNode.cs

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
@ -38,7 +39,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -38,7 +39,7 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Icon => Images.Literal;
public unsafe override bool View(ViewModels.TabPageModel tabPage)
public override bool View(ViewModels.TabPageModel tabPage)
{
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
@ -50,7 +51,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -50,7 +51,7 @@ namespace ICSharpCode.ILSpy.Metadata
NestedClassEntry scrollTargetEntry = default;
var length = metadata.GetTableRowCount(TableIndex.NestedClass);
byte* ptr = metadata.MetadataPointer;
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset;
for (int rid = 1; rid <= length; rid++)
{
@ -79,14 +80,14 @@ namespace ICSharpCode.ILSpy.Metadata @@ -79,14 +80,14 @@ namespace ICSharpCode.ILSpy.Metadata
public readonly TypeDefinitionHandle Nested;
public readonly TypeDefinitionHandle Enclosing;
public unsafe NestedClass(byte* ptr, int typeDefSize)
public NestedClass(ReadOnlySpan<byte> ptr, int typeDefSize)
{
Nested = MetadataTokens.TypeDefinitionHandle(Helpers.GetValue(ptr, typeDefSize));
Enclosing = MetadataTokens.TypeDefinitionHandle(Helpers.GetValue(ptr + typeDefSize, typeDefSize));
Nested = MetadataTokens.TypeDefinitionHandle(Helpers.GetValueLittleEndian(ptr, typeDefSize));
Enclosing = MetadataTokens.TypeDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(typeDefSize), typeDefSize));
}
}
unsafe struct NestedClassEntry
struct NestedClassEntry
{
readonly PEFile module;
readonly MetadataReader metadata;
@ -120,7 +121,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -120,7 +121,7 @@ namespace ICSharpCode.ILSpy.Metadata
string enclosingClassTooltip;
public string EnclosingClassTooltip => GenerateTooltip(ref enclosingClassTooltip, module, nestedClass.Enclosing);
public unsafe NestedClassEntry(PEFile module, byte* ptr, int metadataOffset, int row)
public NestedClassEntry(PEFile module, ReadOnlySpan<byte> ptr, int metadataOffset, int row)
{
this.module = module;
this.metadata = module.Metadata;
@ -129,7 +130,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -129,7 +130,7 @@ namespace ICSharpCode.ILSpy.Metadata
+ metadata.GetTableRowSize(TableIndex.NestedClass) * (row - 1);
this.Offset = metadataOffset + rowOffset;
int typeDefSize = metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4;
this.nestedClass = new NestedClass(ptr + rowOffset, typeDefSize);
this.nestedClass = new NestedClass(ptr.Slice(rowOffset), typeDefSize);
this.nestedClassTooltip = null;
this.enclosingClassTooltip = null;
}

17
ILSpy/Metadata/CorTables/PropertyMapTableTreeNode.cs

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
@ -38,7 +39,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -38,7 +39,7 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Icon => Images.Literal;
public unsafe override bool View(ViewModels.TabPageModel tabPage)
public override bool View(ViewModels.TabPageModel tabPage)
{
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
@ -50,7 +51,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -50,7 +51,7 @@ namespace ICSharpCode.ILSpy.Metadata
PropertyMapEntry scrollTargetEntry = default;
var length = metadata.GetTableRowCount(TableIndex.PropertyMap);
byte* ptr = metadata.MetadataPointer;
ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset;
for (int rid = 1; rid <= length; rid++)
{
@ -79,14 +80,14 @@ namespace ICSharpCode.ILSpy.Metadata @@ -79,14 +80,14 @@ namespace ICSharpCode.ILSpy.Metadata
public readonly TypeDefinitionHandle Parent;
public readonly PropertyDefinitionHandle PropertyList;
public unsafe PropertyMap(byte* ptr, int typeDefSize, int propertyDefSize)
public PropertyMap(ReadOnlySpan<byte> ptr, int typeDefSize, int propertyDefSize)
{
Parent = MetadataTokens.TypeDefinitionHandle(Helpers.GetValue(ptr, typeDefSize));
PropertyList = MetadataTokens.PropertyDefinitionHandle(Helpers.GetValue(ptr + typeDefSize, propertyDefSize));
Parent = MetadataTokens.TypeDefinitionHandle(Helpers.GetValueLittleEndian(ptr, typeDefSize));
PropertyList = MetadataTokens.PropertyDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(typeDefSize, propertyDefSize)));
}
}
unsafe struct PropertyMapEntry
struct PropertyMapEntry
{
readonly PEFile module;
readonly MetadataReader metadata;
@ -120,7 +121,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -120,7 +121,7 @@ namespace ICSharpCode.ILSpy.Metadata
string propertyListTooltip;
public string PropertyListTooltip => GenerateTooltip(ref propertyListTooltip, module, propertyMap.PropertyList);
public PropertyMapEntry(PEFile module, byte* ptr, int metadataOffset, int row)
public PropertyMapEntry(PEFile module, ReadOnlySpan<byte> ptr, int metadataOffset, int row)
{
this.module = module;
this.metadata = module.Metadata;
@ -130,7 +131,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -130,7 +131,7 @@ namespace ICSharpCode.ILSpy.Metadata
this.Offset = metadataOffset + rowOffset;
int typeDefSize = metadata.GetTableRowCount(TableIndex.TypeDef) < ushort.MaxValue ? 2 : 4;
int propertyDefSize = metadata.GetTableRowCount(TableIndex.Property) < ushort.MaxValue ? 2 : 4;
this.propertyMap = new PropertyMap(ptr + rowOffset, typeDefSize, propertyDefSize);
this.propertyMap = new PropertyMap(ptr.Slice(rowOffset), typeDefSize, propertyDefSize);
this.propertyListTooltip = null;
this.parentTooltip = null;
}

4
ILSpy/Metadata/DebugTables/StateMachineMethodTableTreeNode.cs

@ -44,7 +44,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -44,7 +44,7 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Icon => Images.Literal;
public unsafe override bool View(ViewModels.TabPageModel tabPage)
public override bool View(ViewModels.TabPageModel tabPage)
{
tabPage.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false;
@ -53,7 +53,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -53,7 +53,7 @@ namespace ICSharpCode.ILSpy.Metadata
var list = new List<StateMachineMethodEntry>();
StateMachineMethodEntry scrollTargetEntry = default;
var length = metadata.GetTableRowCount(TableIndex.StateMachineMethod);
var reader = new BlobReader(metadata.MetadataPointer, metadata.MetadataLength);
var reader = metadata.AsBlobReader();
reader.Offset = metadata.GetTableMetadataOffset(TableIndex.StateMachineMethod);
for (int rid = 1; rid <= length; rid++)

11
ILSpy/Metadata/Helpers.cs

@ -212,11 +212,20 @@ namespace ICSharpCode.ILSpy.Metadata @@ -212,11 +212,20 @@ namespace ICSharpCode.ILSpy.Metadata
}
}
[Obsolete("Use safe GetValueLittleEndian(ReadOnlySpan<byte>) or appropriate BinaryPrimitives.Read* method")]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe int GetValue(byte* ptr, int size)
=> GetValueLittleEndian(new ReadOnlySpan<byte>(ptr, size));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetValueLittleEndian(ReadOnlySpan<byte> ptr, int size)
=> GetValueLittleEndian(ptr.Slice(0, size));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetValueLittleEndian(ReadOnlySpan<byte> ptr)
{
int result = 0;
for (int i = 0; i < size; i += 2)
for (int i = 0; i < ptr.Length; i += 2)
{
result |= ptr[i] << 8 * i;
result |= ptr[i + 1] << 8 * (i + 1);

Loading…
Cancel
Save