Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
6658d8b
Pass async jit flag to jit in aot tools
jtschuster Oct 15, 2025
1f917e9
Add IsRuntimeAsync override to instantiated MethodDescs
jtschuster Oct 15, 2025
431bfaa
Update src/coreclr/tools/Common/TypeSystem/Common/InstantiatedMethod.cs
jkotas Oct 15, 2025
3a4ffbc
Rename IsRuntimeAsync to IsAsync, add override in MethodDelegator
jtschuster Oct 16, 2025
1030acb
Add AsyncMethodDesc for AsyncCallConv methods
jtschuster Oct 17, 2025
4cc1f5f
Merge branch 'main' of https://github.com/dotnet/runtime into AsyncMe…
jtschuster Oct 17, 2025
7516cba
Remove comments from AsyncMethodDesc
jtschuster Oct 17, 2025
42e1157
Use MethodSignatureBuilder and assert for expected invariants
jtschuster Oct 17, 2025
429f910
Use throwing cast instead of 'as' cast
jtschuster Oct 17, 2025
4e0d53d
Fix assert
jtschuster Oct 17, 2025
c75c536
Add getter to Flags for |=
jtschuster Oct 17, 2025
e8ef453
Implement getAsyncInfo in ILCompiler
jtschuster Oct 17, 2025
5ff7bc6
Use Dictionary instead of ConcurrentDictionary for AsyncMethodDescFac…
jtschuster Oct 17, 2025
e5ea4ce
Refactor AsyncMethodDesc for clarity and efficiency
jtschuster Oct 17, 2025
0cf52dc
Update src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
jtschuster Oct 17, 2025
de10bb5
Update Signature and delete GetOtherAsyncMethod
jtschuster Oct 17, 2025
ff2712d
Remove IsAsync requirement from AsyncMethodDesc
jtschuster Oct 17, 2025
9749653
Formatting and remove unused accessor
jtschuster Oct 17, 2025
c2e3c48
Merge branch 'GetAsyncInfoR2R' into AsyncMethodDesc
jtschuster Oct 17, 2025
7bb7b1b
Merge branch 'main' of https://github.com/dotnet/runtime into GetAsyn…
jtschuster Oct 18, 2025
a728fdb
Use new CORINFO_ASYNC_INFO, PR Feedback
jtschuster Oct 19, 2025
bada361
Delete old UnboxingMethodDescFactory, move AsyncMethodDescFactory to …
jtschuster Oct 20, 2025
5fd0330
Merge branch 'GetAsyncInfoR2R' into AsyncR2R
jtschuster Oct 20, 2025
1bae281
Add support for async method wrappers and related functionality
jtschuster Oct 22, 2025
0b4dca8
Merge branch 'main' of https://github.com/dotnet/runtime into AsyncR2R
jtschuster Oct 22, 2025
0e6d23c
Couple other cleanup fixes
jtschuster Oct 22, 2025
a828d07
Adjustment to get the compiler to finish the jitting
davidwrighton Oct 23, 2025
7f24e0b
WIP
jtschuster Oct 23, 2025
4802a7f
Merge pull request #2 from davidwrighton/AsyncR2RTweaks
jtschuster Oct 23, 2025
4834a15
Merge branch 'AsyncR2R' of https://github.com/jtschuster/runtime into…
jtschuster Oct 23, 2025
cfb856b
Compiling, runs until failed assert
jtschuster Oct 26, 2025
7643bb9
Remove unused TaskReturningAsyncWrapper and undo formatting changes
jtschuster Oct 26, 2025
845b5d3
Runs the R2R image without jitting main when main doesnt await
jtschuster Oct 29, 2025
a9dafc3
Create thunk MethodDescs, put thunks into InstanceMethod
jtschuster Oct 30, 2025
89f9d1d
Update csproj
jtschuster Oct 30, 2025
c9a3382
Merge branch 'main' of https://github.com/dotnet/runtime into AsyncR2R
jtschuster Oct 30, 2025
fe73474
Just committing everything for now
jtschuster Nov 3, 2025
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
1 change: 1 addition & 0 deletions docs/design/coreclr/botr/readytorun-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ token, and additional data determined by the flags.
| READYTORUN_METHOD_SIG_Constrained | 0x20 | Constrained type for method resolution. Typespec appended as additional data.
| READYTORUN_METHOD_SIG_OwnerType | 0x40 | Method type. Typespec appended as additional data.
| READYTORUN_METHOD_SIG_UpdateContext | 0x80 | If set, update the module which is used to parse tokens before performing any token processing. A uint index into the modules table immediately follows the flags
| READYTORUN_METHOD_SIG_AsyncVariant | 0x100 | If set, the token is the AsyncCallConv variant of a runtime async method

