Skip to content

Commit 2a75e65

Browse files
AssemblyBuilder.Save add custom attributes handling. (#84580)
* Initial custom attributes handling * Pseudo custom attributes handling and tests * Use ReadOnlySpan for CustomAttribute binaryData * Update some pseudo attributes handling and apply feedback * Add one more pseudo attribute and a few small changes * Move pseudo attributes handling * Remove type loading logic from CustomAttributes parsing, use constants for some values * Add MarshalAsAttribute handling and apply other feedbacks --------- Co-authored-by: Aaron Robinson <[email protected]>
1 parent 184d17d commit 2a75e65

File tree

48 files changed

+1654
-437
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1654
-437
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,14 @@ namespace System.Reflection.Emit
2121
{
2222
public class CustomAttributeBuilder
2323
{
24-
internal readonly ConstructorInfo m_con;
24+
private readonly ConstructorInfo m_con;
2525
private readonly object?[] m_constructorArgs;
2626
private readonly byte[] m_blob;
2727

28+
internal ConstructorInfo Ctor => m_con;
29+
30+
internal byte[] Data => m_blob;
31+
2832
// public constructor to form the custom attribute with constructor and constructor
2933
// parameters.
3034
public CustomAttributeBuilder(ConstructorInfo con, object?[] constructorArgs) :

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

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ public override Assembly GetSatelliteAssembly(CultureInfo culture, Version? vers
288288
/// <summary>
289289
/// Use this function if client decides to form the custom attribute blob themselves.
290290
/// </summary>
291-
protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute)
291+
protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan<byte> binaryAttribute)
292292
{
293293
lock (SyncRoot)
294294
{
@@ -299,16 +299,5 @@ protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binar
299299
binaryAttribute);
300300
}
301301
}
302-
303-
/// <summary>
304-
/// Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder.
305-
/// </summary>
306-
protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder)
307-
{
308-
lock (SyncRoot)
309-
{
310-
customBuilder.CreateCustomAttribute(_manifestModuleBuilder, AssemblyDefToken);
311-
}
312-
}
313302
}
314303
}

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,16 +157,11 @@ internal override Type GetReturnType()
157157
return m_methodBuilder.ReturnType;
158158
}
159159

160-
protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute)
160+
protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan<byte> binaryAttribute)
161161
{
162162
m_methodBuilder.SetCustomAttribute(con, binaryAttribute);
163163
}
164164

165-
protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder)
166-
{
167-
m_methodBuilder.SetCustomAttribute(customBuilder);
168-
}
169-
170165
protected override void SetImplementationFlagsCore(MethodImplAttributes attributes)
171166
{
172167
m_methodBuilder.SetImplementationFlags(attributes);

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

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -274,26 +274,18 @@ public override object[] GetCustomAttributes(Type attributeType, bool inherit)
274274
}
275275

276276
// Use this function if client decides to form the custom attribute blob themselves
277-
278-
protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute)
277+
protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan<byte> binaryAttribute)
279278
{
280279
m_typeBuilder.SetCustomAttribute(con, binaryAttribute);
281280
}
282281

283-
// Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder
284-
protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder)
285-
{
286-
m_typeBuilder.SetCustomAttribute(customBuilder);
287-
}
288-
289282
// Return the class that declared this Field.
290283
public override Type? DeclaringType => m_typeBuilder.DeclaringType;
291284

292285
// Return the class that was used to obtain this field.
293286

294287
public override Type? ReflectedType => m_typeBuilder.ReflectedType;
295288

296-
297289
// Returns true if one or more instance of attributeType is defined on this member.
298290
public override bool IsDefined(Type attributeType, bool inherit)
299291
{
@@ -329,7 +321,6 @@ public override Type MakeArrayType(int rank)
329321
return SymbolType.FormCompoundType(s, this, 0)!;
330322
}
331323

332-
333324
// Constructs a EnumBuilder.
334325
// EnumBuilder can only be a top-level (not nested) enum type.
335326
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2064:UnrecognizedReflectionPattern",

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

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ protected override void AddOtherMethodCore(MethodBuilder mdBuilder)
8080

