Browse Source

Port ILFunction and SequencePointBuilder

pull/1198/head
Siegfried Pammer 7 years ago
parent
commit
adca1f8867
  1. 4
      ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs
  2. 10
      ICSharpCode.Decompiler/CecilExtensions.cs
  3. 22
      ICSharpCode.Decompiler/DecompilerException.cs
  4. 8
      ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs
  5. 226
      ICSharpCode.Decompiler/SRMExtensions.cs
  6. 8
      ICSharpCode.Decompiler/TypeSystem/SpecializingDecompilerTypeSystem.cs
  7. 14
      ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs
  8. 26
      ILSpy/Languages/Language.cs

4
ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs

@ -314,10 +314,10 @@ namespace ICSharpCode.Decompiler.CSharp @@ -314,10 +314,10 @@ namespace ICSharpCode.Decompiler.CSharp
newList.Add(sequencePoint);
pos = sequencePoint.EndOffset;
}
if (pos < function.CecilMethod.Body.CodeSize) {
if (pos < function.CodeSize) {
var hidden = new Metadata.SequencePoint();
hidden.Offset = pos;
hidden.EndOffset = function.CecilMethod.Body.CodeSize;
hidden.EndOffset = function.CodeSize;
hidden.SetHidden();
newList.Add(hidden);
}

10
ICSharpCode.Decompiler/CecilExtensions.cs

@ -31,16 +31,6 @@ namespace ICSharpCode.Decompiler @@ -31,16 +31,6 @@ namespace ICSharpCode.Decompiler
/// </summary>
public static class CecilExtensions
{
/// <summary>
/// Gets the (exclusive) end offset of this instruction.
/// </summary>
public static int GetEndOffset(this Instruction inst)
{
if (inst == null)
throw new ArgumentNullException(nameof(inst));
return inst.Offset + inst.GetSize();
}
public static string OffsetToString(int offset)
{
return string.Format("IL_{0:x4}", offset);

22
ICSharpCode.Decompiler/DecompilerException.cs

@ -20,12 +20,12 @@ using System; @@ -20,12 +20,12 @@ using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Reflection.Metadata;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Security;
using System.Text;
using ICSharpCode.Decompiler.TypeSystem;
using Mono.Cecil;
namespace ICSharpCode.Decompiler
{
@ -34,20 +34,26 @@ namespace ICSharpCode.Decompiler @@ -34,20 +34,26 @@ namespace ICSharpCode.Decompiler
/// </summary>
public class DecompilerException : Exception, ISerializable
{
public AssemblyNameDefinition AssemblyName => DecompiledMethod.Module.Assembly.Name;
public string AssemblyName => Module.FullName;
public string FileName => DecompiledMethod.Module.FileName;
public string FileName => Module.FileName;
public FullTypeName DecompiledType => new FullTypeName(DecompiledMethod.DeclaringType.FullName);
public MethodDefinitionHandle DecompiledMethod { get; }
public Metadata.PEFile Module { get; }
public MethodDefinition DecompiledMethod { get; }
public DecompilerException(MethodDefinition decompiledMethod, Exception innerException)
: base("Error decompiling " + decompiledMethod.FullName + Environment.NewLine, innerException)
public DecompilerException(Metadata.PEFile module, MethodDefinitionHandle decompiledMethod, Exception innerException)
: base("Error decompiling " + GetFullName(decompiledMethod, module.GetMetadataReader()) + Environment.NewLine, innerException)
{
this.Module = module;
this.DecompiledMethod = decompiledMethod;
}
private static string GetFullName(MethodDefinitionHandle decompiledMethod, MetadataReader metadata)
{
var method = metadata.GetMethodDefinition(decompiledMethod);
return $"{method.GetDeclaringType().GetFullTypeName(metadata).ToString()}.{metadata.GetString(method.Name)}";
}
// This constructor is needed for serialization.
protected DecompilerException(SerializationInfo info, StreamingContext context) : base(info, context)
{

8
ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs

@ -19,7 +19,6 @@ @@ -19,7 +19,6 @@
using System;
using System.Collections.Generic;
using ICSharpCode.Decompiler.IL.Transforms;
using Mono.Cecil;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
@ -30,7 +29,7 @@ namespace ICSharpCode.Decompiler.IL @@ -30,7 +29,7 @@ namespace ICSharpCode.Decompiler.IL
partial class ILFunction
{
public readonly IMethod Method;
public readonly MethodDefinition CecilMethod;
public readonly int CodeSize;
public readonly ILVariableCollection Variables;
/// <summary>
@ -73,11 +72,10 @@ namespace ICSharpCode.Decompiler.IL @@ -73,11 +72,10 @@ namespace ICSharpCode.Decompiler.IL
public readonly IReadOnlyList<IParameter> Parameters;
public ILFunction(IMethod method, MethodDefinition cecilMethod, ILInstruction body) : base(OpCode.ILFunction)
public ILFunction(IMethod method, int codeSize, ILInstruction body) : base(OpCode.ILFunction)
{
this.Body = body;
this.Method = method;
this.CecilMethod = cecilMethod;
this.ReturnType = Method?.ReturnType;
this.Parameters = Method?.Parameters;
this.Variables = new ILVariableCollection(this);
@ -164,7 +162,7 @@ namespace ICSharpCode.Decompiler.IL @@ -164,7 +162,7 @@ namespace ICSharpCode.Decompiler.IL
{
var usedILRanges = new List<LongInterval>();
MarkUsedILRanges(body);
return new LongSet(new LongInterval(0, CecilMethod.Body.CodeSize)).ExceptWith(new LongSet(usedILRanges));
return new LongSet(new LongInterval(0, CodeSize)).ExceptWith(new LongSet(usedILRanges));
void MarkUsedILRanges(ILInstruction inst)
{

226
ICSharpCode.Decompiler/SRMExtensions.cs

@ -1,8 +1,10 @@ @@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
@ -82,11 +84,7 @@ namespace ICSharpCode.Decompiler @@ -82,11 +84,7 @@ namespace ICSharpCode.Decompiler
public static bool IsExtensionMethod(this MethodDefinition methodDefinition, MetadataReader reader)
{
if (methodDefinition.HasFlag(MethodAttributes.Static)) {
foreach (var attribute in methodDefinition.GetCustomAttributes()) {
string typeName = reader.GetCustomAttribute(attribute).GetAttributeType(reader).GetFullTypeName(reader).ToString();
if (typeName == "System.Runtime.CompilerServices.ExtensionAttribute")
return true;
}
return methodDefinition.GetCustomAttributes().HasAttributeOfType<System.Runtime.CompilerServices.ExtensionAttribute>(reader);
}
return false;
}
@ -136,23 +134,6 @@ namespace ICSharpCode.Decompiler @@ -136,23 +134,6 @@ namespace ICSharpCode.Decompiler
return accessors.Raiser;
}
/// <summary>
/// Gets the type of the attribute.
/// </summary>
public static EntityHandle GetAttributeType(this CustomAttribute attribute, MetadataReader reader)
{
switch (attribute.Constructor.Kind) {
case HandleKind.MethodDefinition:
var md = reader.GetMethodDefinition((MethodDefinitionHandle)attribute.Constructor);
return md.GetDeclaringType();
case HandleKind.MemberReference:
var mr = reader.GetMemberReference((MemberReferenceHandle)attribute.Constructor);
return mr.Parent;
default:
throw new NotSupportedException();
}
}
public static TypeReferenceHandle GetDeclaringType(this TypeReference tr)
{
switch (tr.ResolutionScope.Kind) {
@ -234,5 +215,206 @@ namespace ICSharpCode.Decompiler @@ -234,5 +215,206 @@ namespace ICSharpCode.Decompiler
throw new NotSupportedException();
}
}
public static bool IsAnonymousType(this TypeDefinition type, MetadataReader metadata)
{
string name = metadata.GetString(type.Name);
if (type.Namespace.IsNil && type.HasGeneratedName(metadata) && (name.Contains("AnonType") || name.Contains("AnonymousType"))) {
return type.IsCompilerGenerated(metadata);
}
return false;
}
#region HasGeneratedName
public static bool IsGeneratedName(this StringHandle handle, MetadataReader metadata)
{
return !handle.IsNil && metadata.GetString(handle).StartsWith("<", StringComparison.Ordinal);
}
public static bool HasGeneratedName(this MethodDefinitionHandle handle, MetadataReader metadata)
{
return metadata.GetMethodDefinition(handle).Name.IsGeneratedName(metadata);
}
public static bool HasGeneratedName(this TypeDefinitionHandle handle, MetadataReader metadata)
{
return metadata.GetTypeDefinition(handle).Name.IsGeneratedName(metadata);
}
public static bool HasGeneratedName(this TypeDefinition type, MetadataReader metadata)
{
return type.Name.IsGeneratedName(metadata);
}
public static bool HasGeneratedName(this FieldDefinitionHandle handle, MetadataReader metadata)
{
return metadata.GetFieldDefinition(handle).Name.IsGeneratedName(metadata);
}
#endregion
#region IsCompilerGenerated
public static bool IsCompilerGenerated(this MethodDefinitionHandle handle, MetadataReader metadata)
{
return metadata.GetMethodDefinition(handle).IsCompilerGenerated(metadata);
}
public static bool IsCompilerGenerated(this MethodDefinition method, MetadataReader metadata)
{
return method.GetCustomAttributes().HasCompilerGeneratedAttribute(metadata);
}
public static bool IsCompilerGenerated(this FieldDefinitionHandle handle, MetadataReader metadata)
{
return metadata.GetFieldDefinition(handle).IsCompilerGenerated(metadata);
}
public static bool IsCompilerGenerated(this FieldDefinition field, MetadataReader metadata)
{
return field.GetCustomAttributes().HasCompilerGeneratedAttribute(metadata);
}
public static bool IsCompilerGenerated(this TypeDefinitionHandle handle, MetadataReader metadata)
{
return metadata.GetTypeDefinition(handle).IsCompilerGenerated(metadata);
}
public static bool IsCompilerGenerated(this TypeDefinition type, MetadataReader metadata)
{
return type.GetCustomAttributes().HasCompilerGeneratedAttribute(metadata);
}
#endregion
#region Attribute extensions
/// <summary>
/// Gets the type of the attribute.
/// </summary>
public static EntityHandle GetAttributeType(this CustomAttribute attribute, MetadataReader reader)
{
switch (attribute.Constructor.Kind) {
case HandleKind.MethodDefinition:
var md = reader.GetMethodDefinition((MethodDefinitionHandle)attribute.Constructor);
return md.GetDeclaringType();
case HandleKind.MemberReference:
var mr = reader.GetMemberReference((MemberReferenceHandle)attribute.Constructor);
return mr.Parent;
default:
throw new NotSupportedException();
}
}
public static bool HasCompilerGeneratedAttribute(this CustomAttributeHandleCollection customAttributes, MetadataReader metadata)
{
return customAttributes.HasAttributeOfType<System.Runtime.CompilerServices.CompilerGeneratedAttribute>(metadata);
}
public static bool HasParamArrayAttribute(this CustomAttributeHandleCollection customAttributes, MetadataReader metadata)
{
return customAttributes.HasAttributeOfType<System.ParamArrayAttribute>(metadata);
}
public static bool HasDefaultMemberAttribute(this CustomAttributeHandleCollection customAttributes, MetadataReader metadata)
{
return customAttributes.HasAttributeOfType<System.Reflection.DefaultMemberAttribute>(metadata);
}
public static bool HasAttributeOfType(this CustomAttributeHandleCollection customAttributes, MetadataReader metadata, Type type)
{
var typeName = type.FullName;
foreach (var handle in customAttributes) {
var customAttribute = metadata.GetCustomAttribute(handle);
var attributeTypeName = customAttribute.GetAttributeType(metadata).GetFullTypeName(metadata).ToString();
if (typeName == attributeTypeName)
return true;
}
return false;
}
public static bool HasAttributeOfType<TAttribute>(this CustomAttributeHandleCollection customAttributes, MetadataReader metadata) where TAttribute : Attribute
{
return HasAttributeOfType(customAttributes, metadata, typeof(TAttribute));
}
#endregion
public static byte[] GetInitialValue(this FieldDefinition field, PEReader pefile)
{
if (!field.HasFlag(FieldAttributes.HasFieldRVA) || field.GetRelativeVirtualAddress() == 0)
return Empty<byte>.Array;
int rva = field.GetRelativeVirtualAddress();
int size = field.DecodeSignature(new FieldValueSizeDecoder(), default);
var headers = pefile.PEHeaders;
int index = headers.GetContainingSectionIndex(rva);
var sectionHeader = headers.SectionHeaders[index];
var sectionData = pefile.GetEntireImage();
int totalOffset = rva + sectionHeader.PointerToRawData - sectionHeader.VirtualAddress;
var reader = sectionData.GetReader();
reader.Offset += totalOffset;
int offset = field.GetOffset();
if (offset > 0)
reader.Offset += offset;
return reader.ReadBytes(size);
}
class FieldValueSizeDecoder : ISignatureTypeProvider<int, Unit>
{
public int GetArrayType(int elementType, ArrayShape shape) => elementType;
public int GetByReferenceType(int elementType) => elementType;
public int GetFunctionPointerType(MethodSignature<int> signature) => IntPtr.Size;
public int GetGenericInstantiation(int genericType, ImmutableArray<int> typeArguments) => throw new NotSupportedException();
public int GetGenericMethodParameter(Unit genericContext, int index) => throw new NotSupportedException();
public int GetGenericTypeParameter(Unit genericContext, int index) => throw new NotSupportedException();
public int GetModifiedType(int modifier, int unmodifiedType, bool isRequired) => unmodifiedType;
public int GetPinnedType(int elementType) => elementType;
public int GetPointerType(int elementType) => elementType;
public int GetPrimitiveType(PrimitiveTypeCode typeCode)
{
switch (typeCode) {
case PrimitiveTypeCode.Boolean:
case PrimitiveTypeCode.Byte:
case PrimitiveTypeCode.SByte:
return 1;
case PrimitiveTypeCode.Char:
case PrimitiveTypeCode.Int16:
case PrimitiveTypeCode.UInt16:
return 2;
case PrimitiveTypeCode.Int32:
case PrimitiveTypeCode.UInt32:
case PrimitiveTypeCode.Single:
return 4;
case PrimitiveTypeCode.Int64:
case PrimitiveTypeCode.UInt64:
case PrimitiveTypeCode.Double:
return 8;
case PrimitiveTypeCode.IntPtr:
case PrimitiveTypeCode.UIntPtr:
return IntPtr.Size;
default:
throw new NotSupportedException();
}
}
public int GetSZArrayType(int elementType) => throw new NotSupportedException();
public int GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
{
var td = reader.GetTypeDefinition(handle);
return td.GetLayout().Size;
}
public int GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
{
throw new NotImplementedException();
}
public int GetTypeFromSpecification(MetadataReader reader, Unit genericContext, TypeSpecificationHandle handle, byte rawTypeKind)
{
throw new NotImplementedException();
}
}
}
}

8
ICSharpCode.Decompiler/TypeSystem/SpecializingDecompilerTypeSystem.cs

@ -80,14 +80,14 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -80,14 +80,14 @@ namespace ICSharpCode.Decompiler.TypeSystem
return context.GetSpecializingTypeSystem(newSubstitution);
}
public Mono.Cecil.TypeDefinition GetCecil(ITypeDefinition typeDefinition)
public System.Reflection.Metadata.MetadataReader GetMetadata()
{
return context.GetCecil(typeDefinition);
return context.GetMetadata();
}
public Mono.Cecil.MemberReference GetCecil(IMember member)
public IMember ResolveAsMember(System.Reflection.Metadata.EntityHandle memberReference)
{
return context.GetCecil(member);
throw new NotImplementedException();
}
}
}

14
ICSharpCode.Decompiler/TypeSystem/TypeSystemExtensions.cs

@ -757,7 +757,19 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -757,7 +757,19 @@ namespace ICSharpCode.Decompiler.TypeSystem
throw new NotSupportedException("Unknown entity type");
}
#endregion
#region IsCompilerGenerated
static readonly FullTypeName compilerGeneratedAttributeTypeName = new FullTypeName("System.Runtime.CompilerServices.CompilerGeneratedAttribute");
public static bool IsCompilerGenereated(this IEntity entity)
{
if (entity == null)
throw new ArgumentNullException(nameof(entity));
return entity.GetAttribute(compilerGeneratedAttributeTypeName) != null;
}
#endregion
#region IAssembly.GetTypeDefinition(string,string,int)
/// <summary>
/// Gets the type definition for a top-level type.

26
ILSpy/Languages/Language.cs

@ -287,22 +287,26 @@ namespace ICSharpCode.ILSpy @@ -287,22 +287,26 @@ namespace ICSharpCode.ILSpy
}
}
public static string GetRuntimeDisplayName(PEFile module)
{
string version = module.GetMetadataReader().MetadataVersion;
switch (version[1]) {
case '1':
if (version[3] == 1)
return ".NET 1.1";
else
return ".NET 1.0";
case '2':
public static string GetRuntimeDisplayName(TargetRuntime runtime)
{
switch (runtime) {
case TargetRuntime.Net_1_0:
return ".NET 1.1";
case TargetRuntime.Net_1_1:
return ".NET 1.0";
case TargetRuntime.Net_2_0:
return ".NET 2.0";
case '4':
case TargetRuntime.Net_4_0:
return ".NET 4.0";
}
return null;
}
public static string GetRuntimeDisplayName(PEFile module)
{
return GetRuntimeDisplayName(module.GetRuntime());
}
}
class ILSignatureProvider : SRM.ISignatureTypeProvider<string, GenericContext>

Loading…
Cancel
Save