#### Field Signatures

Expand Down
1 change: 1 addition & 0 deletions src/coreclr/inc/readytorun.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ enum ReadyToRunMethodSigFlags
READYTORUN_METHOD_SIG_Constrained = 0x20,
READYTORUN_METHOD_SIG_OwnerType = 0x40,
READYTORUN_METHOD_SIG_UpdateContext = 0x80,
READYTORUN_METHOD_SIG_AsyncVariant = 0x100,
};

enum ReadyToRunFieldSigFlags
Expand Down
11 changes: 11 additions & 0 deletions src/coreclr/tools/Common/Compiler/NativeAotNameMangler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Internal.TypeSystem;
using Internal.TypeSystem.Ecma;
using System.Diagnostics;
using Internal.JitInterface;

namespace ILCompiler
{
Expand Down Expand Up @@ -432,6 +433,16 @@ private Utf8String ComputeUnqualifiedMangledMethodName(MethodDesc method)
return _unqualifiedMangledMethodNames[method];
}
}
#if READYTORUN
if (method is AsyncMethodThunk)
{
return "<Async>_" + ComputeUnqualifiedMangledMethodName(method.GetTypicalMethodDefinition());
}
if (method is TaskReturningAsyncThunk)
{
return "<TaskReturningAsync>_" + ComputeUnqualifiedMangledMethodName(method.GetTypicalMethodDefinition());
}
#endif

Utf8String utf8MangledName;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public enum ReadyToRunImportSectionFlags : ushort
/// Constants for method and field encoding
/// </summary>
[Flags]
public enum ReadyToRunMethodSigFlags : byte
public enum ReadyToRunMethodSigFlags : uint
{
READYTORUN_METHOD_SIG_None = 0x00,
READYTORUN_METHOD_SIG_UnboxingStub = 0x01,
Expand All @@ -52,6 +52,7 @@ public enum ReadyToRunMethodSigFlags : byte
READYTORUN_METHOD_SIG_Constrained = 0x20,
READYTORUN_METHOD_SIG_OwnerType = 0x40,
READYTORUN_METHOD_SIG_UpdateContext = 0x80,
READYTORUN_METHOD_SIG_AsyncVariant = 0x100,
}

[Flags]
Expand Down
37 changes: 23 additions & 14 deletions src/coreclr/tools/Common/JitInterface/AsyncMethodDesc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ namespace Internal.JitInterface
{
/// <summary>
/// Represents the async-callable (CORINFO_CALLCONV_ASYNCCALL) variant of a Task/ValueTask returning method.
/// The wrapper should be short‑lived and only used while interacting with the JIT interface.
/// </summary>
internal sealed class AsyncMethodDesc : MethodDelegator, IJitHashableOnly
internal sealed class AsyncMethodDesc : MethodDelegator
{
private readonly AsyncMethodDescFactory _factory;
private readonly int _jitVisibleHashCode;
Expand Down Expand Up @@ -46,9 +45,10 @@ public override MethodDesc GetMethodDefinition()
public override MethodDesc GetTypicalMethodDefinition()
{
MethodDesc real = _wrappedMethod.GetTypicalMethodDefinition();
if (real != _wrappedMethod)
return _factory.GetAsyncMethod(real);
return this;
return real;
//if (real != _wrappedMethod)
// return _factory.GetAsyncMethod(real);
//return this;
}

public override MethodDesc InstantiateSignature(Instantiation typeInstantiation, Instantiation methodInstantiation)
Expand All @@ -72,19 +72,28 @@ public override MethodSignature Signature
}
}

