Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 30 additions & 10 deletions ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
Expand Down Expand Up @@ -384,11 +385,13 @@ public static IEnumerable<MethodSpecificationHandle> GetMethodSpecifications(thi
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)
{
Expand All @@ -398,7 +401,7 @@ public static IEnumerable<MethodSpecificationHandle> GetMethodSpecifications(thi
{
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);
}
}

Expand All @@ -411,9 +414,9 @@ public static IEnumerable<EntityHandle> GetFieldLayouts(this MetadataReader meta
}
}

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);
Expand All @@ -422,14 +425,31 @@ public unsafe static (int Offset, FieldDefinitionHandle FieldDef) GetFieldLayout
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 changes: 11 additions & 9 deletions ILSpy/Metadata/CorTables/ClassLayoutTableTreeNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -38,7 +40,7 @@ public ClassLayoutTableTreeNode(PEFile module)

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;
Expand All @@ -49,7 +51,7 @@ public unsafe override bool View(ViewModels.TabPageModel tabPage)
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;

Expand Down Expand Up @@ -80,15 +82,15 @@ readonly struct ClassLayout
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;
Expand Down Expand Up @@ -117,15 +119,15 @@ public void OnParentClick()
[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;
this.RID = row;
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;
}
}
Expand Down
17 changes: 9 additions & 8 deletions ILSpy/Metadata/CorTables/EventMapTableTreeNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -38,7 +39,7 @@ public EventMapTableTreeNode(PEFile module)

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;
Expand All @@ -50,7 +51,7 @@ public unsafe override bool View(ViewModels.TabPageModel tabPage)
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++)
{
Expand Down Expand Up @@ -79,14 +80,14 @@ readonly struct EventMap
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;
Expand Down Expand Up @@ -120,7 +121,7 @@ public void OnEventListClick()
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;
Expand All @@ -130,7 +131,7 @@ public EventMapEntry(PEFile module, byte* ptr, int metadataOffset, int row)
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;
}
Expand Down
18 changes: 10 additions & 8 deletions ILSpy/Metadata/CorTables/FieldLayoutTableTreeNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -38,7 +40,7 @@ public FieldLayoutTableTreeNode(PEFile module)

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;
Expand All @@ -50,7 +52,7 @@ public unsafe override bool View(ViewModels.TabPageModel tabPage)
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++)
{
Expand Down Expand Up @@ -79,14 +81,14 @@ readonly struct FieldLayout
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;
Expand All @@ -112,7 +114,7 @@ public void OnFieldClick()
[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;
Expand All @@ -121,7 +123,7 @@ public FieldLayoutEntry(PEFile module, byte* ptr, int metadataOffset, int row)
+ 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;
}
}
Expand Down
17 changes: 9 additions & 8 deletions ILSpy/Metadata/CorTables/FieldMarshalTableTreeNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -38,7 +39,7 @@ public FieldMarshalTableTreeNode(PEFile module)

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;
Expand All @@ -50,7 +51,7 @@ public unsafe override bool View(ViewModels.TabPageModel tabPage)
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++)
{
Expand Down Expand Up @@ -79,14 +80,14 @@ readonly struct FieldMarshal
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;
Expand All @@ -112,7 +113,7 @@ public void OnParentClick()
[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;
Expand All @@ -122,7 +123,7 @@ public FieldMarshalEntry(PEFile module, byte* ptr, int metadataOffset, int row)
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;
}
}
Expand Down
18 changes: 10 additions & 8 deletions ILSpy/Metadata/CorTables/FieldRVATableTreeNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -38,7 +40,7 @@ public FieldRVATableTreeNode(PEFile module)

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;
Expand All @@ -50,7 +52,7 @@ public unsafe override bool View(ViewModels.TabPageModel tabPage)
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++)
{
Expand Down Expand Up @@ -79,14 +81,14 @@ readonly struct FieldRVA
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;
Expand All @@ -112,7 +114,7 @@ public void OnFieldClick()
[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;
Expand All @@ -121,7 +123,7 @@ public FieldRVAEntry(PEFile module, byte* ptr, int metadataOffset, int row)
+ 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;
}
}
Expand Down
Loading