Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

System.Reflection: Replicate custom modifiers of method parameters in MemberRef signatures #17881

Merged
3 commits merged into from
May 16, 2018
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 @@ -216,6 +216,8 @@ public override void EmitCalli(OpCode opcode,
sig = GetMemberRefSignature(callingConvention,
returnType,
parameterTypes,
null,
null,
optionalParameterTypes);

EnsureCapacity(7);
Expand Down Expand Up @@ -440,8 +442,6 @@ public override void EndScope()

private int GetMemberRefToken(MethodBase methodInfo, Type[] optionalParameterTypes)
{
Type[] parameterTypes;

if (optionalParameterTypes != null && (methodInfo.CallingConvention & CallingConventions.VarArgs) == 0)
throw new InvalidOperationException(SR.InvalidOperation_NotAVarArgCallingConvention);

Expand All @@ -451,21 +451,17 @@ private int GetMemberRefToken(MethodBase methodInfo, Type[] optionalParameterTyp
if (rtMeth == null && dm == null)
throw new ArgumentException(SR.Argument_MustBeRuntimeMethodInfo, nameof(methodInfo));

ParameterInfo[] paramInfo = methodInfo.GetParametersNoCopy();
if (paramInfo != null && paramInfo.Length != 0)
{
parameterTypes = new Type[paramInfo.Length];
for (int i = 0; i < paramInfo.Length; i++)
parameterTypes[i] = paramInfo[i].ParameterType;
}
else
{
parameterTypes = null;
}
SignatureHelper.ExtractParametersTypeArrays(
methodInfo.GetParametersNoCopy(),
out Type[] parameterTypes,
out Type[][] parameterTypeRequiredCustomModifiers,
out Type[][] parameterTypeOptionalCustomModifiers);

SignatureHelper sig = GetMemberRefSignature(methodInfo.CallingConvention,
MethodBuilder.GetMethodBaseReturnType(methodInfo),
parameterTypes,
parameterTypeRequiredCustomModifiers,
parameterTypeOptionalCustomModifiers,
optionalParameterTypes);

if (rtMeth != null)
Expand All @@ -478,13 +474,24 @@ internal override SignatureHelper GetMemberRefSignature(
CallingConventions call,
Type returnType,
Type[] parameterTypes,
Type[][] parameterTypeRequiredCustomModifiers,
Type[][] parameterTypeOptionalCustomModifiers,
Type[] optionalParameterTypes)
{
SignatureHelper sig = SignatureHelper.GetMethodSigHelper(call, returnType);

Debug.Assert(parameterTypeRequiredCustomModifiers == null
|| (parameterTypeRequiredCustomModifiers.Length == (parameterTypes?.Length ?? 0)));

Debug.Assert(parameterTypeOptionalCustomModifiers == null
|| (parameterTypeOptionalCustomModifiers.Length == (parameterTypes?.Length ?? 0)));

if (parameterTypes != null)
{
foreach (Type t in parameterTypes)
sig.AddArgument(t);
for (int i = 0; i < parameterTypes.Length; i++)
{
sig.AddArgument(parameterTypes[i], parameterTypeRequiredCustomModifiers?[i], parameterTypeOptionalCustomModifiers?[i]);
}
}
if (optionalParameterTypes != null && optionalParameterTypes.Length != 0)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,15 +207,17 @@ private int GetMethodToken(MethodBase method, Type[] optionalParameterTypes, boo
}

internal virtual SignatureHelper GetMemberRefSignature(CallingConventions call, Type returnType,
Type[] parameterTypes, Type[] optionalParameterTypes)
Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers,
Type[] optionalParameterTypes)
{
return GetMemberRefSignature(call, returnType, parameterTypes, optionalParameterTypes, 0);
return GetMemberRefSignature(call, returnType, parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, optionalParameterTypes, 0);
}

private SignatureHelper GetMemberRefSignature(CallingConventions call, Type returnType,
Type[] parameterTypes, Type[] optionalParameterTypes, int cGenericParameters)
Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers,
Type[] optionalParameterTypes, int cGenericParameters)
{
return ((ModuleBuilder)m_methodBuilder.Module).GetMemberRefSignature(call, returnType, parameterTypes, optionalParameterTypes, cGenericParameters);
return ((ModuleBuilder)m_methodBuilder.Module).GetMemberRefSignature(call, returnType, parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, optionalParameterTypes, cGenericParameters);
}

internal byte[] BakeByteArray()
Expand Down Expand Up @@ -506,6 +508,8 @@ public virtual void EmitCalli(OpCode opcode, CallingConventions callingConventio
sig = GetMemberRefSignature(callingConvention,
returnType,
parameterTypes,
null,
null,
optionalParameterTypes);

EnsureCapacity(7);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,21 +298,18 @@ internal MethodToken InternalGetConstructorToken(ConstructorInfo con, bool using
ParameterInfo[] parameters = con.GetParameters();
if (parameters == null)
throw new ArgumentException(SR.Argument_InvalidConstructorInfo);

Type[] parameterTypes = new Type[parameters.Length];
Type[][] requiredCustomModifiers = new Type[parameters.Length][];
Type[][] optionalCustomModifiers = new Type[parameters.Length][];

for (int i = 0; i < parameters.Length; i++)
{
if (parameters[i] == null)
throw new ArgumentException(SR.Argument_InvalidConstructorInfo);

parameterTypes[i] = parameters[i].ParameterType;
requiredCustomModifiers[i] = parameters[i].GetRequiredCustomModifiers();
optionalCustomModifiers[i] = parameters[i].GetOptionalCustomModifiers();
}

SignatureHelper.ExtractParametersTypeArrays(
parameters,
out Type[] parameterTypes,
out Type[][] requiredCustomModifiers,
out Type[][] optionalCustomModifiers);

tr = GetTypeTokenInternal(con.ReflectedType).Token;

SignatureHelper sigHelp = SignatureHelper.GetMethodSigHelper(this, con.CallingConvention, null, null, null, parameterTypes, requiredCustomModifiers, optionalCustomModifiers);
Expand Down Expand Up @@ -380,7 +377,7 @@ private static RuntimeModule GetRuntimeModuleFromModule(Module m)

private int GetMemberRefToken(MethodBase method, IEnumerable<Type> optionalParameterTypes)
{
Type[] parameterTypes;
ParameterInfo[] parameters;
Type returnType;
int tkParent;
int cGenericParameters = 0;
Expand Down Expand Up @@ -447,17 +444,24 @@ private int GetMemberRefToken(MethodBase method, IEnumerable<Type> optionalParam
}
}

parameterTypes = methDef.GetParameterTypes();
parameters = methDef.GetParameters();
returnType = MethodBuilder.GetMethodBaseReturnType(methDef);
}
else
{
parameterTypes = method.GetParameterTypes();
parameters = method.GetParameters();
returnType = MethodBuilder.GetMethodBaseReturnType(method);
}

SignatureHelper.ExtractParametersTypeArrays(
parameters,
out Type[] parameterTypes,
out Type[][] parameterTypeRequiredCustomModifiers,
out Type[][] parameterTypeOptionalCustomModifiers);

int sigLength;
byte[] sigBytes = GetMemberRefSignature(method.CallingConvention, returnType, parameterTypes,
parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers,
optionalParameterTypes, cGenericParameters).InternalGetSignature(out sigLength);

if (method.DeclaringType.IsGenericType)
Expand All @@ -484,15 +488,22 @@ private int GetMemberRefToken(MethodBase method, IEnumerable<Type> optionalParam
}

internal SignatureHelper GetMemberRefSignature(CallingConventions call, Type returnType,
Type[] parameterTypes, IEnumerable<Type> optionalParameterTypes, int cGenericParameters)
Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers,
IEnumerable<Type> optionalParameterTypes, int cGenericParameters)
{
SignatureHelper sig = SignatureHelper.GetMethodSigHelper(this, call, returnType, cGenericParameters);

Debug.Assert(parameterTypeRequiredCustomModifiers == null
|| (parameterTypeRequiredCustomModifiers.Length == (parameterTypes?.Length ?? 0)));

Debug.Assert(parameterTypeOptionalCustomModifiers == null
|| (parameterTypeOptionalCustomModifiers.Length == (parameterTypes?.Length ?? 0)));

if (parameterTypes != null)
{
foreach (Type t in parameterTypes)
for (int i = 0; i < parameterTypes.Length; i++)
{
sig.AddArgument(t);
sig.AddArgument(parameterTypes[i], parameterTypeRequiredCustomModifiers?[i], parameterTypeOptionalCustomModifiers?[i]);
}
}

Expand Down Expand Up @@ -1268,16 +1279,11 @@ private MethodToken GetMethodTokenNoLock(MethodInfo method, bool getGenericTypeD
// go through the slower code path, i.e. retrieve parameters and form signature helper.
ParameterInfo[] parameters = method.GetParameters();

Type[] parameterTypes = new Type[parameters.Length];
Type[][] requiredCustomModifiers = new Type[parameterTypes.Length][];
Type[][] optionalCustomModifiers = new Type[parameterTypes.Length][];

for (int i = 0; i < parameters.Length; i++)
{
parameterTypes[i] = parameters[i].ParameterType;
requiredCustomModifiers[i] = parameters[i].GetRequiredCustomModifiers();
optionalCustomModifiers[i] = parameters[i].GetOptionalCustomModifiers();
}
SignatureHelper.ExtractParametersTypeArrays(
parameters,
out Type[] parameterTypes,
out Type[][] requiredCustomModifiers,
out Type[][] optionalCustomModifiers);

tr = getGenericTypeDefinition ? GetTypeToken(method.DeclaringType).Token : GetTypeTokenInternal(method.DeclaringType).Token;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,58 @@ internal static SignatureHelper GetTypeSigToken(Module module, Type type)

return new SignatureHelper(module, type);
}

internal static void ExtractParametersTypeArrays(ParameterInfo[] parameters,
out Type[] parameterTypes,
out Type[][] parameterTypeRequiredCustomModifiers,
out Type[][] parameterTypeOptionalCustomModifiers)
{
// This method tries to allocate as few arrays as possible. In the absence of parameters or
// custom modifiers, arrays or single items will default to null. The returned arrays will
// generally be fed back to a `SignatureHelper` which must perform null checks where necessary.

Type[] types = null;
Type[][] requiredCustomModifiers = null;
Type[][] optionalCustomModifiers = null;

Debug.Assert(parameters != null);

if (parameters.Length > 0)
{
types = new Type[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
{
Debug.Assert(parameters[i] != null);

types[i] = parameters[i].ParameterType;

Type[] rcms = parameters[i].GetRequiredCustomModifiers();
if (rcms.Length > 0)
{
if (requiredCustomModifiers == null)
{
requiredCustomModifiers = new Type[parameters.Length][];
}
requiredCustomModifiers[i] = rcms;
}

Type[] ocms = parameters[i].GetOptionalCustomModifiers();
if (ocms.Length > 0)
{
if (optionalCustomModifiers == null)
{
optionalCustomModifiers = new Type[parameters.Length][];
}
optionalCustomModifiers[i] = ocms;
}
}
}

parameterTypes = types;
parameterTypeRequiredCustomModifiers = requiredCustomModifiers;
parameterTypeOptionalCustomModifiers = optionalCustomModifiers;
}

#endregion

#region Private Data Members
Expand Down