Browse Source

Implementation of MetadataLoader mostly completed (CecilLoader.cs)

pull/1198/head
Siegfried Pammer 7 years ago
parent
commit
3d9cbb71bd
  1. 8
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
  2. 736
      ICSharpCode.Decompiler/TypeSystem/CecilLoader.cs
  3. 98
      ICSharpCode.Decompiler/TypeSystem/Implementation/TypeSpecification.cs
  4. 72
      ICSharpCode.Decompiler/TypeSystem/MetadataExtensions.cs

8
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

@ -426,11 +426,11 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -426,11 +426,11 @@ namespace ICSharpCode.Decompiler.Disassembler
void WriteMarshalInfo(BlobReader marshalInfo)
{
output.Write("marshal(");
WriteNativeType(marshalInfo);
WriteNativeType(ref marshalInfo);
output.Write(") ");
}
void WriteNativeType(BlobReader blob)
void WriteNativeType(ref BlobReader blob)
{
byte type;
switch (type = blob.ReadByte()) {
@ -483,7 +483,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -483,7 +483,7 @@ namespace ICSharpCode.Decompiler.Disassembler
goto default; // ??
case 0x2a: // NATIVE_TYPE_ARRAY
if (blob.RemainingBytes > 0)
WriteNativeType(blob);
WriteNativeType(ref blob);
output.Write('[');
int sizeParameterIndex = blob.TryReadCompressedInteger(out int value) ? value : -1;
int size = blob.TryReadCompressedInteger(out value) ? value : -1;
@ -596,7 +596,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -596,7 +596,7 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Write("fixed array");
output.Write("[{0}]", blob.TryReadCompressedInteger(out value) ? value : 0);
output.Write(' ');
WriteNativeType(blob);
WriteNativeType(ref blob);
break;
case 0x22: // ByValStr
output.Write("byvalstr");

736
ICSharpCode.Decompiler/TypeSystem/CecilLoader.cs

File diff suppressed because it is too large Load Diff

98
ICSharpCode.Decompiler/TypeSystem/Implementation/TypeSpecification.cs

@ -73,16 +73,35 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -73,16 +73,35 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public sealed class PinnedTypeReference : ITypeReference
{
readonly ITypeReference elementType;
public ITypeReference ElementType { get; }
public PinnedTypeReference(ITypeReference elementType)
{
this.elementType = elementType;
ElementType = elementType;
}
public IType Resolve(ITypeResolveContext context)
{
return new PinnedType(elementType.Resolve(context));
return new PinnedType(ElementType.Resolve(context));
}
}
public sealed class ModifiedTypeReference : ITypeReference
{
public ITypeReference ElementType { get; }
public ITypeReference ModifierType { get; }
public bool IsRequired { get; }
public ModifiedTypeReference(ITypeReference elementType, ITypeReference modifierType, bool isRequired)
{
ElementType = elementType;
ModifierType = modifierType;
IsRequired = isRequired;
}
public IType Resolve(ITypeResolveContext context)
{
return ElementType.Resolve(context);
}
}
@ -122,7 +141,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -122,7 +141,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public ITypeReference GetModifiedType(ITypeReference modifier, ITypeReference unmodifiedType, bool isRequired)
{
return unmodifiedType;
return new ModifiedTypeReference(unmodifiedType, modifier, isRequired);
}
public ITypeReference GetPinnedType(ITypeReference elementType)
@ -147,7 +166,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -147,7 +166,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public ITypeReference GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
{
return new DefaultUnresolvedTypeDefinition(handle.GetFullTypeName(reader).ReflectionName);
return new GetClassTypeReference(handle.GetFullTypeName(reader), DefaultAssemblyReference.CurrentAssembly);
}
public ITypeReference GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
@ -165,40 +184,47 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -165,40 +184,47 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
}
}
class TypeSystemAttributeTypeProvider : ICustomAttributeTypeProvider<ITypeReference>
class TypeSystemAttributeTypeProvider : ICustomAttributeTypeProvider<IType>
{
public ITypeReference GetPrimitiveType(PrimitiveTypeCode typeCode)
readonly ITypeResolveContext context;
public TypeSystemAttributeTypeProvider(ITypeResolveContext context)
{
return KnownTypeReference.Get(typeCode.ToKnownTypeCode());
this.context = context;
}
public ITypeReference GetSystemType()
public IType GetPrimitiveType(PrimitiveTypeCode typeCode)
{
return KnownTypeReference.Get(KnownTypeCode.Type);
return context.Compilation.FindType(typeCode.ToKnownTypeCode());
}
public ITypeReference GetSZArrayType(ITypeReference elementType)
public IType GetSystemType()
{
return new ArrayTypeReference(elementType);
return context.Compilation.FindType(KnownTypeCode.Type);
}
public ITypeReference GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
public IType GetSZArrayType(IType elementType)
{
return new ArrayType(context.Compilation, elementType);
}
public IType GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
{
var type = reader.GetTypeDefinition(handle);
return new DefaultUnresolvedTypeDefinition(type.GetFullTypeName(reader).ToString());
return new DefaultUnresolvedTypeDefinition(type.GetFullTypeName(reader).ToString()).Resolve(context);
}
public ITypeReference GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
public IType GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
{
return new DefaultUnresolvedTypeDefinition(handle.GetFullTypeName(reader).ToString());
return new DefaultUnresolvedTypeDefinition(handle.GetFullTypeName(reader).ToString()).Resolve(context);
}
public ITypeReference GetTypeFromSerializedName(string name)
public IType GetTypeFromSerializedName(string name)
{
return new GetClassTypeReference(new FullTypeName(name));
return new GetClassTypeReference(new FullTypeName(name)).Resolve(context);
}
public PrimitiveTypeCode GetUnderlyingEnumType(ITypeReference type)
public PrimitiveTypeCode GetUnderlyingEnumType(IType type)
{
var def = type.GetEnumUnderlyingType().GetDefinition();
if (def == null)
@ -211,4 +237,38 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -211,4 +237,38 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return type.IsKnownType(KnownTypeCode.Type);
}
}
public class MetadataUnresolvedAttributeBlob : IUnresolvedAttribute, ISupportsInterning
{
MetadataReader reader;
ITypeReference attributeType;
CustomAttribute attribute;
public MetadataUnresolvedAttributeBlob(MetadataReader reader, ITypeReference attributeType, CustomAttribute attribute)
{
this.reader = reader;
this.attributeType = attributeType;
this.attribute = attribute;
}
public DomRegion Region => DomRegion.Empty;
public IAttribute CreateResolvedAttribute(ITypeResolveContext context)
{
var blob = reader.GetBlobBytes(attribute.Value);
var signature = attribute.DecodeValue(new TypeSystemAttributeTypeProvider(context));
return new UnresolvedAttributeBlob(attributeType, signature.FixedArguments.Select(t => t.Type.ToTypeReference()).ToArray(), blob)
.CreateResolvedAttribute(context);
}
bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
{
throw new NotImplementedException();
}
int ISupportsInterning.GetHashCodeForInterning()
{
throw new NotImplementedException();
}
}
}

