Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support non core types for signature and other type references #85112

Merged
merged 4 commits into from
Apr 23, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 0 additions & 42 deletions src/libraries/System.Reflection.Emit/System.Reflection.Emit.sln
Original file line number Diff line number Diff line change
Expand Up @@ -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}"
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,7 @@
<data name="Argument_InvalidName" xml:space="preserve">
<value>Invalid name.</value>
</data>
<data name="InvalidOperation_InvalidHanlde" xml:space="preserve">
<value>Emitted handle is not valid.</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -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<CustomAttributeBuilder>? assemblyAttributes)
{
Expand All @@ -29,6 +30,7 @@ internal AssemblyBuilderImpl(AssemblyName name, Assembly coreAssembly, IEnumerab

_assemblyName = name;
_coreAssembly = coreAssembly;
_metadataBuilder = new MetadataBuilder();

if (assemblyAttributes != null)
{
Expand Down Expand Up @@ -75,24 +77,22 @@ 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
#pragma warning restore SYSLIB0037
);

// Add module's metadata
_module.AppendMetadata(metadata);
_module.AppendMetadata();

var ilBuilder = new BlobBuilder();
WritePEImage(stream, metadata, ilBuilder);
WritePEImage(stream, _metadataBuilder, ilBuilder);
buyaa-n marked this conversation as resolved.
Show resolved Hide resolved
_previouslySaved = true;
}

Expand All @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,23 @@ internal sealed class ModuleBuilderImpl : ModuleBuilder
{
private readonly Assembly _coreAssembly;
private readonly string _name;
private Type?[]? _coreTypes;
private readonly Dictionary<Assembly, AssemblyReferenceHandle> _assemblyRefStore = new();
private readonly Dictionary<Type, TypeReferenceHandle> _typeRefStore = new();
private readonly List<TypeBuilderImpl> _typeDefStore = new();
private readonly MetadataBuilder _metadataBuilder;
private readonly Dictionary<Assembly, AssemblyReferenceHandle> _assemblyReferences = new();
private readonly Dictionary<Type, TypeReferenceHandle> _typeReferences = new();
private readonly Dictionary<TypeBuilderImpl, TypeDefinitionHandle> _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")]
Expand Down Expand Up @@ -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 <Module> type that holds global functions
metadata.AddTypeDefinition(
_metadataBuilder.AddTypeDefinition(
attributes: default,
@namespace: default,
name: metadata.GetOrAddString("<Module>"),
name: _metadataBuilder.GetOrAddString("<Module>"),
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)
buyaa-n marked this conversation as resolved.
Show resolved Hide resolved
{
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);
buyaa-n marked this conversation as resolved.
Show resolved Hide resolved
ThrowIfInvalidHandle(typeHandle, typeDefinitionHandle);
buyaa-n marked this conversation as resolved.
Show resolved Hide resolved

// 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))
buyaa-n marked this conversation as resolved.
Show resolved Hide resolved
{
return handle;
}

return MetadataHelper.AddAssemblyReference(assembly, metadata);
return GetTypeReference(type);
}

[RequiresAssemblyFiles("Returns <Unknown> for modules with no file path")]
public override string Name => "<In Memory Module>";
public override string ScopeName => _name;
Expand All @@ -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();
Expand Down
Loading