Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove more Helper Method Frames #100116

Merged
merged 7 commits into from
Mar 23, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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 @@ -765,7 +766,7 @@ private static void ParseNamedArgs(
}

// Match name
if (!namedParam.MemberInfo.Name.Equals(argName))
if (!namedParam.Name.Equals(argName))
AaronRobinsonMSFT marked this conversation as resolved.
Show resolved Hide resolved
{
continue;
}
Expand Down Expand Up @@ -1057,12 +1058,29 @@ internal sealed class CustomAttributeCtorParameter(CustomAttributeType type)
public CustomAttributeEncodedArgument? EncodedArgument { get; set; }
}

internal sealed class CustomAttributeNamedParameter(MemberInfo memberInfo, CustomAttributeEncoding fieldOrProperty, CustomAttributeType type)
internal sealed class CustomAttributeNamedParameter
{
public MemberInfo MemberInfo => memberInfo;
public CustomAttributeType CustomAttributeType => type;
public CustomAttributeEncoding FieldOrProperty => fieldOrProperty;
public CustomAttributeNamedParameter(MemberInfo memberInfo, CustomAttributeEncoding fieldOrProperty, CustomAttributeType type)
{
MemberInfo = memberInfo;
Name = MemberInfo.Name;
AaronRobinsonMSFT marked this conversation as resolved.
Show resolved Hide resolved
FieldOrProperty = fieldOrProperty;
CustomAttributeType = type;
}

public CustomAttributeNamedParameter(string memberName, CustomAttributeEncoding fieldOrProperty, CustomAttributeType type)
{
MemberInfo = null;
Name = memberName;
FieldOrProperty = fieldOrProperty;
CustomAttributeType = type;
}

public string Name { get; }
public CustomAttributeType CustomAttributeType { get; }
public CustomAttributeEncoding FieldOrProperty { get; }
public CustomAttributeEncodedArgument? EncodedArgument { get; set; }
public MemberInfo? MemberInfo { get; }
}

internal sealed class CustomAttributeType
Expand Down Expand Up @@ -1114,7 +1132,7 @@ public CustomAttributeType(RuntimeType parameterType)
public Type? EnumType { get; }
}

internal static unsafe class CustomAttribute
internal static unsafe partial class CustomAttribute
AaronRobinsonMSFT marked this conversation as resolved.
Show resolved Hide resolved
{
#region Internal Static Members
internal static bool IsDefined(RuntimeType type, RuntimeType? caType, bool inherit)
Expand Down Expand Up @@ -1526,7 +1544,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 @@ -1783,6 +1801,23 @@ internal static AttributeUsageAttribute GetAttributeUsage(RuntimeType decoratedA

AttributeUsageAttribute? attributeUsageAttribute = null;

CustomAttributeCtorParameter[] ctorParams =
{
new CustomAttributeCtorParameter(new CustomAttributeType((RuntimeType)typeof(int)))
};

CustomAttributeNamedParameter[] namedParams =
{
new CustomAttributeNamedParameter(
"Inherited",
CustomAttributeEncoding.Property,
new CustomAttributeType((RuntimeType)typeof(bool))),
new CustomAttributeNamedParameter(
"AllowMultiple",
CustomAttributeEncoding.Property,
new CustomAttributeType((RuntimeType)typeof(bool))),
};

for (int i = 0; i < car.Length; i++)
{
ref CustomAttributeRecord caRecord = ref car[i];
Expand All @@ -1794,8 +1829,26 @@ 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);
CustomAttributeEncodedArgument.ParseAttributeArguments(
AaronRobinsonMSFT marked this conversation as resolved.
Show resolved Hide resolved
caRecord.blob,
ctorParams,
namedParams,
(RuntimeModule)typeof(AttributeUsageAttribute).Module);

// Convert parsed attribute arguments
AttributeTargets attrTargets = (AttributeTargets)(ctorParams[0].EncodedArgument?.PrimitiveValue.Byte4 ?? 0);

CustomAttributeEncodedArgument? encodedArg = namedParams[0].EncodedArgument;
bool inherited = encodedArg is not null
? encodedArg.PrimitiveValue.Byte4 != 0
: true; // default

encodedArg = namedParams[1].EncodedArgument;
bool allowMultiple = encodedArg is not null
? encodedArg.PrimitiveValue.Byte4 != 0
: false; // default

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

return attributeUsageAttribute ?? AttributeUsageAttribute.Default;
Expand Down Expand Up @@ -1838,42 +1891,68 @@ 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_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 +1997,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
AaronRobinsonMSFT marked this conversation as resolved.
Show resolved Hide resolved
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
Loading