72
ICSharpCode.Decompiler/TypeSystem/MetadataExtensions.cs

@ -1,7 +1,10 @@ @@ -1,7 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
@ -9,6 +12,28 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -9,6 +12,28 @@ namespace ICSharpCode.Decompiler.TypeSystem
{
static class MetadataExtensions
{
public static string GetFullAssemblyName(this MetadataReader reader)
{
if (!reader.IsAssembly)
return string.Empty;
var asm = reader.GetAssemblyDefinition();
string publicKey = "null";
if (!asm.PublicKey.IsNil) {
SHA1 sha1 = SHA1.Create();
var publicKeyTokenBytes = sha1.ComputeHash(reader.GetBlobBytes(asm.PublicKey)).Skip(12).ToArray();
publicKey = publicKeyTokenBytes.ToHexString();
}
return $"{reader.GetString(asm.Name)}, Version={asm.Version}, Culture={reader.GetString(asm.Culture)}, PublicKeyToken={publicKey}";
}
static string ToHexString(this byte[] bytes)
{
StringBuilder sb = new StringBuilder(bytes.Length * 2);
foreach (var b in bytes)
sb.AppendFormat("{0:x2}", b);
return sb.ToString();
}
/// <summary>
/// Gets the type of the attribute.
/// </summary>
@ -90,6 +115,23 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -90,6 +115,23 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
}
public unsafe static 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);
int token = reader.GetToken(handle);
for (int row = rowCount - 1; row >= 0; row--) {
byte* ptr = startPointer + offset + rowSize * row;
ushort methodToken = *(ptr + 2);
if (token == methodToken) {
return (MethodSemanticsAttributes)(*ptr);
}
}
return 0;
}
public static bool IsValueType(this TypeDefinition typeDefinition, MetadataReader reader)
{
if (typeDefinition.BaseType.IsNil)
@ -101,6 +143,13 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -101,6 +143,13 @@ namespace ICSharpCode.Decompiler.TypeSystem
return baseType == "System.ValueType" && thisType != "System.Enum";
}
public static bool IsConstructor(this MethodDefinition methodDefinition, MetadataReader reader)
{
string name = reader.GetString(methodDefinition.Name);
return (methodDefinition.Attributes & (MethodAttributes.RTSpecialName | MethodAttributes.SpecialName)) != 0
&& (name == ".cctor" || name == ".ctor");
}
public static bool IsEnum(this TypeDefinition typeDefinition, MetadataReader reader)
{
if (typeDefinition.BaseType.IsNil)
@ -108,6 +157,29 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -108,6 +157,29 @@ namespace ICSharpCode.Decompiler.TypeSystem
return typeDefinition.BaseType.GetFullTypeName(reader).ToString() == "System.Enum";
}
public static bool HasOverrides(this MethodDefinitionHandle handle, MetadataReader reader)
{
for (int row = 1; row <= reader.GetTableRowCount(TableIndex.MethodImpl); row++) {
var impl = reader.GetMethodImplementation(MetadataTokens.MethodImplementationHandle(row));
if (impl.MethodBody == handle) return true;
}
return false;
}
public static bool HasParameters(this PropertyDefinitionHandle handle, MetadataReader reader)
{
var a = reader.GetPropertyDefinition(handle).GetAccessors();
if (!a.Getter.IsNil) {
var m = reader.GetMethodDefinition(a.Getter);
return m.GetParameters().Count > 0;
}
if (!a.Setter.IsNil) {
var m = reader.GetMethodDefinition(a.Setter);
return m.GetParameters().Count > 1;
}
return false;
}
public static PrimitiveTypeCode ToPrimtiveTypeCode(this KnownTypeCode typeCode)
{
switch (typeCode) {

Loading…
Cancel
Save