| File: Compiler\LibraryRootProvider.cs | Web Access |
| Project: src\runtime\src\coreclr\tools\aot\ILCompiler.Compiler\ILCompiler.Compiler.csproj (ILCompiler.Compiler) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Internal.TypeSystem.Ecma; using Internal.TypeSystem; namespace ILCompiler { /// <summary> /// Provides compilation group for a library that compiles everything in the input IL module. /// </summary> public class LibraryRootProvider : ICompilationRootProvider { private EcmaModule _module; public LibraryRootProvider(EcmaModule module) { _module = module; } public void AddCompilationRoots(IRootingServiceProvider rootProvider) { foreach (TypeDesc type in _module.GetAllTypes()) { try { rootProvider.AddCompilationRoot(type, "Library module type"); } catch (TypeSystemException) { // TODO: fail compilation if a switch was passed // Swallow type load exceptions while rooting continue; // TODO: Log as a warning } // If this is not a generic definition, root all methods if (!type.HasInstantiation) { RootMethods(type, "Library module method", rootProvider); rootProvider.RootThreadStaticBaseForType(type, "Library module type statics"); rootProvider.RootGCStaticBaseForType(type, "Library module type statics"); rootProvider.RootNonGCStaticBaseForType(type, "Library module type statics"); } } } private static void RootMethods(TypeDesc type, string reason, IRootingServiceProvider rootProvider) { foreach (MethodDesc method in type.GetAllMethodsAndAsyncVariants()) { // Skip methods with no IL and uninstantiated generic methods if (method.IsAbstract || method.HasInstantiation) continue; if (method.IsInternalCall) continue; try { CheckCanGenerateMethod(method); rootProvider.AddCompilationRoot(method, reason); } catch (TypeSystemException) { // TODO: fail compilation if a switch was passed // Individual methods can fail to load types referenced in their signatures. // Skip them in library mode since they're not going to be callable. continue; // TODO: Log as a warning } } } /// <summary> /// Validates that it will be possible to generate '<paramref name="method"/>' based on the types /// in its signature. Unresolvable types in a method's signature prevent RyuJIT from generating /// even a stubbed out throwing implementation. /// </summary> public static void CheckCanGenerateMethod(MethodDesc method) { MethodSignature signature = method.Signature; // Vararg methods are not supported if ((signature.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask) == MethodSignatureFlags.CallingConventionVarargs) ThrowHelper.ThrowInvalidProgramException(); CheckTypeCanBeUsedInSignature(signature.ReturnType); for (int i = 0; i < signature.Length; i++) { CheckTypeCanBeUsedInSignature(signature[i]); } } private static void CheckTypeCanBeUsedInSignature(TypeDesc type) { ((CompilerTypeSystemContext)type.Context).EnsureLoadableType(type); } } }