Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,7 @@ public override IList<CustomAttributeNamedArgument> NamedArguments
if (p.EncodedArgument is not null
&& p.EncodedArgument.CustomAttributeType.EncodedType != CustomAttributeEncoding.Undefined)
{
Debug.Assert(p.MemberInfo is not null);
namedArgs[j++] = new CustomAttributeNamedArgument(
p.MemberInfo,
new CustomAttributeTypedArgument(m_scope, p.EncodedArgument));
Expand Down Expand Up @@ -1114,7 +1115,7 @@ public CustomAttributeType(RuntimeType parameterType)
public Type? EnumType { get; }
}

internal static unsafe class CustomAttribute
internal static unsafe partial class CustomAttribute
{
#region Internal Static Members
internal static bool IsDefined(RuntimeType type, RuntimeType? caType, bool inherit)
Expand Down Expand Up @@ -1526,7 +1527,7 @@ private static void AddCustomAttributes(
object attribute;
if (ctorWithParameters is not null)
{
attribute = CreateCaObject(decoratedModule, attributeType, ctorWithParameters, ref blobStart, blobEnd, out cNamedArgs);
attribute = CreateCustomAttributeInstance(decoratedModule, attributeType, ctorWithParameters, ref blobStart, blobEnd, out cNamedArgs);
}
else
{
Expand Down Expand Up @@ -1794,8 +1795,16 @@ internal static AttributeUsageAttribute GetAttributeUsage(RuntimeType decoratedA
if (attributeUsageAttribute is not null)
throw new FormatException(SR.Format(SR.Format_AttributeUsage, attributeType));

ParseAttributeUsageAttribute(caRecord.blob, out AttributeTargets targets, out bool inherited, out bool allowMultiple);
attributeUsageAttribute = new AttributeUsageAttribute(targets, allowMultiple, inherited);
if (!ParseAttributeUsageAttribute(
caRecord.blob,
out AttributeTargets attrTargets,
out bool allowMultiple,
out bool inherited))
{
throw new CustomAttributeFormatException();
}

attributeUsageAttribute = new AttributeUsageAttribute(attrTargets, allowMultiple: allowMultiple, inherited: inherited);
}

return attributeUsageAttribute ?? AttributeUsageAttribute.Default;
Expand Down Expand Up @@ -1838,42 +1847,93 @@ internal static object[] CreateAttributeArrayHelper(RuntimeType caType, int elem
}
#endregion

#region Private Static FCalls
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void _ParseAttributeUsageAttribute(
IntPtr pCa, int cCa, out int targets, out bool inherited, out bool allowMultiple);
private static void ParseAttributeUsageAttribute(
ConstArray ca, out AttributeTargets targets, out bool inherited, out bool allowMultiple)
{
_ParseAttributeUsageAttribute(ca.Signature, ca.Length, out int _targets, out inherited, out allowMultiple);
targets = (AttributeTargets)_targets;
}

[MethodImpl(MethodImplOptions.InternalCall)]
private static extern object _CreateCaObject(RuntimeModule pModule, RuntimeType type, IRuntimeMethodInfo pCtor, byte** ppBlob, byte* pEndBlob, int* pcNamedArgs);
private static object CreateCaObject(RuntimeModule module, RuntimeType type, IRuntimeMethodInfo ctor, ref IntPtr blob, IntPtr blobEnd, out int namedArgs)
{
byte* pBlob = (byte*)blob;
byte* pBlobEnd = (byte*)blobEnd;
int cNamedArgs;
object ca = _CreateCaObject(module, type, ctor, &pBlob, pBlobEnd, &cNamedArgs);
blob = (IntPtr)pBlob;
namedArgs = cNamedArgs;
return ca;
}
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "CustomAttribute_ParseAttributeUsageAttribute")]
[SuppressGCTransition]
private static partial int ParseAttributeUsageAttribute(
IntPtr pData,
int cData,
int* pTargets,
int* pAllowMultiple,
int* pInherited);

private static bool ParseAttributeUsageAttribute(
ConstArray blob,
out AttributeTargets attrTargets,
out bool allowMultiple,
out bool inherited)
{
int attrTargetsLocal = 0;
int allowMultipleLocal = 0;
int inheritedLocal = 0;
int result = ParseAttributeUsageAttribute(blob.Signature, blob.Length, &attrTargetsLocal, &allowMultipleLocal, &inheritedLocal);
attrTargets = (AttributeTargets)attrTargetsLocal;
allowMultiple = allowMultipleLocal != 0;
inherited = inheritedLocal != 0;
return result != 0;
}

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "CustomAttribute_CreateCustomAttributeInstance")]
private static partial void CreateCustomAttributeInstance(
QCallModule pModule,
ObjectHandleOnStack type,
ObjectHandleOnStack pCtor,
ref IntPtr ppBlob,
IntPtr pEndBlob,
out int pcNamedArgs,
ObjectHandleOnStack instance);

