| File: Internal\Runtime\TypeLoader\TypeLoaderTypeSystemContext.cs | Web Access |
| Project: src\runtime\src\coreclr\nativeaot\System.Private.TypeLoader\src\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.TypeSystem; namespace Internal.Runtime.TypeLoader { /// <summary> /// TypeSystemContext that can interfact with the /// NativeAOT runtime type system and native metadata /// </summary> public partial class TypeLoaderTypeSystemContext : TypeSystemContext { private static readonly NoMetadataRuntimeInterfacesAlgorithm s_noMetadataRuntimeInterfacesAlgorithm = new NoMetadataRuntimeInterfacesAlgorithm(); private static readonly NativeLayoutInterfacesAlgorithm s_nativeLayoutInterfacesAlgorithm = new NativeLayoutInterfacesAlgorithm(); public TypeLoaderTypeSystemContext(TargetDetails targetDetails) : base(targetDetails) { } protected override RuntimeInterfacesAlgorithm GetRuntimeInterfacesAlgorithmForDefType(DefType type) { if (type.RetrieveRuntimeTypeHandleIfPossible()) { // If the type is already constructed, use the NoMetadataRuntimeInterfacesAlgorithm. // its more efficient than loading from native layout or metadata. return s_noMetadataRuntimeInterfacesAlgorithm; } else if (type.HasNativeLayout) { return s_nativeLayoutInterfacesAlgorithm; } return s_noMetadataRuntimeInterfacesAlgorithm; } protected internal sealed override bool IsIDynamicInterfaceCastableInterface(DefType type) { throw new NotImplementedException(); } protected override RuntimeInterfacesAlgorithm GetRuntimeInterfacesAlgorithmForNonPointerArrayType(ArrayType type) { // At runtime, we're instantiating an Array<T> instantiation as the template, so we know we'll always have // a NativeLayoutInterfacesAlgorithm to work with return s_nativeLayoutInterfacesAlgorithm; } public override DefType GetWellKnownType(WellKnownType wellKnownType, bool throwIfNotFound = true) { switch (wellKnownType) { case WellKnownType.Void: return (DefType)ResolveRuntimeTypeHandle(typeof(void).TypeHandle); case WellKnownType.Boolean: return (DefType)ResolveRuntimeTypeHandle(typeof(bool).TypeHandle); case WellKnownType.Char: return (DefType)ResolveRuntimeTypeHandle(typeof(char).TypeHandle); case WellKnownType.SByte: return (DefType)ResolveRuntimeTypeHandle(typeof(sbyte).TypeHandle); case WellKnownType.Byte: return (DefType)ResolveRuntimeTypeHandle(typeof(byte).TypeHandle); case WellKnownType.Int16: return (DefType)ResolveRuntimeTypeHandle(typeof(short).TypeHandle); case WellKnownType.UInt16: return (DefType)ResolveRuntimeTypeHandle(typeof(ushort).TypeHandle); case WellKnownType.Int32: return (DefType)ResolveRuntimeTypeHandle(typeof(int).TypeHandle); case WellKnownType.UInt32: return (DefType)ResolveRuntimeTypeHandle(typeof(uint).TypeHandle); case WellKnownType.Int64: return (DefType)ResolveRuntimeTypeHandle(typeof(long).TypeHandle); case WellKnownType.UInt64: return (DefType)ResolveRuntimeTypeHandle(typeof(ulong).TypeHandle); case WellKnownType.IntPtr: return (DefType)ResolveRuntimeTypeHandle(typeof(IntPtr).TypeHandle); case WellKnownType.UIntPtr: return (DefType)ResolveRuntimeTypeHandle(typeof(UIntPtr).TypeHandle); case WellKnownType.Single: return (DefType)ResolveRuntimeTypeHandle(typeof(float).TypeHandle); case WellKnownType.Double: return (DefType)ResolveRuntimeTypeHandle(typeof(double).TypeHandle); case WellKnownType.ValueType: return (DefType)ResolveRuntimeTypeHandle(typeof(ValueType).TypeHandle); case WellKnownType.Enum: return (DefType)ResolveRuntimeTypeHandle(typeof(Enum).TypeHandle); case WellKnownType.Nullable: return (DefType)ResolveRuntimeTypeHandle(typeof(Nullable<>).TypeHandle); case WellKnownType.Object: return (DefType)ResolveRuntimeTypeHandle(typeof(object).TypeHandle); case WellKnownType.String: return (DefType)ResolveRuntimeTypeHandle(typeof(string).TypeHandle); case WellKnownType.Array: return (DefType)ResolveRuntimeTypeHandle(typeof(Array).TypeHandle); case WellKnownType.MulticastDelegate: return (DefType)ResolveRuntimeTypeHandle(typeof(MulticastDelegate).TypeHandle); case WellKnownType.RuntimeTypeHandle: return (DefType)ResolveRuntimeTypeHandle(typeof(RuntimeTypeHandle).TypeHandle); case WellKnownType.RuntimeMethodHandle: return (DefType)ResolveRuntimeTypeHandle(typeof(RuntimeMethodHandle).TypeHandle); case WellKnownType.RuntimeFieldHandle: return (DefType)ResolveRuntimeTypeHandle(typeof(RuntimeFieldHandle).TypeHandle); case WellKnownType.Exception: return (DefType)ResolveRuntimeTypeHandle(typeof(Exception).TypeHandle); default: if (throwIfNotFound) throw new TypeLoadException(); else return null; } } protected internal override Instantiation ConvertInstantiationToCanonForm(Instantiation instantiation, CanonicalFormKind kind, out bool changed) { return StandardCanonicalizationAlgorithm.ConvertInstantiationToCanonForm(instantiation, kind, out changed); } protected internal override TypeDesc ConvertToCanon(TypeDesc typeToConvert, CanonicalFormKind kind) { return StandardCanonicalizationAlgorithm.ConvertToCanon(typeToConvert, kind); } protected internal override bool ComputeHasStaticConstructor(TypeDesc type) { // This assumes we can compute the information from a type definition // (`type` is going to be a definition here because that's how the type system is structured). // We don't maintain consistency for this at runtime. Different instantiations of // a single definition may or may not have a static constructor after AOT compilation. // Asking about this for a definition is an invalid question. // If this is ever needed, we need to restructure things in the common type system. throw new NotImplementedException(); } public override bool SupportsUniversalCanon => false; public override bool SupportsCanon => true; } }