| File: Internal\Runtime\TypeLoader\TypeBuilderState.cs | Web Access |
| Project: System.Private.TypeLoader.csproj (System.Private.TypeLoader) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Diagnostics; using Internal.NativeFormat; using Internal.TypeSystem; namespace Internal.Runtime.TypeLoader { internal struct NativeLayoutInfo { public uint Offset; public NativeFormatModuleInfo Module; public NativeReader Reader; public NativeLayoutInfoLoadContext LoadContext; } // // TypeBuilder per-Type state. It is attached to each TypeDesc that gets involved in type building. // internal class TypeBuilderState { public TypeBuilderState(TypeDesc typeBeingBuilt) { TypeBeingBuilt = typeBeingBuilt; } public readonly TypeDesc TypeBeingBuilt; // // We cache and try to reuse the most recently used TypeSystemContext. The TypeSystemContext is used by not just type builder itself, // but also in several random other places in reflection. There can be multiple ResolutionContexts in flight at any given moment. // This check ensures that the RuntimeTypeHandle cache in the current resolution context is refreshed in case there were new // types built using a different TypeSystemContext in the meantime. // NOTE: For correctness, this value must be recomputed every time the context is recycled. This requires flushing the TypeBuilderState // from each type that has one if context is recycled. // public bool AttemptedAndFailedToRetrieveTypeHandle; public bool NeedsTypeHandle; public bool HasBeenPrepared; public RuntimeTypeHandle HalfBakedRuntimeTypeHandle; public IntPtr HalfBakedDictionary; private bool _templateComputed; private TypeDesc _templateType; public TypeDesc TemplateType { get { if (!_templateComputed) { // Multidimensional arrays don't implement generic interfaces and are special cases. They use // typeof(object[,]) as their template. if (TypeBeingBuilt.IsMdArray) { _templateType = TypeBeingBuilt.Context.ResolveRuntimeTypeHandle(typeof(object[,]).TypeHandle); } else if (TypeBeingBuilt.IsSzArray && ((ArrayType)TypeBeingBuilt).ElementType is TypeDesc elementType && (elementType.IsPointer || elementType.IsFunctionPointer)) { // Pointer arrays don't implement generic interfaces. _templateType = TypeBeingBuilt.Context.ResolveRuntimeTypeHandle(typeof(char*[]).TypeHandle); } else { _templateType = TemplateLocator.TryGetTypeTemplate(TypeBeingBuilt, ref _nativeLayoutInfo); Debug.Assert(_templateType is null || !_templateType.RuntimeTypeHandle.IsNull()); } _templateComputed = true; } return _templateType; } } private bool _nativeLayoutComputed; private NativeLayoutInfo _nativeLayoutInfo; private void EnsureNativeLayoutInfoComputed() { if (!_nativeLayoutComputed) { _ = TemplateType; if (_nativeLayoutInfo.Module is not null) { FinishInitNativeLayoutInfo(TypeBeingBuilt, ref _nativeLayoutInfo); } _nativeLayoutComputed = true; } } /// <summary> /// Initialize the Reader and LoadContext fields of the native layout info /// </summary> /// <param name="type"></param> /// <param name="nativeLayoutInfo"></param> private static void FinishInitNativeLayoutInfo(TypeDesc type, ref NativeLayoutInfo nativeLayoutInfo) { var nativeLayoutInfoLoadContext = new NativeLayoutInfoLoadContext(); nativeLayoutInfoLoadContext._typeSystemContext = type.Context; nativeLayoutInfoLoadContext._module = nativeLayoutInfo.Module; if (type is DefType) { nativeLayoutInfoLoadContext._typeArgumentHandles = ((DefType)type).Instantiation; } else if (type is ArrayType) { nativeLayoutInfoLoadContext._typeArgumentHandles = new Instantiation(new TypeDesc[] { ((ArrayType)type).ElementType }); } else { Debug.Assert(false); } nativeLayoutInfoLoadContext._methodArgumentHandles = new Instantiation(null); nativeLayoutInfo.Reader = TypeLoaderEnvironment.GetNativeLayoutInfoReader(nativeLayoutInfo.Module.Handle); nativeLayoutInfo.LoadContext = nativeLayoutInfoLoadContext; } public NativeLayoutInfo NativeLayoutInfo { get { EnsureNativeLayoutInfoComputed(); return _nativeLayoutInfo; } } public NativeParser GetParserForNativeLayoutInfo() { EnsureNativeLayoutInfoComputed(); if (_nativeLayoutInfo.Reader is not null) return new NativeParser(_nativeLayoutInfo.Reader, _nativeLayoutInfo.Offset); else return default(NativeParser); } public GenericTypeDictionary Dictionary; public int NonGcDataSize; public bool HasStaticConstructor => ClassConstructorPointer.HasValue; public IntPtr? ClassConstructorPointer; public IntPtr GcStaticDesc; public IntPtr ThreadStaticDesc; public uint ThreadStaticOffset; } }