mirror of https://github.com/icsharpcode/ILSpy.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
62 lines
2.5 KiB
62 lines
2.5 KiB
using System; |
|
using System.Collections.Generic; |
|
using System.Collections.Immutable; |
|
using System.Linq; |
|
using System.Reflection; |
|
using System.Reflection.Metadata; |
|
using System.Reflection.Metadata.Ecma335; |
|
using System.Text; |
|
using System.Threading.Tasks; |
|
using ICSharpCode.Decompiler.Metadata; |
|
|
|
namespace ICSharpCode.Decompiler |
|
{ |
|
public static partial class SRMExtensions |
|
{ |
|
public static unsafe MethodSemanticsAttributes GetMethodSemanticsAttributes(this MethodDefinitionHandle handle, MetadataReader reader) |
|
{ |
|
byte* startPointer = reader.MetadataPointer; |
|
int offset = reader.GetTableMetadataOffset(TableIndex.MethodSemantics); |
|
int rowSize = reader.GetTableRowSize(TableIndex.MethodSemantics); |
|
int rowCount = reader.GetTableRowCount(TableIndex.MethodSemantics); |
|
var small = reader.IsSmallReference(TableIndex.MethodDef); |
|
|
|
int methodRowNo = reader.GetRowNumber(handle); |
|
for (int row = rowCount - 1; row >= 0; row--) { |
|
byte* ptr = startPointer + offset + rowSize * row; |
|
uint rowNo = small ? *(ushort*)(ptr + 2) : *(uint*)(ptr + 2); |
|
if (methodRowNo == rowNo) { |
|
return (MethodSemanticsAttributes)(*(ushort*)ptr); |
|
} |
|
} |
|
return 0; |
|
} |
|
|
|
public static unsafe ImmutableArray<MethodImplementationHandle> GetMethodImplementations(this MethodDefinitionHandle handle, MetadataReader reader) |
|
{ |
|
byte* startPointer = reader.MetadataPointer; |
|
int offset = reader.GetTableMetadataOffset(TableIndex.MethodImpl); |
|
int rowSize = reader.GetTableRowSize(TableIndex.MethodImpl); |
|
int rowCount = reader.GetTableRowCount(TableIndex.MethodImpl); |
|
var methodDefSize = reader.GetReferenceSize(TableIndex.MethodDef); |
|
var typeDefSize = reader.GetReferenceSize(TableIndex.TypeDef); |
|
|
|
var containingTypeRow = reader.GetRowNumber(reader.GetMethodDefinition(handle).GetDeclaringType()); |
|
var methodDefRow = reader.GetRowNumber(handle); |
|
|
|
var list = new List<MethodImplementationHandle>(); |
|
|
|
// TODO : if sorted -> binary search? |
|
for (int row = 0; row < reader.GetTableRowCount(TableIndex.MethodImpl); row++) { |
|
byte* ptr = startPointer + offset + rowSize * row; |
|
uint currentTypeRow = typeDefSize == 2 ? *(ushort*)ptr : *(uint*)ptr; |
|
if (currentTypeRow != containingTypeRow) continue; |
|
uint currentMethodRowCoded = methodDefSize == 2 ? *(ushort*)(ptr + typeDefSize) : *(uint*)(ptr + typeDefSize); |
|
if ((currentMethodRowCoded >> 1) != methodDefRow) continue; |
|
list.Add(MetadataTokens.MethodImplementationHandle(row + 1)); |
|
} |
|
|
|
return list.ToImmutableArray(); |
|
} |
|
} |
|
}
|
|
|