Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
db314fe
Passing async tests
jtschuster Feb 5, 2026
fcf110f
Undo extra changes
jtschuster Feb 5, 2026
e1dec2b
Fix merge issues
jtschuster Feb 5, 2026
696b6b6
Cleanup ManifestModuleWrappedIL creation
jtschuster Feb 6, 2026
d0a228c
Use correct OwningMethod for ManifestMetadataModuleWrappedMethodIL.In…
jtschuster Feb 6, 2026
dea51a8
Merge branch 'main' of https://github.com/dotnet/runtime into runtime16
jtschuster Feb 6, 2026
d37bfc8
Undo formatting in CorInfoImpl.ReadyToRun.cs
jtschuster Feb 6, 2026
af114a0
Remove duplicated method from merge, remove unnecessary token manipul…
jtschuster Feb 6, 2026
bf8f402
Merge branch 'main' of https://github.com/dotnet/runtime into runtime16
jtschuster Feb 6, 2026
435c5d9
Remove duplicates from merge
jtschuster Feb 6, 2026
8465ceb
Use the same version resilient hash code for resumption stub and asyn…
jtschuster Feb 8, 2026
49101ed
Generalize CreateR2RBackedILStub
jtschuster Feb 9, 2026
5bcb9b5
Allow async methods without resumption stubs
jtschuster Feb 9, 2026
17e3358
Allow using code for methods without resumption stubs in the r2r image
jtschuster Feb 9, 2026
c66218c
Enable RuntimeAsync library tests
jtschuster Feb 9, 2026
14973b0
Merge branch 'main' of https://github.com/dotnet/runtime into runtime16
jtschuster Feb 9, 2026
18754ac
Apply suggestions from code review
jtschuster Feb 9, 2026
4dfdfe2
Clean up extraneous changes and fix build
jtschuster Feb 9, 2026
a887cf6
Merge branch 'runtime16' of https://github.com/jtschuster/runtime int…
jtschuster Feb 9, 2026
7f36d5a
Don't use async method code if we can't find resumption stub
jtschuster Feb 10, 2026
5e4a0cd
Merge branch 'main' of https://github.com/dotnet/runtime into runtime16
jtschuster Feb 12, 2026
5c37396
Fix merge issues
jtschuster Feb 12, 2026
d9af071
Add label for resume stub code in r2rdump
jtschuster Feb 12, 2026
d0ff7c1
Don't emit async thunks - there are some issues to sort out
jtschuster Feb 12, 2026
c1ecd59
SetIsAsyncCall even if method is dispatch cell in ComputeCallRefMap
jtschuster Feb 12, 2026
b7604a8
Remove PInvokeTargetNativeMethod from GetPrimaryMethodDesc
jtschuster Feb 12, 2026
5c9cd91
Fix build error
jtschuster Feb 12, 2026
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
24 changes: 24 additions & 0 deletions eng/pipelines/coreclr/crossgen2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,30 @@ extends:
creator: dotnet-bot
testRunNamePrefixSuffix: TestReadyToRun_$(_BuildConfig)

- template: /eng/pipelines/common/platform-matrix.yml
parameters:
jobTemplate: /eng/pipelines/common/global-build-job.yml
helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml
buildConfig: Release
platforms:
- linux_x64
- windows_x64
jobParameters:
testGroup: innerloop
buildArgs: -s clr+libs+libs.tests
-c $(_BuildConfig)
/p:TestReadyToRun=true
/p:TestRuntimeAsync=true
/p:UseRuntimeAsync=true
/p:ArchiveTests=true
nameSuffix: TestReadyToRun_RuntimeAsync_Libraries
timeoutInMinutes: 360
postBuildSteps:
- template: /eng/pipelines/libraries/helix.yml
parameters:
creator: dotnet-bot
testRunNamePrefixSuffix: TestReadyToRun_RuntimeAsync_$(_BuildConfig)

# Run pri0 tests with hot/cold splitting enabled (only supported on x64 at the moment)
# TODO: test on arm64 once supported
- template: /eng/pipelines/common/platform-matrix.yml
Expand Down
7 changes: 6 additions & 1 deletion eng/testing/tests.targets
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<!-- Enable runtime async for all .NET 11+ test projects. -->
<PropertyGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net11.0'))
and '$(TestNativeAot)' != 'true'
and '$(TestReadyToRun)' != 'true'
and '$(UseNativeAOTRuntime)' != 'true'
and '$(TargetOS)' != 'browser'
and '$(TargetOS)' != 'wasi'
Expand All @@ -12,6 +11,12 @@
<EnablePreviewFeatures>true</EnablePreviewFeatures>
<Features>$(Features);runtime-async=on</Features>
</PropertyGroup>