8181
// Use this function if client decides to form the custom attribute blob themselves
8282

83-
protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute)
83+
protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan<byte> binaryAttribute)
8484
{
8585
m_type.ThrowIfCreated();
8686

@@ -91,13 +91,6 @@ protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binar
9191
binaryAttribute);
9292
}
9393

94-
// Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder
95-
protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder)
96-
{
97-
m_type.ThrowIfCreated();
98-
customBuilder.CreateCustomAttribute(m_module, m_evToken);
99-
}
100-
10194
private readonly string m_name; // The name of the event
10295
private readonly int m_evToken; // The token of this event
10396
private readonly RuntimeModuleBuilder m_module;

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

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ protected override void SetConstantCore(object? defaultValue)
150150
RuntimeTypeBuilder.SetConstantValue(m_typeBuilder.GetModuleBuilder(), m_fieldTok, m_fieldType, defaultValue);
151151
}
152152

153-
protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute)
153+
protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan<byte> binaryAttribute)
154154
{
155155
RuntimeModuleBuilder moduleBuilder = (RuntimeModuleBuilder)m_typeBuilder.Module;
156156

@@ -160,13 +160,6 @@ protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binar
160160
m_fieldTok, moduleBuilder.GetMethodMetadataToken(con), binaryAttribute);
161161
}
162162

163-
protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder)
164-
{
165-
m_typeBuilder.ThrowIfCreated();
166-
167-
customBuilder.CreateCustomAttribute((RuntimeModuleBuilder)m_typeBuilder.Module, m_fieldTok);
168-
}
169-
170163
#endregion
171164
}
172165
}

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -215,16 +215,11 @@ public override Type MakeArrayType(int rank)
215215
#endregion
216216

217217
#region Protected Members Overrides
218-
protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute)
218+
protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan<byte> binaryAttribute)
219219
{
220220
m_type.SetGenParamCustomAttribute(con, binaryAttribute);
221221
}
222222

223-
protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder)
224-
{
225-
m_type.SetGenParamCustomAttribute(customBuilder);
226-
}
227-
228223
protected override void SetBaseTypeConstraintCore([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type? baseTypeConstraint)
229224
{
230225
m_type.SetParent(baseTypeConstraint);

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

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,7 @@ internal Module GetModule()
695695
return GetModuleBuilder();
696696
}
697697

698-
protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute)
698+
protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan<byte> binaryAttribute)
699699
{
700700
ThrowIfGeneric();
701701
RuntimeTypeBuilder.DefineCustomAttribute(m_module, MetadataToken,
@@ -706,15 +706,6 @@ protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binar
706706
ParseCA(con);
707707
}
708708

709-
protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder)
710-
{
711-
ThrowIfGeneric();
712-
customBuilder.CreateCustomAttribute(m_module, MetadataToken);
713-
714-
if (IsKnownCA(customBuilder.m_con))
715-
ParseCA(customBuilder.m_con);
716-
}
717-
718709
// this method should return true for any and every ca that requires more work
719710
// than just setting the ca
720711
private static bool IsKnownCA(ConstructorInfo con)

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,7 +1289,7 @@ internal int GetSignatureToken(byte[] sigBytes, int sigLength)
12891289

12901290
#region Other
12911291

1292-
protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute)
1292+
protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan<byte> binaryAttribute)
12931293
{
12941294
RuntimeTypeBuilder.DefineCustomAttribute(
12951295
this,
@@ -1298,11 +1298,6 @@ protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binar
12981298
binaryAttribute);
12991299
}
13001300

1301-
protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder)
1302-
{
1303-
customBuilder.CreateCustomAttribute(this, 1); // This is hard coding the module token to 1
1304-
}
1305-
13061301
#endregion
13071302

13081303
#endregion

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

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,7 @@ protected override void AddOtherMethodCore(MethodBuilder mdBuilder)
9797
}
9898