#if !SUPPORT_JIT
// Same pattern as UnboxingMethodDesc: these should not escape JIT hashing scope.
protected override int ClassCode => throw new NotImplementedException();
protected override int CompareToImpl(MethodDesc other, TypeSystemComparer comparer) => throw new NotImplementedException();
protected override int ComputeHashCode() => _jitVisibleHashCode;
int IJitHashableOnly.GetJitVisibleHashCode() => _jitVisibleHashCode;
#else
int IJitHashableOnly.GetJitVisibleHashCode() => _jitVisibleHashCode;
#endif
protected override int ClassCode => 0x554d08b9;

protected override int CompareToImpl(MethodDesc other, TypeSystemComparer comparer)
{
if (other is AsyncMethodDesc otherAsync)
{
return comparer.Compare(_wrappedMethod, otherAsync._wrappedMethod);
}
return -1;
}
public override string ToString()
{
return "Async MethodDesc: " + _wrappedMethod.ToString();
}
}

internal static class AsyncMethodDescExtensions
{
public static bool IsAsyncCallConv(this MethodDesc method)
{
return method is AsyncMethodDesc;
}
/// <summary>
/// Returns true if the method returns Task, Task&lt;T&gt;, ValueTask, or ValueTask&lt;T&gt;, otherwise false.
/// </summary>
Expand Down
24 changes: 0 additions & 24 deletions src/coreclr/tools/Common/JitInterface/AsyncMethodDescFactory.cs

This file was deleted.

84 changes: 71 additions & 13 deletions src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@

using ILCompiler;
using ILCompiler.DependencyAnalysis;
using Internal.IL.Stubs;



#if READYTORUN
using System.Reflection.Metadata.Ecma335;
Expand Down Expand Up @@ -126,10 +129,10 @@ public LikelyClassMethodRecord(IntPtr handle, uint likelihood)
}

[DllImport(JitLibrary)]
private static extern uint getLikelyClasses(LikelyClassMethodRecord* pLikelyClasses, uint maxLikelyClasses, PgoInstrumentationSchema* schema, uint countSchemaItems, byte*pInstrumentationData, int ilOffset);
private static extern uint getLikelyClasses(LikelyClassMethodRecord* pLikelyClasses, uint maxLikelyClasses, PgoInstrumentationSchema* schema, uint countSchemaItems, byte* pInstrumentationData, int ilOffset);

[DllImport(JitLibrary)]
private static extern uint getLikelyMethods(LikelyClassMethodRecord* pLikelyMethods, uint maxLikelyMethods, PgoInstrumentationSchema* schema, uint countSchemaItems, byte*pInstrumentationData, int ilOffset);
private static extern uint getLikelyMethods(LikelyClassMethodRecord* pLikelyMethods, uint maxLikelyMethods, PgoInstrumentationSchema* schema, uint countSchemaItems, byte* pInstrumentationData, int ilOffset);

[DllImport(JitSupportLibrary)]
private static extern IntPtr GetJitHost(IntPtr configProvider);
Expand All @@ -150,7 +153,7 @@ private static extern CorJitResult JitCompileMethod(out IntPtr exception,
ref CORINFO_METHOD_INFO info, uint flags, out IntPtr nativeEntry, out uint codeSize);

[DllImport(JitSupportLibrary)]
private static extern IntPtr AllocException([MarshalAs(UnmanagedType.LPWStr)]string message, int messageLength);
private static extern IntPtr AllocException([MarshalAs(UnmanagedType.LPWStr)] string message, int messageLength);

