| File: parent\parent\Common\TypeSystem\Interop\IL\NativeStructType.cs | Web Access |
| Project: 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; using System.Collections.Generic; using ILCompiler; using Internal.Text; using Debug = System.Diagnostics.Debug; namespace Internal.TypeSystem.Interop { public partial class NativeStructType : MetadataType { // The managed struct that this type will imitate public MetadataType ManagedStructType { get; } public override ModuleDesc Module { get; } public override Utf8Span Name { get { return "__NativeType__"u8.Append(ManagedStructType.Name); } } public override string DiagnosticName { get { return "__NativeType__" + ManagedStructType.DiagnosticName; } } public override Utf8Span Namespace { get { return "Internal.CompilerGenerated"u8; } } public override string DiagnosticNamespace { get { return "Internal.CompilerGenerated"; } } public override PInvokeStringFormat PInvokeStringFormat { get { return ManagedStructType.PInvokeStringFormat; } } public override bool IsExplicitLayout { get { return ManagedStructType.IsExplicitLayout; } } public override bool IsSequentialLayout { get { return ManagedStructType.IsSequentialLayout; } } public override bool IsExtendedLayout { get { return ManagedStructType.IsExtendedLayout; } } public override bool IsAutoLayout { get { return ManagedStructType.IsAutoLayout; } } public override bool IsBeforeFieldInit { get { return ManagedStructType.IsBeforeFieldInit; } } public override MetadataType BaseType { get { return (MetadataType)Context.GetWellKnownType(WellKnownType.ValueType); } } public override bool IsSealed { get { return true; } } public override bool IsAbstract { get { return false; } } public override MetadataType ContainingType { get { return null; } } public override DefType[] ExplicitlyImplementedInterfaces { get { return Array.Empty<DefType>(); } } public override TypeSystemContext Context { get { return ManagedStructType.Context; } } private NativeStructField[] _fields; private InteropStateManager _interopStateManager; private bool _hasInvalidLayout; private DefType _typeForFieldIteration; public bool HasInvalidLayout { get { return _hasInvalidLayout; } } public FieldDesc[] Fields { get { return _fields; } } [ThreadStatic] private static Stack<MetadataType> s_typesBeingLookedAt; public NativeStructType(ModuleDesc owningModule, MetadataType managedStructType, InteropStateManager interopStateManager) { Debug.Assert(!managedStructType.IsGenericDefinition); Module = owningModule; ManagedStructType = managedStructType; _interopStateManager = interopStateManager; _hasInvalidLayout = managedStructType.IsAutoLayout; _typeForFieldIteration = managedStructType.IsInlineArray ? new TypeWithRepeatedFields(managedStructType) : managedStructType; Stack<MetadataType> typesBeingLookedAt = (s_typesBeingLookedAt ??= new Stack<MetadataType>()); if (typesBeingLookedAt.Contains(managedStructType)) ThrowHelper.ThrowTypeLoadException(managedStructType); typesBeingLookedAt.Push(managedStructType); try { CalculateFields(); } finally { MetadataType popped = typesBeingLookedAt.Pop(); Debug.Assert(popped == managedStructType); } } private void CalculateFields() { bool isAnsi = ManagedStructType.PInvokeStringFormat == PInvokeStringFormat.AnsiClass; int numFields = 0; foreach (FieldDesc field in _typeForFieldIteration.GetFields()) { if (field.IsStatic) { continue; } numFields++; } _fields = new NativeStructField[numFields]; int index = 0; foreach (FieldDesc field in _typeForFieldIteration.GetFields()) { if (field.IsStatic) { continue; } var managedType = field.FieldType; TypeDesc nativeType; try { nativeType = MarshalHelpers.GetNativeStructFieldType(managedType, field.GetMarshalAsDescriptor(), _interopStateManager, isAnsi); } catch (NotSupportedException) { // if marshalling is not supported for this type the generated stubs will emit appropriate // error message. We just set native type to be same as managedtype nativeType = managedType; _hasInvalidLayout = true; } _fields[index++] = new NativeStructField(nativeType, this, field); } } public override ClassLayoutMetadata GetClassLayout() => ManagedStructType.GetClassLayout(); public override bool HasCustomAttribute(string attributeNamespace, string attributeName) { return false; } public override IEnumerable<MetadataType> GetNestedTypes() { return Array.Empty<MetadataType>(); } public override MetadataType GetNestedType(Utf8Span name) { return null; } protected override MethodImplRecord[] ComputeVirtualMethodImplsForType() { return Array.Empty<MethodImplRecord>(); } public override MethodImplRecord[] FindMethodsImplWithMatchingDeclName(Utf8Span name) { return Array.Empty<MethodImplRecord>(); } private int _hashCode; private int InitializeHashCode() { return _hashCode = VersionResilientHashCode.NameHashCode(Namespace, Name); } public override int GetHashCode() { if (_hashCode != 0) { return _hashCode; } return InitializeHashCode(); } protected override TypeFlags ComputeTypeFlags(TypeFlags mask) { TypeFlags flags = 0; if ((mask & TypeFlags.HasGenericVarianceComputed) != 0) { flags |= TypeFlags.HasGenericVarianceComputed; } if ((mask & TypeFlags.CategoryMask) != 0) { flags |= TypeFlags.ValueType; } flags |= TypeFlags.HasFinalizerComputed; flags |= TypeFlags.AttributeCacheComputed; return flags; } public override IEnumerable<FieldDesc> GetFields() { return _fields; } /// <summary> /// Synthetic field on <see cref="NativeStructType"/>. /// </summary> private partial class NativeStructField : FieldDesc { private TypeDesc _fieldType; private MetadataType _owningType; private FieldDesc _managedField; public override TypeSystemContext Context { get { return _owningType.Context; } } public override TypeDesc FieldType { get { return _fieldType; } } public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null; public override bool HasEmbeddedSignatureData => false; public override bool HasRva { get { return false; } } public override bool IsInitOnly { get { return false; } } public override bool IsLiteral { get { return false; } } public override bool IsStatic { get { return false; } } public override bool IsThreadStatic { get { return false; } } public override MetadataType OwningType { get { return _owningType; } } public override bool HasCustomAttribute(string attributeNamespace, string attributeName) { return false; } public override Utf8Span Name { get { return _managedField.Name; } } public override LayoutInt MetadataOffset { get { return _managedField.MetadataOffset; } } public NativeStructField(TypeDesc nativeType, MetadataType owningType, FieldDesc managedField) { _fieldType = nativeType; _owningType = owningType; _managedField = managedField; } } } }