diff --git a/ICSharpCode.Decompiler/IL/ILReader.cs b/ICSharpCode.Decompiler/IL/ILReader.cs index 4d98af2fd..d9e3a2b83 100644 --- a/ICSharpCode.Decompiler/IL/ILReader.cs +++ b/ICSharpCode.Decompiler/IL/ILReader.cs @@ -1401,12 +1401,17 @@ namespace ICSharpCode.Decompiler.IL var signatureHandle = (StandaloneSignatureHandle)ReadAndDecodeMetadataToken(); var signature = module.DecodeMethodSignature(signatureHandle, genericContext); var functionPointer = Pop(StackType.I); - Debug.Assert(!signature.Header.IsInstance); - var arguments = new ILInstruction[signature.ParameterTypes.Length]; + int firstArgument = signature.Header.IsInstance ? 1 : 0; + var arguments = new ILInstruction[firstArgument + signature.ParameterTypes.Length]; for (int i = signature.ParameterTypes.Length - 1; i >= 0; i--) { - arguments[i] = Pop(signature.ParameterTypes[i].GetStackType()); + arguments[firstArgument + i] = Pop(signature.ParameterTypes[i].GetStackType()); + } + if (firstArgument == 1) { + arguments[0] = Pop(); } var call = new CallIndirect( + signature.Header.IsInstance, + signature.Header.HasExplicitThis, signature.Header.CallingConvention, signature.ReturnType, signature.ParameterTypes, diff --git a/ICSharpCode.Decompiler/IL/Instructions/CallIndirect.cs b/ICSharpCode.Decompiler/IL/Instructions/CallIndirect.cs index 07f980fa7..e2b751218 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/CallIndirect.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/CallIndirect.cs @@ -32,7 +32,8 @@ namespace ICSharpCode.Decompiler.IL public readonly InstructionCollection Arguments; ILInstruction functionPointer; - + public bool IsInstance { get; } + public bool HasExplicitThis { get; } public System.Reflection.Metadata.SignatureCallingConvention CallingConvention { get; } public IType ReturnType { get; } public ImmutableArray ParameterTypes { get; } @@ -61,9 +62,11 @@ namespace ICSharpCode.Decompiler.IL functionPointer.ChildIndex = Arguments.Count; } - public CallIndirect(System.Reflection.Metadata.SignatureCallingConvention callingConvention, IType returnType, ImmutableArray parameterTypes, + public CallIndirect(bool isInstance, bool hasExplicitThis, System.Reflection.Metadata.SignatureCallingConvention callingConvention, IType returnType, ImmutableArray parameterTypes, IEnumerable arguments, ILInstruction functionPointer) : base(OpCode.CallIndirect) { + this.IsInstance = isInstance; + this.HasExplicitThis = hasExplicitThis; this.CallingConvention = callingConvention; this.ReturnType = returnType ?? throw new ArgumentNullException("returnType"); this.ParameterTypes = parameterTypes.ToImmutableArray(); @@ -74,7 +77,7 @@ namespace ICSharpCode.Decompiler.IL public override ILInstruction Clone() { - return new CallIndirect(CallingConvention, ReturnType, ParameterTypes, + return new CallIndirect(IsInstance, HasExplicitThis, CallingConvention, ReturnType, ParameterTypes, this.Arguments.Select(inst => inst.Clone()), functionPointer.Clone() ).WithILRange(this); } @@ -84,7 +87,7 @@ namespace ICSharpCode.Decompiler.IL internal override void CheckInvariant(ILPhase phase) { base.CheckInvariant(phase); - Debug.Assert(Arguments.Count == ParameterTypes.Length); + Debug.Assert(Arguments.Count == ParameterTypes.Length + (IsInstance ? 1 : 0)); } public override void WriteTo(ITextOutput output, ILAstWritingOptions options) @@ -94,7 +97,12 @@ namespace ICSharpCode.Decompiler.IL ReturnType.WriteTo(output); output.Write('('); bool first = true; - foreach (var (inst, type) in Arguments.Zip(ParameterTypes, (a,b) => (a,b))) { + int firstArgument = IsInstance ? 1 : 0; + if (firstArgument == 1) { + Arguments[0].WriteTo(output, options); + first = false; + } + foreach (var (inst, type) in Arguments.Skip(firstArgument).Zip(ParameterTypes, (a,b) => (a,b))) { if (first) first = false; else @@ -155,6 +163,10 @@ namespace ICSharpCode.Decompiler.IL bool EqualSignature(CallIndirect other) { + if (IsInstance != other.IsInstance) + return false; + if (HasExplicitThis != other.HasExplicitThis) + return false; if (CallingConvention != other.CallingConvention) return false; if (ParameterTypes.Length != other.ParameterTypes.Length)