9999
// Use this function if client decides to form the custom attribute blob themselves
100-
101-
protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute)
100+
protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan<byte> binaryAttribute)
102101
{
103102
m_containingType.ThrowIfCreated();
104103
RuntimeTypeBuilder.DefineCustomAttribute(
@@ -108,13 +107,6 @@ protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binar
108107
binaryAttribute);
109108
}
110109

111-
// Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder
112-
protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder)
113-
{
114-
m_containingType.ThrowIfCreated();
115-
customBuilder.CreateCustomAttribute(m_moduleBuilder, m_tkProperty);
116-
}
117-
118110
// Not supported functions in dynamic module.
119111
public override object GetValue(object? obj, object?[]? index)
120112
{

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

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,12 @@ private sealed class CustAttr
111111
private readonly byte[]? m_binaryAttribute;
112112
private readonly CustomAttributeBuilder? m_customBuilder;
113113

114-
public CustAttr(ConstructorInfo con, byte[] binaryAttribute)
114+
public CustAttr(ConstructorInfo con, ReadOnlySpan<byte> binaryAttribute)
115115
{
116116
ArgumentNullException.ThrowIfNull(con);
117-
ArgumentNullException.ThrowIfNull(binaryAttribute);
118117

119118
m_con = con;
120-
m_binaryAttribute = binaryAttribute;
119+
m_binaryAttribute = binaryAttribute.ToArray();
121120
}
122121

123122
public CustAttr(CustomAttributeBuilder customBuilder)
@@ -173,21 +172,13 @@ private static partial void SetMethodIL(QCallModule module, int tk, [MarshalAs(U
173172

174173
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "TypeBuilder_DefineCustomAttribute")]
175174
private static partial void DefineCustomAttribute(QCallModule module, int tkAssociate, int tkConstructor,
176-
byte[]? attr, int attrLength);
175+
ReadOnlySpan<byte> attr, int attrLength);
177176

178177
internal static void DefineCustomAttribute(RuntimeModuleBuilder module, int tkAssociate, int tkConstructor,
179-
byte[]? attr)
178+
ReadOnlySpan<byte> attr)
180179
{
181-
byte[]? localAttr = null;
182-
183-
if (attr != null)
184-
{
185-
localAttr = new byte[attr.Length];
186-
Buffer.BlockCopy(attr, 0, localAttr, 0, attr.Length);
187-
}
188-
189180
DefineCustomAttribute(new QCallModule(ref module), tkAssociate, tkConstructor,
190-
localAttr, (localAttr != null) ? localAttr.Length : 0);
181+
attr, attr.Length);
191182
}
192183

193184
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "TypeBuilder_DefineProperty", StringMarshalling = StringMarshalling.Utf16)]
@@ -670,7 +661,7 @@ internal void SetGenParamAttributes(GenericParameterAttributes genericParameterA
670661
m_genParamAttributes = genericParameterAttributes;
671662
}
672663

673-
internal void SetGenParamCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
664+
internal void SetGenParamCustomAttribute(ConstructorInfo con, ReadOnlySpan<byte> binaryAttribute)
674665
{
675666
CustAttr ca = new CustAttr(con, binaryAttribute);
676667

@@ -1858,14 +1849,14 @@ internal int TypeToken
18581849
}
18591850
}
18601851

1861-
protected override void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute)
1852+
internal void SetCustomAttribute(ConstructorInfo con, ReadOnlySpan<byte> binaryAttribute)
18621853
{
1863-
DefineCustomAttribute(m_module, m_tdType, m_module.GetMethodMetadataToken(con), binaryAttribute);
1854+
SetCustomAttributeCore(con, binaryAttribute);
18641855
}
18651856

1866-
protected override void SetCustomAttributeCore(CustomAttributeBuilder customBuilder)
1857+
protected override void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan<byte> binaryAttribute)
18671858
{
1868-
customBuilder.CreateCustomAttribute(m_module, m_tdType);
1859+
DefineCustomAttribute(m_module, m_tdType, m_module.GetMethodMetadataToken(con), binaryAttribute);
18691860
}
18701861

18711862
#endregion

