From cfd4e7e1b7af1ebc54698d16b27896ed5d612023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Fri, 28 Apr 2023 14:45:42 +0900 Subject: [PATCH 1/4] Emission and reading of custom modifiers Fixes #71883. * Emit custom modifiers to the native metadata format * Read custom modifiers at runtime * Bugfix in the type loader --- .../src/Internal/Runtime/MethodTable.cs | 2 +- .../Reflection/ModifiedType.NativeAot.cs | 115 ++++++++++++++- .../NativeFormatRuntimeFieldInfo.cs | 2 + .../Runtime/General/QSignatureTypeHandle.cs | 5 + .../RuntimeMethodParameterInfo.cs | 2 + .../NativeFormatRuntimePropertyInfo.cs | 6 + .../Runtime/TypeLoader/EETypeCreator.cs | 18 +++ .../Runtime/TypeLoader/TypeBuilder.cs | 24 ++++ .../TypeLoader/TypeLoaderEnvironment.cs | 26 +++- .../TypeSystem/TypeSystemContext.Runtime.cs | 2 +- .../NativeFormat/Generator/SchemaDef.cs | 4 +- .../NativeFormat/NativeFormatReaderGen.cs | 4 +- .../Common/TypeSystem/Common/FieldDesc.cs | 2 + .../Common/FieldForInstantiatedType.cs | 8 ++ .../TypeSystem/Common/PropertySignature.cs | 13 +- .../tools/Common/TypeSystem/Ecma/EcmaField.cs | 20 ++- .../TypeSystem/Ecma/EcmaSignatureParser.cs | 21 ++- .../IL/Stubs/PInvokeLazyFixupField.cs | 2 + .../TypeSystem/Interop/IL/InlineArrayType.cs | 2 + .../TypeSystem/Interop/IL/NativeStructType.cs | 2 + .../TypeSystemMetadataEmitter.cs | 5 +- .../DependencyAnalysis/FieldMetadataNode.cs | 7 + .../DependencyAnalysis/MethodMetadataNode.cs | 7 + .../Compiler/ExternSymbolMappedField.cs | 1 + .../ILCompiler/Metadata/Transform.Field.cs | 21 ++- .../ILCompiler/Metadata/Transform.Method.cs | 50 ++++++- .../ILCompiler/Metadata/Transform.Property.cs | 17 ++- .../ILCompiler/Metadata/Transform.Type.cs | 136 ++++++++++++++++++ .../Writer/NativeFormatWriterGen.cs | 6 +- .../TypeRefTypeSystemField.cs | 2 + .../FunctionPointerCallingConventionTests.cs | 8 -- .../System/FunctionPointerEqualityTests.cs | 3 - .../tests/System/FunctionPointerTests.cs | 4 - .../Common/tests/System/ModifiedTypeTests.cs | 36 +---- .../System.Runtime/tests/default.rd.xml | 6 + src/tests/issues.targets | 9 -- 36 files changed, 509 insertions(+), 89 deletions(-) diff --git a/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs b/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs index 0f8a9feb4ba55..6ae1888d18290 100644 --- a/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs +++ b/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs @@ -1742,7 +1742,7 @@ public MethodTable* this[int index] if (((nint)_pFirst & IsRelative) != 0) return (((RelativePointer*)((nint)_pFirst - IsRelative)) + index)->Value; - return *(MethodTable**)_pFirst + index; + return *((MethodTable**)_pFirst + index); } #if TYPE_LOADER_IMPLEMENTATION set diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/ModifiedType.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/ModifiedType.NativeAot.cs index 7cf1313aed901..32f171f1b5d83 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/ModifiedType.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/ModifiedType.NativeAot.cs @@ -1,20 +1,123 @@ // 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 System.Reflection.Runtime.General; + +using Internal.Metadata.NativeFormat; + +using Debug = System.Diagnostics.Debug; + namespace System.Reflection { internal partial class ModifiedType { - internal struct TypeSignature + internal readonly struct TypeSignature + { + internal readonly MetadataReader Reader; + internal readonly Handle Handle; + public TypeSignature(MetadataReader reader, Handle handle) + => (Reader, Handle) = (reader, handle); + } + + internal Type GetTypeParameter(Type unmodifiedType, int index) + { + MetadataReader reader = _typeSignature.Reader; + Handle handle = _typeSignature.Handle; + + while (handle.HandleType == HandleType.ModifiedType) + handle = reader.GetModifiedType(handle.ToModifiedTypeHandle(reader)).Type; + + if (handle.HandleType == HandleType.TypeSpecification) + handle = reader.GetTypeSpecification(handle.ToTypeSpecificationHandle(reader)).Signature; + + switch (handle.HandleType) + { + case HandleType.SZArraySignature: + Debug.Assert(index == 0); + return Create(unmodifiedType, new TypeSignature(reader, reader.GetSZArraySignature(handle.ToSZArraySignatureHandle(reader)).ElementType)); + case HandleType.ArraySignature: + Debug.Assert(index == 0); + return Create(unmodifiedType, new TypeSignature(reader, reader.GetArraySignature(handle.ToArraySignatureHandle(reader)).ElementType)); + case HandleType.PointerSignature: + Debug.Assert(index == 0); + return Create(unmodifiedType, new TypeSignature(reader, reader.GetPointerSignature(handle.ToPointerSignatureHandle(reader)).Type)); + case HandleType.ByReferenceSignature: + Debug.Assert(index == 0); + return Create(unmodifiedType, new TypeSignature(reader, reader.GetByReferenceSignature(handle.ToByReferenceSignatureHandle(reader)).Type)); + case HandleType.FunctionPointerSignature: + { + MethodSignature functionSig = reader.GetMethodSignature( + reader.GetFunctionPointerSignature(handle.ToFunctionPointerSignatureHandle(reader)).Signature); + if (index-- == 0) + return Create(unmodifiedType, new TypeSignature(reader, functionSig.ReturnType)); + + Debug.Assert(index <= functionSig.Parameters.Count); + foreach (Handle paramHandle in functionSig.Parameters) + if (index-- == 0) + return Create(unmodifiedType, new TypeSignature(reader, paramHandle)); + } + break; + case HandleType.TypeInstantiationSignature: + { + TypeInstantiationSignature typeInst = + reader.GetTypeInstantiationSignature(handle.ToTypeInstantiationSignatureHandle(reader)); + Debug.Assert(index < typeInst.GenericTypeArguments.Count); + foreach (Handle paramHandle in typeInst.GenericTypeArguments) + if (index-- == 0) + return Create(unmodifiedType, new TypeSignature(reader, paramHandle)); + } + break; + } + + Debug.Fail(handle.HandleType.ToString()); + return null; + } + + internal SignatureCallingConvention GetCallingConventionFromFunctionPointer() { + MetadataReader reader = _typeSignature.Reader; + Handle fnPtrTypeSigHandle = reader.GetTypeSpecification( + _typeSignature.Handle.ToTypeSpecificationHandle(reader)).Signature; + MethodSignatureHandle methodSigHandle = reader.GetFunctionPointerSignature( + fnPtrTypeSigHandle.ToFunctionPointerSignatureHandle(reader)).Signature; + + Debug.Assert((int)Internal.Metadata.NativeFormat.SignatureCallingConvention.StdCall == (int)SignatureCallingConvention.StdCall); + Debug.Assert((int)Internal.Metadata.NativeFormat.SignatureCallingConvention.Unmanaged == (int)SignatureCallingConvention.Unmanaged); + return (SignatureCallingConvention)(reader.GetMethodSignature(methodSigHandle).CallingConvention + & Internal.Metadata.NativeFormat.SignatureCallingConvention.UnmanagedCallingConventionMask); } -#pragma warning disable IDE0060 - internal Type GetTypeParameter(Type unmodifiedType, int index) => throw new NotSupportedException(); + private Type[] GetCustomModifiers(bool required) + { + ArrayBuilder builder = default; + + MetadataReader reader = _typeSignature.Reader; + Handle handle = _typeSignature.Handle; + + while (handle.HandleType == HandleType.ModifiedType) + { + var modifiedType = reader.GetModifiedType(handle.ToModifiedTypeHandle(reader)); - internal SignatureCallingConvention GetCallingConventionFromFunctionPointer() => throw new NotSupportedException(); + handle = modifiedType.Type; + + if (modifiedType.IsOptional == required) + continue; + + builder.Add(modifiedType.ModifierType.Resolve(reader, new TypeContext(null, null))); + } + + Type[] result = builder.ToArray(); + + // We call Reverse for compat with CoreCLR that also reverses these. + // ILDasm also reverses these but don't be fooled: you can go to + // View -> MetaInfo -> Show to see the file format order in ILDasm. + Array.Reverse(result); + + return result; + } - private Type[] GetCustomModifiers(bool required) => throw new NotSupportedException(); -#pragma warning restore IDE0060 + public static Type Create(Type unmodifiedType, MetadataReader reader, Handle typeSignature) + => ModifiedType.Create(unmodifiedType, new TypeSignature(reader, typeSignature)); } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/FieldInfos/NativeFormat/NativeFormatRuntimeFieldInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/FieldInfos/NativeFormat/NativeFormatRuntimeFieldInfo.cs index be8721f006b25..e4272119e698c 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/FieldInfos/NativeFormat/NativeFormatRuntimeFieldInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/FieldInfos/NativeFormat/NativeFormatRuntimeFieldInfo.cs @@ -162,6 +162,8 @@ protected sealed override RuntimeTypeInfo FieldRuntimeType protected sealed override int ExplicitLayoutFieldOffsetData => (int)(_field.Offset); + public sealed override Type GetModifiedFieldType() => ModifiedType.Create(FieldRuntimeType, _reader, FieldTypeHandle); + private Handle FieldTypeHandle => _field.Signature.GetFieldSignature(_reader).Type; private readonly NativeFormatRuntimeNamedTypeInfo _definingTypeInfo; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/QSignatureTypeHandle.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/QSignatureTypeHandle.cs index 116249d661f40..c7892602a1487 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/QSignatureTypeHandle.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/QSignatureTypeHandle.cs @@ -61,5 +61,10 @@ internal Type[] GetCustomModifiers(TypeContext typeContext, bool optional) return _handle.GetCustomModifiers((global::Internal.Metadata.NativeFormat.MetadataReader)Reader, typeContext, optional); #endif } + + internal Type GetModifiedType(TypeContext typeContext) + { + return ModifiedType.Create(Resolve(typeContext), (global::Internal.Metadata.NativeFormat.MetadataReader)Reader, _handle); + } } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimeMethodParameterInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimeMethodParameterInfo.cs index b146eadb260b9..6f8ba75970dcc 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimeMethodParameterInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimeMethodParameterInfo.cs @@ -36,6 +36,8 @@ public sealed override Type ParameterType } } + public sealed override Type GetModifiedParameterType() => QualifiedParameterTypeHandle.GetModifiedType(_typeContext); + protected readonly QSignatureTypeHandle QualifiedParameterTypeHandle; private readonly TypeContext _typeContext; private volatile Type _lazyParameterType; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/PropertyInfos/NativeFormat/NativeFormatRuntimePropertyInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/PropertyInfos/NativeFormat/NativeFormatRuntimePropertyInfo.cs index 7966647740c76..813a40073a2c9 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/PropertyInfos/NativeFormat/NativeFormatRuntimePropertyInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/PropertyInfos/NativeFormat/NativeFormatRuntimePropertyInfo.cs @@ -75,6 +75,12 @@ public sealed override IEnumerable CustomAttributes } } + public override Type GetModifiedPropertyType() + { + return ModifiedType.Create(PropertyType, _reader, _reader.GetPropertySignature(_property.Signature).Type); + + } + public sealed override bool HasSameMetadataDefinitionAs(MemberInfo other) { ArgumentNullException.ThrowIfNull(other); diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs index f77e10b0ff91d..726639afedc84 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs @@ -637,6 +637,24 @@ private static unsafe int CreateGCDesc(LowLevelList bitfield, int size, bo return numSeries; } + public static RuntimeTypeHandle CreateFunctionPointerEEType(uint hashCodeOfNewType, RuntimeTypeHandle returnTypeHandle, RuntimeTypeHandle[] parameterHandles, FunctionPointerType functionPointerType) + { + TypeBuilderState state = new TypeBuilderState(functionPointerType); + + CreateEETypeWorker(typeof(delegate*).TypeHandle.ToEETypePtr(), hashCodeOfNewType, 0, state); + Debug.Assert(!state.HalfBakedRuntimeTypeHandle.IsNull()); + + TypeLoaderLogger.WriteLine("Allocated new FUNCTION POINTER type " + functionPointerType.ToString() + " with hashcode value = 0x" + hashCodeOfNewType.LowLevelToString() + " with MethodTable = " + state.HalfBakedRuntimeTypeHandle.ToIntPtr().LowLevelToString()); + + state.HalfBakedRuntimeTypeHandle.ToEETypePtr()->FunctionPointerReturnType = returnTypeHandle.ToEETypePtr(); + Debug.Assert(state.HalfBakedRuntimeTypeHandle.ToEETypePtr()->NumFunctionPointerParameters == parameterHandles.Length); + MethodTableList paramList = state.HalfBakedRuntimeTypeHandle.ToEETypePtr()->FunctionPointerParameters; + for (int i = 0; i < parameterHandles.Length; i++) + paramList[i] = parameterHandles[i].ToEETypePtr(); + + return state.HalfBakedRuntimeTypeHandle; + } + public static RuntimeTypeHandle CreatePointerEEType(uint hashCodeOfNewType, RuntimeTypeHandle pointeeTypeHandle, TypeDesc pointerType) { TypeBuilderState state = new TypeBuilderState(pointerType); diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs index 33431b3ec32dd..b66c60f60310d 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs @@ -1304,6 +1304,30 @@ public static bool TryBuildByRefType(RuntimeTypeHandle pointeeTypeHandle, out Ru return true; } + public static bool TryBuildFunctionPointerType(RuntimeTypeHandle returnTypeHandle, RuntimeTypeHandle[] parameterHandles, bool isUnmanaged, out RuntimeTypeHandle runtimeTypeHandle) + { + var key = new TypeSystemContext.FunctionPointerTypeKey(returnTypeHandle, parameterHandles, isUnmanaged); + if (!TypeSystemContext.FunctionPointerTypesCache.TryGetValue(key, out runtimeTypeHandle)) + { + TypeSystemContext context = TypeSystemContextFactory.Create(); + FunctionPointerType functionPointerType = context.GetFunctionPointerType(new MethodSignature( + isUnmanaged ? MethodSignatureFlags.UnmanagedCallingConvention : 0, + genericParameterCount: 0, + context.ResolveRuntimeTypeHandle(returnTypeHandle), + context.ResolveRuntimeTypeHandlesInternal(parameterHandles))); + runtimeTypeHandle = EETypeCreator.CreateFunctionPointerEEType((uint)functionPointerType.GetHashCode(), returnTypeHandle, parameterHandles, functionPointerType); + unsafe + { + Debug.Assert(runtimeTypeHandle.ToEETypePtr()->IsFunctionPointerType); + } + TypeSystemContext.FunctionPointerTypesCache.AddOrGetExisting(runtimeTypeHandle); + + // Recycle the context only if we successfully built the type. The state may be partially initialized otherwise. + TypeSystemContextFactory.Recycle(context); + } + return true; + } + internal static bool TryBuildGenericMethod(InstantiatedMethod methodBeingLoaded, out IntPtr methodDictionary) { try diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.cs index 96a701db30cd1..6b306015f03a8 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.cs @@ -349,15 +349,33 @@ public bool TryGetFunctionPointerTypeForComponents(RuntimeTypeHandle returnTypeH using (LockHolder.Hold(_typeLoaderLock)) { - throw new NotImplementedException(); + return TypeBuilder.TryBuildFunctionPointerType(returnTypeHandle, parameterHandles, isUnmanaged, out runtimeTypeHandle); } } public bool TryLookupFunctionPointerTypeForComponents(RuntimeTypeHandle returnTypeHandle, RuntimeTypeHandle[] parameterHandles, bool isUnmanaged, out RuntimeTypeHandle runtimeTypeHandle) { - // TODO: cache same as for arrays - // TODO: lookup dynamically built ones - return TryGetStaticFunctionPointerTypeForComponents(returnTypeHandle, parameterHandles, isUnmanaged, out runtimeTypeHandle); + var key = new TypeSystemContext.FunctionPointerTypeKey(returnTypeHandle, parameterHandles, isUnmanaged); + if (TypeSystemContext.FunctionPointerTypesCache.TryGetValue(key, out runtimeTypeHandle)) + return true; + + if (!RuntimeAugments.IsDynamicType(returnTypeHandle) + && AllNonDynamicTypes(parameterHandles) + && TryGetStaticFunctionPointerTypeForComponents(returnTypeHandle, parameterHandles, isUnmanaged, out runtimeTypeHandle)) + { + TypeSystemContext.FunctionPointerTypesCache.AddOrGetExisting(runtimeTypeHandle); + return true; + } + + return false; + + static bool AllNonDynamicTypes(RuntimeTypeHandle[] handles) + { + foreach (RuntimeTypeHandle h in handles) + if (RuntimeAugments.IsDynamicType(h)) + return false; + return true; + } } // Get an array RuntimeTypeHandle given an element's RuntimeTypeHandle and rank. Pass false for isMdArray, and rank == -1 for SzArrays diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs index e9796dce6164c..6f81634daccbf 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs @@ -162,7 +162,7 @@ internal static RuntimeTypeHandleToParameterTypeRuntimeTypeHandleHashtable GetAr internal static FunctionPointerRuntimeTypeHandleHashtable FunctionPointerTypesCache { get; } = new FunctionPointerRuntimeTypeHandleHashtable(); - private TypeDesc[] ResolveRuntimeTypeHandlesInternal(RuntimeTypeHandle[] runtimeTypeHandles) + public TypeDesc[] ResolveRuntimeTypeHandlesInternal(RuntimeTypeHandle[] runtimeTypeHandles) { TypeDesc[] TypeDescs = new TypeDesc[runtimeTypeHandles.Length]; for (int i = 0; i < runtimeTypeHandles.Length; i++) diff --git a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/SchemaDef.cs b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/SchemaDef.cs index 8961c1bc1b452..d9a5122209d85 100644 --- a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/SchemaDef.cs +++ b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/SchemaDef.cs @@ -558,7 +558,7 @@ from primitiveType in PrimitiveTypes select name: "MethodInstantiation", members: new MemberDef[] { new MemberDef("Method", MethodDefOrRef, MemberDefFlags.RecordRef), - new MemberDef("GenericTypeArguments", TypeDefOrRefOrSpec, MemberDefFlags.List | MemberDefFlags.RecordRef), + new MemberDef("GenericTypeArguments", TypeDefOrRefOrSpecOrMod, MemberDefFlags.List | MemberDefFlags.RecordRef), // COMPLETENESS: new MemberDef("CustomAttributes", "CustomAttribute", MemberDefFlags.List | MemberDefFlags.RecordRef | MemberDefFlags.Child), } ), @@ -674,7 +674,7 @@ from primitiveType in PrimitiveTypes select name: "TypeInstantiationSignature", members: new MemberDef[] { new MemberDef("GenericType", TypeDefOrRefOrSpec, MemberDefFlags.RecordRef), - new MemberDef("GenericTypeArguments", TypeDefOrRefOrSpec, MemberDefFlags.List | MemberDefFlags.RecordRef), + new MemberDef("GenericTypeArguments", TypeDefOrRefOrSpecOrMod, MemberDefFlags.List | MemberDefFlags.RecordRef), } ), new RecordDef( diff --git a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs index dd88c6f2b1d3a..3a248bcb226fa 100644 --- a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs +++ b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs @@ -4901,7 +4901,7 @@ public Handle Method } // Method internal Handle _method; - /// One of: TypeDefinition, TypeReference, TypeSpecification + /// One of: TypeDefinition, TypeReference, TypeSpecification, ModifiedType public HandleCollection GenericTypeArguments { @@ -7756,7 +7756,7 @@ public Handle GenericType } // GenericType internal Handle _genericType; - /// One of: TypeDefinition, TypeReference, TypeSpecification + /// One of: TypeDefinition, TypeReference, TypeSpecification, ModifiedType public HandleCollection GenericTypeArguments { diff --git a/src/coreclr/tools/Common/TypeSystem/Common/FieldDesc.cs b/src/coreclr/tools/Common/TypeSystem/Common/FieldDesc.cs index 13b22edc3609a..1047c075c2f62 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/FieldDesc.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/FieldDesc.cs @@ -47,6 +47,8 @@ public abstract TypeDesc FieldType // Get the embedded signature data used to hold custom modifiers and such within a field signature public abstract EmbeddedSignatureData[] GetEmbeddedSignatureData(); + public abstract bool HasEmbeddedSignatureData { get; } + public abstract bool IsStatic { get; diff --git a/src/coreclr/tools/Common/TypeSystem/Common/FieldForInstantiatedType.cs b/src/coreclr/tools/Common/TypeSystem/Common/FieldForInstantiatedType.cs index 692e4db2a0aa9..04e403356ba47 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/FieldForInstantiatedType.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/FieldForInstantiatedType.cs @@ -54,6 +54,14 @@ public override EmbeddedSignatureData[] GetEmbeddedSignatureData() return _fieldDef.GetEmbeddedSignatureData(); } + public override bool HasEmbeddedSignatureData + { + get + { + return _fieldDef.HasEmbeddedSignatureData; + } + } + public override bool IsStatic { get diff --git a/src/coreclr/tools/Common/TypeSystem/Common/PropertySignature.cs b/src/coreclr/tools/Common/TypeSystem/Common/PropertySignature.cs index 8a99786b4a49c..3e130eb2d3f77 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/PropertySignature.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/PropertySignature.cs @@ -11,6 +11,8 @@ public struct PropertySignature public readonly TypeDesc ReturnType; + private readonly EmbeddedSignatureData[] _embeddedSignatureData; + [System.Runtime.CompilerServices.IndexerName("Parameter")] public TypeDesc this[int index] { @@ -28,11 +30,20 @@ public int Length } } - public PropertySignature(bool isStatic, TypeDesc[] parameters, TypeDesc returnType) + public bool HasEmbeddedSignatureData + { + get + { + return _embeddedSignatureData != null; + } + } + + public PropertySignature(bool isStatic, TypeDesc[] parameters, TypeDesc returnType, EmbeddedSignatureData[] embeddedSignatureData) { IsStatic = isStatic; _parameters = parameters; ReturnType = returnType; + _embeddedSignatureData = embeddedSignatureData; } } } diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaField.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaField.cs index c7128495897b9..01356a7200052 100644 --- a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaField.cs +++ b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaField.cs @@ -22,6 +22,9 @@ private static class FieldFlags public const int AttributeMetadataCache = 0x0100; public const int ThreadStatic = 0x0200; public const int Intrinsic = 0x0400; + + // Computed when field type is computed + public const int HasEmbeddedSignatureData = 0x0800; }; private EcmaType _type; @@ -98,7 +101,11 @@ private TypeDesc InitializeFieldType() BlobReader signatureReader = metadataReader.GetBlobReader(metadataReader.GetFieldDefinition(_handle).Signature); EcmaSignatureParser parser = new EcmaSignatureParser(Module, signatureReader, NotFoundBehavior.Throw); - var fieldType = parser.ParseFieldSignature(); + var fieldType = parser.ParseFieldSignature(out EmbeddedSignatureData[] data); + + if (data != null) + _fieldFlags.AddFlags(FieldFlags.HasEmbeddedSignatureData); + return (_fieldType = fieldType); } @@ -112,6 +119,17 @@ public override TypeDesc FieldType } } + public override bool HasEmbeddedSignatureData + { + get + { + if (_fieldType == null) + InitializeFieldType(); + + return _fieldFlags.HasFlags(FieldFlags.HasEmbeddedSignatureData); + } + } + // This is extremely rarely needed. Don't cache it at all. public override EmbeddedSignatureData[] GetEmbeddedSignatureData() { diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs index 318ca38f80021..cb80a557687ab 100644 --- a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs +++ b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs @@ -420,6 +420,23 @@ private MethodSignature ParseMethodSignatureImpl(bool skipEmbeddedSignatureData) } public PropertySignature ParsePropertySignature() + { + try + { + _indexStack = new Stack(); + _indexStack.Push(0); + _embeddedSignatureDataList = new List(); + return ParsePropertySignatureInternal(); + } + finally + { + _indexStack = null; + _embeddedSignatureDataList = null; + } + + } + + private PropertySignature ParsePropertySignatureInternal() { // As PropertySignature is a struct, we cannot return null if (_notFoundBehavior != NotFoundBehavior.Throw) @@ -450,7 +467,9 @@ public PropertySignature ParsePropertySignature() parameters = TypeDesc.EmptyTypes; } - return new PropertySignature(isStatic, parameters, returnType); + EmbeddedSignatureData[] embeddedSignatureDataArray = (_embeddedSignatureDataList == null || _embeddedSignatureDataList.Count == 0) ? null : _embeddedSignatureDataList.ToArray(); + + return new PropertySignature(isStatic, parameters, returnType, embeddedSignatureDataArray); } public TypeDesc ParseFieldSignature() diff --git a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs index 5b49bfdb50faa..b74dc75b46dee 100644 --- a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs +++ b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs @@ -58,6 +58,8 @@ public override TypeDesc FieldType public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null; + public override bool HasEmbeddedSignatureData => false; + public override bool HasRva { get diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/InlineArrayType.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/InlineArrayType.cs index 78fd7bc25a4d2..c0b52d45c9968 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/InlineArrayType.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/InlineArrayType.cs @@ -446,6 +446,8 @@ public override TypeDesc FieldType } public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null; + public override bool HasEmbeddedSignatureData => false; + public override bool HasRva { get diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/NativeStructType.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/NativeStructType.cs index fcfee2dbab998..adc127cd95325 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/NativeStructType.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/NativeStructType.cs @@ -372,6 +372,8 @@ public override TypeDesc FieldType public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null; + public override bool HasEmbeddedSignatureData => false; + public override bool HasRva { get diff --git a/src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs b/src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs index 7f465939fc3fc..368008ca261f5 100644 --- a/src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs +++ b/src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs @@ -269,11 +269,10 @@ private BlobHandle GetMethodSignatureBlobHandle(MethodSignature sig) private BlobHandle GetFieldSignatureBlobHandle(FieldDesc field) { - var embeddedSigData = field.GetEmbeddedSignatureData(); EmbeddedSignatureDataEmitter signatureDataEmitter; - if (embeddedSigData != null && embeddedSigData.Length != 0) + if (field.HasEmbeddedSignatureData) { - signatureDataEmitter = new EmbeddedSignatureDataEmitter(embeddedSigData, this); + signatureDataEmitter = new EmbeddedSignatureDataEmitter(field.GetEmbeddedSignatureData(), this); } else { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FieldMetadataNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FieldMetadataNode.cs index 325a7bb794627..5c49cfddb1c2c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FieldMetadataNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FieldMetadataNode.cs @@ -51,6 +51,13 @@ public override IEnumerable GetStaticDependencies(NodeFacto GenericArgumentDataFlow.ProcessGenericArgumentDataFlow(ref dependencies, factory, new MessageOrigin(_field), ecmaField.FieldType, ecmaField.OwningType); } + if (_field.HasEmbeddedSignatureData) + { + foreach (var sigData in _field.GetEmbeddedSignatureData()) + if (sigData.type != null) + TypeMetadataNode.GetMetadataDependencies(ref dependencies, factory, sigData.type, "Modifier in a field signature"); + } + return dependencies; } protected override string GetName(NodeFactory factory) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodMetadataNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodMetadataNode.cs index d29fefdccafaa..7f44064c45089 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodMetadataNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodMetadataNode.cs @@ -50,6 +50,13 @@ public override IEnumerable GetStaticDependencies(NodeFacto TypeMetadataNode.GetMetadataDependencies(ref dependencies, factory, paramType, reason); } + if (sig.HasEmbeddedSignatureData) + { + foreach (var sigData in sig.GetEmbeddedSignatureData()) + if (sigData.type != null) + TypeMetadataNode.GetMetadataDependencies(ref dependencies, factory, sigData.type, "Modifier in a method signature"); + } + if (_method is EcmaMethod ecmaMethod) { DynamicDependencyAttributesOnEntityNode.AddDependenciesDueToDynamicDependencyAttribute(ref dependencies, factory, ecmaMethod); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExternSymbolMappedField.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExternSymbolMappedField.cs index 8a4bce713efe4..18d655748937c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExternSymbolMappedField.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExternSymbolMappedField.cs @@ -27,6 +27,7 @@ public ExternSymbolMappedField(TypeDesc fieldType, string symbolName) public override TypeDesc FieldType => _fieldType; public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null; + public override bool HasEmbeddedSignatureData => false; public override bool IsStatic => true; diff --git a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Field.cs b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Field.cs index c7b400a8400a8..ebb6a9e0be582 100644 --- a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Field.cs +++ b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Field.cs @@ -47,11 +47,6 @@ private Field HandleFieldDefinition(Cts.FieldDesc field) private void InitializeFieldDefinition(Cts.FieldDesc entity, Field record) { record.Name = HandleString(entity.Name); - record.Signature = new FieldSignature - { - Type = HandleType(entity.FieldType), - // TODO: CustomModifiers - }; record.Flags = GetFieldAttributes(entity); var ecmaField = entity as Cts.Ecma.EcmaField; @@ -59,6 +54,14 @@ private void InitializeFieldDefinition(Cts.FieldDesc entity, Field record) { Ecma.MetadataReader reader = ecmaField.MetadataReader; Ecma.FieldDefinition fieldDef = reader.GetFieldDefinition(ecmaField.Handle); + + record.Signature = new FieldSignature + { + Type = entity.HasEmbeddedSignatureData + ? HandleFieldSignature(ecmaField.Module, fieldDef.Signature) + : HandleType(entity.FieldType), + }; + Ecma.ConstantHandle defaultValueHandle = fieldDef.GetDefaultValue(); if (!defaultValueHandle.IsNil) { @@ -77,6 +80,14 @@ private void InitializeFieldDefinition(Cts.FieldDesc entity, Field record) } } + private MetadataRecord HandleFieldSignature(Cts.Ecma.EcmaModule module, Ecma.BlobHandle sigBlob) + { + Ecma.BlobReader reader = module.MetadataReader.GetBlobReader(sigBlob); + Ecma.SignatureHeader header = reader.ReadSignatureHeader(); + Debug.Assert(header.Kind == Ecma.SignatureKind.Field); + return HandleType(module, ref reader); + } + private MemberReference HandleFieldReference(Cts.FieldDesc field) { return (MemberReference)_fields.GetOrCreate(field, _initFieldRef ??= InitializeFieldReference); diff --git a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Method.cs b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Method.cs index ac044cb45cc50..354b7913d533e 100644 --- a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Method.cs +++ b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Method.cs @@ -61,7 +61,6 @@ private Method HandleMethodDefinition(Cts.MethodDesc method) private void InitializeMethodDefinition(Cts.MethodDesc entity, Method record) { record.Name = HandleString(entity.Name); - record.Signature = HandleMethodSignature(entity.Signature); if (entity.HasInstantiation) { @@ -77,6 +76,11 @@ private void InitializeMethodDefinition(Cts.MethodDesc entity, Method record) Ecma.MethodDefinition methodDef = reader.GetMethodDefinition(ecmaEntity.Handle); Ecma.ParameterHandleCollection paramHandles = methodDef.GetParameters(); + Cts.MethodSignature sig = entity.Signature; + record.Signature = sig.HasEmbeddedSignatureData + ? HandleMethodSignature(ecmaEntity.Module, methodDef.Signature) + : HandleMethodSignature(entity.Signature); + record.Parameters.Capacity = paramHandles.Count; foreach (var paramHandle in paramHandles) { @@ -170,6 +174,37 @@ public override MethodSignature HandleMethodSignature(Cts.MethodSignature signat return result; } + private MethodSignature HandleMethodSignature(Cts.Ecma.EcmaModule module, Ecma.BlobHandle sigBlobHandle) + { + Ecma.BlobReader blobReader = module.MetadataReader.GetBlobReader(sigBlobHandle); + return HandleMethodSignature(module, ref blobReader); + } + + private MethodSignature HandleMethodSignature(Cts.Ecma.EcmaModule module, ref Ecma.BlobReader blobReader) + { + Ecma.SignatureHeader header = blobReader.ReadSignatureHeader(); + + int arity = header.IsGeneric ? blobReader.ReadCompressedInteger() : 0; + + int count = blobReader.ReadCompressedInteger(); + + var result = new MethodSignature + { + CallingConvention = GetSignatureCallingConvention(header), + GenericParameterCount = arity, + ReturnType = HandleType(module, ref blobReader), + // TODO-NICE: VarArgParameters + }; + + result.Parameters.Capacity = count; + for (int i = 0; i < count; i++) + { + result.Parameters.Add(HandleType(module, ref blobReader)); + } + + return result; + } + private static MethodAttributes GetMethodAttributes(Cts.MethodDesc method) { var ecmaMethod = method as Cts.Ecma.EcmaMethod; @@ -208,5 +243,18 @@ private static SignatureCallingConvention GetSignatureCallingConvention(Cts.Meth } return callingConvention; } + + private static SignatureCallingConvention GetSignatureCallingConvention(Ecma.SignatureHeader signature) + { + Debug.Assert((int)Ecma.SignatureCallingConvention.CDecl == (int)SignatureCallingConvention.Cdecl); + Debug.Assert((int)Ecma.SignatureCallingConvention.ThisCall == (int)SignatureCallingConvention.ThisCall); + Debug.Assert((int)Ecma.SignatureCallingConvention.Unmanaged == (int)SignatureCallingConvention.Unmanaged); + SignatureCallingConvention callingConvention = (SignatureCallingConvention)(signature.CallingConvention); + if (signature.IsInstance) + { + callingConvention |= SignatureCallingConvention.HasThis; + } + return callingConvention; + } } } diff --git a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Property.cs b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Property.cs index 342709536b4ad..786d694be1dd6 100644 --- a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Property.cs +++ b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Property.cs @@ -40,13 +40,24 @@ private Property HandleProperty(Cts.Ecma.EcmaModule module, Ecma.PropertyDefinit Signature = new PropertySignature { CallingConvention = sig.IsStatic ? CallingConventions.Standard : CallingConventions.HasThis, - Type = HandleType(sig.ReturnType) }, }; result.Signature.Parameters.Capacity = sig.Length; - for (int i = 0; i < sig.Length; i++) - result.Signature.Parameters.Add(HandleType(sig[i])); + if (!sig.HasEmbeddedSignatureData) + { + result.Signature.Type = HandleType(sig.ReturnType); + for (int i = 0; i < sig.Length; i++) + result.Signature.Parameters.Add(HandleType(sig[i])); + } + else + { + sigBlobReader.ReadSignatureHeader(); + int count = sigBlobReader.ReadCompressedInteger(); + result.Signature.Type = HandleType(module, ref sigBlobReader); + for (int i = 0; i < count; i++) + result.Signature.Parameters.Add(HandleType(module, ref sigBlobReader)); + } if (getterHasMetadata) { diff --git a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Type.cs b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Type.cs index 226e8ea0f9c7f..632118848a614 100644 --- a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Type.cs +++ b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Type.cs @@ -376,6 +376,142 @@ static bool HasNestedTypes(Cts.MetadataType entity) => entity.GetNestedTypes().GetEnumerator().MoveNext(); } + private MetadataRecord HandleType(Cts.Ecma.EcmaModule module, ref Ecma.BlobReader reader) + { + switch (reader.ReadSignatureTypeCode()) + { + case Ecma.SignatureTypeCode.Void: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.Void)); + case Ecma.SignatureTypeCode.Boolean: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.Boolean)); + case Ecma.SignatureTypeCode.SByte: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.SByte)); + case Ecma.SignatureTypeCode.Byte: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.Byte)); + case Ecma.SignatureTypeCode.Int16: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.Int16)); + case Ecma.SignatureTypeCode.UInt16: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.UInt16)); + case Ecma.SignatureTypeCode.Int32: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.Int32)); + case Ecma.SignatureTypeCode.UInt32: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.UInt32)); + case Ecma.SignatureTypeCode.Int64: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.Int64)); + case Ecma.SignatureTypeCode.UInt64: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.UInt64)); + case Ecma.SignatureTypeCode.Single: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.Single)); + case Ecma.SignatureTypeCode.Double: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.Double)); + case Ecma.SignatureTypeCode.Char: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.Char)); + case Ecma.SignatureTypeCode.String: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.String)); + case Ecma.SignatureTypeCode.IntPtr: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.IntPtr)); + case Ecma.SignatureTypeCode.UIntPtr: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.UIntPtr)); + case Ecma.SignatureTypeCode.Object: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.Object)); + case Ecma.SignatureTypeCode.TypeHandle: + return HandleType(module.GetType(reader.ReadTypeHandle())); + case Ecma.SignatureTypeCode.SZArray: + return new TypeSpecification + { + Signature = new SZArraySignature() + { + ElementType = HandleType(module, ref reader) + } + }; + case Ecma.SignatureTypeCode.Array: + { + MetadataRecord elementType = HandleType(module, ref reader); + int rank = reader.ReadCompressedInteger(); + + var boundsCount = reader.ReadCompressedInteger(); + for (int i = 0; i < boundsCount; i++) + reader.ReadCompressedInteger(); + var lowerBoundsCount = reader.ReadCompressedInteger(); + for (int j = 0; j < lowerBoundsCount; j++) + reader.ReadCompressedSignedInteger(); + + return new TypeSpecification + { + Signature = new ArraySignature() + { + ElementType = elementType, + Rank = rank, + // TODO: sizes & lower bounds + } + }; + } + case Ecma.SignatureTypeCode.ByReference: + return new TypeSpecification + { + Signature = new ByReferenceSignature() + { + Type = HandleType(module, ref reader) + } + }; + case Ecma.SignatureTypeCode.Pointer: + return new TypeSpecification + { + Signature = new PointerSignature() + { + Type = HandleType(module, ref reader) + } + }; + case Ecma.SignatureTypeCode.GenericTypeParameter: + return HandleType(module.Context.GetSignatureVariable(reader.ReadCompressedInteger(), false)); + case Ecma.SignatureTypeCode.GenericMethodParameter: + return HandleType(module.Context.GetSignatureVariable(reader.ReadCompressedInteger(), true)); + case Ecma.SignatureTypeCode.GenericTypeInstance: + { + var sig = new TypeInstantiationSignature + { + GenericType = HandleType(module, ref reader) + }; + + int count = reader.ReadCompressedInteger(); + for (int i = 0; i < count; i++) + sig.GenericTypeArguments.Add(HandleType(module, ref reader)); + + return new TypeSpecification + { + Signature = sig + }; + } + case Ecma.SignatureTypeCode.TypedReference: + return HandleType(module.Context.GetWellKnownType(Cts.WellKnownType.TypedReference)); + case Ecma.SignatureTypeCode.FunctionPointer: + return new TypeSpecification + { + Signature = new FunctionPointerSignature + { + Signature = HandleMethodSignature(module, ref reader) + } + }; + case Ecma.SignatureTypeCode.OptionalModifier: + return new ModifiedType + { + IsOptional = true, + ModifierType = HandleType(module.GetType(reader.ReadTypeHandle())), + Type = HandleType(module, ref reader), + }; + case Ecma.SignatureTypeCode.RequiredModifier: + return new ModifiedType + { + IsOptional = false, + ModifierType = HandleType(module.GetType(reader.ReadTypeHandle())), + Type = HandleType(module, ref reader), + }; + + default: + throw new BadImageFormatException(); + } + } + private static TypeAttributes GetTypeAttributes(Cts.MetadataType type) { TypeAttributes result; diff --git a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/Internal/Metadata/NativeFormat/Writer/NativeFormatWriterGen.cs b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/Internal/Metadata/NativeFormat/Writer/NativeFormatWriterGen.cs index 1691371d451e5..db1581d939a72 100644 --- a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/Internal/Metadata/NativeFormat/Writer/NativeFormatWriterGen.cs +++ b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/Internal/Metadata/NativeFormat/Writer/NativeFormatWriterGen.cs @@ -2994,7 +2994,8 @@ internal override void Save(NativeWriter writer) Debug.Assert(GenericTypeArguments.TrueForAll(handle => handle == null || handle.HandleType == HandleType.TypeDefinition || handle.HandleType == HandleType.TypeReference || - handle.HandleType == HandleType.TypeSpecification)); + handle.HandleType == HandleType.TypeSpecification || + handle.HandleType == HandleType.ModifiedType)); writer.Write(GenericTypeArguments); } // Save @@ -4692,7 +4693,8 @@ internal override void Save(NativeWriter writer) Debug.Assert(GenericTypeArguments.TrueForAll(handle => handle == null || handle.HandleType == HandleType.TypeDefinition || handle.HandleType == HandleType.TypeReference || - handle.HandleType == HandleType.TypeSpecification)); + handle.HandleType == HandleType.TypeSpecification || + handle.HandleType == HandleType.ModifiedType)); writer.Write(GenericTypeArguments); } // Save diff --git a/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemField.cs b/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemField.cs index a380db86080bc..3e2d09aec92f8 100644 --- a/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemField.cs +++ b/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemField.cs @@ -32,6 +32,8 @@ public TypeRefTypeSystemField(TypeRefTypeSystemType type, string name, TypeDesc public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => _embeddedSignatureData; + public override bool HasEmbeddedSignatureData => _embeddedSignatureData != null; + public override bool IsStatic => throw new NotImplementedException(); public override bool IsInitOnly => throw new NotImplementedException(); diff --git a/src/libraries/Common/tests/System/FunctionPointerCallingConventionTests.cs b/src/libraries/Common/tests/System/FunctionPointerCallingConventionTests.cs index 6150907e43d81..27da31695a697 100644 --- a/src/libraries/Common/tests/System/FunctionPointerCallingConventionTests.cs +++ b/src/libraries/Common/tests/System/FunctionPointerCallingConventionTests.cs @@ -16,7 +16,6 @@ public partial class FunctionPointerCallingConventionTests [InlineData(true)] [InlineData(false)] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void ManagedCallingConvention(bool modified) { Type t = typeof(FunctionPointerHolder).Project(); @@ -38,7 +37,6 @@ public static unsafe void ManagedCallingConvention(bool modified) [InlineData(nameof(FunctionPointerHolder.MethodCallConv_Thiscall))] [InlineData(nameof(FunctionPointerHolder.MethodCallConv_Fastcall))] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void UnmanagedCallConv_Param_Unmodified(string methodName) { Type t = typeof(FunctionPointerHolder).Project(); @@ -57,7 +55,6 @@ public static unsafe void UnmanagedCallConv_Param_Unmodified(string methodName) [InlineData(nameof(FunctionPointerHolder.MethodCallConv_Thiscall), typeof(CallConvThiscall))] [InlineData(nameof(FunctionPointerHolder.MethodCallConv_Fastcall), typeof(CallConvFastcall))] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void UnmanagedCallConv_Param_Modified(string methodName, Type callingConventionRuntime) { Type callingConvention = callingConventionRuntime.Project(); @@ -75,7 +72,6 @@ public static unsafe void UnmanagedCallConv_Param_Modified(string methodName, Ty [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void UnmanagedCallConvs_Return_Unmodified() { Type t = typeof(FunctionPointerHolder).Project(); @@ -96,7 +92,6 @@ public static unsafe void UnmanagedCallConvs_Return_Unmodified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void UnmanagedCallConvs_Return_Modified() { Type t = typeof(FunctionPointerHolder).Project(); @@ -124,7 +119,6 @@ public static unsafe void UnmanagedCallConvs_Return_Modified() [InlineData(nameof(FunctionPointerHolder.MethodCallConv_Thiscall_SuppressGCTransition))] [InlineData(nameof(FunctionPointerHolder.MethodCallConv_Fastcall_SuppressGCTransition))] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void UnmanagedCallConv_PhysicalModifiers_Unmodified(string methodName) { Type t = typeof(FunctionPointerHolder).Project(); @@ -144,7 +138,6 @@ public static unsafe void UnmanagedCallConv_PhysicalModifiers_Unmodified(string [InlineData(nameof(FunctionPointerHolder.MethodCallConv_Thiscall_SuppressGCTransition), typeof(CallConvThiscall))] [InlineData(nameof(FunctionPointerHolder.MethodCallConv_Fastcall_SuppressGCTransition), typeof(CallConvFastcall))] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void UnmanagedCallConv_PhysicalModifiers_Modified(string methodName, Type callingConventionRuntime) { Type suppressGcTransitionType = typeof(CallConvSuppressGCTransition).Project(); @@ -169,7 +162,6 @@ public static unsafe void UnmanagedCallConv_PhysicalModifiers_Modified(string me [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void GenericTypeParameter() { Type holder = typeof(FunctionPointerHolder).Project(); diff --git a/src/libraries/Common/tests/System/FunctionPointerEqualityTests.cs b/src/libraries/Common/tests/System/FunctionPointerEqualityTests.cs index a916b338472fd..47cac32cfa76a 100644 --- a/src/libraries/Common/tests/System/FunctionPointerEqualityTests.cs +++ b/src/libraries/Common/tests/System/FunctionPointerEqualityTests.cs @@ -32,7 +32,6 @@ public static unsafe void DifferentReturnValue() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void ObjectEquals_ModifiedTypes() { Type holder = typeof(FunctionPointerHolder).Project(); @@ -49,7 +48,6 @@ public static unsafe void ObjectEquals_ModifiedTypes() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void ObjectEquals_OneSideModifiedType() { Type holder = typeof(FunctionPointerHolder).Project(); @@ -86,7 +84,6 @@ public static unsafe void CallingConvention_Unmodified(string methodName1, strin [InlineData(nameof(FunctionPointerHolder.MethodCallConv_Cdecl), nameof(FunctionPointerHolder.MethodCallConv_Thiscall))] [InlineData(nameof(FunctionPointerHolder.MethodCallConv_Cdecl), nameof(FunctionPointerHolder.MethodCallConv_Fastcall))] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void CallingConvention_Modified(string methodName1, string methodName2) { Type t = typeof(FunctionPointerHolder).Project(); diff --git a/src/libraries/Common/tests/System/FunctionPointerTests.cs b/src/libraries/Common/tests/System/FunctionPointerTests.cs index 9b06a179dc2a8..66458be8bcad9 100644 --- a/src/libraries/Common/tests/System/FunctionPointerTests.cs +++ b/src/libraries/Common/tests/System/FunctionPointerTests.cs @@ -164,7 +164,6 @@ public static unsafe void FunctionPointerReturn() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void RequiredModifiers() { Type t = typeof(FunctionPointerHolder).Project(); @@ -190,7 +189,6 @@ public static unsafe void RequiredModifiers() "System.Double(System.String, System.Boolean*&, System.Tests.Types.FunctionPointerTests+FunctionPointerHolder+MyClass, System.Tests.Types.FunctionPointerTests+FunctionPointerHolder+MyStruct&)", "String", "Boolean*&", "MyClass", "MyStruct&")] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void MethodInfo( string methodName, string methodToStringPostfix, @@ -219,7 +217,6 @@ public static unsafe void MethodInfo( [InlineData(nameof(FunctionPointerHolder.Prop_Int), "System.Int32()")] [InlineData(nameof(FunctionPointerHolder.Prop_MyClass), "System.Tests.Types.FunctionPointerTests+FunctionPointerHolder+MyClass()")] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Property(string name, string expectedToString) { Type t = typeof(FunctionPointerHolder).Project(); @@ -239,7 +236,6 @@ public static unsafe void Property(string name, string expectedToString) [InlineData(nameof(FunctionPointerHolder.Field_Int), "System.Int32()")] [InlineData(nameof(FunctionPointerHolder.Field_MyClass), "System.Tests.Types.FunctionPointerTests+FunctionPointerHolder+MyClass()")] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Field(string name, string expectedToString) { Type t = typeof(FunctionPointerHolder).Project(); diff --git a/src/libraries/Common/tests/System/ModifiedTypeTests.cs b/src/libraries/Common/tests/System/ModifiedTypeTests.cs index 86909691ac007..c429806989b65 100644 --- a/src/libraries/Common/tests/System/ModifiedTypeTests.cs +++ b/src/libraries/Common/tests/System/ModifiedTypeTests.cs @@ -18,7 +18,6 @@ public partial class ModifiedTypeTests [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void TypeMembers() { FieldInfo fi = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._volatileInt), Bindings); @@ -125,7 +124,10 @@ void UnmodifiedTypeMembers(Type t) Assert.Null(t.DeclaringType); Assert.Null(t.ReflectedType); Assert.Null(t.TypeInitializer); - Assert.True(t.MetadataToken != 0); + + if (PlatformDetection.IsMetadataTokenSupported) + Assert.True(t.MetadataToken != 0); + Assert.False(t.IsNested); Assert.True(t.IsVisible); } @@ -152,7 +154,6 @@ void ModifiedTypeMembers(Type t) [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Fields_Modified() { Type volatileInt = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._volatileInt), Bindings).GetModifiedFieldType(); @@ -191,7 +192,6 @@ void Verify(Type type) [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Fields_Generic_Unmodified() { Type arrayGenericFcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._arrayGenericFcnPtr), Bindings).FieldType; @@ -213,7 +213,6 @@ public static unsafe void Fields_Generic_Unmodified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Fields_Generic_Modified() { Type arrayGenericFcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._arrayGenericFcnPtr), Bindings).GetModifiedFieldType(); @@ -237,7 +236,6 @@ public static unsafe void Fields_Generic_Modified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Methods_OpenGeneric_Unmodified() { MethodInfo mi = typeof(ModifiedTypeHolder).Project().GetMethod(nameof(ModifiedTypeHolder.M_ArrayOpenGenericFcnPtr), Bindings); @@ -261,7 +259,6 @@ public static unsafe void Methods_OpenGeneric_Unmodified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Methods_OpenGeneric_Modified() { MethodInfo mi = typeof(ModifiedTypeHolder).Project().GetMethod(nameof(ModifiedTypeHolder.M_ArrayOpenGenericFcnPtr), Bindings); @@ -287,7 +284,6 @@ public static unsafe void Methods_OpenGeneric_Modified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Fields_Unmodified() { Type volatileInt = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._volatileInt), Bindings).FieldType; @@ -320,7 +316,6 @@ void Verify(Type type) [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Fields_Parameterized_Basic() { Type ptr_ptr_int = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._ptr_ptr_int), Bindings).GetModifiedFieldType(); @@ -342,7 +337,6 @@ void Verify(Type type) [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Fields_Parameterized_FcnPtr() { Type ptr_fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._ptr_fcnPtr), Bindings).GetModifiedFieldType(); @@ -374,7 +368,6 @@ void Verify(Type type) [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Fields_VerifyIdempotency() { // Call these again to ensure any backing caching strategy works. @@ -386,7 +379,6 @@ public static unsafe void Fields_VerifyIdempotency() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void MethodParameters() { ParameterInfo[] parameters = typeof(ModifiedTypeHolder).Project().GetMethod(nameof(ModifiedTypeHolder.M_P0IntOut), Bindings).GetParameters(); @@ -411,7 +403,6 @@ public static unsafe void MethodParameters() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void ConstructorParameters_Unmodified() { ParameterInfo[] parameters = typeof(ModifiedTypeHolder).Project().GetConstructors()[0].GetParameters(); @@ -425,7 +416,6 @@ public static unsafe void ConstructorParameters_Unmodified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void ConstructorParameters_Modified() { ParameterInfo[] parameters = typeof(ModifiedTypeHolder).Project().GetConstructors()[0].GetParameters(); @@ -440,7 +430,6 @@ public static unsafe void ConstructorParameters_Modified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void FunctionPointerParameters_fcnPtrP0Out_Unmodified() { Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtrP0Out), Bindings).GetModifiedFieldType(); @@ -452,7 +441,6 @@ public static unsafe void FunctionPointerParameters_fcnPtrP0Out_Unmodified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void FunctionPointerParameters_fcnPtrP0Out_Modified() { Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtrP0Out), Bindings).FieldType; @@ -464,7 +452,6 @@ public static unsafe void FunctionPointerParameters_fcnPtrP0Out_Modified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Out_Unmodified() { Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtr_fcnPtrP0Out), Bindings).FieldType; @@ -478,7 +465,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Out_Unmodifie [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Out_Modified() { // Modified @@ -494,7 +480,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Out_Modified( [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Ref_Unmodified() { Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtr_fcnPtrP0Ref), Bindings).FieldType; @@ -509,7 +494,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Ref_Unmodifie [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Ref_Modified() { Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtr_fcnPtrP0Ref), Bindings).GetModifiedFieldType(); @@ -524,7 +508,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrP0Ref_Modified( [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrRetP0Ref_Unmodified() { Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtr_fcnPtrRetP0Out), Bindings).FieldType; @@ -536,7 +519,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrRetP0Ref_Unmodi [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrRetP0Ref_Modified() { Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtr_fcnPtrRetP0Out), Bindings).GetModifiedFieldType(); @@ -549,7 +531,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_fcnPtrRetP0Ref_Modifi [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void FunctionPointerParameters_fcnPtr_complex_Unmodified() { Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtr_complex), Bindings).FieldType; @@ -574,7 +555,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_complex_Unmodified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void FunctionPointerParameters_fcnPtr_complex_Modified() { Type fcnPtr = typeof(ModifiedTypeHolder).Project().GetField(nameof(ModifiedTypeHolder._fcnPtr_complex), Bindings).GetModifiedFieldType(); @@ -600,7 +580,6 @@ public static unsafe void FunctionPointerParameters_fcnPtr_complex_Modified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Property_FcnPtr_Complex_Unmodified() { Type mt = typeof(ModifiedTypeHolder).Project().GetProperty(nameof(ModifiedTypeHolder.Property_FcnPtr_Complex), Bindings).PropertyType; @@ -618,7 +597,6 @@ public static unsafe void Property_FcnPtr_Complex_Unmodified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void Property_FcnPtr_Complex_Modified() { Type mt = typeof(ModifiedTypeHolder).Project().GetProperty(nameof(ModifiedTypeHolder.Property_FcnPtr_Complex), Bindings).GetModifiedPropertyType(); @@ -637,7 +615,6 @@ public static unsafe void Property_FcnPtr_Complex_Modified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void MethodWithGenericParameter_Unmodified() { MethodInfo mi = typeof(GenericWithModifiers).Project().GetMethod(nameof(GenericWithModifiers.MethodWithGenericParameter), Bindings); @@ -659,7 +636,6 @@ public static unsafe void MethodWithGenericParameter_Unmodified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void MethodWithGenericParameter_Modified() { MethodInfo mi = typeof(GenericWithModifiers).Project().GetMethod(nameof(GenericWithModifiers.MethodWithGenericParameter), Bindings); @@ -683,7 +659,6 @@ public static unsafe void MethodWithGenericParameter_Modified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void GenericMethod_Unmodified() { MethodInfo mi = typeof(GenericWithModifiers).Project().GetMethod(nameof(GenericWithModifiers.GenericMethod), Bindings); @@ -697,7 +672,6 @@ public static unsafe void GenericMethod_Unmodified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static unsafe void GenericMethod_Modified() { MethodInfo mi = typeof(GenericWithModifiers).Project().GetMethod(nameof(GenericWithModifiers.GenericMethod), Bindings); @@ -711,7 +685,6 @@ public static unsafe void GenericMethod_Modified() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static void ParameterConstraints1() { MethodInfo mi = typeof(ModifiedTypeHolder).Project().GetMethod(nameof(ModifiedTypeHolder.M_GenericWithParameterConstraint1), Bindings); @@ -737,7 +710,6 @@ public static void ParameterConstraints1() [Fact] [ActiveIssue("https://github.com/dotnet/runtime/issues/71095", TestRuntimes.Mono)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/71883", typeof(PlatformDetection), nameof(PlatformDetection.IsNativeAot))] public static void ParameterConstraints2() { MethodInfo mi = typeof(ModifiedTypeHolder).Project().GetMethod(nameof(ModifiedTypeHolder.M_GenericWithParameterConstraint2), Bindings); diff --git a/src/libraries/System.Runtime/tests/default.rd.xml b/src/libraries/System.Runtime/tests/default.rd.xml index b78da0bb4022b..c594df1579d56 100644 --- a/src/libraries/System.Runtime/tests/default.rd.xml +++ b/src/libraries/System.Runtime/tests/default.rd.xml @@ -251,6 +251,12 @@ + + + + + + diff --git a/src/tests/issues.targets b/src/tests/issues.targets index d4e21b611155a..879689f9a4d7a 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -1249,12 +1249,6 @@ https://github.com/dotnet/runtimelab/issues/154 - - https://github.com/dotnet/runtime/issues/71883 - - - https://github.com/dotnet/runtime/issues/71883 - Won't fix https://github.com/dotnet/corert/issues/2396 @@ -1321,9 +1315,6 @@ https://github.com/dotnet/runtimelab/issues/155: Assembly.Load - - https://github.com/dotnet/runtime/issues/71883 - https://github.com/dotnet/runtimelab/issues/155: Reflection emit From 803ce9ec91d9cb1e9660ab81be1800dd3068c83b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Fri, 28 Apr 2023 17:27:30 +0900 Subject: [PATCH 2/4] More IL corner cases --- .../Internal/Metadata/NativeFormat/Generator/SchemaDef.cs | 2 +- .../Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs | 2 +- .../Metadata/NativeFormat/Writer/NativeFormatWriterGen.cs | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/SchemaDef.cs b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/SchemaDef.cs index d9a5122209d85..dc160a802a495 100644 --- a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/SchemaDef.cs +++ b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/SchemaDef.cs @@ -695,7 +695,7 @@ from primitiveType in PrimitiveTypes select new RecordDef( name: "ByReferenceSignature", members: new MemberDef[] { - new MemberDef("Type", TypeDefOrRefOrSpec, MemberDefFlags.RecordRef), + new MemberDef("Type", TypeDefOrRefOrSpecOrMod, MemberDefFlags.RecordRef), } ), new RecordDef( diff --git a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs index 3a248bcb226fa..7753561a6eab9 100644 --- a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs +++ b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs @@ -182,7 +182,7 @@ public ByReferenceSignatureHandle Handle return _handle; } } // Handle - /// One of: TypeDefinition, TypeReference, TypeSpecification + /// One of: TypeDefinition, TypeReference, TypeSpecification, ModifiedType public Handle Type { diff --git a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/Internal/Metadata/NativeFormat/Writer/NativeFormatWriterGen.cs b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/Internal/Metadata/NativeFormat/Writer/NativeFormatWriterGen.cs index db1581d939a72..9ef7f2c603428 100644 --- a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/Internal/Metadata/NativeFormat/Writer/NativeFormatWriterGen.cs +++ b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/Internal/Metadata/NativeFormat/Writer/NativeFormatWriterGen.cs @@ -151,7 +151,8 @@ internal override void Save(NativeWriter writer) Debug.Assert(Type == null || Type.HandleType == HandleType.TypeDefinition || Type.HandleType == HandleType.TypeReference || - Type.HandleType == HandleType.TypeSpecification); + Type.HandleType == HandleType.TypeSpecification || + Type.HandleType == HandleType.ModifiedType); writer.Write(Type); } // Save From 2f52156f17664ecd2d5b5f61401d29efb99b5d21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Mon, 1 May 2023 11:26:14 +0900 Subject: [PATCH 3/4] Support modopts in ArraySignature --- .../Internal/Metadata/NativeFormat/Generator/SchemaDef.cs | 2 +- .../Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs | 2 +- .../Metadata/NativeFormat/Writer/NativeFormatWriterGen.cs | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/SchemaDef.cs b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/SchemaDef.cs index dc160a802a495..981fb442bece9 100644 --- a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/SchemaDef.cs +++ b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/Generator/SchemaDef.cs @@ -686,7 +686,7 @@ from primitiveType in PrimitiveTypes select new RecordDef( name: "ArraySignature", members: new MemberDef[] { - new MemberDef("ElementType", TypeDefOrRefOrSpec, MemberDefFlags.RecordRef), + new MemberDef("ElementType", TypeDefOrRefOrSpecOrMod, MemberDefFlags.RecordRef), new MemberDef("Rank", "int"), new MemberDef("Sizes", "Int32", MemberDefFlags.Array), new MemberDef("LowerBounds", "Int32", MemberDefFlags.Array), diff --git a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs index 7753561a6eab9..d21f809903d5c 100644 --- a/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs +++ b/src/coreclr/tools/Common/Internal/Metadata/NativeFormat/NativeFormatReaderGen.cs @@ -37,7 +37,7 @@ public ArraySignatureHandle Handle return _handle; } } // Handle - /// One of: TypeDefinition, TypeReference, TypeSpecification + /// One of: TypeDefinition, TypeReference, TypeSpecification, ModifiedType public Handle ElementType { diff --git a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/Internal/Metadata/NativeFormat/Writer/NativeFormatWriterGen.cs b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/Internal/Metadata/NativeFormat/Writer/NativeFormatWriterGen.cs index 9ef7f2c603428..0e61942db03ca 100644 --- a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/Internal/Metadata/NativeFormat/Writer/NativeFormatWriterGen.cs +++ b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/Internal/Metadata/NativeFormat/Writer/NativeFormatWriterGen.cs @@ -77,7 +77,8 @@ internal override void Save(NativeWriter writer) Debug.Assert(ElementType == null || ElementType.HandleType == HandleType.TypeDefinition || ElementType.HandleType == HandleType.TypeReference || - ElementType.HandleType == HandleType.TypeSpecification); + ElementType.HandleType == HandleType.TypeSpecification || + ElementType.HandleType == HandleType.ModifiedType); writer.Write(ElementType); writer.Write(Rank); writer.Write(Sizes); From 5390a2219f54f3b24727a9fad0f7fe5a7f91ca6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Mon, 1 May 2023 11:40:36 +0900 Subject: [PATCH 4/4] FB --- .../TypeSystem/Ecma/EcmaSignatureParser.cs | 17 ++++------------- .../ILCompiler/Metadata/Transform.Field.cs | 4 ++++ 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs index cb80a557687ab..aa881697835e2 100644 --- a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs +++ b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs @@ -421,19 +421,10 @@ private MethodSignature ParseMethodSignatureImpl(bool skipEmbeddedSignatureData) public PropertySignature ParsePropertySignature() { - try - { - _indexStack = new Stack(); - _indexStack.Push(0); - _embeddedSignatureDataList = new List(); - return ParsePropertySignatureInternal(); - } - finally - { - _indexStack = null; - _embeddedSignatureDataList = null; - } - + _indexStack = new Stack(); + _indexStack.Push(0); + _embeddedSignatureDataList = new List(); + return ParsePropertySignatureInternal(); } private PropertySignature ParsePropertySignatureInternal() diff --git a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Field.cs b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Field.cs index ebb6a9e0be582..9c04f3ca3c214 100644 --- a/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Field.cs +++ b/src/coreclr/tools/aot/ILCompiler.MetadataTransform/ILCompiler/Metadata/Transform.Field.cs @@ -78,6 +78,10 @@ private void InitializeFieldDefinition(Cts.FieldDesc entity, Field record) if (offset >= 0) record.Offset = (uint)offset; } + else + { + throw new NotImplementedException(); + } } private MetadataRecord HandleFieldSignature(Cts.Ecma.EcmaModule module, Ecma.BlobHandle sigBlob)