Repository: dotnet/runtime
File: src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs (C#)

Code before:
                {
                    EnsureTypeDefTokensAreReady(type.GetTypeDefinition());

                    foreach (TypeDesc instParam in type.Instantiation)
                    {
                        EnsureTypeDefTokensAreReady(instParam);
                    }
                }
                else if (type.IsParameterizedType)
                {
                    EnsureTypeDefTokensAreReady(type.GetParameterType());
                }
            }
        }

        private void AddNecessaryAsyncReferences(MethodDesc method)
        {
            if (_hasAddedAsyncReferences)
                return;

            // Keep in sync with CorInfoImpl.getAsyncInfo()
            DefType continuation = TypeSystemContext.ContinuationType;
            var runtimeHelpers = TypeSystemContext.SystemModule.GetKnownType("System.Runtime.CompilerServices"u8, "RuntimeHelpers"u8);
            var asyncHelpers = TypeSystemContext.SystemModule.GetKnownType("System.Runtime.CompilerServices"u8, "AsyncHelpers"u8);
            // AsyncHelpers should already be referenced in the module for the call to Await()
            Debug.Assert(!_nodeFactory.Resolver.GetModuleTokenForType(asyncHelpers, allowDynamicallyCreatedReference: true, throwIfNotFound: true).IsNull);
            TypeDesc[] requiredTypes = [continuation];
            FieldDesc[] requiredFields =
            [
                // For CorInfoImpl.getAsyncInfo
                continuation.GetKnownField("Next"u8),
                continuation.GetKnownField("ResumeInfo"u8),
                continuation.GetKnownField("State"u8),
                continuation.GetKnownField("Flags"u8),
            ];
            MethodDesc[] requiredMethods =
            [
                // For CorInfoImpl.getAsyncInfo
                asyncHelpers.GetKnownMethod("CaptureExecutionContext"u8, null),
                asyncHelpers.GetKnownMethod("RestoreExecutionContext"u8, null),
                asyncHelpers.GetKnownMethod("CaptureContinuationContext"u8, null),
                asyncHelpers.GetKnownMethod("CaptureContexts"u8, null),
                asyncHelpers.GetKnownMethod("RestoreContexts"u8, null),
                asyncHelpers.GetKnownMethod("RestoreContextsOnSuspension"u8, null),

                // R2R Helpers
                asyncHelpers.GetKnownMethod("AllocContinuation"u8, null),
                asyncHelpers.GetKnownMethod("AllocContinuationClass"u8, null),
                asyncHelpers.GetKnownMethod("AllocContinuationMethod"u8, null),
            ];
            _nodeFactory.ManifestMetadataTable._mutableModule.ModuleThatIsCurrentlyTheSourceOfNewReferences = ((EcmaMethod)method.GetPrimaryMethodDesc().GetTypicalMethodDefinition()).Module;

Review comment (bug):
This `Debug.Assert` calls `GetModuleTokenForType(..., throwIfNotFound: true)`, which will throw in both Debug and Release if `AsyncHelpers` doesn't already have a resolvable token. Since `IsAsyncCall()` can be true for async-call-convention intrinsics that may not reference `AsyncHelpers.Await`, this makes compilation fragile. Prefer using `throwIfNotFound: false` for the assert (or remove the assert) and rely on the subsequent `TryGetEntityHandle` calls to add the needed references.
```suggestion
            Debug.Assert(!_nodeFactory.Resolver.GetModuleTokenForType(asyncHelpers, allowDynamicallyCreatedReference: true, throwIfNotFound: false).IsNull);
```

Code after:
                {
                    EnsureTypeDefTokensAreReady(type.GetTypeDefinition());

                    foreach (TypeDesc instParam in type.Instantiation)
                    {
                        EnsureTypeDefTokensAreReady(instParam);
                    }
                }
                else if (type.IsParameterizedType)
                {
                    EnsureTypeDefTokensAreReady(type.GetParameterType());
                }
            }
        }

        private void AddNecessaryAsyncReferences(MethodDesc method)
        {
            if (_hasAddedAsyncReferences)
                return;

            // Keep in sync with CorInfoImpl.getAsyncInfo()
            DefType continuation = TypeSystemContext.ContinuationType;
            var asyncHelpers = TypeSystemContext.SystemModule.GetKnownType("System.Runtime.CompilerServices"u8, "AsyncHelpers"u8);
            // AsyncHelpers should already be referenced in the module for the call to Await()
            Debug.Assert(!_nodeFactory.Resolver.GetModuleTokenForType(asyncHelpers, allowDynamicallyCreatedReference: true, throwIfNotFound: false).IsNull);
            TypeDesc[] requiredTypes = [continuation];
            FieldDesc[] requiredFields =
            [
                // For CorInfoImpl.getAsyncInfo
                continuation.GetKnownField("Next"u8),
                continuation.GetKnownField("ResumeInfo"u8),
                continuation.GetKnownField("State"u8),
                continuation.GetKnownField("Flags"u8),
            ];
            MethodDesc[] requiredMethods =
            [
                // For CorInfoImpl.getAsyncInfo
                asyncHelpers.GetKnownMethod("CaptureExecutionContext"u8, null),
                asyncHelpers.GetKnownMethod("RestoreExecutionContext"u8, null),
                asyncHelpers.GetKnownMethod("CaptureContinuationContext"u8, null),
                asyncHelpers.GetKnownMethod("CaptureContexts"u8, null),
                asyncHelpers.GetKnownMethod("RestoreContexts"u8, null),
                asyncHelpers.GetKnownMethod("RestoreContextsOnSuspension"u8, null),

                // R2R Helpers
                asyncHelpers.GetKnownMethod("AllocContinuation"u8, null),
                asyncHelpers.GetKnownMethod("AllocContinuationClass"u8, null),
                asyncHelpers.GetKnownMethod("AllocContinuationMethod"u8, null),
            ];
            _nodeFactory.ManifestMetadataTable._mutableModule.ModuleThatIsCurrentlyTheSourceOfNewReferences = ((EcmaMethod)method.GetPrimaryMethodDesc().GetTypicalMethodDefinition()).Module;
            try