<!-- Allow explicitly enabling runtime async for test projects via TestRuntimeAsync. -->
<PropertyGroup Condition="'$(TestRuntimeAsync)' == 'true'">
<EnablePreviewFeatures>true</EnablePreviewFeatures>
<Features>$(Features);runtime-async=on</Features>
</PropertyGroup>
<PropertyGroup>
<RunScriptWindowsCmd Condition="'$(OS)' == 'Windows_NT' and '$(RunScriptWindowsCmd)' == ''">true</RunScriptWindowsCmd>
<RunScriptWindowsCmd Condition="'$(OS)' != 'Windows_NT' and '$(RunScriptWindowsCmd)' == ''">false</RunScriptWindowsCmd>
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/inc/corcompile.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ enum EncodeMethodSigFlags
ENCODE_METHOD_SIG_OwnerType = 0x40,
ENCODE_METHOD_SIG_UpdateContext = 0x80,
ENCODE_METHOD_SIG_AsyncVariant = 0x100,
ENCODE_METHOD_SIG_ResumptionStub = 0x200,
};

enum EncodeFieldSigFlags
Expand Down
7 changes: 4 additions & 3 deletions src/coreclr/inc/readytorun.h
Original file line number Diff line number Diff line change
Expand Up @@ -468,9 +468,10 @@ enum ReadyToRunHelper

READYTORUN_HELPER_GetCurrentManagedThreadId = 0x112,

READYTORUN_HELPER_AllocContinuation = 0x113,
READYTORUN_HELPER_AllocContinuationClass = 0x114,
READYTORUN_HELPER_AllocContinuationMethod = 0x115,
// Async continuation helpers
READYTORUN_HELPER_AllocContinuation = 0x113,
READYTORUN_HELPER_AllocContinuationClass = 0x114,
READYTORUN_HELPER_AllocContinuationMethod = 0x115,
};

