Пример #1
0
        private void RootMethod(IRootingServiceProvider rootProvider, MethodDesc method)
        {
            try
            {
                LibraryRootProvider.CheckCanGenerateMethod(method);

                // Virtual methods should be rooted as if they were called virtually
                if (method.IsVirtual)
                {
                    MethodDesc slotMethod = MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(method);
                    rootProvider.RootVirtualMethodForReflection(slotMethod, "RD.XML root");
                }

                if (!method.IsAbstract)
                {
                    rootProvider.AddCompilationRoot(method, "RD.XML root");
                }
            }
            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.
                return;

                // TODO: Log as a warning
            }
        }
        void ICompilationRootProvider.AddCompilationRoots(IRootingServiceProvider rootProvider)
        {
            MetadataLoadedInfo loadedMetadata = _loadedMetadata.Value;

            // Add all non-generic reflectable methods as roots.
            // Virtual methods need special handling (e.g. with dependency tracking) since they can be abstract.
            foreach (var method in loadedMetadata.MethodMappings.Keys)
            {
                if (method.HasInstantiation || method.OwningType.HasInstantiation)
                {
                    continue;
                }

                if (method.IsVirtual)
                {
                    rootProvider.RootVirtualMethodForReflection(method, "Reflection root");
                }
                else
                {
                    rootProvider.AddCompilationRoot(method, "Reflection root");
                }
            }

            // Root all the generic type instantiations from the pre-computed metadata
            foreach (var type in loadedMetadata.RequiredGenericTypes)
            {
                rootProvider.AddCompilationRoot(type, "Required instantiation");
            }

            // Root all the generic methods (either non-generic methods on generic types, or generic methods) from
            // the pre-computed metadata.
            // Virtual methods need special handling (e.g. with dependency tracking) since they can be abstract.
            foreach (var method in loadedMetadata.RequiredGenericMethods)
            {
                if (method.IsVirtual)
                {
                    rootProvider.RootVirtualMethodForReflection(method, "Required instantiation");
                }
                else
                {
                    rootProvider.AddCompilationRoot(method, "Required instantiation");
                }
            }

            // TODO: required generic fields. Root containing type, and add field to list in ComputeMetadata()
        }
Пример #3
0
        private void RootType(IRootingServiceProvider rootProvider, TypeDesc type)
        {
            rootProvider.AddCompilationRoot(type, "RD.XML root");

            if (type.IsGenericDefinition)
            {
                return;
            }

            if (type.IsDefType)
            {
                foreach (var method in type.GetMethods())
                {
                    // We don't know what to instantiate generic methods over
                    if (method.HasInstantiation)
                    {
                        continue;
                    }

                    try
                    {
                        LibraryRootProvider.CheckCanGenerateMethod(method);

                        // Virtual methods should be rooted as if they were called virtually
                        if (method.IsVirtual)
                        {
                            MethodDesc slotMethod = MetadataVirtualMethodAlgorithm.FindSlotDefiningMethodForVirtualMethod(method);
                            rootProvider.RootVirtualMethodForReflection(slotMethod, "RD.XML root");
                        }

                        if (!method.IsAbstract)
                        {
                            rootProvider.AddCompilationRoot(method, "RD.XML root");
                        }
                    }
                    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
                    }
                }
            }
        }
Пример #4
0
        public static void RootMethod(IRootingServiceProvider rootProvider, MethodDesc method, string reason)
        {
            // Make sure we're not putting something into the graph that will crash later.
            LibraryRootProvider.CheckCanGenerateMethod(method);

            // Virtual methods should be rooted as if they were called virtually
            if (method.IsVirtual)
            {
                rootProvider.RootVirtualMethodForReflection(method, reason);
            }

            if (!method.IsAbstract)
            {
                rootProvider.AddCompilationRoot(method, reason);
            }
        }
