Skip to content

Commit 62d33ee

Browse files
buyaa-nAaronRobinsonMSFTsteveharter
authored
Implement remaining unimplemented APIs for Builder types (#96805)
* Implement 'DefinPInvokeMethod', save required/optional CustomModifiers, fix bugs found * Add global method, get method impl and tests * Implement DefineInitializedData(...) and UninitializedData(...), refactor field/method/type token logic because of global members * Update src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs Co-authored-by: Aaron Robinson <arobins@microsoft.com> * Load assemblies in unloadable context Co-authored-by: Steve Harter <steveharter@users.noreply.github.com> * Add test for DefineUninitializedData(...) * Set parameter count to 0 for RtFieldInfo * Throw when member token is not populated when Module.Get***MetadataToken methods called * Retrieving standalone signature not supported on mono * Create byte array with the size directly instead of null check --------- Co-authored-by: Aaron Robinson <arobins@microsoft.com> Co-authored-by: Steve Harter <steveharter@users.noreply.github.com>
1 parent 993b23f commit 62d33ee

23 files changed

+1405
-441
lines changed

src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/RuntimeModuleBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,7 @@ protected override void CreateGlobalFunctionsCore()
829829
if (_hasGlobalBeenCreated)
830830
{
831831
// cannot create globals twice
832-
throw new InvalidOperationException(SR.InvalidOperation_NotADebugModule);
832+
throw new InvalidOperationException(SR.InvalidOperation_GlobalsHaveBeenCreated);
833833
}
834834
_globalTypeBuilder.CreateType();
835835
_hasGlobalBeenCreated = true;

src/coreclr/System.Private.CoreLib/src/System/Reflection/RtFieldInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,12 +256,12 @@ private RuntimeType InitializeFieldType()
256256

257257
public override Type[] GetRequiredCustomModifiers()
258258
{
259-
return GetSignature().GetCustomModifiers(1, true);
259+
return GetSignature().GetCustomModifiers(0, true);
260260
}
261261

262262
public override Type[] GetOptionalCustomModifiers()
263263
{
264-
return GetSignature().GetCustomModifiers(1, false);
264+
return GetSignature().GetCustomModifiers(0, false);
265265
}
266266

267267
internal Signature GetSignature() => new Signature(this, m_declaringType);

src/libraries/System.Reflection.Emit/src/Resources/Strings.resx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,4 +267,25 @@
267267
<data name="Argument_RedefinedLabel" xml:space="preserve">
268268
<value>Label defined multiple times.</value>
269269
</data>
270+
<data name="Argument_BadPInvokeMethod" xml:space="preserve">
271+
<value>PInvoke methods must be static and native and cannot be abstract.</value>
272+
</data>
273+
<data name="Argument_BadPInvokeOnInterface" xml:space="preserve">
274+
<value>PInvoke methods cannot exist on interfaces.</value>
275+
</data>
276+
<data name="Argument_MethodRedefined" xml:space="preserve">
277+
<value>Method has been already defined.</value>
278+
</data>
279+
<data name="Argument_GlobalMembersMustBeStatic" xml:space="preserve">
280+
<value>Global members must be static.</value>
281+
</data>
282+
<data name="InvalidOperation_GlobalsHaveBeenCreated" xml:space="preserve">
283+
<value>Type definition of the global function has been completed.</value>
284+
</data>
285+
<data name="Argument_BadSizeForData" xml:space="preserve">
286+
<value>Data size must be &amp;gt; 1 and &amp;lt; 0x3f0000.</value>
287+
</data>
288+
<data name="InvalidOperation_TokenNotPopulated" xml:space="preserve">
289+
<value>MetadataToken for the member is not generated until the assembly saved.</value>
290+
</data>
270291
</root>

src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/AssemblyBuilderImpl.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ internal static AssemblyBuilderImpl DefinePersistedAssembly(AssemblyName name, A
4444
IEnumerable<CustomAttributeBuilder>? assemblyAttributes)
4545
=> new AssemblyBuilderImpl(name, coreAssembly, assemblyAttributes);
4646

47-
private void WritePEImage(Stream peStream, BlobBuilder ilBuilder)
47+
private void WritePEImage(Stream peStream, BlobBuilder ilBuilder, BlobBuilder fieldData)
4848
{
4949
var peHeaderBuilder = new PEHeaderBuilder(
5050
// For now only support DLL, DLL files are considered executable files
@@ -55,6 +55,7 @@ private void WritePEImage(Stream peStream, BlobBuilder ilBuilder)
5555
header: peHeaderBuilder,
5656
metadataRootBuilder: new MetadataRootBuilder(_metadataBuilder),
5757
ilStream: ilBuilder,
58+
mappedFieldData: fieldData,
5859
strongNameSignatureSize: 0);
5960

6061
// Write executable into the specified stream.
@@ -91,10 +92,11 @@ internal void Save(Stream stream)
9192
_module.WriteCustomAttributes(_customAttributes, assemblyHandle);
9293

9394
var ilBuilder = new BlobBuilder();
95+
var fieldDataBuilder = new BlobBuilder();
9496
MethodBodyStreamEncoder methodBodyEncoder = new MethodBodyStreamEncoder(ilBuilder);
95-
_module.AppendMetadata(methodBodyEncoder);
97+
_module.AppendMetadata(methodBodyEncoder, fieldDataBuilder);
9698

97-
WritePEImage(stream, ilBuilder);
99+
WritePEImage(stream, ilBuilder, fieldDataBuilder);
98100
_previouslySaved = true;
99101
}
100102

@@ -137,5 +139,9 @@ protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan
137139
}
138140

