From: Andrew Au Date: Tue, 5 Nov 2019 16:25:32 +0000 (-0800) Subject: Handling generic attribute in AttributePresenceFilterNode (dotnet/coreclr#27667) X-Git-Tag: submit/tizen/20210909.063632~11030^2~114 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3a0b32ba8ea21922d52ac4a6286c217ed7188d03;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Handling generic attribute in AttributePresenceFilterNode (dotnet/coreclr#27667) Commit migrated from https://github.com/dotnet/coreclr/commit/a11f07461ec65dd7d4bc133196d26ad786cb2ce1 --- diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/AttributePresenceFilterNode.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/AttributePresenceFilterNode.cs index 9f97896380c..100565eb2ec 100644 --- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/AttributePresenceFilterNode.cs +++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/AttributePresenceFilterNode.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Diagnostics; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; @@ -101,6 +102,118 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun return customAttributeEntries; } + /** + * This class is used to extract the first type handle in a signature. + * + * In the case that a custom attribute's constructor is a MemberReference, + * and its parent is a TypeSpec, we have to parse the signature, but we do + * not want to actually resolve the types. So we used this dummy signature + * type provider to extract the first type handle. + */ + private class FirstTypeHandleExtractor : ISignatureTypeProvider + { + private EntityHandle _firstTypeHandle; + + public EntityHandle FirstTypeHandle => _firstTypeHandle; + + public DummyType GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind) + { + if (_firstTypeHandle.IsNil) + { + _firstTypeHandle = handle; + } + return new DummyType(); + } + + public DummyType GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind) + { + if (_firstTypeHandle.IsNil) + { + _firstTypeHandle = handle; + } + return DummyType.Instance; + } + + #region Uninteresting dummy methods + + // These methods are required by the interface, but it is otherwise uninteresting for our purpose here + + public DummyType GetArrayType(DummyType elementType, ArrayShape shape) + { + return DummyType.Instance; + } + + public DummyType GetByReferenceType(DummyType elementType) + { + return DummyType.Instance; + } + + public DummyType GetFunctionPointerType(MethodSignature signature) + { + return DummyType.Instance; + } + + public DummyType GetGenericInstantiation(DummyType genericType, ImmutableArray typeArguments) + { + return DummyType.Instance; + } + + public DummyType GetGenericMethodParameter(DummyGenericContext genericContext, int index) + { + return DummyType.Instance; + } + + public DummyType GetGenericTypeParameter(DummyGenericContext genericContext, int index) + { + return DummyType.Instance; + } + + public DummyType GetModifiedType(DummyType modifier, DummyType unmodifiedType, bool isRequired) + { + return DummyType.Instance; + } + + public DummyType GetPinnedType(DummyType elementType) + { + return DummyType.Instance; + } + + public DummyType GetPointerType(DummyType elementType) + { + return DummyType.Instance; + } + + public DummyType GetPrimitiveType(PrimitiveTypeCode typeCode) + { + return new DummyType(); + } + + public DummyType GetSZArrayType(DummyType elementType) + { + return DummyType.Instance; + } + + public DummyType GetTypeFromSpecification(MetadataReader reader, DummyGenericContext genericContext, TypeSpecificationHandle handle, byte rawTypeKind) + { + return DummyType.Instance; + } + + #endregion + } + + #region Uninteresting dummy types + + private class DummyType + { + public static DummyType Instance = new DummyType(); + } + + private class DummyGenericContext + { + } + + #endregion + private void ReadCustomAttributeTypeNameWithoutResolving(EntityHandle customAttributeConstructorHandle, out string customAttributeTypeNamespace, out string customAttributeTypeName) { /** @@ -115,26 +228,40 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun if (customAttributeConstructorHandle.Kind == HandleKind.MethodDefinition) { MethodDefinitionHandle customAttributeConstructorDefinitionHandle = (MethodDefinitionHandle)customAttributeConstructorHandle; - MethodDefinition customAttributeConstructorDefinition = _module.MetadataReader.GetMethodDefinition(customAttributeConstructorDefinitionHandle); + MethodDefinition customAttributeConstructorDefinition = _module.MetadataReader.GetMethodDefinition(customAttributeConstructorDefinitionHandle); TypeDefinitionHandle customAttributeConstructorTypeDefinitionHandle = customAttributeConstructorDefinition.GetDeclaringType(); - TypeDefinition customAttributeConstructorTypeDefinition = _module.MetadataReader.GetTypeDefinition(customAttributeConstructorTypeDefinitionHandle); - StringHandle customAttributeConstructorTypeNamespaceHandle = customAttributeConstructorTypeDefinition.Namespace; - StringHandle customAttributeConstructorTypeNameHandle = customAttributeConstructorTypeDefinition.Name; - customAttributeTypeNamespace = _module.MetadataReader.GetString(customAttributeConstructorTypeNamespaceHandle); - customAttributeTypeName = _module.MetadataReader.GetString(customAttributeConstructorTypeNameHandle); + GetTypeNameFromTypeDefinitionHandle(customAttributeConstructorTypeDefinitionHandle, out customAttributeTypeNamespace, out customAttributeTypeName); } else if (customAttributeConstructorHandle.Kind == HandleKind.MemberReference) { MemberReferenceHandle customAttributeConstructorReferenceHandle = (MemberReferenceHandle)customAttributeConstructorHandle; - MemberReference customAttributeConstructorReference = _module.MetadataReader.GetMemberReference(customAttributeConstructorReferenceHandle); + MemberReference customAttributeConstructorReference = _module.MetadataReader.GetMemberReference(customAttributeConstructorReferenceHandle); EntityHandle customAttributeConstructorReferenceParentHandle = customAttributeConstructorReference.Parent; - Debug.Assert(customAttributeConstructorReferenceParentHandle.Kind == HandleKind.TypeReference); - TypeReferenceHandle customAttributeConstructorTypeReferenceHandle = (TypeReferenceHandle)customAttributeConstructorReferenceParentHandle; - TypeReference customAttributeConstructorTypeReference = _module.MetadataReader.GetTypeReference(customAttributeConstructorTypeReferenceHandle); - StringHandle customAttributeConstructorTypeNamespaceHandle = customAttributeConstructorTypeReference.Namespace; - StringHandle customAttributeConstructorTypeNameHandle = customAttributeConstructorTypeReference.Name; - customAttributeTypeNamespace = _module.MetadataReader.GetString(customAttributeConstructorTypeNamespaceHandle); - customAttributeTypeName = _module.MetadataReader.GetString(customAttributeConstructorTypeNameHandle); + if (customAttributeConstructorReferenceParentHandle.Kind == HandleKind.TypeReference) + { + TypeReferenceHandle customAttributeConstructorTypeReferenceHandle = (TypeReferenceHandle)customAttributeConstructorReferenceParentHandle; + GetTypeNameFromTypeReferenceHandle(customAttributeConstructorTypeReferenceHandle, out customAttributeTypeNamespace, out customAttributeTypeName); + } + else + { + Debug.Assert(customAttributeConstructorReferenceParentHandle.Kind == HandleKind.TypeSpecification); + TypeSpecificationHandle customAttributeConstructorTypeSpecificationHandle = (TypeSpecificationHandle)customAttributeConstructorReferenceParentHandle; + TypeSpecification customAttributeConstructorTypeSpecification = _module.MetadataReader.GetTypeSpecification(customAttributeConstructorTypeSpecificationHandle); + FirstTypeHandleExtractor fakeSignatureTypeProvider = new FirstTypeHandleExtractor(); + customAttributeConstructorTypeSpecification.DecodeSignature(fakeSignatureTypeProvider, new DummyGenericContext()); + EntityHandle firstTypeHandle = fakeSignatureTypeProvider.FirstTypeHandle; + if (firstTypeHandle.Kind == HandleKind.TypeDefinition) + { + TypeDefinitionHandle customAttributeConstructorTypeDefinitionHandle = (TypeDefinitionHandle)firstTypeHandle; + GetTypeNameFromTypeDefinitionHandle(customAttributeConstructorTypeDefinitionHandle, out customAttributeTypeNamespace, out customAttributeTypeName); + } + else + { + Debug.Assert(firstTypeHandle.Kind == HandleKind.TypeReference); + TypeReferenceHandle customAttributeConstructorTypeReferenceHandle = (TypeReferenceHandle)firstTypeHandle; + GetTypeNameFromTypeReferenceHandle(customAttributeConstructorTypeReferenceHandle, out customAttributeTypeNamespace, out customAttributeTypeName); + } + } } else { @@ -144,6 +271,24 @@ namespace ILCompiler.DependencyAnalysis.ReadyToRun } } + private void GetTypeNameFromTypeReferenceHandle(TypeReferenceHandle typeReferenceHandle, out string typeNamespace, out string typeName) + { + TypeReference typeReference = _module.MetadataReader.GetTypeReference(typeReferenceHandle); + StringHandle typeNamespaceHandle = typeReference.Namespace; + StringHandle typeNameHandle = typeReference.Name; + typeNamespace = _module.MetadataReader.GetString(typeNamespaceHandle); + typeName = _module.MetadataReader.GetString(typeNameHandle); + } + + private void GetTypeNameFromTypeDefinitionHandle(TypeDefinitionHandle typeDefinitionHandle, out string typeNamespace, out string typeName) + { + TypeDefinition typeDefinition = _module.MetadataReader.GetTypeDefinition(typeDefinitionHandle); + StringHandle typeNamespaceHandle = typeDefinition.Namespace; + StringHandle typeNameHandle = typeDefinition.Name; + typeNamespace = _module.MetadataReader.GetString(typeNamespaceHandle); + typeName = _module.MetadataReader.GetString(typeNameHandle); + } + // Algorithm "xor128" from p. 5 of Marsaglia, "Xorshift RNGs" private uint XorShift128(uint[] state) {