#include "readytoruninstructionset.h"
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/inc/readytorunhelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ HELPER(READYTORUN_HELPER_RngChkFail, CORINFO_HELP_RNGCHKFAIL,
HELPER(READYTORUN_HELPER_FailFast, CORINFO_HELP_FAIL_FAST, OPTIMIZEFORSIZE)
HELPER(READYTORUN_HELPER_ThrowNullRef, CORINFO_HELP_THROWNULLREF, OPTIMIZEFORSIZE)
HELPER(READYTORUN_HELPER_ThrowDivZero, CORINFO_HELP_THROWDIVZERO, OPTIMIZEFORSIZE)
HELPER(READYTORUN_HELPER_ThrowExact, CORINFO_HELP_THROWEXACT, OPTIMIZEFORSIZE)

HELPER(READYTORUN_HELPER_WriteBarrier, CORINFO_HELP_ASSIGN_REF, )
HELPER(READYTORUN_HELPER_CheckedWriteBarrier, CORINFO_HELP_CHECKED_ASSIGN_REF, )
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/tools/Common/Compiler/AsyncMethodVariant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public static bool IsAsyncVariant(this MethodDesc method)

public static bool IsAsyncThunk(this MethodDesc method)
{
return method.IsAsyncVariant() ^ method.IsAsync;
return (method.IsAsyncVariant() ^ method.IsAsync) || method is AsyncResumptionStub;
}

public static MethodDesc GetAsyncVariant(this MethodDesc method)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ protected override bool CompareValueToValue(AsyncMethodVariant value1, AsyncMeth
public MetadataType GetContinuationType(GCPointerMap pointerMap)
{
var cont = _continuationTypeHashtable.GetOrCreateValue(pointerMap);
_validTypes.TryAdd(cont);
return cont;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public enum ReadyToRunMethodSigFlags : uint
READYTORUN_METHOD_SIG_OwnerType = 0x40,
READYTORUN_METHOD_SIG_UpdateContext = 0x80,
READYTORUN_METHOD_SIG_AsyncVariant = 0x100,
READYTORUN_METHOD_SIG_ResumptionStub = 0x200,
}

[Flags]
Expand Down
13 changes: 10 additions & 3 deletions src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
using ILCompiler.DependencyAnalysis;

#if READYTORUN
using ILCompiler.ReadyToRun.TypeSystem;
using System.Reflection.Metadata.Ecma335;
using ILCompiler.DependencyAnalysis.ReadyToRun;
#endif
Expand Down Expand Up @@ -118,7 +119,7 @@ public LikelyClassMethodRecord(IntPtr handle, uint likelihood)
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 Down Expand Up @@ -1382,8 +1383,10 @@ private bool resolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO* info)
// a safe condition, and we could delete this assert. This assert exists in order to help identify
// cases where the virtual function resolution algorithm either does not function, or is not used
// correctly.
// TODO: Async variant devirtualization algorithm
#if DEBUG
if (info->detail == CORINFO_DEVIRTUALIZATION_DETAIL.CORINFO_DEVIRTUALIZATION_UNKNOWN)
if (info->detail == CORINFO_DEVIRTUALIZATION_DETAIL.CORINFO_DEVIRTUALIZATION_UNKNOWN
&& !decl.IsAsyncVariant())
{
Console.Error.WriteLine($"Failed devirtualization with unexpected unknown failure while compiling {MethodBeingCompiled} with decl {decl} targeting type {objType}");
Debug.Assert(info->detail != CORINFO_DEVIRTUALIZATION_DETAIL.CORINFO_DEVIRTUALIZATION_UNKNOWN);
Expand Down Expand Up @@ -3803,7 +3806,11 @@ private bool getTailCallHelpers(ref CORINFO_RESOLVED_TOKEN callToken, CORINFO_SI
#pragma warning restore CA1822 // Mark members as static
{
#if READYTORUN
throw new NotImplementedException("Crossgen2 does not support runtime-async yet");
var resumptionStub = new AsyncResumptionStub(MethodBeingCompiled, MethodBeingCompiled.OwningType);

// CompiledMethodNode instead of MethodEntrypoint for the pointer to the code instead of a fixup
entryPoint = (void*)ObjectToHandle(_compilation.NodeFactory.CompiledMethodNode(resumptionStub));
return ObjectToHandle(resumptionStub);
#else
_asyncResumptionStub ??= new AsyncResumptionStub(MethodBeingCompiled, _compilation.TypeSystemContext.GeneratedAssembly.GetGlobalModuleType());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ public InstantiatedMethodIL(MethodDesc owningMethod, MethodIL methodIL)
{
Debug.Assert(methodIL.GetMethodILDefinition() == methodIL);
Debug.Assert(owningMethod.HasInstantiation || owningMethod.OwningType.HasInstantiation);
Debug.Assert(owningMethod.GetTypicalMethodDefinition() == methodIL.OwningMethod);

_methodIL = methodIL;
_method = owningMethod;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;

using Internal.IL;
using Internal.IL.Stubs;
using Internal.TypeSystem;
Expand All @@ -26,7 +25,7 @@ public AsyncResumptionStub(MethodDesc targetMethod, TypeDesc owningType)
}

public override ReadOnlySpan<byte> Name => _targetMethod.Name;
public override string DiagnosticName => _targetMethod.DiagnosticName;
public override string DiagnosticName => "RESUME_" + _targetMethod.DiagnosticName;

public override TypeDesc OwningType => _owningType;

Expand All @@ -36,6 +35,12 @@ public AsyncResumptionStub(MethodDesc targetMethod, TypeDesc owningType)

public MethodDesc TargetMethod => _targetMethod;

/// <summary>
/// The hash of the async variant method is used at runtime to find the bucket of the resumption stub.
/// These should be identical for the async variant and the resumption stub.
/// </summary>
protected override int ComputeHashCode() => _targetMethod.GetHashCode();

private MethodSignature InitializeSignature()
{
TypeDesc objectType = Context.GetWellKnownType(WellKnownType.Object);
Expand Down Expand Up @@ -109,6 +114,7 @@ public override MethodIL EmitIL()
}
ilStream.EmitLdLoc(newContinuationLocal);
ilStream.Emit(ILOpcode.ret);
ilEmitter.SetHasGeneratedTokens();

return ilEmitter.Link(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ internal void LayoutMethodsWithEHInfo()

foreach (MethodWithGCInfo method in _nodeFactory.EnumerateCompiledMethods())
{
if (method.Method is AsyncResumptionStub)
{
continue;
}
ObjectData ehInfo = method.EHInfo;
if (ehInfo != null && ehInfo.Data.Length != 0)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using System.Diagnostics;
using System.IO;
using System.Reflection.Metadata.Ecma335;

using ILCompiler.ReadyToRun.TypeSystem;
using Internal;
using Internal.NativeFormat;
using Internal.ReadyToRunConstants;
Expand Down Expand Up @@ -67,8 +67,17 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)
foreach (MethodWithGCInfo methodNode in factory.EnumerateCompiledMethods(_module, CompiledMethodCategory.All))
{
MethodDesc[] inlinees = methodNode.InlinedMethods;
if (inlinees.Length == 0)
{
continue;
}
MethodDesc inliner = methodNode.Method;
EcmaMethod inlinerDefinition = (EcmaMethod)inliner.GetTypicalMethodDefinition();
if (inliner.IsAsyncThunk())
{
// Async thunks are generated by crossgen and diagnostic tools don't need to worry about them
continue;
}
EcmaMethod inlinerDefinition = (EcmaMethod)inliner.GetPrimaryMethodDesc().GetTypicalMethodDefinition();

if (inlinerDefinition.IsNonVersionable())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using System.IO;
using System.Linq;
using System.Reflection.Metadata.Ecma335;

using ILCompiler.ReadyToRun.TypeSystem;
using Internal;
using Internal.JitInterface;
using Internal.NativeFormat;
Expand Down Expand Up @@ -53,17 +53,17 @@ public override void AppendMangledName(NameMangler nameMangler, Utf8StringBuilde

public static byte[] BuildSignatureForMethodDefinedInModule(MethodDesc method, NodeFactory factory)
{
EcmaMethod typicalMethod = (EcmaMethod)method.GetTypicalMethodDefinition();
EcmaMethod ecmaMethod = (EcmaMethod)method.GetPrimaryMethodDesc().GetTypicalMethodDefinition();

ModuleToken moduleToken;
if (factory.CompilationModuleGroup.VersionsWithMethodBody(typicalMethod))
if (factory.CompilationModuleGroup.VersionsWithMethodBody(ecmaMethod))
{
moduleToken = new ModuleToken(typicalMethod.Module, typicalMethod.Handle);
moduleToken = new ModuleToken(ecmaMethod.Module, ecmaMethod.Handle);
}
else
{
MutableModule manifestMetadata = factory.ManifestMetadataTable._mutableModule;
var handle = manifestMetadata.TryGetExistingEntityHandle(method.GetTypicalMethodDefinition());
var handle = manifestMetadata.TryGetExistingEntityHandle(ecmaMethod);
Debug.Assert(handle.HasValue);
moduleToken = new ModuleToken(factory.ManifestMetadataTable._mutableModule, handle.Value);
}
Expand Down Expand Up @@ -102,7 +102,7 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)

foreach (MethodWithGCInfo method in factory.EnumerateCompiledMethods(null, CompiledMethodCategory.Instantiated))
{
Debug.Assert(method.Method.HasInstantiation || method.Method.OwningType.HasInstantiation);
Debug.Assert(method.Method.HasInstantiation || method.Method.OwningType.HasInstantiation || method.Method.IsAsyncVariant() || method.Method is AsyncResumptionStub);

int methodIndex = factory.RuntimeFunctionsTable.GetIndex(method);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)

MethodWithToken method = _method;

if (factory.CompilationModuleGroup.VersionsWithMethodBody(method.Method) && !method.Method.IsAsyncVariant())
if (factory.CompilationModuleGroup.VersionsWithMethodBody(method.Method) && !method.Method.IsAsyncVariant() && method.Method is not AsyncResumptionStub)
{
if (method.Token.TokenType == CorTokenType.mdtMethodSpec)
{
Expand All @@ -130,6 +130,7 @@ public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false)

SignatureContext innerContext = dataBuilder.EmitFixup(factory, fixupKind, method.Token.Module, factory.SignatureContext);

// We should emit AsyncVariants and ResumptionStubs differently even if the ModuleToken is a Def or Ref
if (optimized && method.Token.TokenType == CorTokenType.mdtMethodDef)
{
dataBuilder.EmitMethodDefToken(method.Token);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Internal.TypeSystem.Ecma;
using Internal.CorConstants;
using System.Diagnostics;
using ILCompiler.ReadyToRun.TypeSystem;

namespace ILCompiler.DependencyAnalysis.ReadyToRun
{
Expand Down Expand Up @@ -61,7 +62,6 @@ public ModuleToken GetModuleTokenForType(TypeDesc type, bool allowDynamicallyCre
{
return new ModuleToken(ecmaType.Module, (mdToken)MetadataTokens.GetToken(ecmaType.Handle));
}

if (_typeToRefTokens.TryGetValue(ecmaType, out token))
{
return token;
Expand Down Expand Up @@ -100,7 +100,7 @@ public ModuleToken GetModuleTokenForMethod(MethodDesc method, bool allowDynamica
{
method = method.GetCanonMethodTarget(CanonicalFormKind.Specific);

if (method.GetTypicalMethodDefinition() is EcmaMethod ecmaMethod)
if (method.GetPrimaryMethodDesc().GetTypicalMethodDefinition() is EcmaMethod ecmaMethod)
{
if (_compilationModuleGroup.VersionsWithMethodBody(ecmaMethod))
{
Expand Down Expand Up @@ -129,6 +129,31 @@ public ModuleToken GetModuleTokenForMethod(MethodDesc method, bool allowDynamica
}
}

public void AddModuleTokenForMethod(MethodDesc method, ModuleToken token)
{
if (token.TokenType == CorTokenType.mdtMethodSpec)
{
MethodSpecification methodSpec = token.MetadataReader.GetMethodSpecification((MethodSpecificationHandle)token.Handle);
DecodeMethodSpecificationSignatureToDiscoverUsedTypeTokens(methodSpec.Signature, token);
token = new ModuleToken(token.Module, methodSpec.Method);
}

if (token.TokenType == CorTokenType.mdtMemberRef)
{
MemberReference memberRef = token.MetadataReader.GetMemberReference((MemberReferenceHandle)token.Handle);
EntityHandle owningTypeHandle = memberRef.Parent;
TypeDesc owningType = (TypeDesc)token.Module.GetObject(owningTypeHandle, NotFoundBehavior.Throw);
AddModuleTokenForType(owningType, new ModuleToken(token.Module, owningTypeHandle));
DecodeMethodSignatureToDiscoverUsedTypeTokens(memberRef.Signature, token);
}
if (token.TokenType == CorTokenType.mdtMethodDef)
{
MethodDefinition methodDef = token.MetadataReader.GetMethodDefinition((MethodDefinitionHandle)token.Handle);
TokenResolverProvider rentedProvider = TokenResolverProvider.Rent(this, token.Module);
DecodeMethodSignatureToDiscoverUsedTypeTokens(methodDef.Signature, token);
}
}

public ModuleToken GetModuleTokenForField(FieldDesc field, bool allowDynamicallyCreatedReference, bool throwIfNotFound)
{
if (field.GetTypicalFieldDefinition() is EcmaField ecmaField)
Expand Down Expand Up @@ -160,32 +185,6 @@ public ModuleToken GetModuleTokenForField(FieldDesc field, bool allowDynamically
}
}


public void AddModuleTokenForMethod(MethodDesc method, ModuleToken token)
{
if (token.TokenType == CorTokenType.mdtMethodSpec)
{
MethodSpecification methodSpec = token.MetadataReader.GetMethodSpecification((MethodSpecificationHandle)token.Handle);
DecodeMethodSpecificationSignatureToDiscoverUsedTypeTokens(methodSpec.Signature, token);
token = new ModuleToken(token.Module, methodSpec.Method);
}

if (token.TokenType == CorTokenType.mdtMemberRef)
{
MemberReference memberRef = token.MetadataReader.GetMemberReference((MemberReferenceHandle)token.Handle);
EntityHandle owningTypeHandle = memberRef.Parent;
TypeDesc owningType = (TypeDesc)token.Module.GetObject(owningTypeHandle, NotFoundBehavior.Throw);
AddModuleTokenForType(owningType, new ModuleToken(token.Module, owningTypeHandle));
DecodeMethodSignatureToDiscoverUsedTypeTokens(memberRef.Signature, token);
}
if (token.TokenType == CorTokenType.mdtMethodDef)
{
MethodDefinition methodDef = token.MetadataReader.GetMethodDefinition((MethodDefinitionHandle)token.Handle);
TokenResolverProvider rentedProvider = TokenResolverProvider.Rent(this, token.Module);
DecodeMethodSignatureToDiscoverUsedTypeTokens(methodDef.Signature, token);
}
}

private void DecodeMethodSpecificationSignatureToDiscoverUsedTypeTokens(BlobHandle signatureHandle, ModuleToken token)
{
MetadataReader metadataReader = token.MetadataReader;
Expand Down Expand Up @@ -332,6 +331,10 @@ public void AddModuleTokenForType(TypeDesc type, ModuleToken token)
SetModuleTokenForTypeSystemEntity(_typeToRefTokens, ecmaType, token);
}
}
else if (type.IsCanonicalDefinitionType(CanonicalFormKind.Specific))
{
return;
}
else if (!specialTypeFound)
{
throw new NotImplementedException(type.ToString());
Expand Down
Loading
Loading