| File: Compiler\DependencyAnalysis\ReflectedFieldNode.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 System.Collections.Generic; using ILCompiler.DependencyAnalysisFramework; using Internal.TypeSystem; using Debug = System.Diagnostics.Debug; namespace ILCompiler.DependencyAnalysis { /// <summary> /// Represents a field that is gettable/settable from reflection. /// The field can be on a non-generic type, generic type definition, or an instantiatied type. /// To match IL semantics, we maintain that a field on a generic type will be consistently /// reflection-accessible. Either the field is accessible on all instantiations or on none of them. /// </summary> public class ReflectedFieldNode : DependencyNodeCore<NodeFactory> { private readonly FieldDesc _field; public ReflectedFieldNode(FieldDesc field) { Debug.Assert(!field.OwningType.IsCanonicalSubtype(CanonicalFormKind.Any) || field.OwningType.ConvertToCanonForm(CanonicalFormKind.Specific) == field.OwningType); _field = field; } public FieldDesc Field => _field; public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFactory factory) { Debug.Assert(!factory.MetadataManager.IsReflectionBlocked(_field.GetTypicalFieldDefinition())); DependencyList dependencies = new DependencyList(); factory.MetadataManager.GetDependenciesDueToReflectability(ref dependencies, factory, _field); // No runtime artifacts needed if this is a generic definition or literal field if (_field.OwningType.IsGenericDefinition || _field.IsLiteral) { return dependencies; } // readonly static fields are not reflection settable, the rest are if (!_field.IsInitOnly || !_field.IsStatic) dependencies.Add(factory.NotReadOnlyField(_field), "Reflection writable field"); FieldDesc typicalField = _field.GetTypicalFieldDefinition(); if (typicalField != _field) { // Ensure we consistently apply reflectability to all fields sharing the same definition. // Bases for different instantiations of the field have a conditional dependency on the definition node that // brings a ReflectableField of the instantiated field if it's necessary for it to be reflectable. dependencies.Add(factory.ReflectedField(typicalField), "Definition of the reflectable field"); } // Runtime reflection stack needs to see the type handle of the owning type dependencies.Add(factory.MaximallyConstructableType(_field.OwningType), "Instance base of a reflectable field"); // Root the static base of the type if (_field.IsStatic && !_field.OwningType.IsCanonicalSubtype(CanonicalFormKind.Any)) { // Infrastructure around static constructors is stashed in the NonGC static base bool needsNonGcStaticBase = factory.PreinitializationManager.HasLazyStaticConstructor(Field.OwningType); if (_field.HasRva) { // No reflection access right now } else if (_field.IsThreadStatic) { dependencies.Add(factory.TypeThreadStaticIndex(_field.OwningType), "Threadstatic base of a reflectable field"); } else if (_field.HasGCStaticBase) { dependencies.Add(factory.TypeGCStaticsSymbol(_field.OwningType), "GC static base of a reflectable field"); } else { dependencies.Add(factory.TypeNonGCStaticsSymbol(_field.OwningType), "NonGC static base of a reflectable field"); needsNonGcStaticBase = false; } if (needsNonGcStaticBase) { dependencies.Add(factory.TypeNonGCStaticsSymbol(_field.OwningType), "CCtor context"); } // For generic types, the reflection mapping table only keeps track of information about offsets // from the static bases. To locate the static base, we need the GenericStaticBaseInfo hashtable. if (_field.OwningType.HasInstantiation) { dependencies.Add(factory.GenericStaticBaseInfo(_field.OwningType), "Field on a generic type"); } } TypeDesc fieldType = _field.FieldType.NormalizeInstantiation(); ReflectionInvokeMapNode.AddSignatureDependency(ref dependencies, factory, _field, fieldType, "Type of the field", isOut: true); return dependencies; } protected override string GetName(NodeFactory factory) { return "Reflectable field: " + _field.ToString(); } public override bool InterestingForDynamicDependencyAnalysis => false; public override bool HasDynamicDependencies => false; public override bool HasConditionalStaticDependencies => false; public override bool StaticDependenciesAreComputed => true; public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory factory) => null; public override IEnumerable<CombinedDependencyListEntry> SearchDynamicDependencies(List<DependencyNodeCore<NodeFactory>> markedNodes, int firstNode, NodeFactory factory) => null; } }