[DllImport(JitSupportLibrary)]
private static extern void JitSetOs(IntPtr jit, CORINFO_OS os);
Expand Down Expand Up @@ -816,12 +819,12 @@ private bool Get_CORINFO_METHOD_INFO(MethodDesc method, MethodIL methodIL, CORIN
private Dictionary<Instantiation, IntPtr[]> _instantiationToJitVisibleInstantiation;
private CORINFO_CLASS_STRUCT_** GetJitInstantiation(Instantiation inst)
{
IntPtr [] jitVisibleInstantiation;
IntPtr[] jitVisibleInstantiation;
_instantiationToJitVisibleInstantiation ??= new Dictionary<Instantiation, IntPtr[]>();

if (!_instantiationToJitVisibleInstantiation.TryGetValue(inst, out jitVisibleInstantiation))
{
jitVisibleInstantiation = new IntPtr[inst.Length];
jitVisibleInstantiation = new IntPtr[inst.Length];
for (int i = 0; i < inst.Length; i++)
jitVisibleInstantiation[i] = (IntPtr)ObjectToHandle(inst[i]);
_instantiationToJitVisibleInstantiation.Add(inst, jitVisibleInstantiation);
Expand All @@ -831,7 +834,9 @@ private bool Get_CORINFO_METHOD_INFO(MethodDesc method, MethodIL methodIL, CORIN

private void Get_CORINFO_SIG_INFO(MethodDesc method, CORINFO_SIG_INFO* sig, MethodILScope scope, bool suppressHiddenArgument = false)
{
Get_CORINFO_SIG_INFO(method.Signature, sig, scope);
var signature = method.AsyncMethodData.IsAsyncCallConv ?
method.AsyncMethodData.Signature : method.Signature;
Get_CORINFO_SIG_INFO(signature, sig, scope);

// Does the method have a hidden parameter?
bool hasHiddenParameter = !suppressHiddenArgument && method.RequiresInstArg();
Expand All @@ -853,6 +858,11 @@ private void Get_CORINFO_SIG_INFO(MethodDesc method, CORINFO_SIG_INFO* sig, Meth
sig->callConv |= CorInfoCallConv.CORINFO_CALLCONV_PARAMTYPE;
}

if (method.AsyncMethodData.IsAsyncCallConv)
{
sig->callConv |= CorInfoCallConv.CORINFO_CALLCONV_ASYNCCALL;
}

Instantiation owningTypeInst = method.OwningType.Instantiation;
sig->sigInst.classInstCount = (uint)owningTypeInst.Length;
if (owningTypeInst.Length != 0)
Expand All @@ -877,6 +887,7 @@ private void Get_CORINFO_SIG_INFO(MethodSignature signature, CORINFO_SIG_INFO* s

if (!signature.IsStatic) sig->callConv |= CorInfoCallConv.CORINFO_CALLCONV_HASTHIS;
if (signature.IsExplicitThis) sig->callConv |= CorInfoCallConv.CORINFO_CALLCONV_EXPLICITTHIS;
if (signature.IsAsyncCallConv) sig->callConv |= CorInfoCallConv.CORINFO_CALLCONV_ASYNCCALL;

TypeDesc returnType = signature.ReturnType;

Expand Down Expand Up @@ -1044,7 +1055,7 @@ private TypeSystemEntity entityFromContext(CORINFO_CONTEXT_STRUCT* contextStruct
{
if (contextStruct == contextFromMethodBeingCompiled())
{
return MethodBeingCompiled.HasInstantiation ? (TypeSystemEntity)MethodBeingCompiled: (TypeSystemEntity)MethodBeingCompiled.OwningType;
return MethodBeingCompiled.HasInstantiation ? (TypeSystemEntity)MethodBeingCompiled : (TypeSystemEntity)MethodBeingCompiled.OwningType;
}

return (TypeSystemEntity)HandleToObject((void*)((nuint)contextStruct & ~(nuint)CorInfoContextFlags.CORINFO_CONTEXTFLAGS_MASK));
Expand Down Expand Up @@ -1801,6 +1812,7 @@ by resolving the token in the definition. */

private void resolveToken(ref CORINFO_RESOLVED_TOKEN pResolvedToken)
{
// If the token is an async method but await tokenkind is not requested, wrap it with a AsyncTaskWrapperMethodDesc
var methodIL = HandleToObject(pResolvedToken.tokenScope);

var typeOrMethodContext = (pResolvedToken.tokenContext == contextFromMethodBeingCompiled()) ?
Expand All @@ -1827,6 +1839,41 @@ private void resolveToken(ref CORINFO_RESOLVED_TOKEN pResolvedToken)

if (result is MethodDesc method)
{
bool requestingAsync = pResolvedToken.tokenType == CorInfoTokenKind.CORINFO_TOKENKIND_Await;
bool isAsync = method.AsyncMethodData.IsAsyncCallConv;
if (requestingAsync && !isAsync)
{
if (method.IsTaskReturning)
{
method = method.GetAsyncOtherVariant();
result = method;
}
else
{
Debug.Assert(method.AsyncMethodData.Kind == AsyncMethodKind.AsyncExplicitImpl);
}
}
if (!requestingAsync && isAsync)
{
if (method.IsTaskReturning)
{
if (typeOrMethodContext == method.GetAsyncOtherVariant())
{
// This is a TaskReturningThunk that wants the asynccallconv method.
// Don't get the other variant
}
else
{
method = method.GetAsyncOtherVariant();
result = method;
}
}
else
{
Debug.Assert(method.AsyncMethodData.Kind == AsyncMethodKind.AsyncExplicitImpl);
}
}

pResolvedToken.hMethod = ObjectToHandle(method);

TypeDesc owningClass = method.OwningType;
Expand Down Expand Up @@ -2258,7 +2305,7 @@ public static int GetClassAlignmentRequirementStatic(DefType type)
//
private static bool ShouldAlign8(int dwR8Fields, int dwTotalFields)
{
return dwR8Fields*2>dwTotalFields && dwR8Fields>=2;
return dwR8Fields * 2 > dwTotalFields && dwR8Fields >= 2;
}

private static bool ShouldAlign8(DefType type)
Expand Down Expand Up @@ -3376,7 +3423,8 @@ private void getAsyncInfo(ref CORINFO_ASYNC_INFO pAsyncInfoOut)
private CORINFO_CLASS_STRUCT_* getContinuationType(nuint dataSize, ref bool objRefs, nuint objRefsSize)
{
Debug.Assert(objRefsSize == (dataSize + (nuint)(PointerSize - 1)) / (nuint)PointerSize);
throw new NotImplementedException("getContinuationType");
return ObjectToHandle(_compilation.TypeSystemContext.SystemModule.GetKnownType("System.Runtime.CompilerServices"u8, "Continuation"u8));
//throw new NotImplementedException("getContinuationType");
}

private mdToken getMethodDefFromMethod(CORINFO_METHOD_STRUCT_* hMethod)
Expand Down Expand Up @@ -3563,7 +3611,7 @@ private uint getThreadTLSIndex(ref void* ppIndirection)
{ throw new NotImplementedException("getThreadTLSIndex"); }

private Dictionary<CorInfoHelpFunc, ISymbolNode> _helperCache = new Dictionary<CorInfoHelpFunc, ISymbolNode>();
private void getHelperFtn(CorInfoHelpFunc ftnNum, CORINFO_CONST_LOOKUP *pNativeEntrypoint, CORINFO_METHOD_STRUCT_** pMethod)
private void getHelperFtn(CorInfoHelpFunc ftnNum, CORINFO_CONST_LOOKUP* pNativeEntrypoint, CORINFO_METHOD_STRUCT_** pMethod)
{
// We never return a method handle from the managed implementation of this method today
if (pMethod != null)
Expand Down Expand Up @@ -3614,7 +3662,12 @@ public static ReadyToRunHelperId GetReadyToRunHelperFromStaticBaseHelper(CorInfo
}

private void getFunctionFixedEntryPoint(CORINFO_METHOD_STRUCT_* ftn, bool isUnsafeFunctionPointer, ref CORINFO_CONST_LOOKUP pResult)
{ throw new NotImplementedException("getFunctionFixedEntryPoint"); }
{
// Called for AsyncResumption stubs
var method = HandleToObject(ftn);
pResult.handle = (CORINFO_GENERIC_STRUCT_*)ObjectToHandle(HandleToObject(ftn));
pResult.accessType = InfoAccessType.IAT_PVALUE;
}

#pragma warning disable CA1822 // Mark members as static
private CorInfoHelpFunc getLazyStringLiteralHelper(CORINFO_MODULE_STRUCT_* handle)
Expand Down Expand Up @@ -3731,7 +3784,12 @@ private bool getTailCallHelpers(ref CORINFO_RESOLVED_TOKEN callToken, CORINFO_SI
private CORINFO_METHOD_STRUCT_* getAsyncResumptionStub()
#pragma warning restore CA1822 // Mark members as static
{
throw new NotImplementedException("Crossgen2 does not support runtime-async yet");
// does m_finalCodeAddressSlot become a reloc? Or will jit give it to us somehow?
#if READYTORUN
return ObjectToHandle(new AsyncResumptionStub(MethodBeingCompiled));
#else
throw new NotImplementedException(nameof(getAsyncResumptionStub));
#endif
}

private byte[] _code;
Expand Down Expand Up @@ -4315,7 +4373,7 @@ private uint getJitFlags(ref CORJIT_FLAGS flags, uint sizeInBytes)
flags.Set(CorJitFlag.CORJIT_FLAG_SOFTFP_ABI);
}

if (this.MethodBeingCompiled.IsAsync)
if (this.MethodBeingCompiled.AsyncMethodData.IsAsyncCallConv)
{
flags.Set(CorJitFlag.CORJIT_FLAG_ASYNC);
}
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ public unsafe struct CORINFO_SIG_INFO
private uint totalILArgs() { return (uint)(numArgs + (hasImplicitThis() ? 1 : 0)); }
private bool isVarArg() { return ((getCallConv() == CorInfoCallConv.CORINFO_CALLCONV_VARARG) || (getCallConv() == CorInfoCallConv.CORINFO_CALLCONV_NATIVEVARARG)); }
internal bool hasTypeArg() { return ((callConv & CorInfoCallConv.CORINFO_CALLCONV_PARAMTYPE) != 0); }
private bool isAsync() { return ((callConv & CorInfoCallConv.CORINFO_CALLCONV_ASYNCCALL) != 0); }
};

//----------------------------------------------------------------------------
Expand Down Expand Up @@ -377,6 +378,7 @@ public enum CorInfoCallConv
CORINFO_CALLCONV_HASTHIS = 0x20,
CORINFO_CALLCONV_EXPLICITTHIS = 0x40,
CORINFO_CALLCONV_PARAMTYPE = 0x80, // Passed last. Same as CORINFO_GENERICS_CTXT_FROM_PARAMTYPEARG
CORINFO_CALLCONV_ASYNCCALL = 0x100, // Is this a call to an async function?
}

// Represents the calling conventions supported with the extensible calling convention syntax
Expand Down Expand Up @@ -1364,6 +1366,9 @@ public enum CorInfoTokenKind

// token comes from resolved static virtual method
CORINFO_TOKENKIND_ResolvedStaticVirtualMethod = 0x1000 | CORINFO_TOKENKIND_Method,

// token comes from a runtime-async Await pattern
CORINFO_TOKENKIND_Await = 0x2000 | CORINFO_TOKENKIND_Method,
};

// These are error codes returned by CompileMethod
Expand Down Expand Up @@ -1423,6 +1428,7 @@ public enum CorJitFlag : uint
// ARM only
CORJIT_FLAG_RELATIVE_CODE_RELOCS = 29, // JIT should generate PC-relative address computations instead of EE relocation records
CORJIT_FLAG_SOFTFP_ABI = 30, // Enable armel calling convention

CORJIT_FLAG_ASYNC = 31, // Generate code for use as an async function
}

Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/tools/Common/JitInterface/UnboxingMethodDesc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public UnboxingMethodDesc(MethodDesc wrappedMethod, UnboxingMethodDescFactory fa
_jitVisibleHashCode = HashCode.Combine(wrappedMethod.GetHashCode(), 401752602);
}

public override AsyncMethodData AsyncMethodData => _wrappedMethod.AsyncMethodData;

public override MethodDesc GetCanonMethodTarget(CanonicalFormKind kind)
{
MethodDesc realCanonTarget = _wrappedMethod.GetCanonMethodTarget(kind);
Expand Down
Loading
Loading