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 @@
using System; using System;
using System.Buffers.Binary;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq; using System.Linq;
@ -384,11 +385,13 @@ namespace ICSharpCode.Decompiler.Metadata
yield return Read(row); 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; var span = metadata.AsReadOnlySpan();
int methodDef = methodSmall ? *(ushort*)(ptr + 2) : (int)*(uint*)(ptr + 2); var methodDefSpan = span.Slice(offset + rowSize * row + 2);
int assocDef = assocSmall ? *(ushort*)(ptr + assocOffset) : (int)*(uint*)(ptr + assocOffset); 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; EntityHandle propOrEvent;
if ((assocDef & 0x1) == 1) if ((assocDef & 0x1) == 1)
{ {
@ -398,7 +401,7 @@ namespace ICSharpCode.Decompiler.Metadata
{ {
propOrEvent = MetadataTokens.EventDefinitionHandle(assocDef >> 1); 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
} }
} }
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 offset = metadata.GetTableMetadataOffset(TableIndex.FieldLayout);
int rowSize = metadata.GetTableRowSize(TableIndex.FieldLayout); int rowSize = metadata.GetTableRowSize(TableIndex.FieldLayout);
int rowCount = metadata.GetTableRowCount(TableIndex.FieldLayout); int rowCount = metadata.GetTableRowCount(TableIndex.FieldLayout);
@ -422,14 +425,31 @@ namespace ICSharpCode.Decompiler.Metadata
bool small = metadata.GetTableRowCount(TableIndex.Field) <= ushort.MaxValue; bool small = metadata.GetTableRowCount(TableIndex.Field) <= ushort.MaxValue;
for (int row = rowCount - 1; row >= 0; row--) for (int row = rowCount - 1; row >= 0; row--)
{ {
byte* ptr = startPointer + offset + rowSize * row; ReadOnlySpan<byte> ptr = startPointer.Slice(offset + rowSize * row);
uint rowNo = small ? *(ushort*)(ptr + 4) : *(uint*)(ptr + 4); var rowNoSpan = ptr.Slice(4);
uint rowNo = small ? BinaryPrimitives.ReadUInt16LittleEndian(rowNoSpan) : BinaryPrimitives.ReadUInt32LittleEndian(rowNoSpan);
if (fieldRowNo == rowNo) if (fieldRowNo == rowNo)
{ {
return (*(int*)ptr, MetadataTokens.FieldDefinitionHandle(fieldRowNo)); return (BinaryPrimitives.ReadInt32LittleEndian(ptr), MetadataTokens.FieldDefinitionHandle(fieldRowNo));
} }
} }
return (0, default); 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 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Buffers.Binary;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
@ -38,7 +40,7 @@ namespace ICSharpCode.ILSpy.Metadata
public override object Icon => Images.Literal; 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.Title = Text.ToString();
tabPage.SupportsLanguageSwitching = false; tabPage.SupportsLanguageSwitching = false;
@ -49,7 +51,7 @@ namespace ICSharpCode.ILSpy.Metadata
var list = new List<ClassLayoutEntry>(); var list = new List<ClassLayoutEntry>();
var length = metadata.GetTableRowCount(TableIndex.ClassLayout); var length = metadata.GetTableRowCount(TableIndex.ClassLayout);
byte* ptr = metadata.MetadataPointer; ReadOnlySpan<byte> ptr = metadata.AsReadOnlySpan();
int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset; int metadataOffset = module.Reader.PEHeaders.MetadataStartOffset;
ClassLayoutEntry scrollTargetEntry = default; ClassLayoutEntry scrollTargetEntry = default;
@ -80,15 +82,15 @@ namespace ICSharpCode.ILSpy.Metadata
public readonly EntityHandle Parent; public readonly EntityHandle Parent;
public readonly uint ClassSize; public readonly uint ClassSize;
public unsafe ClassLayout(byte* ptr, int typeDefSize) public ClassLayout(ReadOnlySpan<byte> ptr, int typeDefSize)
{ {
PackingSize = (ushort)Helpers.GetValue(ptr, 2); PackingSize = BinaryPrimitives.ReadUInt16LittleEndian(ptr);
ClassSize = (uint)Helpers.GetValue(ptr + 2, 4); ClassSize = BinaryPrimitives.ReadUInt32LittleEndian(ptr.Slice(2, 4));
Parent = MetadataTokens.TypeDefinitionHandle(Helpers.GetValue(ptr + 6, typeDefSize)); Parent = MetadataTokens.TypeDefinitionHandle(Helpers.GetValueLittleEndian(ptr.Slice(6, typeDefSize)));
} }
} }
unsafe struct ClassLayoutEntry struct ClassLayoutEntry
{ {
readonly PEFile module; readonly PEFile module;
readonly MetadataReader metadata; readonly MetadataReader metadata;
@ -117,7 +119,7 @@ namespace ICSharpCode.ILSpy.Metadata
[ColumnInfo("X8", Kind = ColumnKind.Other)] [ColumnInfo("X8", Kind = ColumnKind.Other)]
public uint ClassSize => classLayout.ClassSize; 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.module = module;
this.metadata = module.Metadata; this.metadata = module.Metadata;
@ -125,7 +127,7 @@ namespace ICSharpCode.ILSpy.Metadata
var rowOffset = metadata.GetTableMetadataOffset(TableIndex.ClassLayout) var rowOffset = metadata.GetTableMetadataOffset(TableIndex.ClassLayout)
+ metadata.GetTableRowSize(TableIndex.ClassLayout) * (row - 1); + metadata.GetTableRowSize(TableIndex.ClassLayout) * (row - 1);
this.Offset = metadataOffset + rowOffset; 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; this.parentTooltip = null;
} }
} }

17
ILSpy/Metadata/CorTables/EventMapTableTreeNode.cs

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

18
ILSpy/Metadata/CorTables/FieldLayoutTableTreeNode.cs

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

17
ILSpy/Metadata/CorTables/FieldMarshalTableTreeNode.cs

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

18
ILSpy/Metadata/CorTables/FieldRVATableTreeNode.cs

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

26
ILSpy/Metadata/CorTables/ImplMapTableTreeNode.cs

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

17
ILSpy/Metadata/CorTables/InterfaceImplTableTreeNode.cs

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

17
ILSpy/Metadata/CorTables/NestedClassTableTreeNode.cs

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

17
ILSpy/Metadata/CorTables/PropertyMapTableTreeNode.cs

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

4
ILSpy/Metadata/DebugTables/StateMachineMethodTableTreeNode.cs

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

11
ILSpy/Metadata/Helpers.cs

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

Loading…
Cancel
Save