139141
public override string? FullName => _assemblyName.FullName;
142+
143+
public override Module ManifestModule => _module ?? throw new InvalidOperationException(SR.InvalidOperation_AModuleRequired);
144+
145+
public override AssemblyName GetName(bool copiedName) => (AssemblyName)_assemblyName.Clone();
140146
}
141147
}

src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ConstructorBuilderImpl.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ internal sealed class ConstructorBuilderImpl : ConstructorBuilder
1010
internal readonly MethodBuilderImpl _methodBuilder;
1111
internal bool _isDefaultConstructor;
1212

13-
public ConstructorBuilderImpl(string name, MethodAttributes attributes, CallingConventions callingConvention,
14-
Type[]? parameterTypes, ModuleBuilderImpl mod, TypeBuilderImpl type)
13+
public ConstructorBuilderImpl(string name, MethodAttributes attributes, CallingConventions callingConvention, Type[]? parameterTypes,
14+
Type[][]? requiredCustomModifiers, Type[][]? optionalCustomModifiers, ModuleBuilderImpl module, TypeBuilderImpl type)
1515
{
16-
_methodBuilder = new MethodBuilderImpl(name, attributes, callingConvention, null, parameterTypes, mod, type);
16+
_methodBuilder = new MethodBuilderImpl(name, attributes, callingConvention, returnType: null, returnTypeRequiredCustomModifiers: null,
17+
returnTypeOptionalCustomModifiers: null, parameterTypes, requiredCustomModifiers, optionalCustomModifiers, module, type);
1718

1819
type._methodDefinitions.Add(_methodBuilder);
1920
}
@@ -60,7 +61,7 @@ public override CallingConventions CallingConvention
6061
}
6162
}
6263

63-
public override TypeBuilder DeclaringType => _methodBuilder.DeclaringType;
64+
public override Type DeclaringType => _methodBuilder.DeclaringType!;
6465

6566
public override Module Module => _methodBuilder.Module;
6667

src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/FieldBuilderImpl.cs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,34 @@ internal sealed class FieldBuilderImpl : FieldBuilder
1515
private readonly TypeBuilderImpl _typeBuilder;
1616
private readonly string _fieldName;
1717
private readonly Type _fieldType;
18+
private readonly Type[]? _requiredCustomModifiers;
19+
private readonly Type[]? _optionalCustomModifiers;
1820
private FieldAttributes _attributes;
1921

2022
internal MarshallingData? _marshallingData;
2123
internal int _offset;
2224
internal List<CustomAttributeWrapper>? _customAttributes;
2325
internal object? _defaultValue = DBNull.Value;
2426
internal FieldDefinitionHandle _handle;
27+
internal byte[]? _rvaData;
2528

26-
internal FieldBuilderImpl(TypeBuilderImpl typeBuilder, string fieldName, Type type, FieldAttributes attributes)
29+
internal FieldBuilderImpl(TypeBuilderImpl typeBuilder, string fieldName, Type type, FieldAttributes attributes, Type[]? requiredCustomModifiers, Type[]? optionalCustomModifiers)
2730
{
2831
_fieldName = fieldName;
2932
_typeBuilder = typeBuilder;
3033
_fieldType = type;
3134
_attributes = attributes & ~FieldAttributes.ReservedMask;
3235
_offset = -1;
36+
_requiredCustomModifiers = requiredCustomModifiers;
37+
_optionalCustomModifiers = optionalCustomModifiers;
3338
}
3439

3540
protected override void SetConstantCore(object? defaultValue)
3641
{
3742
_typeBuilder.ThrowIfCreated();
3843
ValidateDefaultValueType(defaultValue, _fieldType);
3944
_defaultValue = defaultValue;
45+
_attributes |= FieldAttributes.HasDefault;
4046
}
4147

4248
internal static void ValidateDefaultValueType(object? defaultValue, Type destinationType)
@@ -100,6 +106,12 @@ internal static void ValidateDefaultValueType(object? defaultValue, Type destina
100106
}
101107
}
102108

