Browse Source

Eliminate SpecializingDecompilerTypeSystem and use GenericContext instead.

pull/1030/head
Daniel Grunwald 7 years ago
parent
commit
107fe5eb1c
  1. 2
      ICSharpCode.Decompiler.Tests/DataFlowTest.cs
  2. 14
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  3. 3
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  4. 11
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  5. 1
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  6. 13
      ICSharpCode.Decompiler/IL/BlockBuilder.cs
  7. 22
      ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs
  8. 89
      ICSharpCode.Decompiler/IL/ILReader.cs
  9. 12
      ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs
  10. 37
      ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs
  11. 10
      ICSharpCode.Decompiler/IL/Transforms/IILTransform.cs
  12. 13
      ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs
  13. 3
      ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs
  14. 18
      ICSharpCode.Decompiler/NRExtensions.cs
  15. 9
      ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
  16. 6
      ICSharpCode.Decompiler/TypeSystem/IDecompilerTypeSystem.cs
  17. 5
      ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedParameter.cs
  18. 80
      ICSharpCode.Decompiler/TypeSystem/MetadataModule.cs
  19. 124
      ICSharpCode.Decompiler/TypeSystem/SpecializingDecompilerTypeSystem.cs
  20. 8
      ICSharpCode.Decompiler/TypeSystem/TypeParameterSubstitution.cs
  21. 11
      ILSpy.BamlDecompiler/ConnectMethodDecompiler.cs
  22. 9
      ILSpy/Languages/ILAstLanguage.cs

2
ICSharpCode.Decompiler.Tests/DataFlowTest.cs

