Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,4 @@
<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 @@ -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
@@ -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 @@ -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 @@ -16,14 +17,14 @@ internal sealed class ModuleBuilderImpl : ModuleBuilder
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 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, MetadataBuilder builder)
{
Expand Down Expand Up @@ -113,41 +114,32 @@ 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++;
}
}
}

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

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

Expand All @@ -139,5 +134,6 @@ internal enum CoreTypeId
String,
IntPtr,
UIntPtr,
TypedReference,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ internal interface IAccess

public interface IOneMethod
{
string Func();
object Func();
}

public struct EmptyStruct
Expand Down