Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 0 additions & 109 deletions src/coreclr/tools/Common/JitInterface/AsyncMethodDesc.cs

This file was deleted.

24 changes: 0 additions & 24 deletions src/coreclr/tools/Common/JitInterface/AsyncMethodDescFactory.cs

This file was deleted.

8 changes: 8 additions & 0 deletions src/coreclr/tools/Common/JitInterface/UnboxingMethodDesc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ public override MethodDesc InstantiateSignature(Instantiation typeInstantiation,
return this;
}

public override AsyncMethodData AsyncMethodData
{
get
{
return _wrappedMethod.AsyncMethodData;
}
}

public override string ToString()
{
return "Unboxing MethodDesc: " + _wrappedMethod.ToString();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Internal.TypeSystem
{
/// <summary>
/// Represents the async-callable (CORINFO_CALLCONV_ASYNCCALL) variant of a Task/ValueTask returning method.
/// </summary>
public sealed partial class AsyncMethodThunk : MethodDelegator
{
public override MethodDesc GetCanonMethodTarget(CanonicalFormKind kind)
{
return _wrappedMethod.GetCanonMethodTarget(kind).GetAsyncOtherVariant();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Internal.TypeSystem
{
/// <summary>
/// Represents the Task-returning variant of an async call convention method.
/// </summary>
public sealed partial class TaskReturningAsyncThunk : MethodDelegator
{
public override MethodDesc GetCanonMethodTarget(CanonicalFormKind kind)
{
return _wrappedMethod.GetCanonMethodTarget(kind).GetAsyncOtherVariant();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;

namespace Internal.TypeSystem
{
/// <summary>
/// Represents the async-callable (CORINFO_CALLCONV_ASYNCCALL) variant of a Task/ValueTask returning method.
/// </summary>
public sealed partial class AsyncMethodThunk : MethodDelegator
{
public override string DiagnosticName
{
get
{
return "Async thunk: " + _wrappedMethod.DiagnosticName;
}
}
}
}
69 changes: 69 additions & 0 deletions src/coreclr/tools/Common/TypeSystem/Common/AsyncMethodThunk.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;

namespace Internal.TypeSystem
{
/// <summary>
/// Represents the async-callable (CORINFO_CALLCONV_ASYNCCALL) variant of a Task/ValueTask returning method.
/// </summary>
public sealed partial class AsyncMethodThunk : MethodDelegator
{
private readonly AsyncMethodData _asyncMethodData;

public AsyncMethodThunk(MethodDesc wrappedMethod)
: base(wrappedMethod)
{
Debug.Assert(wrappedMethod.IsTaskReturning);
Debug.Assert(!wrappedMethod.IsAsync);
_asyncMethodData = new AsyncMethodData()
{
Kind = AsyncMethodKind.AsyncVariantThunk,
Signature = _wrappedMethod.Signature.CreateAsyncSignature()
};
}

public override AsyncMethodData AsyncMethodData
{
get
{
return _asyncMethodData;
}
}

public override MethodDesc GetMethodDefinition()
{
return _wrappedMethod.GetMethodDefinition();
}

public override MethodDesc GetTypicalMethodDefinition()
{
return _wrappedMethod.GetTypicalMethodDefinition();
}

public override MethodDesc GetAsyncOtherVariant()
{
return _wrappedMethod;
}

public override MethodDesc InstantiateSignature(Instantiation typeInstantiation, Instantiation methodInstantiation)
{
MethodDesc real = _wrappedMethod.InstantiateSignature(typeInstantiation, methodInstantiation);
return real.GetAsyncOtherVariant();
}

public override MethodSignature Signature
{
get
{
return _asyncMethodData.Signature;
}
}

public override string ToString()
{
return "Async thunk: " + _wrappedMethod.ToString();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing using System.Threading; directive. The code uses Interlocked.CompareExchange on line 46 but doesn't import the System.Threading namespace. While the main InstantiatedMethod.cs file has this import, partial class files need their own using directives for the types they reference.

Suggested change
using System.Diagnostics;
using System.Diagnostics;
using System.Threading;

Copilot uses AI. Check for mistakes.
using System.Threading;

namespace Internal.TypeSystem
{
public sealed partial class InstantiatedMethod
{
private AsyncMethodData _asyncMethodData;
private MethodDesc _asyncOtherVariant;

public override AsyncMethodData AsyncMethodData
{
get
{
if (!_asyncMethodData.Equals(default(AsyncMethodData)))
return _asyncMethodData;

if (IsAsync)
{
// If the method is already async, the template signature should already have been updated to reflect the AsyncCallConv
Debug.Assert(!Signature.ReturnsTaskOrValueTask() && Signature.IsAsyncCallConv);
_asyncMethodData = new AsyncMethodData() { Kind = AsyncMethodKind.AsyncVariantImpl, Signature = Signature };
}
else if (Signature.ReturnsTaskOrValueTask())
{
_asyncMethodData = new AsyncMethodData() { Kind = AsyncMethodKind.TaskReturning, Signature = Signature };
}
else
{
_asyncMethodData = new AsyncMethodData() { Kind = AsyncMethodKind.NotAsync, Signature = Signature };
}

return _asyncMethodData;
}
}

public override MethodDesc GetAsyncOtherVariant()
{
if (_asyncOtherVariant is null)
{
MethodDesc otherVariant = IsAsync ?
new TaskReturningAsyncThunk(this, InstantiateSignature(_methodDef.GetAsyncOtherVariant().Signature))
: new AsyncMethodThunk(this);
Interlocked.CompareExchange(ref _asyncOtherVariant, otherVariant, null);
}
return _asyncOtherVariant;
}
}
}
28 changes: 17 additions & 11 deletions src/coreclr/tools/Common/TypeSystem/Common/InstantiatedMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Diagnostics;
using System.Threading;
using Internal.NativeFormat;

namespace Internal.TypeSystem
Expand Down Expand Up @@ -58,21 +59,27 @@ private TypeDesc Instantiate(TypeDesc type)
return type.InstantiateSignature(default(Instantiation), _instantiation);
}

private void InitializeSignature()
{
var template = _methodDef.Signature;
_signature = InstantiateSignature(template);
}

private MethodSignature InstantiateSignature(MethodSignature template)
{
var builder = new MethodSignatureBuilder(template);
builder.ReturnType = Instantiate(template.ReturnType);
for (int i = 0; i < template.Length; i++)
builder[i] = Instantiate(template[i]);
return builder.ToSignature();
}

public override MethodSignature Signature
{
get
{
if (_signature == null)
{
MethodSignature template = _methodDef.Signature;
MethodSignatureBuilder builder = new MethodSignatureBuilder(template);

builder.ReturnType = Instantiate(template.ReturnType);
for (int i = 0; i < template.Length; i++)
builder[i] = Instantiate(template[i]);

_signature = builder.ToSignature();
}
InitializeSignature();

return _signature;
}
Expand Down Expand Up @@ -134,7 +141,6 @@ public override bool IsAsync
}
}


public override bool HasCustomAttribute(string attributeNamespace, string attributeName)
{
return _methodDef.HasCustomAttribute(attributeNamespace, attributeName);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;

namespace Internal.TypeSystem
{
/// <summary>
/// Wraps a <see cref="MethodDesc"/> object and delegates methods to that <see cref="MethodDesc"/>.
/// </summary>
public abstract partial class MethodDelegator : MethodDesc
{
public abstract override AsyncMethodData AsyncMethodData { get; }
}
}
Loading
Loading