@ -55,7 +55,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -55,7 +55,7 @@ namespace ICSharpCode.Decompiler.Tests
public void TryFinallyWithAssignmentInFinally()
{
ILVariable v = new ILVariable(VariableKind.Local, SpecialType.UnknownType, 0);
ILFunction f = new ILFunction((IMethod)null, 0, new TryFinally(
ILFunction f = new ILFunction((IMethod)null, 0, new GenericContext(), new TryFinally(
new Nop(),
new StLoc(v, new LdcI4(0))
));

14
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -1001,14 +1001,14 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1001,14 +1001,14 @@ namespace ICSharpCode.Decompiler.CSharp
void DecompileBody(IMethod method, EntityDeclaration entityDecl, DecompileRun decompileRun, ITypeResolveContext decompilationContext)
{
try {
var specializingTypeSystem = typeSystem.GetSpecializingTypeSystem(decompilationContext);
var ilReader = new ILReader(specializingTypeSystem) {
var ilReader = new ILReader(typeSystem.MainModule) {
UseDebugSymbols = settings.UseDebugSymbols,
DebugInfo = DebugInfoProvider
};
var genericContext = new Decompiler.TypeSystem.GenericContext(decompilationContext);
var methodDef = typeSystem.ModuleDefinition.Metadata.GetMethodDefinition((MethodDefinitionHandle)method.MetadataToken);
var methodBody = typeSystem.ModuleDefinition.Reader.GetMethodBody(methodDef.RelativeVirtualAddress);
var function = ilReader.ReadIL(typeSystem.ModuleDefinition, (MethodDefinitionHandle)method.MetadataToken, methodBody, CancellationToken);
var function = ilReader.ReadIL((MethodDefinitionHandle)method.MetadataToken, methodBody, genericContext, CancellationToken);
function.CheckInvariant(ILPhase.Normal);
if (entityDecl != null) {
@ -1029,7 +1029,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1029,7 +1029,7 @@ namespace ICSharpCode.Decompiler.CSharp
localSettings.AlwaysCastTargetsOfExplicitInterfaceImplementationCalls = true;
}
var context = new ILTransformContext(function, specializingTypeSystem, DebugInfoProvider, localSettings) {
var context = new ILTransformContext(function, typeSystem, DebugInfoProvider, localSettings) {
CancellationToken = CancellationToken,
DecompileRun = decompileRun
};
@ -1047,8 +1047,8 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1047,8 +1047,8 @@ namespace ICSharpCode.Decompiler.CSharp
var body = BlockStatement.Null;
// Generate C# AST only if bodies should be displayed.
if (localSettings.DecompileMemberBodies) {
AddDefinesForConditionalAttributes(function, decompileRun, decompilationContext);
var statementBuilder = new StatementBuilder(specializingTypeSystem, decompilationContext, function, localSettings, CancellationToken);
AddDefinesForConditionalAttributes(function, decompileRun);
var statementBuilder = new StatementBuilder(typeSystem, decompilationContext, function, localSettings, CancellationToken);
body = statementBuilder.ConvertAsBlock(function.Body);
Comment prev = null;
@ -1112,7 +1112,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1112,7 +1112,7 @@ namespace ICSharpCode.Decompiler.CSharp
return false;
}
void AddDefinesForConditionalAttributes(ILFunction function, DecompileRun decompileRun, ITypeResolveContext decompilationContext)
void AddDefinesForConditionalAttributes(ILFunction function, DecompileRun decompileRun)
{
foreach (var call in function.Descendants.OfType<CallInstruction>()) {
var attr = call.Method.GetAttribute(KnownAttribute.Conditional, inherit: true);

3
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -1491,8 +1491,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1491,8 +1491,7 @@ namespace ICSharpCode.Decompiler.CSharp
ame.IsAsync = function.IsAsync;
ame.Parameters.AddRange(MakeParameters(function.Parameters, function));
ame.HasParameterList = ame.Parameters.Count > 0;
var targetTS = method == null ? typeSystem : typeSystem.GetSpecializingTypeSystem(method.Substitution);
StatementBuilder builder = new StatementBuilder(targetTS, this.decompilationContext, function, settings, cancellationToken);
StatementBuilder builder = new StatementBuilder(typeSystem, this.decompilationContext, function, settings, cancellationToken);
var body = builder.ConvertAsBlock(function.Body);
Comment prev = null;

11
ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

@ -476,11 +476,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -476,11 +476,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
var p = (i < parameters.Count) ? parameters[i] : null;
attr.Arguments.Add(ConvertConstantValue(p?.Type ?? arg.Type, arg.Type, arg.Value));
}
if (attribute.HasDecodeErrors) {
attr.HasArgumentList = true;
attr.AddChild(new Comment("Could not decode attribute arguments.", CommentType.MultiLine), Roles.Comment);
attr.AddChild(new CSharpTokenNode(TextLocation.Empty, Roles.RPar), Roles.RPar);
}
if (attribute.NamedArguments.Length > 0) {
InitializedObjectResolveResult targetResult = new InitializedObjectResolveResult(attribute.AttributeType);
foreach (var namedArg in attribute.NamedArguments) {
@ -494,6 +489,12 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -494,6 +489,12 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
attr.Arguments.Add(namedArgument);
}
}
if (attribute.HasDecodeErrors) {
attr.HasArgumentList = true;
attr.AddChild(new Comment("Could not decode attribute arguments.", CommentType.MultiLine), Roles.Comment);
// insert explicit rpar token to make the comment appear within the parentheses
attr.AddChild(new CSharpTokenNode(TextLocation.Empty, Roles.RPar), Roles.RPar);
}
return attr;
}

1
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -547,7 +547,6 @@ @@ -547,7 +547,6 @@
<Compile Include="TypeSystem\TypeParameterSubstitution.cs" />
<Compile Include="TypeSystem\TypeSystemExtensions.cs" />
<Compile Include="TypeSystem\TypeUtils.cs" />
<Compile Include="TypeSystem\SpecializingDecompilerTypeSystem.cs" />
<Compile Include="TypeSystem\IDecompilerTypeSystem.cs" />
<Compile Include="TypeSystem\ReferenceResolvingException.cs" />
<Compile Include="TypeSystem\TypeVisitor.cs" />

13
ICSharpCode.Decompiler/IL/BlockBuilder.cs

@ -21,17 +21,16 @@ using System.Collections; @@ -21,17 +21,16 @@ using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection.Metadata;
using System.Threading;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.IL
{
class BlockBuilder
{
readonly System.Reflection.Metadata.MethodBodyBlock body;
readonly IDecompilerTypeSystem typeSystem;
readonly Dictionary<System.Reflection.Metadata.ExceptionRegion, ILVariable> variableByExceptionHandler;
readonly MethodBodyBlock body;
readonly Dictionary<ExceptionRegion, ILVariable> variableByExceptionHandler;
/// <summary>
/// Gets/Sets whether to create extended basic blocks instead of basic blocks.
@ -39,14 +38,12 @@ namespace ICSharpCode.Decompiler.IL @@ -39,14 +38,12 @@ namespace ICSharpCode.Decompiler.IL
/// </summary>
public bool CreateExtendedBlocks;
internal BlockBuilder(System.Reflection.Metadata.MethodBodyBlock body, IDecompilerTypeSystem typeSystem,
Dictionary<System.Reflection.Metadata.ExceptionRegion, ILVariable> variableByExceptionHandler)
internal BlockBuilder(MethodBodyBlock body,
Dictionary<ExceptionRegion, ILVariable> variableByExceptionHandler)
{
Debug.Assert(body != null);
Debug.Assert(typeSystem != null);
Debug.Assert(variableByExceptionHandler != null);
this.body = body;
this.typeSystem = typeSystem;
this.variableByExceptionHandler = variableByExceptionHandler;
}

22
ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs

@ -373,20 +373,14 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -373,20 +373,14 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
if (!methodDef.HasBody())
throw new SymbolicAnalysisFailedException();
var sdtp = typeSystem as SpecializingDecompilerTypeSystem;
if (sdtp != null) {
typeSystem = new SpecializingDecompilerTypeSystem(
sdtp.Context,
new TypeParameterSubstitution(
(sdtp.Substitution.ClassTypeArguments ?? EmptyList<IType>.Instance)
.Concat(sdtp.Substitution.MethodTypeArguments ?? EmptyList<IType>.Instance).ToArray(),
EmptyList<IType>.Instance
)
);
}
var body = typeSystem.ModuleDefinition.Reader.GetMethodBody(methodDef.RelativeVirtualAddress);
var il = context.CreateILReader(typeSystem)
.ReadIL(typeSystem.ModuleDefinition, method, body, context.CancellationToken);
GenericContext genericContext = context.Function.GenericContext;
genericContext = new GenericContext(
classTypeParameters: (genericContext.ClassTypeParameters ?? EmptyList<ITypeParameter>.Instance)
.Concat(genericContext.MethodTypeParameters ?? EmptyList<ITypeParameter>.Instance).ToArray(),
methodTypeParameters: null);
var body = context.TypeSystem.MainModule.PEFile.Reader.GetMethodBody(methodDef.RelativeVirtualAddress);
var il = context.CreateILReader()
.ReadIL(method, body, genericContext, context.CancellationToken);
il.RunTransforms(CSharpDecompiler.EarlyILTransforms(true),
new ILTransformContext(il, typeSystem, context.DebugInfo, context.Settings) {
CancellationToken = context.CancellationToken,

89
ICSharpCode.Decompiler/IL/ILReader.cs

@ -34,24 +34,38 @@ using System.Reflection.Metadata.Ecma335; @@ -34,24 +34,38 @@ using System.Reflection.Metadata.Ecma335;
namespace ICSharpCode.Decompiler.IL
{
/// <summary>
/// Reads IL bytecodes and converts them into ILAst instructions.
/// </summary>
/// <remarks>
/// Instances of this class are not thread-safe. Use separate instances to decompile multiple members in parallel.
/// </remarks>
public class ILReader
{
readonly ICompilation compilation;
readonly IDecompilerTypeSystem typeSystem;
readonly MetadataModule module;
readonly MetadataReader metadata;
public bool UseDebugSymbols { get; set; }
public DebugInfo.IDebugInfoProvider DebugInfo { get; set; }
public List<string> Warnings { get; } = new List<string>();
public ILReader(IDecompilerTypeSystem typeSystem)
/// <summary>
/// Creates a new ILReader instance.
/// </summary>
/// <param name="module">
/// The module used to resolve metadata tokens in the type system.
/// </param>
public ILReader(MetadataModule module)
{
if (typeSystem == null)
throw new ArgumentNullException(nameof(typeSystem));
this.typeSystem = typeSystem;
this.compilation = typeSystem.Compilation;
if (module == null)
throw new ArgumentNullException(nameof(module));
this.module = module;
this.compilation = module.Compilation;
this.metadata = module.metadata;
}
MetadataReader metadata;
GenericContext genericContext;
IMethod method;
MethodBodyBlock body;
StackType methodReturnStackType;
@ -70,12 +84,23 @@ namespace ICSharpCode.Decompiler.IL @@ -70,12 +84,23 @@ namespace ICSharpCode.Decompiler.IL
List<(ILVariable, ILVariable)> stackMismatchPairs;
IEnumerable<ILVariable> stackVariables;
void Init(Metadata.PEFile module, MethodDefinitionHandle methodDefinitionHandle, MethodBodyBlock body)
void Init(MethodDefinitionHandle methodDefinitionHandle, MethodBodyBlock body, GenericContext genericContext)
{
if (body == null)
throw new ArgumentNullException(nameof(body));
this.metadata = module.Metadata;
this.method = typeSystem.ResolveAsMethod(methodDefinitionHandle);
if (methodDefinitionHandle.IsNil)
throw new ArgumentException("methodDefinitionHandle.IsNil");
this.method = module.GetDefinition(methodDefinitionHandle);
if (genericContext.ClassTypeParameters == null && genericContext.MethodTypeParameters == null) {
if (method.DeclaringType.TypeParameterCount > 0 || method.TypeParameters.Count > 0) {
// no generic context specified, but it's a generic method: use the method's own type parameters
genericContext = new GenericContext(method);
}
} else {
// generic context specified, so specialize the method for it:
this.method = this.method.Specialize(new TypeParameterSubstitution(genericContext.ClassTypeParameters, genericContext.MethodTypeParameters));
}
this.genericContext = genericContext;
var methodDefinition = metadata.GetMethodDefinition(methodDefinitionHandle);
this.body = body;
this.reader = body.GetILReader();
@ -111,22 +136,19 @@ namespace ICSharpCode.Decompiler.IL @@ -111,22 +136,19 @@ namespace ICSharpCode.Decompiler.IL
IType ReadAndDecodeTypeReference()
{
var typeReference = ReadAndDecodeMetadataToken();
return typeSystem.ResolveAsType(typeReference);
return module.ResolveType(typeReference, genericContext);
}
IMethod ReadAndDecodeMethodReference()
{
var methodReference = ReadAndDecodeMetadataToken();
IMethod m = typeSystem.ResolveAsMethod(methodReference);
if (m == null)
throw new BadImageFormatException("Invalid method token");
return m;
return module.ResolveMethod(methodReference, genericContext);
}
IField ReadAndDecodeFieldReference()
{
var fieldReference = ReadAndDecodeMetadataToken();
IField f = typeSystem.ResolveAsField(fieldReference);
var f = module.ResolveEntity(fieldReference, genericContext) as IField;
if (f == null)
throw new BadImageFormatException("Invalid field token");
return f;
@ -135,7 +157,7 @@ namespace ICSharpCode.Decompiler.IL @@ -135,7 +157,7 @@ namespace ICSharpCode.Decompiler.IL
ILVariable[] InitLocalVariables()
{
if (body.LocalSignature.IsNil) return Empty<ILVariable>.Array;
var variableTypes = typeSystem.DecodeLocalSignature(body.LocalSignature);
var variableTypes = module.DecodeLocalSignature(body.LocalSignature, genericContext);
var localVariables = new ILVariable[variableTypes.Length];
foreach (var (index, type) in variableTypes.WithIndex()) {
localVariables[index] = CreateILVariable(index, type);
@ -317,14 +339,15 @@ namespace ICSharpCode.Decompiler.IL @@ -317,14 +339,15 @@ namespace ICSharpCode.Decompiler.IL
foreach (var eh in body.ExceptionRegions) {
ImmutableStack<ILVariable> ehStack = null;
if (eh.Kind == ExceptionRegionKind.Catch) {
var v = new ILVariable(VariableKind.Exception, typeSystem.ResolveAsType(eh.CatchType), eh.HandlerOffset) {
var catchType = module.ResolveType(eh.CatchType, genericContext);
var v = new ILVariable(VariableKind.Exception, catchType, eh.HandlerOffset) {
Name = "E_" + eh.HandlerOffset,
HasGeneratedName = true
};
variableByExceptionHandler.Add(eh, v);
ehStack = ImmutableStack.Create(v);
} else if (eh.Kind == ExceptionRegionKind.Filter) {
var v = new ILVariable(VariableKind.Exception, typeSystem.Compilation.FindType(KnownTypeCode.Object), eh.HandlerOffset) {
var v = new ILVariable(VariableKind.Exception, compilation.FindType(KnownTypeCode.Object), eh.HandlerOffset) {
Name = "E_" + eh.HandlerOffset,
HasGeneratedName = true
};
@ -409,10 +432,10 @@ namespace ICSharpCode.Decompiler.IL @@ -409,10 +432,10 @@ namespace ICSharpCode.Decompiler.IL
/// <summary>
/// Debugging helper: writes the decoded instruction stream interleaved with the inferred evaluation stack layout.
/// </summary>
public void WriteTypedIL(Metadata.PEFile module,
MethodDefinitionHandle method, MethodBodyBlock body, ITextOutput output, CancellationToken cancellationToken = default)
public void WriteTypedIL(MethodDefinitionHandle method, MethodBodyBlock body,
ITextOutput output, GenericContext genericContext = default, CancellationToken cancellationToken = default)
{
Init(module, method, body);
Init(method, body, genericContext);
ReadInstructions(cancellationToken);
foreach (var inst in instructionBuilder) {
if (inst is StLoc stloc && stloc.IsStackAdjustment) {
@ -444,21 +467,20 @@ namespace ICSharpCode.Decompiler.IL @@ -444,21 +467,20 @@ namespace ICSharpCode.Decompiler.IL
output.WriteLine();
}
new Disassembler.MethodBodyDisassembler(output, cancellationToken) { DetectControlStructure = false }
.WriteExceptionHandlers(module, method, body);
.WriteExceptionHandlers(module.PEFile, method, body);
}
/// <summary>
/// Decodes the specified method body and returns an ILFunction.
/// </summary>
public ILFunction ReadIL(Metadata.PEFile module, MethodDefinitionHandle method, MethodBodyBlock body, CancellationToken cancellationToken = default(CancellationToken))
public ILFunction ReadIL(MethodDefinitionHandle method, MethodBodyBlock body, GenericContext genericContext = default, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
Init(module, method, body);
Init(method, body, genericContext);
ReadInstructions(cancellationToken);
var blockBuilder = new BlockBuilder(body, typeSystem, variableByExceptionHandler);
var blockBuilder = new BlockBuilder(body, variableByExceptionHandler);
blockBuilder.CreateBlocks(mainContainer, instructionBuilder, isBranchTarget, cancellationToken);
var resolvedMethod = typeSystem.ResolveAsMethod(method);
var function = new ILFunction(resolvedMethod, body.GetCodeSize(), mainContainer);
var function = new ILFunction(this.method, body.GetCodeSize(), genericContext, mainContainer);
CollectionExtensions.AddRange(function.Variables, parameterVariables);
CollectionExtensions.AddRange(function.Variables, localVariables);
CollectionExtensions.AddRange(function.Variables, stackVariables);
@ -1358,7 +1380,7 @@ namespace ICSharpCode.Decompiler.IL @@ -1358,7 +1380,7 @@ namespace ICSharpCode.Decompiler.IL
ILInstruction DecodeCallIndirect()
{
var signatureHandle = (StandaloneSignatureHandle)ReadAndDecodeMetadataToken();
var signature = typeSystem.DecodeMethodSignature(signatureHandle);
var signature = module.DecodeMethodSignature(signatureHandle, genericContext);
var functionPointer = Pop(StackType.I);
Debug.Assert(!signature.Header.IsInstance);
var arguments = new ILInstruction[signature.ParameterTypes.Length];
@ -1586,9 +1608,12 @@ namespace ICSharpCode.Decompiler.IL @@ -1586,9 +1608,12 @@ namespace ICSharpCode.Decompiler.IL
ILInstruction LdToken(EntityHandle token)
{
if (token.Kind.IsTypeKind())
return new LdTypeToken(typeSystem.ResolveAsType(token));
if (token.Kind.IsMemberKind())
return new LdMemberToken(typeSystem.ResolveAsMember(token));
return new LdTypeToken(module.ResolveType(token, genericContext));
if (token.Kind.IsMemberKind()) {
var entity = module.ResolveEntity(token, genericContext);
if (entity is IMember member)
return new LdMemberToken(member);
}
throw new BadImageFormatException("Invalid metadata token for ldtoken instruction.");
}
}

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

@ -29,6 +29,7 @@ namespace ICSharpCode.Decompiler.IL @@ -29,6 +29,7 @@ namespace ICSharpCode.Decompiler.IL
partial class ILFunction
{
public readonly IMethod Method;
public readonly GenericContext GenericContext;
public readonly int CodeSize;
public readonly ILVariableCollection Variables;
@ -52,7 +53,7 @@ namespace ICSharpCode.Decompiler.IL @@ -52,7 +53,7 @@ namespace ICSharpCode.Decompiler.IL
/// Gets whether this function is async.
/// This flag gets set by the AsyncAwaitDecompiler.
/// </summary>
public bool IsAsync { get => AsyncReturnType != null; }
public bool IsAsync => AsyncReturnType != null;
/// <summary>
/// Return element type -- if the async method returns Task{T}, this field stores T.
@ -72,17 +73,20 @@ namespace ICSharpCode.Decompiler.IL @@ -72,17 +73,20 @@ namespace ICSharpCode.Decompiler.IL
public readonly IReadOnlyList<IParameter> Parameters;
public ILFunction(IMethod method, int codeSize, ILInstruction body) : base(OpCode.ILFunction)
public ILFunction(IMethod method, int codeSize, GenericContext genericContext, ILInstruction body) : base(OpCode.ILFunction)
{
this.Body = body;
this.Method = method;
this.CodeSize = codeSize;
this.GenericContext = genericContext;
this.Body = body;
this.ReturnType = Method?.ReturnType;
this.Parameters = Method?.Parameters;
this.Variables = new ILVariableCollection(this);
}
public ILFunction(IType returnType, IReadOnlyList<IParameter> parameters, ILInstruction body) : base(OpCode.ILFunction)
public ILFunction(IType returnType, IReadOnlyList<IParameter> parameters, GenericContext genericContext, ILInstruction body) : base(OpCode.ILFunction)
{
this.GenericContext = genericContext;
this.Body = body;
this.ReturnType = returnType;
this.Parameters = parameters;

37
ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs

@ -125,6 +125,29 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -125,6 +125,29 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return true;
}
internal static GenericContext? GenericContextFromTypeArguments(TypeParameterSubstitution subst)
{
var classTypeParameters = new List<ITypeParameter>();
var methodTypeParameters = new List<ITypeParameter>();
if (subst.ClassTypeArguments != null) {
foreach (var t in subst.ClassTypeArguments) {
if (t is ITypeParameter tp)
classTypeParameters.Add(tp);
else
return null;
}
}
if (subst.MethodTypeArguments != null) {
foreach (var t in subst.MethodTypeArguments) {
if (t is ITypeParameter tp)
classTypeParameters.Add(tp);
else
return null;
}
}
return new GenericContext(classTypeParameters, methodTypeParameters);
}
ILFunction TransformDelegateConstruction(NewObj value, out ILInstruction target)
{
target = null;
@ -140,9 +163,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -140,9 +163,12 @@ namespace ICSharpCode.Decompiler.IL.Transforms
var methodDefinition = metadata.GetMethodDefinition((MethodDefinitionHandle)targetMethod.MetadataToken);
if (!methodDefinition.HasBody())
return null;
var localTypeSystem = context.TypeSystem.GetSpecializingTypeSystem(targetMethod.Substitution);
var ilReader = context.CreateILReader(localTypeSystem);
var function = ilReader.ReadIL(context.TypeSystem.ModuleDefinition, (MethodDefinitionHandle)targetMethod.MetadataToken, context.TypeSystem.ModuleDefinition.Reader.GetMethodBody(methodDefinition.RelativeVirtualAddress), context.CancellationToken);
var genericContext = GenericContextFromTypeArguments(targetMethod.Substitution);
if (genericContext == null)
return null;
var ilReader = context.CreateILReader();
var body = context.TypeSystem.ModuleDefinition.Reader.GetMethodBody(methodDefinition.RelativeVirtualAddress);
var function = ilReader.ReadIL((MethodDefinitionHandle)targetMethod.MetadataToken, body, genericContext.Value, context.CancellationToken);
function.DelegateType = value.Method.DeclaringType;
function.CheckInvariant(ILPhase.Normal);
@ -151,10 +177,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -151,10 +177,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
v.Name = contextPrefix + v.Name;
}
var nestedContext = new ILTransformContext(function, localTypeSystem, context.DebugInfo, context.Settings) {
CancellationToken = context.CancellationToken,
DecompileRun = context.DecompileRun
};
var nestedContext = new ILTransformContext(context, function);
function.RunTransforms(CSharpDecompiler.GetILTransforms().TakeWhile(t => !(t is DelegateConstruction)), nestedContext);
function.AcceptVisitor(new ReplaceDelegateTargetVisitor(target, function.Variables.SingleOrDefault(v => v.Index == -1 && v.Kind == VariableKind.Parameter)));
// handle nested lambdas

10
ICSharpCode.Decompiler/IL/Transforms/IILTransform.cs

@ -60,9 +60,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -60,9 +60,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
Stepper = new Stepper();
}
public ILTransformContext(ILTransformContext context)
public ILTransformContext(ILTransformContext context, ILFunction function = null)
{
this.Function = context.Function;
this.Function = function ?? context.Function;
this.TypeSystem = context.TypeSystem;
this.DebugInfo = context.DebugInfo;
this.Settings = context.Settings;
@ -71,11 +71,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -71,11 +71,9 @@ namespace ICSharpCode.Decompiler.IL.Transforms
this.Stepper = context.Stepper;
}
public ILReader CreateILReader(IDecompilerTypeSystem typeSystem = null)
public ILReader CreateILReader()
{
if (typeSystem == null)
typeSystem = this.TypeSystem;
return new ILReader(typeSystem) {
return new ILReader(TypeSystem.MainModule) {
UseDebugSymbols = Settings.UseDebugSymbols,
DebugInfo = DebugInfo
};

13
ICSharpCode.Decompiler/IL/Transforms/ProxyCallReplacer.cs

@ -29,15 +29,14 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -29,15 +29,14 @@ namespace ICSharpCode.Decompiler.IL.Transforms
MethodDefinition methodDef = metadata.GetMethodDefinition((MethodDefinitionHandle)inst.Method.MetadataToken);
if (!methodDef.HasBody())
return;
var genericContext = DelegateConstruction.GenericContextFromTypeArguments(inst.Method.Substitution);
if (genericContext == null)
return;
// partially copied from CSharpDecompiler
var specializingTypeSystem = context.TypeSystem.GetSpecializingTypeSystem(inst.Method.Substitution);
var ilReader = context.CreateILReader(specializingTypeSystem);
var ilReader = context.CreateILReader();
var body = module.Reader.GetMethodBody(methodDef.RelativeVirtualAddress);
var proxyFunction = ilReader.ReadIL(module, handle, body, context.CancellationToken);
var transformContext = new ILTransformContext(proxyFunction, specializingTypeSystem, context.DebugInfo, context.Settings) {
CancellationToken = context.CancellationToken,
DecompileRun = context.DecompileRun
};
var proxyFunction = ilReader.ReadIL(handle, body, genericContext.Value, context.CancellationToken);
var transformContext = new ILTransformContext(context, proxyFunction);
proxyFunction.RunTransforms(CSharp.CSharpDecompiler.EarlyILTransforms(), transformContext);
if (!(proxyFunction.Body is BlockContainer blockContainer))
return;

3
ICSharpCode.Decompiler/IL/Transforms/TransformExpressionTrees.cs

@ -151,7 +151,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -151,7 +151,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return (null, SpecialType.UnknownType);
var container = new BlockContainer();
var functionType = instruction.Method.ReturnType.TypeArguments[0];
var function = new ILFunction(functionType.GetDelegateInvokeMethod()?.ReturnType, parameterList, container);
var returnType = functionType.GetDelegateInvokeMethod()?.ReturnType;
var function = new ILFunction(returnType, parameterList, context.Function.GenericContext, container);
function.DelegateType = functionType;
function.Variables.AddRange(parameterVariablesList);
lambdaStack.Push(function);

18
ICSharpCode.Decompiler/NRExtensions.cs

@ -23,24 +23,6 @@ namespace ICSharpCode.Decompiler @@ -23,24 +23,6 @@ namespace ICSharpCode.Decompiler
{
public static class NRExtensions
{
public static IDecompilerTypeSystem GetSpecializingTypeSystem(this IDecompilerTypeSystem typeSystem, ITypeResolveContext decompilationContext)
{
IReadOnlyList<IType> classTypeParameters = null;
IReadOnlyList<IType> methodTypeParameters = null;
if (decompilationContext.CurrentTypeDefinition != null && decompilationContext.CurrentTypeDefinition.TypeParameterCount > 0)
classTypeParameters = decompilationContext.CurrentTypeDefinition.TypeArguments;
IMethod method = decompilationContext.CurrentMember as IMethod;
if (method != null && method.TypeParameters.Count > 0)
methodTypeParameters = method.TypeArguments;
if (typeSystem is SpecializingDecompilerTypeSystem)
typeSystem = ((SpecializingDecompilerTypeSystem)typeSystem).Context;
if ((classTypeParameters != null && classTypeParameters.Count > 0) || (methodTypeParameters != null && methodTypeParameters.Count > 0))
return new SpecializingDecompilerTypeSystem(typeSystem, new TypeParameterSubstitution(classTypeParameters, methodTypeParameters));
else
return typeSystem;
}
public static bool IsCompilerGenerated(this IEntity entity)
{
if (entity != null) {

9
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -264,14 +264,5 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -264,14 +264,5 @@ namespace ICSharpCode.Decompiler.TypeSystem
return ApplyAttributeTypeVisitor.ApplyAttributesToType(t, compilation, null,
moduleDefinition.Metadata, typeSystemOptions);
}
public IDecompilerTypeSystem GetSpecializingTypeSystem(TypeParameterSubstitution substitution)
{
if (substitution.Equals(TypeParameterSubstitution.Identity)) {
return this;
} else {
return new SpecializingDecompilerTypeSystem(this, substitution);
}
}
}
}

6
ICSharpCode.Decompiler/TypeSystem/IDecompilerTypeSystem.cs

@ -40,11 +40,5 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -40,11 +40,5 @@ namespace ICSharpCode.Decompiler.TypeSystem
MetadataReader GetMetadata();
PEFile ModuleDefinition { get; }
/// <summary>
/// Gets a type system instance that automatically specializes the results
/// of each Resolve() call with the provided substitution.
/// </summary>
IDecompilerTypeSystem GetSpecializingTypeSystem(TypeParameterSubstitution substitution);
}
}

5
ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedParameter.cs

@ -47,5 +47,10 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -47,5 +47,10 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
bool IVariable.IsConst => baseParameter.IsConst;
object IVariable.ConstantValue => baseParameter.ConstantValue;
SymbolKind ISymbol.SymbolKind => SymbolKind.Parameter;
public override string ToString()
{
return DefaultParameter.ToString(this);
}
}
}

80
ICSharpCode.Decompiler/TypeSystem/MetadataModule.cs

@ -170,11 +170,13 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -170,11 +170,13 @@ namespace ICSharpCode.Decompiler.TypeSystem
public ITypeDefinition GetDefinition(TypeDefinitionHandle handle)
{
if (handle.IsNil)
return null;
int row = MetadataTokens.GetRowNumber(handle);
if (row >= typeDefs.Length)
return null;
HandleOutOfRange(handle);
var typeDef = LazyInit.VolatileRead(ref typeDefs[row]);
if (typeDef != null || handle.IsNil)
if (typeDef != null)
return typeDef;
typeDef = new MetadataTypeDefinition(this, handle);
return LazyInit.GetOrSet(ref typeDefs[row], typeDef);
@ -182,11 +184,13 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -182,11 +184,13 @@ namespace ICSharpCode.Decompiler.TypeSystem
public IField GetDefinition(FieldDefinitionHandle handle)
{
if (handle.IsNil)
return null;
int row = MetadataTokens.GetRowNumber(handle);
if (row >= fieldDefs.Length)
return null;
HandleOutOfRange(handle);
var field = LazyInit.VolatileRead(ref fieldDefs[row]);
if (field != null || handle.IsNil)
if (field != null)
return field;
field = new MetadataField(this, handle);
return LazyInit.GetOrSet(ref fieldDefs[row], field);
@ -194,11 +198,14 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -194,11 +198,14 @@ namespace ICSharpCode.Decompiler.TypeSystem
public IMethod GetDefinition(MethodDefinitionHandle handle)
{
if (handle.IsNil)
return null;
int row = MetadataTokens.GetRowNumber(handle);
Debug.Assert(row != 0);
if (row >= methodDefs.Length)
return null;
HandleOutOfRange(handle);
var method = LazyInit.VolatileRead(ref methodDefs[row]);
if (method != null || handle.IsNil)
if (method != null)
return method;
method = new MetadataMethod(this, handle);
return LazyInit.GetOrSet(ref methodDefs[row], method);
@ -206,11 +213,14 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -206,11 +213,14 @@ namespace ICSharpCode.Decompiler.TypeSystem
public IProperty GetDefinition(PropertyDefinitionHandle handle)
{
if (handle.IsNil)
return null;
int row = MetadataTokens.GetRowNumber(handle);
Debug.Assert(row != 0);
if (row >= methodDefs.Length)
return null;
HandleOutOfRange(handle);
var property = LazyInit.VolatileRead(ref propertyDefs[row]);
if (property != null || handle.IsNil)
if (property != null)
return property;
property = new MetadataProperty(this, handle);
return LazyInit.GetOrSet(ref propertyDefs[row], property);
@ -218,15 +228,23 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -218,15 +228,23 @@ namespace ICSharpCode.Decompiler.TypeSystem
public IEvent GetDefinition(EventDefinitionHandle handle)
{
if (handle.IsNil)
return null;
int row = MetadataTokens.GetRowNumber(handle);
Debug.Assert(row != 0);
if (row >= methodDefs.Length)
return null;
HandleOutOfRange(handle);
var ev = LazyInit.VolatileRead(ref eventDefs[row]);
if (ev != null || handle.IsNil)
if (ev != null)
return ev;
ev = new MetadataEvent(this, handle);
return LazyInit.GetOrSet(ref eventDefs[row], ev);
}
void HandleOutOfRange(EntityHandle handle)
{
throw new BadImageFormatException("Handle with invalid row number.");
}
#endregion
#region Resolve Type
@ -271,6 +289,12 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -271,6 +289,12 @@ namespace ICSharpCode.Decompiler.TypeSystem
ty = ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, Compilation, null, metadata, options, typeChildrenOnly: true);
return ty;
}
IType IntroduceTupleTypes(IType ty)
{
// run ApplyAttributeTypeVisitor without attributes, in order to introduce tuple types
return ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, Compilation, null, metadata, options);
}
#endregion
#region Resolve Method
@ -293,9 +317,6 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -293,9 +317,6 @@ namespace ICSharpCode.Decompiler.TypeSystem
IMethod ResolveMethodDefinition(MethodDefinitionHandle methodDefHandle, bool expandVarArgs)
{
var method = GetDefinition(methodDefHandle);
if (method == null) {
throw new BadImageFormatException("MethodDef not found in current assembly.");
}
if (expandVarArgs && method.Parameters.LastOrDefault()?.Type.Kind == TypeKind.ArgList) {
method = new VarArgInstanceMethod(method, EmptyList<IType>.Instance);
}
@ -306,13 +327,12 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -306,13 +327,12 @@ namespace ICSharpCode.Decompiler.TypeSystem
{
var methodSpec = metadata.GetMethodSpecification(methodSpecHandle);
var methodTypeArgs = methodSpec.DecodeSignature(TypeProvider, context)
.SelectReadOnlyArray(ta => ApplyAttributeTypeVisitor.ApplyAttributesToType(ta, Compilation,
methodSpec.GetCustomAttributes(), metadata, this.TypeSystemOptions));
.SelectReadOnlyArray(IntroduceTupleTypes);
IMethod method;
if (methodSpec.Method.Kind == HandleKind.MethodDefinition) {
// generic instance of a methoddef (=generic method in non-generic class in current assembly)
method = ResolveMethodDefinition((MethodDefinitionHandle)methodSpec.Method, expandVarArgs);
method = method.Specialize(new TypeParameterSubstitution(context.ClassTypeParameters, methodTypeArgs));
method = method.Specialize(new TypeParameterSubstitution(null, methodTypeArgs));
} else {
method = ResolveMethodReference((MemberReferenceHandle)methodSpec.Method, context, methodTypeArgs, expandVarArgs);
}
@ -524,6 +544,34 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -524,6 +544,34 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
#endregion
#region Decode Standalone Signature
public MethodSignature<IType> DecodeMethodSignature(StandaloneSignatureHandle handle, GenericContext genericContext)
{
var standaloneSignature = metadata.GetStandaloneSignature(handle);
if (standaloneSignature.GetKind() != StandaloneSignatureKind.Method)
throw new InvalidOperationException("Expected Method signature");
var sig = standaloneSignature.DecodeMethodSignature(TypeProvider, genericContext);
return new MethodSignature<IType>(
sig.Header,
IntroduceTupleTypes(sig.ReturnType),
sig.RequiredParameterCount,
sig.GenericParameterCount,
ImmutableArray.CreateRange(
sig.ParameterTypes, IntroduceTupleTypes
)
);
}
public ImmutableArray<IType> DecodeLocalSignature(StandaloneSignatureHandle handle, GenericContext genericContext)
{
var standaloneSignature = metadata.GetStandaloneSignature(handle);
if (standaloneSignature.GetKind() != StandaloneSignatureKind.LocalVariables)
throw new InvalidOperationException("Expected Local signature");
var types = standaloneSignature.DecodeLocalSignature(TypeProvider, genericContext);
return ImmutableArray.CreateRange(types, IntroduceTupleTypes);
}
#endregion
#region Module / Assembly attributes
/// <summary>
/// Gets the list of all assembly attributes in the project.

124
ICSharpCode.Decompiler/TypeSystem/SpecializingDecompilerTypeSystem.cs

@ -1,124 +0,0 @@ @@ -1,124 +0,0 @@
// Copyright (c) 2014 Daniel Grunwald
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// 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.Immutable;
using System.Reflection.Metadata;
using ICSharpCode.Decompiler.Metadata;
namespace ICSharpCode.Decompiler.TypeSystem
{
/// <summary>
/// Decompiler type system for generic types or methods:
/// used to replace the dummy type parameters by the actual type parameters of the method being decompiled.
/// </summary>
public class SpecializingDecompilerTypeSystem : IDecompilerTypeSystem
{
readonly IDecompilerTypeSystem context;
readonly TypeParameterSubstitution substitution;
public SpecializingDecompilerTypeSystem(IDecompilerTypeSystem context, TypeParameterSubstitution substitution)
{
if (context == null)
throw new ArgumentNullException(nameof(context));
if (substitution == null)
throw new ArgumentNullException(nameof(substitution));
this.context = context;
this.substitution = substitution;
}
internal IDecompilerTypeSystem Context {
get { return context; }
}
public ICompilation Compilation {
get { return context.Compilation; }
}
public Metadata.PEFile ModuleDefinition => context.ModuleDefinition;
public MetadataModule MainModule => context.MainModule;
public TypeParameterSubstitution Substitution {
get { return substitution; }
}
public IType ResolveAsType(EntityHandle typeReference)
{
return context.ResolveAsType(typeReference).AcceptVisitor(substitution);
}
public IField ResolveAsField(EntityHandle fieldReference)
{
IField field = context.ResolveAsField(fieldReference);
if (field != null)
field = (IField)field.Specialize(substitution);
return field;
}
public IMethod ResolveAsMethod(EntityHandle methodReference)
{
IMethod method = context.ResolveAsMethod(methodReference);
if (method != null)
method = (IMethod)method.Specialize(substitution);
return method;
}
public IDecompilerTypeSystem GetSpecializingTypeSystem(TypeParameterSubstitution newSubstitution)
{
//return context.GetSpecializingTypeSystem(TypeParameterSubstitution.Compose(newSubstitution, this.substitution));
// Because the input new substitution is taken from IMember.Substitution for some member that
// was resolved by this type system, it already contains 'this.substitution'.
return context.GetSpecializingTypeSystem(newSubstitution);
}
public MetadataReader GetMetadata()
{
return context.GetMetadata();
}
public IMember ResolveAsMember(EntityHandle memberReference)
{
IMember member = context.ResolveAsMember(memberReference);
if (member != null)
member = member.Specialize(substitution);
return member;
}
MethodSignature<IType> IDecompilerTypeSystem.DecodeMethodSignature(StandaloneSignatureHandle standaloneSignatureHandle)
{
var sig = context.DecodeMethodSignature(standaloneSignatureHandle);
return new MethodSignature<IType>(
sig.Header,
sig.ReturnType.AcceptVisitor(substitution),
sig.RequiredParameterCount,
sig.GenericParameterCount,
ImmutableArray.CreateRange(
sig.ParameterTypes, t => t.AcceptVisitor(substitution)
)
);
}
ImmutableArray<IType> IDecompilerTypeSystem.DecodeLocalSignature(StandaloneSignatureHandle standaloneSignatureHandle)
{
var sig = context.DecodeLocalSignature(standaloneSignatureHandle);
return ImmutableArray.CreateRange(
sig, t => t.AcceptVisitor(substitution)
);
}
}
}

8
ICSharpCode.Decompiler/TypeSystem/TypeParameterSubstitution.cs

@ -200,6 +200,10 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -200,6 +200,10 @@ namespace ICSharpCode.Decompiler.TypeSystem
b.Append(" -> ");
b.Append(classTypeArguments[i].ReflectionName);
}
if (classTypeArguments.Count == 0) {
if (first) first = false; else b.Append(", ");
b.Append("[]");
}
}
if (methodTypeArguments != null) {
for (int i = 0; i < methodTypeArguments.Count; i++) {
@ -209,6 +213,10 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -209,6 +213,10 @@ namespace ICSharpCode.Decompiler.TypeSystem
b.Append(" -> ");
b.Append(methodTypeArguments[i].ReflectionName);
}
if (methodTypeArguments.Count == 0) {
if (first) first = false; else b.Append(", ");
b.Append("[]");
}
}
b.Append(']');
return b.ToString();

11
ILSpy.BamlDecompiler/ConnectMethodDecompiler.cs

@ -54,11 +54,14 @@ namespace ILSpy.BamlDecompiler @@ -54,11 +54,14 @@ namespace ILSpy.BamlDecompiler
if (method == null || metadataEntry.RelativeVirtualAddress <= 0)
return result;
var body = module.Reader.GetMethodBody(metadataEntry.RelativeVirtualAddress);
var genericContext = new ICSharpCode.Decompiler.TypeSystem.GenericContext(
classTypeParameters: method.DeclaringType?.TypeParameters,
methodTypeParameters: method.TypeParameters);
// decompile method and optimize the switch
var ilReader = new ILReader(typeSystem);
var function = ilReader.ReadIL(module, (MethodDefinitionHandle)method.MetadataToken,
module.Reader.GetMethodBody(metadataEntry.RelativeVirtualAddress), cancellationToken);
var ilReader = new ILReader(typeSystem.MainModule);
var function = ilReader.ReadIL((MethodDefinitionHandle)method.MetadataToken, body, genericContext, cancellationToken);
var context = new ILTransformContext(function, typeSystem, null) {
CancellationToken = cancellationToken

9
ILSpy/Languages/ILAstLanguage.cs

@ -91,9 +91,9 @@ namespace ICSharpCode.ILSpy @@ -91,9 +91,9 @@ namespace ICSharpCode.ILSpy
if (!methodDef.HasBody())
return;
var typeSystem = new DecompilerTypeSystem(module, module.GetAssemblyResolver());
ILReader reader = new ILReader(typeSystem);
ILReader reader = new ILReader(typeSystem.MainModule);
var methodBody = module.Reader.GetMethodBody(methodDef.RelativeVirtualAddress);
reader.WriteTypedIL(module, (SRM.MethodDefinitionHandle)method.MetadataToken, methodBody, output, options.CancellationToken);
reader.WriteTypedIL((SRM.MethodDefinitionHandle)method.MetadataToken, methodBody, output, cancellationToken: options.CancellationToken);
}
}
@ -116,11 +116,10 @@ namespace ICSharpCode.ILSpy @@ -116,11 +116,10 @@ namespace ICSharpCode.ILSpy
return;
IAssemblyResolver assemblyResolver = module.GetAssemblyResolver();
var typeSystem = new DecompilerTypeSystem(module, assemblyResolver);
var specializingTypeSystem = typeSystem.GetSpecializingTypeSystem(new SimpleTypeResolveContext(typeSystem.ResolveAsMethod(method.MetadataToken)));
var reader = new ILReader(specializingTypeSystem);
var reader = new ILReader(typeSystem.MainModule);
reader.UseDebugSymbols = options.DecompilerSettings.UseDebugSymbols;
var methodBody = module.Reader.GetMethodBody(methodDef.RelativeVirtualAddress);
ILFunction il = reader.ReadIL(module, (SRM.MethodDefinitionHandle)method.MetadataToken, methodBody, options.CancellationToken);
ILFunction il = reader.ReadIL((SRM.MethodDefinitionHandle)method.MetadataToken, methodBody, cancellationToken: options.CancellationToken);
var namespaces = new HashSet<string>();
var decompiler = new CSharpDecompiler(typeSystem, assemblyResolver, options.DecompilerSettings) { CancellationToken = options.CancellationToken };
ILTransformContext context = decompiler.CreateILTransformContext(il);

Loading…
Cancel
Save