namespace System.Reflection.Emit
{
- // This static helper class adds common entities to a Metadata Builder.
+ // This static helper class adds common entities to a MetadataBuilder.
internal static class MetadataHelper
{
internal static AssemblyReferenceHandle AddAssemblyReference(Assembly assembly, MetadataBuilder metadata)
// Add type metadata
return metadata.AddTypeDefinition(
attributes: typeBuilder.Attributes,
- (typeBuilder.Namespace == null) ? default : metadata.GetOrAddString(typeBuilder.Namespace),
+ @namespace: (typeBuilder.Namespace == null) ? default : metadata.GetOrAddString(typeBuilder.Namespace),
name: metadata.GetOrAddString(typeBuilder.Name),
baseType: baseType,
fieldList: MetadataTokens.FieldDefinitionHandle(fieldToken),
internal static TypeReferenceHandle AddTypeReference(MetadataBuilder metadata, AssemblyReferenceHandle parent, string name, string? nameSpace)
{
return metadata.AddTypeReference(
- parent,
- (nameSpace == null) ? default : metadata.GetOrAddString(nameSpace),
- metadata.GetOrAddString(name)
+ 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(
- methodBuilder.Attributes,
- MethodImplAttributes.IL,
- metadata.GetOrAddString(methodBuilder.Name),
- metadata.GetOrAddBlob(methodSignatureBlob),
- -1, // No body supported yet
+ 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)
+ internal static FieldDefinitionHandle AddFieldDefinition(MetadataBuilder metadata, FieldInfo field, BlobBuilder fieldSignatureBlob)
{
- return metadata.AddFieldDefinition(field.Attributes, metadata.GetOrAddString(field.Name),
- metadata.GetOrAddBlob(MetadataSignatureHelper.FieldSignatureEncoder(field.FieldType)));
+ return metadata.AddFieldDefinition(
+ attributes: field.Attributes,
+ name: metadata.GetOrAddString(field.Name),
+ signature: metadata.GetOrAddBlob(fieldSignatureBlob));
}
}
}
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Reflection.Metadata;
-using System.Reflection.Metadata.Ecma335;
namespace System.Reflection.Emit
{
Type[]? parameterTypes, ModuleBuilderImpl module, TypeBuilderImpl declaringType)
{
_module = module;
- _returnType = returnType ?? _module.GetTypeFromCoreAssembly("System.Void"); ;
+ _returnType = returnType ?? _module.GetTypeFromCoreAssembly(CoreTypeId.Void);
_name = name;
_attributes = attributes;
_callingConventions = callingConventions;
{
private readonly Assembly _coreAssembly;
private readonly string _name;
- private readonly Dictionary<string, Type> _coreTypes = new();
+ private Type?[]? _coreTypes;
private readonly Dictionary<Assembly, AssemblyReferenceHandle> _assemblyRefStore = new();
private readonly Dictionary<Type, TypeReferenceHandle> _typeRefStore = new();
private readonly List<TypeBuilderImpl> _typeDefStore = new();
private int _nextMethodDefRowId = 1;
private int _nextFieldDefRowId = 1;
+ private bool _coreTypesFullPopulated;
+ 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)
{
_name = name;
}
- internal Type GetTypeFromCoreAssembly(string name)
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Types are preserved via s_coreTypes")]
+ internal Type GetTypeFromCoreAssembly(CoreTypeId typeId)
{
- Type? type;
+ if (_coreTypes == null)
+ {
+ // Use s_coreTypes directly for runtime reflection
+ if (_coreAssembly == typeof(object).Assembly)
+ {
+ _coreTypes = s_coreTypes;
+ _coreTypesFullPopulated = true;
+ }
+ else
+ {
+ _coreTypes = new Type[s_coreTypes.Length];
+ }
+ }
- // TODO: Use Enum as the key for perf
- if (!_coreTypes.TryGetValue(name, out type))
+ int index = (int)typeId;
+ return _coreTypes[index] ?? (_coreTypes[index] = _coreAssembly.GetType(s_coreTypes[index].FullName!, throwOnError: true)!);
+ }
+
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "Types are preserved via s_coreTypes")]
+ internal CoreTypeId? GetTypeIdFromCoreTypes(Type type)
+ {
+ if (_coreTypes == null)
{
-#pragma warning disable IL2026 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code
- type = _coreAssembly.GetType(name, throwOnError: true)!;
-#pragma warning restore IL2026
- _coreTypes.Add(name, type);
+ // Use s_coreTypes directly for runtime reflection
+ if (_coreAssembly == typeof(object).Assembly)
+ {
+ _coreTypes = s_coreTypes;
+ _coreTypesFullPopulated = true;
+ }
+ else
+ {
+ _coreTypes = new Type[s_coreTypes.Length];
+ }
+ }
+
+ if (!_coreTypesFullPopulated)
+ {
+ for (int i = 0; i < _coreTypes.Length; i++)
+ {
+ if (_coreTypes[i] == null)
+ {
+ _coreTypes[i] = _coreAssembly.GetType(s_coreTypes[i].FullName!, throwOnError: false)!;
+ }
+ }
+ _coreTypesFullPopulated = true;
+ }
+
+ for (int i = 0; i < _coreTypes.Length; i++)
+ {
+ if (_coreTypes[i] == type)
+ {
+ return (CoreTypeId)i;
+ }
}
- return type;
+ return null;
}
internal void AppendMetadata(MetadataBuilder metadata)
foreach (FieldBuilderImpl field in typeBuilder._fieldDefStore)
{
- MetadataHelper.AddFieldDefinition(metadata, field);
+ MetadataHelper.AddFieldDefinition(metadata, field, MetadataSignatureHelper.FieldSignatureEncoder(field.FieldType, this));
_nextFieldDefRowId++;
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Diagnostics.CodeAnalysis;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
// TODO: Only support simple signatures. More complex signatures will be added.
internal static class MetadataSignatureHelper
{
- internal static BlobBuilder FieldSignatureEncoder(Type fieldType)
+ internal static BlobBuilder FieldSignatureEncoder(Type fieldType, ModuleBuilderImpl module)
{
BlobBuilder fieldSignature = new();
- WriteSignatureTypeForReflectionType(new BlobEncoder(fieldSignature).FieldSignature(), fieldType);
+ WriteSignatureTypeForReflectionType(new BlobEncoder(fieldSignature).FieldSignature(), fieldType, module);
return fieldSignature;
}
- internal static BlobBuilder MethodSignatureEncoder(ModuleBuilderImpl _module, Type[]? parameters, Type? returnType, bool isInstance)
+ internal static BlobBuilder MethodSignatureEncoder(ModuleBuilderImpl module, Type[]? parameters, Type? returnType, bool isInstance)
{
// Encoding return type and parameters.
BlobBuilder methodSignature = new();
MethodSignature(isInstanceMethod: isInstance).
Parameters((parameters == null) ? 0 : parameters.Length, out retEncoder, out parEncoder);
- if (returnType != null && returnType != _module.GetTypeFromCoreAssembly("System.Void"))
+ if (returnType != null && returnType != module.GetTypeFromCoreAssembly(CoreTypeId.Void))
{
- WriteSignatureTypeForReflectionType(retEncoder.Type(), returnType);
+ WriteSignatureTypeForReflectionType(retEncoder.Type(), returnType, module);
}
else // If null mark ReturnTypeEncoder as void
{
{
foreach (Type parameter in parameters)
{
- WriteSignatureTypeForReflectionType(parEncoder.AddParameter().Type(), parameter);
+ WriteSignatureTypeForReflectionType(parEncoder.AddParameter().Type(), parameter, module);
}
}
return methodSignature;
}
- private static void WriteSignatureTypeForReflectionType(SignatureTypeEncoder signature, Type type)
+ private static void WriteSignatureTypeForReflectionType(SignatureTypeEncoder signature, Type type, ModuleBuilderImpl module)
{
- // We need to translate from Reflection.Type to SignatureTypeEncoder. Most common types for proof of concept. More types will be added.
- // TODO: This switch should be done by comparing Type objects, without fetching FullName.
- switch (type.FullName)
+ CoreTypeId? typeId = module.GetTypeIdFromCoreTypes(type);
+
+ // We need to translate from Reflection.Type to SignatureTypeEncoder.
+ switch (typeId)
{
- case "System.Boolean":
+ case CoreTypeId.Boolean:
signature.Boolean();
break;
- case "System.Byte":
+ case CoreTypeId.Byte:
signature.Byte();
break;
- case "System.Char":
+ case CoreTypeId.SByte:
+ signature.SByte();
+ break;
+ case CoreTypeId.Char:
signature.Char();
break;
- case "System.Double":
- signature.Double();
+ case CoreTypeId.Int16:
+ signature.Int16();
+ break;
+ case CoreTypeId.UInt16:
+ signature.UInt16();
break;
- case "System.Int32":
+ case CoreTypeId.Int32:
signature.Int32();
break;
- case "System.Int64":
+ case CoreTypeId.UInt32:
+ signature.UInt32();
+ break;
+ case CoreTypeId.Int64:
signature.Int64();
break;
- case "System.Object":
+ 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 "System.String":
+ case CoreTypeId.String:
signature.String();
break;
-
- default: throw new NotSupportedException(SR.Format(SR.NotSupported_Signature, type.FullName));
+ default:
+ throw new NotSupportedException(SR.Format(SR.NotSupported_Signature, type.FullName));
}
}
}
+
+ internal enum CoreTypeId
+ {
+ Void,
+ Object,
+ Boolean,
+ Char,
+ SByte,
+ Byte,
+ Int16,
+ UInt16,
+ Int32,
+ UInt32,
+ Int64,
+ UInt64,
+ Single,
+ Double,
+ String,
+ IntPtr,
+ UIntPtr,
+ }
}
protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute) => throw new NotImplementedException();
protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder) => throw new NotImplementedException();
- protected override void SetParentCore([DynamicallyAccessedMembers((DynamicallyAccessedMemberTypes)(-1))] Type? parent)
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2074:DynamicallyAccessedMembers",
+ Justification = "TODO: Need to figure out how to preserve System.Object public constructor")]
+ protected override void SetParentCore([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? parent)
{
if (parent != null)
{
{
if ((_attributes & TypeAttributes.Interface) != TypeAttributes.Interface)
{
-#pragma warning disable IL2074 // Value stored in field does not satisfy 'DynamicallyAccessedMembersAttribute' requirements. The return value of the source method does not have matching annotations.
- _typeParent = _module.GetTypeFromCoreAssembly("System.Object");
-#pragma warning restore IL2074
+ _typeParent = _module.GetTypeFromCoreAssembly(CoreTypeId.Object);
}
else
{
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(IMultipleMethod), typeof(EmptyStruct), typeof(INoMethod2), typeof(StructWithField) } };
}
[Theory]