private static object CreateCustomAttributeInstance(RuntimeModule module, RuntimeType type, IRuntimeMethodInfo ctor, ref IntPtr blob, IntPtr blobEnd, out int namedArgs)
{
if (module is null)
{
throw new ArgumentNullException(SR.Arg_InvalidHandle);
}

object? result = null;
CreateCustomAttributeInstance(
new QCallModule(ref module),
ObjectHandleOnStack.Create(ref type),
ObjectHandleOnStack.Create(ref ctor),
ref blob,
blobEnd,
out namedArgs,
ObjectHandleOnStack.Create(ref result));
return result!;
}

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "CustomAttribute_CreatePropertyOrFieldData", StringMarshalling = StringMarshalling.Utf16)]
private static partial void CreatePropertyOrFieldData(
QCallModule pModule,
ref IntPtr ppBlobStart,
IntPtr pBlobEnd,
StringHandleOnStack name,
[MarshalAs(UnmanagedType.Bool)] out bool bIsProperty,
ObjectHandleOnStack type,
ObjectHandleOnStack value);

[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void _GetPropertyOrFieldData(
RuntimeModule pModule, byte** ppBlobStart, byte* pBlobEnd, out string name, out bool bIsProperty, out RuntimeType type, out object value);
private static void GetPropertyOrFieldData(
RuntimeModule module, ref IntPtr blobStart, IntPtr blobEnd, out string name, out bool isProperty, out RuntimeType? type, out object? value)
{
byte* pBlobStart = (byte*)blobStart;
_GetPropertyOrFieldData(
module, &pBlobStart, (byte*)blobEnd, out name, out isProperty, out type, out value);
blobStart = (IntPtr)pBlobStart;
if (module is null)
{
throw new ArgumentNullException(SR.Arg_InvalidHandle);
}

string? nameLocal = null;
RuntimeType? typeLocal = null;
object? valueLocal = null;
CreatePropertyOrFieldData(
new QCallModule(ref module),
ref blobStart,
blobEnd,
new StringHandleOnStack(ref nameLocal),
out isProperty,
ObjectHandleOnStack.Create(ref typeLocal),
ObjectHandleOnStack.Create(ref valueLocal));
name = nameLocal!;
type = typeLocal;
value = valueLocal;
}
#endregion
}

internal static class PseudoCustomAttribute
Expand Down Expand Up @@ -1918,12 +1978,18 @@ private static HashSet<RuntimeType> CreatePseudoCustomAttributeHashSet()
private static void VerifyPseudoCustomAttribute(RuntimeType pca)
{
// If any of these are invariants are no longer true will have to
// re-architect the PCA product logic and test cases -- you've been warned!
Debug.Assert(pca.BaseType == typeof(Attribute), "Pseudo CA Error");
// re-architect the PCA product logic and test cases.
Debug.Assert(pca.BaseType == typeof(Attribute), "Pseudo CA Error - Incorrect base type");
AttributeUsageAttribute usage = CustomAttribute.GetAttributeUsage(pca);
Debug.Assert(!usage.Inherited, "Pseudo CA Error");
// AllowMultiple is true for TypeForwardedToAttribute
// Debug.Assert(usage.AllowMultiple == false, "Pseudo CA Error");
Debug.Assert(!usage.Inherited, "Pseudo CA Error - Unexpected Inherited value");
if (pca == typeof(TypeForwardedToAttribute))
{
Debug.Assert(usage.AllowMultiple, "Pseudo CA Error - Unexpected AllowMultiple value");
}
else
{
Debug.Assert(!usage.AllowMultiple, "Pseudo CA Error - Unexpected AllowMultiple value");
}
}
#endregion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2373,7 +2373,9 @@ private static bool FilterApplyMethodBase(
#region Private Data Members

#pragma warning disable CA1823
#pragma warning disable CS0169
private readonly object m_keepalive; // This will be filled with a LoaderAllocator reference when this RuntimeType represents a collectible type
#pragma warning restore CS0169
#pragma warning restore CA1823
private IntPtr m_cache;
internal IntPtr m_handle;
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/vm/callconvbuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ HRESULT CallConv::TryGetCallingConventionFromUnmanagedCallConv(

InlineFactory<SArray<CaValue>, 4> caValueArrayFactory;
DomainAssembly* domainAssembly = pMD->GetLoaderModule()->GetDomainAssembly();
IfFailThrow(Attribute::ParseAttributeArgumentValues(
IfFailThrow(Attribute::ParseArgumentValues(
pData,
cData,
&caValueArrayFactory,
Expand Down Expand Up @@ -528,7 +528,7 @@ bool CallConv::TryGetCallingConventionFromUnmanagedCallersOnly(_In_ MethodDesc*

InlineFactory<SArray<CaValue>, 4> caValueArrayFactory;
DomainAssembly* domainAssembly = pMD->GetLoaderModule()->GetDomainAssembly();
IfFailThrow(Attribute::ParseAttributeArgumentValues(
IfFailThrow(Attribute::ParseArgumentValues(
pData,
cData,
&caValueArrayFactory,
Expand Down
Loading