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 2 commits
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 @@ -5,6 +5,7 @@
<ContractTypesPartiallyMoved>true</ContractTypesPartiallyMoved>
</PropertyGroup>
<ItemGroup>
<Compile Include="System\Reflection\Emit\HandleWrappers.cs" />
<Compile Include="System\Reflection\Emit\MetadataHelper.cs" />
<Compile Include="System\Reflection\Emit\AssemblyBuilderImpl.cs" />
<Compile Include="System\Reflection\Emit\FieldBuilderImpl.cs" />
Expand Down
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
@@ -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;
}
}
}
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 @@ -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;
Expand All @@ -13,20 +14,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 List<TypeDefinitionWrapper> _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)
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 +94,90 @@ 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 (TypeDefinitionWrapper typeDefinition in _typeDefinitions)
{
TypeReferenceHandle parent = default;
if (typeBuilder.BaseType is not null)
EntityHandle parent = default;
if (typeDefinition.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(typeDefinition.typeBuilder.BaseType);
}

TypeDefinitionHandle typeDefinitionHandle = MetadataHelper.AddTypeDefinition(metadata, typeBuilder, parent, _nextMethodDefRowId, _nextFieldDefRowId);
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(metadata, method, method.GetMethodSignatureBlob());
MetadataHelper.AddMethodDefinition(_metadataBuilder, method, method.GetMethodSignatureBlob());
_nextMethodDefRowId++;
}

foreach (FieldBuilderImpl field in typeBuilder._fieldDefStore)
foreach (FieldBuilderImpl field in typeDefinition.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 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))
{
return handle;
handle = MetadataHelper.AddAssemblyReference(_metadataBuilder, assembly);
_assemblyReferences.Add(assembly, handle);
}

return MetadataHelper.AddAssemblyReference(assembly, metadata);
return handle;
}

internal EntityHandle GetTypeHandle(Type type)
{
if (type is TypeBuilderImpl tb && Equals(tb.Module))
{
foreach(TypeDefinitionWrapper typeDef in _typeDefinitions)
buyaa-n marked this conversation as resolved.
Show resolved Hide resolved
{
if (!typeDef.typeBuilder.Equals(tb))
{
return typeDef.handle;
}
}
}

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 +196,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(new TypeDefinitionWrapper(_type, typeHandle));
return _type;
}
protected override FieldBuilder DefineUninitializedDataCore(string name, int size, FieldAttributes attributes) => throw new NotImplementedException();
Expand Down
Loading