From 99f716bd12779051ea973edaee73250e0083c1ea Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Thu, 20 Apr 2023 08:40:24 -0700 Subject: [PATCH 1/4] Support non core types for signature and other type references --- .../System.Reflection.Emit.sln | 42 ------- .../src/Resources/Strings.resx | 3 + .../Reflection/Emit/AssemblyBuilderImpl.cs | 20 ++-- .../System/Reflection/Emit/MetadataHelper.cs | 2 +- .../Reflection/Emit/MethodBuilderImpl.cs | 2 +- .../Reflection/Emit/ModuleBuilderImpl.cs | 77 ++++++++---- .../System/Reflection/Emit/SignatureHelper.cs | 112 ++++++++++-------- .../System/Reflection/Emit/TypeBuilderImpl.cs | 2 +- .../AssemblySaveTestsWithVariousTypes.cs | 38 +++--- .../AssemblyTools.cs | 18 ++- 10 files changed, 165 insertions(+), 151 deletions(-) diff --git a/src/libraries/System.Reflection.Emit/System.Reflection.Emit.sln b/src/libraries/System.Reflection.Emit/System.Reflection.Emit.sln index d71e15aa37b80..b4fa6af73eaec 100644 --- a/src/libraries/System.Reflection.Emit/System.Reflection.Emit.sln +++ b/src/libraries/System.Reflection.Emit/System.Reflection.Emit.sln @@ -43,8 +43,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Reflection.Metadata" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime", "..\System.Runtime\src\System.Runtime.csproj", "{BB96A2BA-44E9-43FA-91B1-CCEE212C6A8A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.CodeDom", "..\System.CodeDom\src\System.CodeDom.csproj", "{D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Reflection.MetadataLoadContext", "..\System.Reflection.MetadataLoadContext\src\System.Reflection.MetadataLoadContext.csproj", "{9F3970FF-F138-4F23-A2F8-2387858E723D}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Collections.Immutable", "..\System.Collections.Immutable\src\System.Collections.Immutable.csproj", "{C2FF5BC7-825E-437E-92C3-F505EB6D1D40}" @@ -53,8 +51,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Collections.Immutabl EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Reflection.MetadataLoadContext", "..\System.Reflection.MetadataLoadContext\ref\System.Reflection.MetadataLoadContext.csproj", "{B2FAA0B4-2976-4742-B186-9C4928BCF9AF}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.CodeDom", "..\System.CodeDom\ref\System.CodeDom.csproj", "{501C1EA6-F7DB-4D3E-A212-F06689A831CD}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Reflection.Metadata", "..\System.Reflection.Metadata\ref\System.Reflection.Metadata.csproj", "{E468274C-8F7E-49FC-BC2A-82C8B9E5B026}" EndProject Global @@ -319,24 +315,6 @@ Global {BB96A2BA-44E9-43FA-91B1-CCEE212C6A8A}.Release|x64.Build.0 = Release|Any CPU {BB96A2BA-44E9-43FA-91B1-CCEE212C6A8A}.Release|x86.ActiveCfg = Release|Any CPU {BB96A2BA-44E9-43FA-91B1-CCEE212C6A8A}.Release|x86.Build.0 = Release|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Checked|Any CPU.Build.0 = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Checked|x64.ActiveCfg = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Checked|x64.Build.0 = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Checked|x86.ActiveCfg = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Checked|x86.Build.0 = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Debug|x64.ActiveCfg = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Debug|x64.Build.0 = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Debug|x86.ActiveCfg = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Debug|x86.Build.0 = Debug|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Release|Any CPU.Build.0 = Release|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Release|x64.ActiveCfg = Release|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Release|x64.Build.0 = Release|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Release|x86.ActiveCfg = Release|Any CPU - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E}.Release|x86.Build.0 = Release|Any CPU {9F3970FF-F138-4F23-A2F8-2387858E723D}.Checked|Any CPU.ActiveCfg = Debug|Any CPU {9F3970FF-F138-4F23-A2F8-2387858E723D}.Checked|Any CPU.Build.0 = Debug|Any CPU {9F3970FF-F138-4F23-A2F8-2387858E723D}.Checked|x64.ActiveCfg = Debug|Any CPU @@ -409,24 +387,6 @@ Global {B2FAA0B4-2976-4742-B186-9C4928BCF9AF}.Release|x64.Build.0 = Release|Any CPU {B2FAA0B4-2976-4742-B186-9C4928BCF9AF}.Release|x86.ActiveCfg = Release|Any CPU {B2FAA0B4-2976-4742-B186-9C4928BCF9AF}.Release|x86.Build.0 = Release|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Checked|Any CPU.ActiveCfg = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Checked|Any CPU.Build.0 = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Checked|x64.ActiveCfg = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Checked|x64.Build.0 = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Checked|x86.ActiveCfg = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Checked|x86.Build.0 = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Debug|x64.ActiveCfg = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Debug|x64.Build.0 = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Debug|x86.ActiveCfg = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Debug|x86.Build.0 = Debug|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Release|Any CPU.Build.0 = Release|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Release|x64.ActiveCfg = Release|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Release|x64.Build.0 = Release|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Release|x86.ActiveCfg = Release|Any CPU - {501C1EA6-F7DB-4D3E-A212-F06689A831CD}.Release|x86.Build.0 = Release|Any CPU {E468274C-8F7E-49FC-BC2A-82C8B9E5B026}.Checked|Any CPU.ActiveCfg = Debug|Any CPU {E468274C-8F7E-49FC-BC2A-82C8B9E5B026}.Checked|Any CPU.Build.0 = Debug|Any CPU {E468274C-8F7E-49FC-BC2A-82C8B9E5B026}.Checked|x64.ActiveCfg = Debug|Any CPU @@ -466,12 +426,10 @@ Global {613C42F2-847A-42B3-9F5E-F5A670356BF7} = {C36D185D-9B3D-42E5-985F-E21B3BAF3B6D} {F33093A8-FF33-4F95-B256-F2AB712C956A} = {74F4AB97-3DBC-48FB-A2EA-2B4141749800} {BB96A2BA-44E9-43FA-91B1-CCEE212C6A8A} = {74F4AB97-3DBC-48FB-A2EA-2B4141749800} - {D13E80A9-A4E9-4399-A2C2-3008DA1C3B4E} = {2FC35C2F-76DB-4D84-B421-9700BEA4D161} {9F3970FF-F138-4F23-A2F8-2387858E723D} = {2FC35C2F-76DB-4D84-B421-9700BEA4D161} {C2FF5BC7-825E-437E-92C3-F505EB6D1D40} = {74F4AB97-3DBC-48FB-A2EA-2B4141749800} {DE04D45B-7E15-409D-A176-985D814A6AEB} = {C36D185D-9B3D-42E5-985F-E21B3BAF3B6D} {B2FAA0B4-2976-4742-B186-9C4928BCF9AF} = {C36D185D-9B3D-42E5-985F-E21B3BAF3B6D} - {501C1EA6-F7DB-4D3E-A212-F06689A831CD} = {C36D185D-9B3D-42E5-985F-E21B3BAF3B6D} {E468274C-8F7E-49FC-BC2A-82C8B9E5B026} = {C36D185D-9B3D-42E5-985F-E21B3BAF3B6D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/src/libraries/System.Reflection.Emit/src/Resources/Strings.resx b/src/libraries/System.Reflection.Emit/src/Resources/Strings.resx index b3ad859f05253..3086fcc6a3c43 100644 --- a/src/libraries/System.Reflection.Emit/src/Resources/Strings.resx +++ b/src/libraries/System.Reflection.Emit/src/Resources/Strings.resx @@ -144,4 +144,7 @@ Invalid name. + + Emitted handle is not valid. + \ No newline at end of file diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/AssemblyBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/AssemblyBuilderImpl.cs index ea7ec68d9d7e1..9ff5de8bc82c1 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/AssemblyBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/AssemblyBuilderImpl.cs @@ -11,10 +11,11 @@ namespace System.Reflection.Emit { internal sealed class AssemblyBuilderImpl : AssemblyBuilder { - private bool _previouslySaved; private readonly AssemblyName _assemblyName; private readonly Assembly _coreAssembly; + private readonly MetadataBuilder _metadataBuilder; private ModuleBuilderImpl? _module; + private bool _previouslySaved; internal AssemblyBuilderImpl(AssemblyName name, Assembly coreAssembly, IEnumerable? assemblyAttributes) { @@ -29,6 +30,7 @@ internal AssemblyBuilderImpl(AssemblyName name, Assembly coreAssembly, IEnumerab _assemblyName = name; _coreAssembly = coreAssembly; + _metadataBuilder = new MetadataBuilder(); if (assemblyAttributes != null) { @@ -75,13 +77,11 @@ internal void Save(Stream stream) } // Add assembly metadata - var metadata = new MetadataBuilder(); - - metadata.AddAssembly( - metadata.GetOrAddString(value: _assemblyName.Name!), + _metadataBuilder.AddAssembly( + _metadataBuilder.GetOrAddString(value: _assemblyName.Name!), version: _assemblyName.Version ?? new Version(0, 0, 0, 0), - culture: _assemblyName.CultureName == null ? default : metadata.GetOrAddString(value: _assemblyName.CultureName), - publicKey: _assemblyName.GetPublicKey() is byte[] publicKey ? metadata.GetOrAddBlob(value: publicKey) : default, + culture: _assemblyName.CultureName == null ? default : _metadataBuilder.GetOrAddString(value: _assemblyName.CultureName), + publicKey: _assemblyName.GetPublicKey() is byte[] publicKey ? _metadataBuilder.GetOrAddBlob(value: publicKey) : default, flags: AddContentType((AssemblyFlags)_assemblyName.Flags, _assemblyName.ContentType), #pragma warning disable SYSLIB0037 // Type or member is obsolete hashAlgorithm: (AssemblyHashAlgorithm)_assemblyName.HashAlgorithm @@ -89,10 +89,10 @@ internal void Save(Stream stream) ); // Add module's metadata - _module.AppendMetadata(metadata); + _module.AppendMetadata(); var ilBuilder = new BlobBuilder(); - WritePEImage(stream, metadata, ilBuilder); + WritePEImage(stream, _metadataBuilder, ilBuilder); _previouslySaved = true; } @@ -114,7 +114,7 @@ protected override ModuleBuilder DefineDynamicModuleCore(string name) throw new InvalidOperationException(SR.InvalidOperation_NoMultiModuleAssembly); } - _module = new ModuleBuilderImpl(name, _coreAssembly); + _module = new ModuleBuilderImpl(name, _coreAssembly, _metadataBuilder); return _module; } diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MetadataHelper.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MetadataHelper.cs index 869c5ef3f1113..a18148847aac8 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MetadataHelper.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MetadataHelper.cs @@ -9,7 +9,7 @@ namespace System.Reflection.Emit // This static helper class adds common entities to a MetadataBuilder. internal static class MetadataHelper { - internal static AssemblyReferenceHandle AddAssemblyReference(Assembly assembly, MetadataBuilder metadata) + internal static AssemblyReferenceHandle AddAssemblyReference(MetadataBuilder metadata, Assembly assembly) { AssemblyName assemblyName = assembly.GetName(); diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MethodBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MethodBuilderImpl.cs index c63e4c26e5d47..1262ae599fc39 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MethodBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MethodBuilderImpl.cs @@ -38,7 +38,7 @@ internal MethodBuilderImpl(string name, MethodAttributes attributes, CallingConv } internal BlobBuilder GetMethodSignatureBlob() => - MetadataSignatureHelper.MethodSignatureEncoder(_module, _parameterTypes, ReturnType, IsStatic); + MetadataSignatureHelper.MethodSignatureEncoder(_module, _parameterTypes, ReturnType, !IsStatic); protected override bool InitLocalsCore { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } protected override GenericTypeParameterBuilder[] DefineGenericParametersCore(params string[] names) => throw new NotImplementedException(); diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs index 07dde6a0746ee..f75f966cdffe2 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs @@ -13,20 +13,23 @@ internal sealed class ModuleBuilderImpl : ModuleBuilder { private readonly Assembly _coreAssembly; private readonly string _name; - private Type?[]? _coreTypes; - private readonly Dictionary _assemblyRefStore = new(); - private readonly Dictionary _typeRefStore = new(); - private readonly List _typeDefStore = new(); + private readonly MetadataBuilder _metadataBuilder; + private readonly Dictionary _assemblyReferences = new(); + private readonly Dictionary _typeReferences = new(); + private readonly Dictionary _typeDefinitions = new(); + private int _nextTypeDefRowId = 1; private int _nextMethodDefRowId = 1; private int _nextFieldDefRowId = 1; private bool _coreTypesFullPopulated; + private Type?[]? _coreTypes; private static readonly Type[] s_coreTypes = { typeof(void), typeof(object), typeof(bool), typeof(char), typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(string), typeof(nint), typeof(nuint) }; - internal ModuleBuilderImpl(string name, Assembly coreAssembly) + internal ModuleBuilderImpl(string name, Assembly coreAssembly, MetadataBuilder builder) { _coreAssembly = coreAssembly; _name = name; + _metadataBuilder = builder; } [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Types are preserved via s_coreTypes")] @@ -90,72 +93,93 @@ internal Type GetTypeFromCoreAssembly(CoreTypeId typeId) return null; } - internal void AppendMetadata(MetadataBuilder metadata) + internal void AppendMetadata() { // Add module metadata - metadata.AddModule( + _metadataBuilder.AddModule( generation: 0, - moduleName: metadata.GetOrAddString(_name), - mvid: metadata.GetOrAddGuid(Guid.NewGuid()), + moduleName: _metadataBuilder.GetOrAddString(_name), + mvid: _metadataBuilder.GetOrAddGuid(Guid.NewGuid()), encId: default, encBaseId: default); // Create type definition for the special type that holds global functions - metadata.AddTypeDefinition( + _metadataBuilder.AddTypeDefinition( attributes: default, @namespace: default, - name: metadata.GetOrAddString(""), + name: _metadataBuilder.GetOrAddString(""), baseType: default, fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: MetadataTokens.MethodDefinitionHandle(1)); ; // Add each type definition to metadata table. - foreach (TypeBuilderImpl typeBuilder in _typeDefStore) + foreach ((TypeBuilderImpl typeBuilder, TypeDefinitionHandle typeHandle) in _typeDefinitions) { - TypeReferenceHandle parent = default; + EntityHandle parent = default; if (typeBuilder.BaseType is not null) { - // TODO: need to handle the case when the base is from same assembly - parent = GetTypeReference(metadata, typeBuilder.BaseType); + parent = GetTypeHandle(typeBuilder.BaseType); } - TypeDefinitionHandle typeDefinitionHandle = MetadataHelper.AddTypeDefinition(metadata, typeBuilder, parent, _nextMethodDefRowId, _nextFieldDefRowId); + + TypeDefinitionHandle typeDefinitionHandle = MetadataHelper.AddTypeDefinition(_metadataBuilder, typeBuilder, parent, _nextMethodDefRowId, _nextFieldDefRowId); + ThrowIfInvalidHandle(typeHandle, typeDefinitionHandle); // Add each method definition to metadata table. foreach (MethodBuilderImpl method in typeBuilder._methodDefStore) { - MetadataHelper.AddMethodDefinition(metadata, method, method.GetMethodSignatureBlob()); + MetadataHelper.AddMethodDefinition(_metadataBuilder, method, method.GetMethodSignatureBlob()); _nextMethodDefRowId++; } foreach (FieldBuilderImpl field in typeBuilder._fieldDefStore) { - MetadataHelper.AddFieldDefinition(metadata, field, MetadataSignatureHelper.FieldSignatureEncoder(field.FieldType, this)); + MetadataHelper.AddFieldDefinition(_metadataBuilder, field, MetadataSignatureHelper.FieldSignatureEncoder(field.FieldType, this)); _nextFieldDefRowId++; } } } - private TypeReferenceHandle GetTypeReference(MetadataBuilder metadata, Type type) + private static void ThrowIfInvalidHandle(TypeDefinitionHandle typeHandle, TypeDefinitionHandle typeDefinitionHandle) + { + if (!typeHandle.Equals(typeDefinitionHandle)) + { + throw new InvalidOperationException(SR.InvalidOperation_InvalidHanlde); + } + } + + private TypeReferenceHandle GetTypeReference(Type type) { - if (!_typeRefStore.TryGetValue(type, out var parentHandle)) + if (!_typeReferences.TryGetValue(type, out var parentHandle)) { - parentHandle = MetadataHelper.AddTypeReference(metadata, type, - GetAssemblyReference(type.Assembly, metadata)); + parentHandle = MetadataHelper.AddTypeReference(_metadataBuilder, type, GetAssemblyReference(type.Assembly)); + _typeReferences.Add(type, parentHandle); } return parentHandle; } - private AssemblyReferenceHandle GetAssemblyReference(Assembly assembly, MetadataBuilder metadata) + private AssemblyReferenceHandle GetAssemblyReference(Assembly assembly) { - if (_assemblyRefStore.TryGetValue(assembly, out var handle)) + if (!_assemblyReferences.TryGetValue(assembly, out var handle)) + { + handle = MetadataHelper.AddAssemblyReference(_metadataBuilder, assembly); + _assemblyReferences.Add(assembly, handle); + } + + return handle; + } + + internal EntityHandle GetTypeHandle(Type type) + { + if (type is TypeBuilderImpl tb && _typeDefinitions.TryGetValue(tb, out var handle)) { return handle; } - return MetadataHelper.AddAssemblyReference(assembly, metadata); + return GetTypeReference(type); } + [RequiresAssemblyFiles("Returns for modules with no file path")] public override string Name => ""; public override string ScopeName => _name; @@ -174,7 +198,8 @@ private AssemblyReferenceHandle GetAssemblyReference(Assembly assembly, Metadata protected override TypeBuilder DefineTypeCore(string name, TypeAttributes attr, [DynamicallyAccessedMembers((DynamicallyAccessedMemberTypes)(-1))] Type? parent, Type[]? interfaces, PackingSize packingSize, int typesize) { TypeBuilderImpl _type = new TypeBuilderImpl(name, attr, parent, this); - _typeDefStore.Add(_type); + TypeDefinitionHandle typeHandle = MetadataTokens.TypeDefinitionHandle(++_nextTypeDefRowId); + _typeDefinitions.Add(_type, typeHandle); return _type; } protected override FieldBuilder DefineUninitializedDataCore(string name, int size, FieldAttributes attributes) => throw new NotImplementedException(); diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/SignatureHelper.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/SignatureHelper.cs index ad950b15152ac..aa0ea4e104b16 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/SignatureHelper.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/SignatureHelper.cs @@ -55,59 +55,67 @@ private static void WriteSignatureTypeForReflectionType(SignatureTypeEncoder sig { CoreTypeId? typeId = module.GetTypeIdFromCoreTypes(type); - // We need to translate from Reflection.Type to SignatureTypeEncoder. - switch (typeId) + if (typeId.HasValue) { - case CoreTypeId.Boolean: - signature.Boolean(); - break; - case CoreTypeId.Byte: - signature.Byte(); - break; - case CoreTypeId.SByte: - signature.SByte(); - break; - case CoreTypeId.Char: - signature.Char(); - break; - case CoreTypeId.Int16: - signature.Int16(); - break; - case CoreTypeId.UInt16: - signature.UInt16(); - break; - case CoreTypeId.Int32: - signature.Int32(); - break; - case CoreTypeId.UInt32: - signature.UInt32(); - break; - case CoreTypeId.Int64: - signature.Int64(); - break; - case CoreTypeId.UInt64: - signature.UInt64(); - break; - case CoreTypeId.Single: - signature.Single(); - break; - case CoreTypeId.Double: - signature.Double(); - break; - case CoreTypeId.IntPtr: - signature.IntPtr(); - break; - case CoreTypeId.UIntPtr: - signature.UIntPtr(); - break; - case CoreTypeId.Object: - signature.Object(); - break; - case CoreTypeId.String: - signature.String(); - break; - default: - throw new NotSupportedException(SR.Format(SR.NotSupported_Signature, type.FullName)); + // We need to translate from Reflection.Type to SignatureTypeEncoder. + switch (typeId.Value) + { + case CoreTypeId.Boolean: + signature.Boolean(); + break; + case CoreTypeId.Byte: + signature.Byte(); + break; + case CoreTypeId.SByte: + signature.SByte(); + break; + case CoreTypeId.Char: + signature.Char(); + break; + case CoreTypeId.Int16: + signature.Int16(); + break; + case CoreTypeId.UInt16: + signature.UInt16(); + break; + case CoreTypeId.Int32: + signature.Int32(); + break; + case CoreTypeId.UInt32: + signature.UInt32(); + break; + case CoreTypeId.Int64: + signature.Int64(); + break; + case CoreTypeId.UInt64: + signature.UInt64(); + break; + case CoreTypeId.Single: + signature.Single(); + break; + case CoreTypeId.Double: + signature.Double(); + break; + case CoreTypeId.IntPtr: + signature.IntPtr(); + break; + case CoreTypeId.UIntPtr: + signature.UIntPtr(); + break; + case CoreTypeId.Object: + signature.Object(); + break; + case CoreTypeId.String: + signature.String(); + break; + default: + throw new NotSupportedException(SR.Format(SR.NotSupported_Signature, type.FullName)); + } + } + else + { + EntityHandle typeHandle = module.GetTypeHandle(type); + signature.Type(typeHandle, type.IsValueType); } } } diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs index 71548abab22ef..4f52719dfaf30 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs @@ -112,7 +112,7 @@ protected override void SetParentCore([DynamicallyAccessedMembers(DynamicallyAcc public override string? Namespace => _namespace; public override Assembly Assembly => _module.Assembly; public override Module Module => _module; - public override Type UnderlyingSystemType => throw new NotSupportedException(); + public override Type UnderlyingSystemType => this; public override Guid GUID => throw new NotSupportedException(); public override Type? BaseType => _typeParent; diff --git a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveTestsWithVariousTypes.cs b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveTestsWithVariousTypes.cs index c459a9be15a56..30114c41ebeb0 100644 --- a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveTestsWithVariousTypes.cs +++ b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveTestsWithVariousTypes.cs @@ -56,14 +56,13 @@ public static IEnumerable VariousInterfacesStructsTestData() { yield return new object[] { new Type[] { typeof(INoMethod) } }; yield return new object[] { new Type[] { typeof(IMultipleMethod) } }; - yield return new object[] { new Type[] { typeof(INoMethod), typeof(INoMethod2) } }; yield return new object[] { new Type[] { typeof(INoMethod), typeof(IOneMethod) } }; - yield return new object[] { new Type[] { typeof(IMultipleMethod), typeof(INoMethod2) } }; - yield return new object[] { new Type[] { typeof(IMultipleMethod), typeof(INoMethod2), typeof(IAccess), typeof(IOneMethod), typeof(INoMethod) } }; + yield return new object[] { new Type[] { typeof(IMultipleMethod), typeof(EmptyTestClass) } }; + yield return new object[] { new Type[] { typeof(IMultipleMethod), typeof(EmptyTestClass), typeof(IAccess), typeof(IOneMethod), typeof(INoMethod) } }; yield return new object[] { new Type[] { typeof(EmptyStruct) } }; - yield return new object[] { new Type[] { typeof(StructWithField) } }; - yield return new object[] { new Type[] { typeof(StructWithField), typeof(EmptyStruct) } }; - yield return new object[] { new Type[] { typeof(IMultipleMethod), typeof(EmptyStruct), typeof(INoMethod2), typeof(StructWithField) } }; + yield return new object[] { new Type[] { typeof(StructWithFields) } }; + yield return new object[] { new Type[] { typeof(StructWithFields), typeof(EmptyStruct) } }; + yield return new object[] { new Type[] { typeof(IMultipleMethod), typeof(StructWithFields), typeof(ClassWithFields), typeof(EmptyTestClass) } }; } [Theory] @@ -177,26 +176,22 @@ public void CreateMembersThatUsesTypeLoadedFromCoreAssemblyTest() } } - // Test Interfaces + // Test Types public interface INoMethod { } - public interface INoMethod2 - { - } - public interface IMultipleMethod { string Func(); - bool MoreFunc(); - double DoIExist(); + IOneMethod MoreFunc(); + StructWithFields DoIExist(); void BuildAPerpetualMotionMachine(); } internal interface IAccess { - public int BuildAI(); + public Version BuildAI(); public int DisableRogueAI(); } @@ -209,8 +204,19 @@ public struct EmptyStruct { } - public struct StructWithField + public struct StructWithFields + { + public int field1; + public string field2; + } + + public class EmptyTestClass + { + } + + public class ClassWithFields : EmptyTestClass { - public int field; + public EmptyTestClass field1; + public byte field2; } } diff --git a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblyTools.cs b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblyTools.cs index 16d16ff84d7ec..b07c04b2ea755 100644 --- a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblyTools.cs +++ b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblyTools.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.IO; -using System.Runtime.InteropServices; namespace System.Reflection.Emit.Tests { @@ -88,6 +87,7 @@ internal static Assembly LoadAssemblyFromStream(Stream stream) => internal sealed class CoreMetadataAssemblyResolver : MetadataAssemblyResolver { public static Assembly s_coreAssembly = typeof(object).Assembly; + public static Assembly s_emitAssembly = typeof(AssemblyTools).Assembly; public CoreMetadataAssemblyResolver() { } public override Assembly Resolve(MetadataLoadContext context, AssemblyName assemblyName) @@ -109,12 +109,26 @@ public override Assembly Resolve(MetadataLoadContext context, AssemblyName assem return _coreAssembly; } + if (name.Equals("System.Reflection.Emit.Tests", StringComparison.OrdinalIgnoreCase)) + { + if (_emitAssembly == null) + { + _emitAssembly = context.LoadFromStream(CreateStreamForEmitAssembly()); + } + + return _emitAssembly; + } + return null; } + private Assembly _emitAssembly; private Assembly _coreAssembly; - public static Stream CreateStreamForCoreAssembly() + private Stream CreateStreamForEmitAssembly() => + File.OpenRead(AssemblyPathHelper.GetAssemblyLocation(s_emitAssembly)); + + private static Stream CreateStreamForCoreAssembly() { // We need a core assembly in IL form. Since this version of this code is for Jitted platforms, the System.Private.Corelib // of the underlying runtime will do just fine. From 232d2f18c887756a1b49fa7b88379cab53b049b7 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Thu, 20 Apr 2023 16:07:37 -0700 Subject: [PATCH 2/4] Apply feedbacks --- .../src/Resources/Strings.resx | 3 - .../src/System.Reflection.Emit.csproj | 1 + .../System/Reflection/Emit/HandleWrappers.cs | 19 +++ .../Reflection/Emit/ModuleBuilderImpl.cs | 40 +++--- .../System/Reflection/Emit/SignatureHelper.cs | 130 +++++++++--------- .../AssemblySaveTestsWithVariousTypes.cs | 2 +- 6 files changed, 103 insertions(+), 92 deletions(-) create mode 100644 src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/HandleWrappers.cs diff --git a/src/libraries/System.Reflection.Emit/src/Resources/Strings.resx b/src/libraries/System.Reflection.Emit/src/Resources/Strings.resx index 3086fcc6a3c43..b3ad859f05253 100644 --- a/src/libraries/System.Reflection.Emit/src/Resources/Strings.resx +++ b/src/libraries/System.Reflection.Emit/src/Resources/Strings.resx @@ -144,7 +144,4 @@ Invalid name. - - Emitted handle is not valid. - \ No newline at end of file diff --git a/src/libraries/System.Reflection.Emit/src/System.Reflection.Emit.csproj b/src/libraries/System.Reflection.Emit/src/System.Reflection.Emit.csproj index 7da2c955d52e6..5445fd5a9ada1 100644 --- a/src/libraries/System.Reflection.Emit/src/System.Reflection.Emit.csproj +++ b/src/libraries/System.Reflection.Emit/src/System.Reflection.Emit.csproj @@ -5,6 +5,7 @@ true + diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/HandleWrappers.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/HandleWrappers.cs new file mode 100644 index 0000000000000..4d6cd95712a12 --- /dev/null +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/HandleWrappers.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Reflection.Metadata; + +namespace System.Reflection.Emit +{ + internal sealed class TypeDefinitionWrapper + { + internal TypeBuilderImpl typeBuilder; + internal TypeDefinitionHandle handle; + + public TypeDefinitionWrapper(TypeBuilderImpl typeBuilder, TypeDefinitionHandle handle) + { + this.typeBuilder = typeBuilder; + this.handle = handle; + } + } +} diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs index f75f966cdffe2..e392d1abba754 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection.Metadata; using System.Reflection.Metadata.Ecma335; @@ -16,14 +17,14 @@ internal sealed class ModuleBuilderImpl : ModuleBuilder private readonly MetadataBuilder _metadataBuilder; private readonly Dictionary _assemblyReferences = new(); private readonly Dictionary _typeReferences = new(); - private readonly Dictionary _typeDefinitions = new(); + private readonly List _typeDefinitions = new(); private int _nextTypeDefRowId = 1; private int _nextMethodDefRowId = 1; private int _nextFieldDefRowId = 1; private bool _coreTypesFullPopulated; private Type?[]? _coreTypes; private static readonly Type[] s_coreTypes = { typeof(void), typeof(object), typeof(bool), typeof(char), typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), - typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(string), typeof(nint), typeof(nuint) }; + typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(string), typeof(nint), typeof(nuint), typeof(TypedReference) }; internal ModuleBuilderImpl(string name, Assembly coreAssembly, MetadataBuilder builder) { @@ -113,26 +114,25 @@ internal void AppendMetadata() methodList: MetadataTokens.MethodDefinitionHandle(1)); ; // Add each type definition to metadata table. - foreach ((TypeBuilderImpl typeBuilder, TypeDefinitionHandle typeHandle) in _typeDefinitions) + foreach (TypeDefinitionWrapper typeDefinition in _typeDefinitions) { EntityHandle parent = default; - if (typeBuilder.BaseType is not null) + if (typeDefinition.typeBuilder.BaseType is not null) { - parent = GetTypeHandle(typeBuilder.BaseType); + parent = GetTypeHandle(typeDefinition.typeBuilder.BaseType); } - - TypeDefinitionHandle typeDefinitionHandle = MetadataHelper.AddTypeDefinition(_metadataBuilder, typeBuilder, parent, _nextMethodDefRowId, _nextFieldDefRowId); - ThrowIfInvalidHandle(typeHandle, typeDefinitionHandle); + TypeDefinitionHandle typeDefinitionHandle = MetadataHelper.AddTypeDefinition(_metadataBuilder, typeDefinition.typeBuilder, parent, _nextMethodDefRowId, _nextFieldDefRowId); + Debug.Assert(typeDefinition.handle.Equals(typeDefinitionHandle)); // Add each method definition to metadata table. - foreach (MethodBuilderImpl method in typeBuilder._methodDefStore) + foreach (MethodBuilderImpl method in typeDefinition.typeBuilder._methodDefStore) { MetadataHelper.AddMethodDefinition(_metadataBuilder, method, method.GetMethodSignatureBlob()); _nextMethodDefRowId++; } - foreach (FieldBuilderImpl field in typeBuilder._fieldDefStore) + foreach (FieldBuilderImpl field in typeDefinition.typeBuilder._fieldDefStore) { MetadataHelper.AddFieldDefinition(_metadataBuilder, field, MetadataSignatureHelper.FieldSignatureEncoder(field.FieldType, this)); _nextFieldDefRowId++; @@ -140,14 +140,6 @@ internal void AppendMetadata() } } - private static void ThrowIfInvalidHandle(TypeDefinitionHandle typeHandle, TypeDefinitionHandle typeDefinitionHandle) - { - if (!typeHandle.Equals(typeDefinitionHandle)) - { - throw new InvalidOperationException(SR.InvalidOperation_InvalidHanlde); - } - } - private TypeReferenceHandle GetTypeReference(Type type) { if (!_typeReferences.TryGetValue(type, out var parentHandle)) @@ -172,9 +164,15 @@ private AssemblyReferenceHandle GetAssemblyReference(Assembly assembly) internal EntityHandle GetTypeHandle(Type type) { - if (type is TypeBuilderImpl tb && _typeDefinitions.TryGetValue(tb, out var handle)) + if (type is TypeBuilderImpl tb && Equals(tb.Module)) { - return handle; + foreach(TypeDefinitionWrapper typeDef in _typeDefinitions) + { + if (!typeDef.typeBuilder.Equals(tb)) + { + return typeDef.handle; + } + } } return GetTypeReference(type); @@ -199,7 +197,7 @@ protected override TypeBuilder DefineTypeCore(string name, TypeAttributes attr, { TypeBuilderImpl _type = new TypeBuilderImpl(name, attr, parent, this); TypeDefinitionHandle typeHandle = MetadataTokens.TypeDefinitionHandle(++_nextTypeDefRowId); - _typeDefinitions.Add(_type, typeHandle); + _typeDefinitions.Add(new TypeDefinitionWrapper(_type, typeHandle)); return _type; } protected override FieldBuilder DefineUninitializedDataCore(string name, int size, FieldAttributes attributes) => throw new NotImplementedException(); diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/SignatureHelper.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/SignatureHelper.cs index aa0ea4e104b16..5404e69da3d46 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/SignatureHelper.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/SignatureHelper.cs @@ -7,15 +7,14 @@ namespace System.Reflection.Emit { - // TODO: Only support simple signatures. More complex signatures will be added. + // TODO: Only support simple signatures. More complex signatures (generics, array, byref, pointers etc) will be added. internal static class MetadataSignatureHelper { internal static BlobBuilder FieldSignatureEncoder(Type fieldType, ModuleBuilderImpl module) { BlobBuilder fieldSignature = new(); - - WriteSignatureTypeForReflectionType(new BlobEncoder(fieldSignature).FieldSignature(), fieldType, module); - + FieldTypeEncoder encoder = new BlobEncoder(fieldSignature).Field(); + WriteSignatureForType(encoder.Type(), fieldType, module, encoder.TypedReference); return fieldSignature; } @@ -33,7 +32,7 @@ internal static BlobBuilder MethodSignatureEncoder(ModuleBuilderImpl module, Typ if (returnType != null && returnType != module.GetTypeFromCoreAssembly(CoreTypeId.Void)) { - WriteSignatureTypeForReflectionType(retEncoder.Type(), returnType, module); + WriteSignatureForType(retEncoder.Type(), returnType, module, retEncoder.TypedReference); } else // If null mark ReturnTypeEncoder as void { @@ -44,79 +43,75 @@ internal static BlobBuilder MethodSignatureEncoder(ModuleBuilderImpl module, Typ { foreach (Type parameter in parameters) { - WriteSignatureTypeForReflectionType(parEncoder.AddParameter().Type(), parameter, module); + ParameterTypeEncoder parameterEncoder = parEncoder.AddParameter(); + WriteSignatureForType(parameterEncoder.Type(), parameter, module, parameterEncoder.TypedReference); } } return methodSignature; } - private static void WriteSignatureTypeForReflectionType(SignatureTypeEncoder signature, Type type, ModuleBuilderImpl module) + private static void WriteSignatureForType(SignatureTypeEncoder signature, Type type, ModuleBuilderImpl module, Action typedReference) { CoreTypeId? typeId = module.GetTypeIdFromCoreTypes(type); - if (typeId.HasValue) + switch (typeId) { - // We need to translate from Reflection.Type to SignatureTypeEncoder. - switch (typeId.Value) - { - case CoreTypeId.Boolean: - signature.Boolean(); - break; - case CoreTypeId.Byte: - signature.Byte(); - break; - case CoreTypeId.SByte: - signature.SByte(); - break; - case CoreTypeId.Char: - signature.Char(); - break; - case CoreTypeId.Int16: - signature.Int16(); - break; - case CoreTypeId.UInt16: - signature.UInt16(); - break; - case CoreTypeId.Int32: - signature.Int32(); - break; - case CoreTypeId.UInt32: - signature.UInt32(); - break; - case CoreTypeId.Int64: - signature.Int64(); - break; - case CoreTypeId.UInt64: - signature.UInt64(); - break; - case CoreTypeId.Single: - signature.Single(); - break; - case CoreTypeId.Double: - signature.Double(); - break; - case CoreTypeId.IntPtr: - signature.IntPtr(); - break; - case CoreTypeId.UIntPtr: - signature.UIntPtr(); - break; - case CoreTypeId.Object: - signature.Object(); - break; - case CoreTypeId.String: - signature.String(); - break; - default: - throw new NotSupportedException(SR.Format(SR.NotSupported_Signature, type.FullName)); - } - } - else - { - EntityHandle typeHandle = module.GetTypeHandle(type); - signature.Type(typeHandle, type.IsValueType); + case CoreTypeId.Boolean: + signature.Boolean(); + return; + case CoreTypeId.Byte: + signature.Byte(); + return; + case CoreTypeId.SByte: + signature.SByte(); + return; + case CoreTypeId.Char: + signature.Char(); + return; + case CoreTypeId.Int16: + signature.Int16(); + return; + case CoreTypeId.UInt16: + signature.UInt16(); + return; + case CoreTypeId.Int32: + signature.Int32(); + return; + case CoreTypeId.UInt32: + signature.UInt32(); + return; + case CoreTypeId.Int64: + signature.Int64(); + return; + case CoreTypeId.UInt64: + signature.UInt64(); + return; + case CoreTypeId.Single: + signature.Single(); + return; + case CoreTypeId.Double: + signature.Double(); + return; + case CoreTypeId.IntPtr: + signature.IntPtr(); + return; + case CoreTypeId.UIntPtr: + signature.UIntPtr(); + return; + case CoreTypeId.Object: + signature.Object(); + return; + case CoreTypeId.String: + signature.String(); + return; + case CoreTypeId.TypedReference: + typedReference(); + return; } + + EntityHandle typeHandle = module.GetTypeHandle(type); + signature.Type(typeHandle, type.IsValueType); } } @@ -139,5 +134,6 @@ internal enum CoreTypeId String, IntPtr, UIntPtr, + TypedReference, } } diff --git a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveTestsWithVariousTypes.cs b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveTestsWithVariousTypes.cs index 30114c41ebeb0..22b85bc9693d9 100644 --- a/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveTestsWithVariousTypes.cs +++ b/src/libraries/System.Reflection.Emit/tests/PersistableAssemblyBuilder/AssemblySaveTestsWithVariousTypes.cs @@ -197,7 +197,7 @@ internal interface IAccess public interface IOneMethod { - string Func(); + object Func(); } public struct EmptyStruct From 46c6a41b8b151519fdc940769d7c6265933deea9 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Thu, 20 Apr 2023 22:05:49 -0700 Subject: [PATCH 3/4] Add handle to TypeBuilderImpl and implement MetadataToken, remove callbacks --- .../src/System.Reflection.Emit.csproj | 1 - .../System/Reflection/Emit/HandleWrappers.cs | 19 ------------- .../Reflection/Emit/ModuleBuilderImpl.cs | 28 ++++++++----------- .../System/Reflection/Emit/SignatureHelper.cs | 14 +++++----- .../System/Reflection/Emit/TypeBuilderImpl.cs | 8 ++++-- 5 files changed, 24 insertions(+), 46 deletions(-) delete mode 100644 src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/HandleWrappers.cs diff --git a/src/libraries/System.Reflection.Emit/src/System.Reflection.Emit.csproj b/src/libraries/System.Reflection.Emit/src/System.Reflection.Emit.csproj index 5445fd5a9ada1..7da2c955d52e6 100644 --- a/src/libraries/System.Reflection.Emit/src/System.Reflection.Emit.csproj +++ b/src/libraries/System.Reflection.Emit/src/System.Reflection.Emit.csproj @@ -5,7 +5,6 @@ true - diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/HandleWrappers.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/HandleWrappers.cs deleted file mode 100644 index 4d6cd95712a12..0000000000000 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/HandleWrappers.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Reflection.Metadata; - -namespace System.Reflection.Emit -{ - internal sealed class TypeDefinitionWrapper - { - internal TypeBuilderImpl typeBuilder; - internal TypeDefinitionHandle handle; - - public TypeDefinitionWrapper(TypeBuilderImpl typeBuilder, TypeDefinitionHandle handle) - { - this.typeBuilder = typeBuilder; - this.handle = handle; - } - } -} diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs index e392d1abba754..63d751c51cddf 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs @@ -17,7 +17,7 @@ internal sealed class ModuleBuilderImpl : ModuleBuilder private readonly MetadataBuilder _metadataBuilder; private readonly Dictionary _assemblyReferences = new(); private readonly Dictionary _typeReferences = new(); - private readonly List _typeDefinitions = new(); + private readonly List _typeDefinitions = new(); private int _nextTypeDefRowId = 1; private int _nextMethodDefRowId = 1; private int _nextFieldDefRowId = 1; @@ -114,25 +114,25 @@ internal void AppendMetadata() methodList: MetadataTokens.MethodDefinitionHandle(1)); ; // Add each type definition to metadata table. - foreach (TypeDefinitionWrapper typeDefinition in _typeDefinitions) + foreach (TypeBuilderImpl typeBuilder in _typeDefinitions) { EntityHandle parent = default; - if (typeDefinition.typeBuilder.BaseType is not null) + if (typeBuilder.BaseType is not null) { - parent = GetTypeHandle(typeDefinition.typeBuilder.BaseType); + parent = GetTypeHandle(typeBuilder.BaseType); } - TypeDefinitionHandle typeDefinitionHandle = MetadataHelper.AddTypeDefinition(_metadataBuilder, typeDefinition.typeBuilder, parent, _nextMethodDefRowId, _nextFieldDefRowId); - Debug.Assert(typeDefinition.handle.Equals(typeDefinitionHandle)); + TypeDefinitionHandle typeDefinitionHandle = MetadataHelper.AddTypeDefinition(_metadataBuilder, typeBuilder, parent, _nextMethodDefRowId, _nextFieldDefRowId); + Debug.Assert(typeBuilder._handle.Equals(typeDefinitionHandle)); // Add each method definition to metadata table. - foreach (MethodBuilderImpl method in typeDefinition.typeBuilder._methodDefStore) + foreach (MethodBuilderImpl method in typeBuilder._methodDefStore) { MetadataHelper.AddMethodDefinition(_metadataBuilder, method, method.GetMethodSignatureBlob()); _nextMethodDefRowId++; } - foreach (FieldBuilderImpl field in typeDefinition.typeBuilder._fieldDefStore) + foreach (FieldBuilderImpl field in typeBuilder._fieldDefStore) { MetadataHelper.AddFieldDefinition(_metadataBuilder, field, MetadataSignatureHelper.FieldSignatureEncoder(field.FieldType, this)); _nextFieldDefRowId++; @@ -166,13 +166,7 @@ internal EntityHandle GetTypeHandle(Type type) { if (type is TypeBuilderImpl tb && Equals(tb.Module)) { - foreach(TypeDefinitionWrapper typeDef in _typeDefinitions) - { - if (!typeDef.typeBuilder.Equals(tb)) - { - return typeDef.handle; - } - } + return tb._handle; } return GetTypeReference(type); @@ -195,9 +189,9 @@ internal EntityHandle GetTypeHandle(Type type) protected override MethodBuilder DefinePInvokeMethodCore(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, Type? returnType, Type[]? parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) => throw new NotImplementedException(); protected override TypeBuilder DefineTypeCore(string name, TypeAttributes attr, [DynamicallyAccessedMembers((DynamicallyAccessedMemberTypes)(-1))] Type? parent, Type[]? interfaces, PackingSize packingSize, int typesize) { - TypeBuilderImpl _type = new TypeBuilderImpl(name, attr, parent, this); TypeDefinitionHandle typeHandle = MetadataTokens.TypeDefinitionHandle(++_nextTypeDefRowId); - _typeDefinitions.Add(new TypeDefinitionWrapper(_type, typeHandle)); + TypeBuilderImpl _type = new TypeBuilderImpl(name, attr, parent, this, typeHandle); + _typeDefinitions.Add(_type); return _type; } protected override FieldBuilder DefineUninitializedDataCore(string name, int size, FieldAttributes attributes) => throw new NotImplementedException(); diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/SignatureHelper.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/SignatureHelper.cs index 5404e69da3d46..ad1701c35ecb9 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/SignatureHelper.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/SignatureHelper.cs @@ -13,8 +13,9 @@ internal static class MetadataSignatureHelper internal static BlobBuilder FieldSignatureEncoder(Type fieldType, ModuleBuilderImpl module) { BlobBuilder fieldSignature = new(); - FieldTypeEncoder encoder = new BlobEncoder(fieldSignature).Field(); - WriteSignatureForType(encoder.Type(), fieldType, module, encoder.TypedReference); + + WriteSignatureForType(new BlobEncoder(fieldSignature).FieldSignature(), fieldType, module); + return fieldSignature; } @@ -32,7 +33,7 @@ internal static BlobBuilder MethodSignatureEncoder(ModuleBuilderImpl module, Typ if (returnType != null && returnType != module.GetTypeFromCoreAssembly(CoreTypeId.Void)) { - WriteSignatureForType(retEncoder.Type(), returnType, module, retEncoder.TypedReference); + WriteSignatureForType(retEncoder.Type(), returnType, module); } else // If null mark ReturnTypeEncoder as void { @@ -43,15 +44,14 @@ internal static BlobBuilder MethodSignatureEncoder(ModuleBuilderImpl module, Typ { foreach (Type parameter in parameters) { - ParameterTypeEncoder parameterEncoder = parEncoder.AddParameter(); - WriteSignatureForType(parameterEncoder.Type(), parameter, module, parameterEncoder.TypedReference); + WriteSignatureForType(parEncoder.AddParameter().Type(), parameter, module); } } return methodSignature; } - private static void WriteSignatureForType(SignatureTypeEncoder signature, Type type, ModuleBuilderImpl module, Action typedReference) + private static void WriteSignatureForType(SignatureTypeEncoder signature, Type type, ModuleBuilderImpl module) { CoreTypeId? typeId = module.GetTypeIdFromCoreTypes(type); @@ -106,7 +106,7 @@ private static void WriteSignatureForType(SignatureTypeEncoder signature, Type t signature.String(); return; case CoreTypeId.TypedReference: - typedReference(); + signature.Builder.WriteByte((byte)SignatureTypeCode.TypedReference); return; } diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs index 4f52719dfaf30..16558aa05ceef 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs @@ -5,6 +5,8 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Globalization; +using System.Reflection.Metadata; +using System.Reflection.Metadata.Ecma335; namespace System.Reflection.Emit { @@ -15,17 +17,19 @@ internal sealed class TypeBuilderImpl : TypeBuilder private readonly ModuleBuilderImpl _module; private readonly string _name; private readonly string? _namespace; + internal readonly TypeDefinitionHandle _handle; [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] private Type? _typeParent; private TypeAttributes _attributes; internal TypeBuilderImpl(string fullName, TypeAttributes typeAttributes, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? parent, ModuleBuilderImpl module) + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? parent, ModuleBuilderImpl module, TypeDefinitionHandle handle) { _name = fullName; _module = module; _attributes = typeAttributes; SetParent(parent); + _handle = handle; // Extract namespace from fullName int idx = _name.LastIndexOf('.'); @@ -115,7 +119,7 @@ protected override void SetParentCore([DynamicallyAccessedMembers(DynamicallyAcc public override Type UnderlyingSystemType => this; public override Guid GUID => throw new NotSupportedException(); public override Type? BaseType => _typeParent; - + public override int MetadataToken => MetadataTokens.GetToken(_handle); [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override object? InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target, object?[]? args, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParameters) => throw new NotSupportedException(); From 3e250a41aa31ad137fb3900fa89fc1ae767bfc03 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Fri, 21 Apr 2023 17:14:38 -0700 Subject: [PATCH 4/4] Remove unnecessary MetadataHelper type --- .../src/System.Reflection.Emit.csproj | 1 - .../Reflection/Emit/AssemblyBuilderImpl.cs | 6 +- .../System/Reflection/Emit/MetadataHelper.cs | 78 ------------------- .../Reflection/Emit/ModuleBuilderImpl.cs | 65 +++++++++++++--- 4 files changed, 57 insertions(+), 93 deletions(-) delete mode 100644 src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MetadataHelper.cs diff --git a/src/libraries/System.Reflection.Emit/src/System.Reflection.Emit.csproj b/src/libraries/System.Reflection.Emit/src/System.Reflection.Emit.csproj index 7da2c955d52e6..bc290ba0b8cf3 100644 --- a/src/libraries/System.Reflection.Emit/src/System.Reflection.Emit.csproj +++ b/src/libraries/System.Reflection.Emit/src/System.Reflection.Emit.csproj @@ -5,7 +5,6 @@ true - diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/AssemblyBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/AssemblyBuilderImpl.cs index 9ff5de8bc82c1..d8543a23602b9 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/AssemblyBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/AssemblyBuilderImpl.cs @@ -44,7 +44,7 @@ internal AssemblyBuilderImpl(AssemblyName name, Assembly coreAssembly, IEnumerab internal static AssemblyBuilderImpl DefinePersistedAssembly(AssemblyName name, Assembly coreAssembly, IEnumerable? assemblyAttributes) => new AssemblyBuilderImpl(name, coreAssembly, assemblyAttributes); - private static void WritePEImage(Stream peStream, MetadataBuilder metadataBuilder, BlobBuilder ilBuilder) + private void WritePEImage(Stream peStream, BlobBuilder ilBuilder) { // Create executable with the managed metadata from the specified MetadataBuilder. var peHeaderBuilder = new PEHeaderBuilder( @@ -53,7 +53,7 @@ private static void WritePEImage(Stream peStream, MetadataBuilder metadataBuilde var peBuilder = new ManagedPEBuilder( peHeaderBuilder, - new MetadataRootBuilder(metadataBuilder), + new MetadataRootBuilder(_metadataBuilder), ilBuilder); // Write executable into the specified stream. @@ -92,7 +92,7 @@ internal void Save(Stream stream) _module.AppendMetadata(); var ilBuilder = new BlobBuilder(); - WritePEImage(stream, _metadataBuilder, ilBuilder); + WritePEImage(stream, ilBuilder); _previouslySaved = true; } diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MetadataHelper.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MetadataHelper.cs deleted file mode 100644 index a18148847aac8..0000000000000 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/MetadataHelper.cs +++ /dev/null @@ -1,78 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Reflection.Metadata; -using System.Reflection.Metadata.Ecma335; - -namespace System.Reflection.Emit -{ - // This static helper class adds common entities to a MetadataBuilder. - internal static class MetadataHelper - { - internal static AssemblyReferenceHandle AddAssemblyReference(MetadataBuilder metadata, Assembly assembly) - { - AssemblyName assemblyName = assembly.GetName(); - - return AddAssemblyReference(metadata, assemblyName.Name!, assemblyName.Version, assemblyName.CultureName, - assemblyName.GetPublicKeyToken(), assemblyName.Flags, assemblyName.ContentType); - } - - internal static AssemblyReferenceHandle AddAssemblyReference(MetadataBuilder metadata, string name, Version? version, - string? culture, byte[]? publicKeyToken, AssemblyNameFlags flags, AssemblyContentType contentType) - { - return metadata.AddAssemblyReference( - name: metadata.GetOrAddString(name), - version: version ?? new Version(0, 0, 0, 0), - culture: (culture == null) ? default : metadata.GetOrAddString(value: culture), - publicKeyOrToken: (publicKeyToken == null) ? default : metadata.GetOrAddBlob(publicKeyToken), // reference has token, not full public key - flags: (AssemblyFlags)((int)contentType << 9) | ((flags & AssemblyNameFlags.Retargetable) != 0 ? AssemblyFlags.Retargetable : 0), - hashValue: default); // .file directive assemblies not supported, no need to handle this value. - } - - internal static TypeDefinitionHandle AddTypeDefinition(MetadataBuilder metadata, TypeBuilderImpl typeBuilder, EntityHandle baseType, int methodToken, int fieldToken) - { - // Add type metadata - return metadata.AddTypeDefinition( - attributes: typeBuilder.Attributes, - @namespace: (typeBuilder.Namespace == null) ? default : metadata.GetOrAddString(typeBuilder.Namespace), - name: metadata.GetOrAddString(typeBuilder.Name), - baseType: baseType, - fieldList: MetadataTokens.FieldDefinitionHandle(fieldToken), - methodList: MetadataTokens.MethodDefinitionHandle(methodToken)); - } - - internal static TypeReferenceHandle AddTypeReference(MetadataBuilder metadata, Type type, AssemblyReferenceHandle parent) - { - return AddTypeReference(metadata, parent, type.Name, type.Namespace); - } - - internal static TypeReferenceHandle AddTypeReference(MetadataBuilder metadata, AssemblyReferenceHandle parent, string name, string? nameSpace) - { - return metadata.AddTypeReference( - resolutionScope: parent, - @namespace: (nameSpace == null) ? default : metadata.GetOrAddString(nameSpace), - name: metadata.GetOrAddString(name) - ); - } - - internal static MethodDefinitionHandle AddMethodDefinition(MetadataBuilder metadata, MethodBuilderImpl methodBuilder, BlobBuilder methodSignatureBlob) - { - return metadata.AddMethodDefinition( - attributes: methodBuilder.Attributes, - implAttributes: MethodImplAttributes.IL, - name: metadata.GetOrAddString(methodBuilder.Name), - signature: metadata.GetOrAddBlob(methodSignatureBlob), - bodyOffset: -1, // No body supported yet - parameterList: MetadataTokens.ParameterHandle(1) - ); - } - - internal static FieldDefinitionHandle AddFieldDefinition(MetadataBuilder metadata, FieldInfo field, BlobBuilder fieldSignatureBlob) - { - return metadata.AddFieldDefinition( - attributes: field.Attributes, - name: metadata.GetOrAddString(field.Name), - signature: metadata.GetOrAddBlob(fieldSignatureBlob)); - } - } -} diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs index 63d751c51cddf..8c17b6794c412 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs @@ -21,10 +21,10 @@ internal sealed class ModuleBuilderImpl : ModuleBuilder private int _nextTypeDefRowId = 1; private int _nextMethodDefRowId = 1; private int _nextFieldDefRowId = 1; - private bool _coreTypesFullPopulated; + private bool _coreTypesFullyPopulated; private Type?[]? _coreTypes; private static readonly Type[] s_coreTypes = { typeof(void), typeof(object), typeof(bool), typeof(char), typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), - typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(string), typeof(nint), typeof(nuint), typeof(TypedReference) }; + typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(string), typeof(nint), typeof(nuint), typeof(TypedReference) }; internal ModuleBuilderImpl(string name, Assembly coreAssembly, MetadataBuilder builder) { @@ -42,7 +42,7 @@ internal Type GetTypeFromCoreAssembly(CoreTypeId typeId) if (_coreAssembly == typeof(object).Assembly) { _coreTypes = s_coreTypes; - _coreTypesFullPopulated = true; + _coreTypesFullyPopulated = true; } else { @@ -63,7 +63,7 @@ internal Type GetTypeFromCoreAssembly(CoreTypeId typeId) if (_coreAssembly == typeof(object).Assembly) { _coreTypes = s_coreTypes; - _coreTypesFullPopulated = true; + _coreTypesFullyPopulated = true; } else { @@ -71,7 +71,7 @@ internal Type GetTypeFromCoreAssembly(CoreTypeId typeId) } } - if (!_coreTypesFullPopulated) + if (!_coreTypesFullyPopulated) { for (int i = 0; i < _coreTypes.Length; i++) { @@ -80,7 +80,7 @@ internal Type GetTypeFromCoreAssembly(CoreTypeId typeId) _coreTypes[i] = _coreAssembly.GetType(s_coreTypes[i].FullName!, throwOnError: false)!; } } - _coreTypesFullPopulated = true; + _coreTypesFullyPopulated = true; } for (int i = 0; i < _coreTypes.Length; i++) @@ -122,29 +122,61 @@ internal void AppendMetadata() parent = GetTypeHandle(typeBuilder.BaseType); } - TypeDefinitionHandle typeDefinitionHandle = MetadataHelper.AddTypeDefinition(_metadataBuilder, typeBuilder, parent, _nextMethodDefRowId, _nextFieldDefRowId); + TypeDefinitionHandle typeDefinitionHandle = AddTypeDefinition(typeBuilder, parent, _nextMethodDefRowId, _nextFieldDefRowId); Debug.Assert(typeBuilder._handle.Equals(typeDefinitionHandle)); // Add each method definition to metadata table. foreach (MethodBuilderImpl method in typeBuilder._methodDefStore) { - MetadataHelper.AddMethodDefinition(_metadataBuilder, method, method.GetMethodSignatureBlob()); + AddMethodDefinition(method, method.GetMethodSignatureBlob()); _nextMethodDefRowId++; } foreach (FieldBuilderImpl field in typeBuilder._fieldDefStore) { - MetadataHelper.AddFieldDefinition(_metadataBuilder, field, MetadataSignatureHelper.FieldSignatureEncoder(field.FieldType, this)); + AddFieldDefinition(field, MetadataSignatureHelper.FieldSignatureEncoder(field.FieldType, this)); _nextFieldDefRowId++; } } } + private FieldDefinitionHandle AddFieldDefinition(FieldBuilderImpl field, BlobBuilder fieldSignature) => + _metadataBuilder.AddFieldDefinition( + attributes: field.Attributes, + name: _metadataBuilder.GetOrAddString(field.Name), + signature: _metadataBuilder.GetOrAddBlob(fieldSignature)); + + private TypeDefinitionHandle AddTypeDefinition(TypeBuilderImpl type, EntityHandle parent, int methodToken, int fieldToken) => + _metadataBuilder.AddTypeDefinition( + attributes: type.Attributes, + @namespace: (type.Namespace == null) ? default : _metadataBuilder.GetOrAddString(type.Namespace), + name: _metadataBuilder.GetOrAddString(type.Name), + baseType: parent, + fieldList: MetadataTokens.FieldDefinitionHandle(fieldToken), + methodList: MetadataTokens.MethodDefinitionHandle(methodToken)); + + private MethodDefinitionHandle AddMethodDefinition(MethodBuilderImpl method, BlobBuilder methodSignature) => + _metadataBuilder.AddMethodDefinition( + attributes: method.Attributes, + implAttributes: MethodImplAttributes.IL, + name: _metadataBuilder.GetOrAddString(method.Name), + signature: _metadataBuilder.GetOrAddBlob(methodSignature), + bodyOffset: -1, // No body supported yet + parameterList: MetadataTokens.ParameterHandle(1) + ); + + private TypeReferenceHandle AddTypeReference(Type type, AssemblyReferenceHandle parent) => + _metadataBuilder.AddTypeReference( + resolutionScope: parent, + @namespace: (type.Namespace == null) ? default : _metadataBuilder.GetOrAddString(type.Namespace), + name: _metadataBuilder.GetOrAddString(type.Name) + ); + private TypeReferenceHandle GetTypeReference(Type type) { if (!_typeReferences.TryGetValue(type, out var parentHandle)) { - parentHandle = MetadataHelper.AddTypeReference(_metadataBuilder, type, GetAssemblyReference(type.Assembly)); + parentHandle = AddTypeReference(type, GetAssemblyReference(type.Assembly)); _typeReferences.Add(type, parentHandle); } @@ -155,13 +187,24 @@ private AssemblyReferenceHandle GetAssemblyReference(Assembly assembly) { if (!_assemblyReferences.TryGetValue(assembly, out var handle)) { - handle = MetadataHelper.AddAssemblyReference(_metadataBuilder, assembly); + AssemblyName aName = assembly.GetName(); + handle = AddAssemblyReference(aName.Name!, aName.Version, aName.CultureName, aName.GetPublicKeyToken(), aName.Flags, aName.ContentType); _assemblyReferences.Add(assembly, handle); } return handle; } + private AssemblyReferenceHandle AddAssemblyReference(string name, Version? version, + string? culture, byte[]? publicKeyToken, AssemblyNameFlags flags, AssemblyContentType contentType) => + _metadataBuilder.AddAssemblyReference( + name: _metadataBuilder.GetOrAddString(name), + version: version ?? new Version(0, 0, 0, 0), + culture: (culture == null) ? default : _metadataBuilder.GetOrAddString(value: culture), + publicKeyOrToken: (publicKeyToken == null) ? default : _metadataBuilder.GetOrAddBlob(publicKeyToken), // reference has token, not full public key + flags: (AssemblyFlags)((int)contentType << 9) | ((flags & AssemblyNameFlags.Retargetable) != 0 ? AssemblyFlags.Retargetable : 0), + hashValue: default); // .file directive assemblies not supported, no need to handle this value. + internal EntityHandle GetTypeHandle(Type type) { if (type is TypeBuilderImpl tb && Equals(tb.Module))