109+
internal void SetData(byte[] data)
110+
{
111+
_rvaData = data;
112+
_attributes |= FieldAttributes.HasFieldRVA;
113+
}
114+
103115
protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan<byte> binaryAttribute)
104116
{
105117
// Handle pseudo custom attributes
@@ -142,9 +154,9 @@ protected override void SetOffsetCore(int iOffset)
142154

143155
public override string Name => _fieldName;
144156

145-
public override Type? DeclaringType => _typeBuilder;
157+
public override Type? DeclaringType => _typeBuilder._isHiddenGlobalType ? null : _typeBuilder;
146158

147-
public override Type? ReflectedType => _typeBuilder;
159+
public override Type? ReflectedType => DeclaringType;
148160

149161
#endregion
150162

@@ -159,6 +171,10 @@ public override void SetValue(object? obj, object? val, BindingFlags invokeAttr,
159171

160172
public override FieldAttributes Attributes => _attributes;
161173

174+
public override Type[] GetRequiredCustomModifiers() => _requiredCustomModifiers ?? Type.EmptyTypes;
175+
176+
public override Type[] GetOptionalCustomModifiers() => _optionalCustomModifiers ?? Type.EmptyTypes;
177+
162178
#endregion
163179

164180
#region ICustomAttributeProvider Implementation

src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/GenericTypeParameterBuilderImpl.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ internal GenericTypeParameterBuilderImpl(string name, int genParamPosition, Type
2929
_type = typeBuilder;
3030
}
3131

32-
public GenericTypeParameterBuilderImpl(string name, int genParamPosition, MethodBuilderImpl methodBuilder)
32+
public GenericTypeParameterBuilderImpl(string name, int genParamPosition, MethodBuilderImpl methodBuilder, TypeBuilderImpl typeBuilder)
3333
{
3434
_name = name;
3535
_genParamPosition = genParamPosition;
3636
_methodBuilder = methodBuilder;
37-
_type = methodBuilder.DeclaringType;
37+
_type = typeBuilder;
3838
}
3939

4040
protected override void SetBaseTypeConstraintCore([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? baseTypeConstraint)

src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ILGeneratorImpl.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -418,12 +418,12 @@ public override void Emit(OpCode opcode, ConstructorInfo con)
418418

419419
EmitOpcode(opcode);
420420
UpdateStackSize(stackChange);
421-
WriteOrReserveToken(_moduleBuilder.GetMethodMetadataToken(con), con);
421+
WriteOrReserveToken(_moduleBuilder.GetConstructorHandle(con), con);
422422
}
423423

424-
private void WriteOrReserveToken(int token, object member)
424+
private void WriteOrReserveToken(EntityHandle handle, object member)
425425
{
426-
if (token == -1)
426+
if (handle.IsNil)
427427
{
428428
// The member is a `***BuilderImpl` and its token is not yet defined.
429429
// Reserve the token bytes and write them later when its ready
@@ -432,7 +432,7 @@ private void WriteOrReserveToken(int token, object member)
432432
}
433433
else
434434
{
435-
_il.Token(token);
435+
_il.Token(MetadataTokens.GetToken(handle));
436436
}
437437
}
438438

@@ -553,7 +553,7 @@ public override void Emit(OpCode opcode, FieldInfo field)
553553
ArgumentNullException.ThrowIfNull(field);
554554

555555
EmitOpcode(opcode);
556-
WriteOrReserveToken(_moduleBuilder.GetFieldMetadataToken(field), field);
556+
WriteOrReserveToken(_moduleBuilder.GetFieldHandle(field), field);
557557
}
558558

559559
public override void Emit(OpCode opcode, MethodInfo meth)
@@ -567,7 +567,7 @@ public override void Emit(OpCode opcode, MethodInfo meth)
567567
else
568568
{
569569
EmitOpcode(opcode);
570-
WriteOrReserveToken(_moduleBuilder.GetMethodMetadataToken(meth), meth);
570+
WriteOrReserveToken(_moduleBuilder.GetMethodHandle(meth), meth);
571571
}
572572
}
573573

@@ -576,7 +576,7 @@ public override void Emit(OpCode opcode, Type cls)
576576
ArgumentNullException.ThrowIfNull(cls);
577577

578578
EmitOpcode(opcode);
579-
WriteOrReserveToken(_moduleBuilder.GetTypeMetadataToken(cls), cls);
579+
WriteOrReserveToken(_moduleBuilder.GetTypeHandle(cls), cls);
580580
}
581581

582582
public override void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[]? optionalParameterTypes)
@@ -592,11 +592,11 @@ public override void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[]? opti
592592
UpdateStackSize(GetStackChange(opcode, methodInfo, optionalParameterTypes));
593593
if (optionalParameterTypes == null || optionalParameterTypes.Length == 0)
594594
{
595-
WriteOrReserveToken(_moduleBuilder.GetMethodMetadataToken(methodInfo), methodInfo);
595+
WriteOrReserveToken(_moduleBuilder.GetMethodHandle(methodInfo), methodInfo);
596596
}
597597
else
598598
{
599-
WriteOrReserveToken(_moduleBuilder.GetMethodMetadataToken(methodInfo, optionalParameterTypes),
599+
WriteOrReserveToken(_moduleBuilder.GetMethodHandle(methodInfo, optionalParameterTypes),
600600
new KeyValuePair<MethodInfo, Type[]>(methodInfo, optionalParameterTypes));
601601
}
602602
}

0 commit comments

Comments
 (0)