Пример #5
0
        void ICompilationRootProvider.AddCompilationRoots(IRootingServiceProvider rootProvider)
        {
            // We go over all the types and members that need a runtime artifact present in the
            // compiled executable and root it.

            const string reason = "Reflection";

            foreach (var pair in _reflectableTypes)
            {
                if ((pair.Value & MetadataCategory.RuntimeMapping) != 0)
                {
                    rootProvider.AddCompilationRoot(pair.Key, reason);
                }
            }

            foreach (var pair in _reflectableMethods)
            {
                if ((pair.Value & MetadataCategory.RuntimeMapping) != 0)
                {
                    MethodDesc method = pair.Key;

                    // We need to root virtual methods as if they were called virtually.
                    // This will possibly trigger the generation of other overrides too.
                    if (method.IsVirtual)
                    {
                        rootProvider.RootVirtualMethodForReflection(method, reason);
                    }

                    if (!method.IsAbstract)
                    {
                        rootProvider.AddCompilationRoot(pair.Key, reason);
                    }
                }
            }

            foreach (var pair in _reflectableFields)
            {
                if ((pair.Value & MetadataCategory.RuntimeMapping) != 0)
                {
                    FieldDesc field = pair.Key;

                    // We only care about static fields at this point. Instance fields don't need
                    // runtime artifacts generated in the image.
                    if (field.IsStatic && !field.IsLiteral)
                    {
                        if (field.IsThreadStatic)
                        {
                            rootProvider.RootThreadStaticBaseForType(field.OwningType, reason);
                        }
                        else if (field.HasGCStaticBase)
                        {
                            rootProvider.RootGCStaticBaseForType(field.OwningType, reason);
                        }
                        else
                        {
                            rootProvider.RootNonGCStaticBaseForType(field.OwningType, reason);
                        }
                    }
                }
            }
        }
        void ICompilationRootProvider.AddCompilationRoots(IRootingServiceProvider rootProvider)
        {
            MetadataLoadedInfo loadedMetadata = _loadedMetadata.Value;

            // Add all non-generic reflectable types as roots.
            foreach (var type in loadedMetadata.TypesWithStrongMetadataMappings)
            {
                rootProvider.AddCompilationRoot(type, "Required non-generic type");
            }

            // Add all non-generic reflectable methods as roots.
            // Virtual methods need special handling (e.g. with dependency tracking) since they can be abstract.
            foreach (var method in loadedMetadata.MethodMappings.Keys)
            {
                if (method.HasInstantiation || method.OwningType.HasInstantiation)
                {
                    continue;
                }

                if (!IsMethodSupportedInPrecomputedReflection(method))
                {
                    continue;
                }

                if (method.IsVirtual)
                {
                    rootProvider.RootVirtualMethodForReflection(method, "Reflection root");
                }
                else
                {
                    if (method.IsConstructor)
                    {
                        rootProvider.AddCompilationRoot(method.OwningType, "Type for method reflection root");
                    }

                    rootProvider.AddCompilationRoot(method, "Reflection root");
                }
            }

            // Root all the generic type instantiations from the pre-computed metadata
            foreach (var type in loadedMetadata.RequiredGenericTypes)
            {
                rootProvider.AddCompilationRoot(type, "Required generic type");
            }

            // Root all the generic methods (either non-generic methods on generic types, or generic methods) from
            // the pre-computed metadata.
            // Virtual methods need special handling (e.g. with dependency tracking) since they can be abstract.
            foreach (var method in loadedMetadata.RequiredGenericMethods)
            {
                if (!IsMethodSupportedInPrecomputedReflection(method))
                {
                    continue;
                }

                if (method.IsVirtual)
                {
                    rootProvider.RootVirtualMethodForReflection(method, "Required generic method");
                }

                if (!method.IsAbstract)
                {
                    if (method.IsConstructor)
                    {
                        rootProvider.AddCompilationRoot(method.OwningType, "Type for method required generic method");
                    }

                    rootProvider.AddCompilationRoot(method, "Required generic method");
                }
            }

            foreach (var field in loadedMetadata.RequiredGenericFields)
            {
                rootProvider.AddCompilationRoot(field.OwningType, "Required generic field's owning type");
                if (field.IsThreadStatic)
                {
                    rootProvider.RootThreadStaticBaseForType(field.OwningType, "Required generic field");
                }
                else if (field.IsStatic)
                {
                    if (field.HasGCStaticBase)
                    {
                        rootProvider.RootGCStaticBaseForType(field.OwningType, "Required generic field");
                    }
                    else
                    {
                        rootProvider.RootNonGCStaticBaseForType(field.OwningType, "Required generic field");
                    }
                }
            }

            foreach (var type in loadedMetadata.RequiredTemplateTypes)
            {
                Debug.Assert(type.IsCanonicalSubtype(CanonicalFormKind.Any));
                rootProvider.AddCompilationRoot(type, "Compiler determined template");
            }

            foreach (var method in loadedMetadata.RequiredTemplateMethods)
            {
                Debug.Assert(method.IsCanonicalMethod(CanonicalFormKind.Any));
                if (method.IsVirtual)
                {
                    rootProvider.RootVirtualMethodForReflection(method, "Compiler determined template");
                }

                if (!method.IsAbstract)
                {
                    if (method.IsConstructor)
                    {
                        rootProvider.AddCompilationRoot(method.OwningType, "Type for method compiler determined template method");
                    }

                    rootProvider.AddCompilationRoot(method, "Compiler determined template");
                }
            }
        }