src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,10 @@ public CustomAttributeBuilder(ConstructorInfo con, object[] constructorArgs, Pro
2424
{
2525
ReflectionEmitThrower.ThrowPlatformNotSupportedException();
2626
}
27+
28+
#pragma warning disable CA1822 // Member 'Ctor' does not access instance data and can be marked as static
29+
internal ConstructorInfo Ctor => default;
30+
internal byte[] Data => default;
31+
#pragma warning restore CA1822
2732
}
2833
}

src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,15 @@ public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
3939
SetCustomAttributeCore(con, binaryAttribute);
4040
}
4141

42-
protected abstract void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute);
42+
protected abstract void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan<byte> binaryAttribute);
4343

4444
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
4545
{
4646
ArgumentNullException.ThrowIfNull(customBuilder);
4747

48-
SetCustomAttributeCore(customBuilder);
48+
SetCustomAttributeCore(customBuilder.Ctor, customBuilder.Data);
4949
}
5050

51-
protected abstract void SetCustomAttributeCore(CustomAttributeBuilder customBuilder);
52-
5351
[System.ObsoleteAttribute("Assembly.CodeBase and Assembly.EscapedCodeBase are only included for .NET Framework compatibility. Use Assembly.Location instead.", DiagnosticId = "SYSLIB0012", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")]
5452
[RequiresAssemblyFiles(ThrowingMessageInRAF)]
5553
public override string? CodeBase => throw new NotSupportedException(SR.NotSupported_DynamicAssembly);

src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/ConstructorBuilder.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,21 @@ public ILGenerator GetILGenerator(int streamSize)
3131
protected abstract ILGenerator GetILGeneratorCore(int streamSize);
3232

3333
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
34-
=> SetCustomAttributeCore(con, binaryAttribute);
34+
{
35+
ArgumentNullException.ThrowIfNull(con);
36+
ArgumentNullException.ThrowIfNull(binaryAttribute);
37+
38+
SetCustomAttributeCore(con, binaryAttribute);
39+
}
3540

36-
protected abstract void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute);
41+
protected abstract void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan<byte> binaryAttribute);
3742

3843
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
39-
=> SetCustomAttributeCore(customBuilder);
44+
{
45+
ArgumentNullException.ThrowIfNull(customBuilder);
4046

41-
protected abstract void SetCustomAttributeCore(CustomAttributeBuilder customBuilder);
47+
SetCustomAttributeCore(customBuilder.Ctor, customBuilder.Data);
48+
}
4249

4350
public void SetImplementationFlags(MethodImplAttributes attributes)
4451
=> SetImplementationFlagsCore(attributes);

src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,9 @@ public FieldBuilder DefineLiteral(string literalName, object? literalValue)
3535
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
3636
=> SetCustomAttributeCore(con, binaryAttribute);
3737

38-
protected abstract void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute);
38+
protected abstract void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan<byte> binaryAttribute);
3939

4040
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
41-
=> SetCustomAttributeCore(customBuilder);
42-
43-
protected abstract void SetCustomAttributeCore(CustomAttributeBuilder customBuilder);
41+
=> SetCustomAttributeCore(customBuilder.Ctor, customBuilder.Data);
4442
}
4543
}

src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/EventBuilder.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,15 @@ public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
2727
SetCustomAttributeCore(con, binaryAttribute);
2828
}
2929

30-
protected abstract void SetCustomAttributeCore(ConstructorInfo con, byte[] binaryAttribute);
30+
protected abstract void SetCustomAttributeCore(ConstructorInfo con, ReadOnlySpan<byte> binaryAttribute);
3131

3232
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
3333
{
3434
ArgumentNullException.ThrowIfNull(customBuilder);
3535

36-
SetCustomAttributeCore(customBuilder);
36+
SetCustomAttributeCore(customBuilder.Ctor, customBuilder.Data);
3737
}
3838

39-
protected abstract void SetCustomAttributeCore(CustomAttributeBuilder customBuilder);
40-
4139
public void SetRaiseMethod(MethodBuilder mdBuilder)
4240
=> SetRaiseMethodCore(mdBuilder);
4341

0 commit comments

Comments
 (0)