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 @@ -49,7 +49,7 @@ public unsafe bool Equals(RuntimeMethodHandle handle)
return false;
if (!thisInfo->Handle.Equals(thatInfo->Handle))
return false;
if (thisInfo->NumGenericArgs != thatInfo->NumGenericArgs)
if (thisInfo->_numGenericArgsAndFlag != thatInfo->_numGenericArgsAndFlag)
return false;

RuntimeTypeHandle* thisFirstArg = &thisInfo->FirstArgument;
Expand Down Expand Up @@ -123,7 +123,19 @@ public struct MethodHandleInfo
{
public RuntimeTypeHandle DeclaringType;
public MethodHandle Handle;
public int NumGenericArgs;
internal int _numGenericArgsAndFlag;
public RuntimeTypeHandle FirstArgument;

public int NumGenericArgs
{
get => _numGenericArgsAndFlag & ~RuntimeMethodHandleConstants.IsAsyncVariant;
set => _numGenericArgsAndFlag = (_numGenericArgsAndFlag & RuntimeMethodHandleConstants.IsAsyncVariant) | value;
}

public bool IsAsyncVariant
{
get => (_numGenericArgsAndFlag & RuntimeMethodHandleConstants.IsAsyncVariant) != 0;
set => _numGenericArgsAndFlag = value ? _numGenericArgsAndFlag | RuntimeMethodHandleConstants.IsAsyncVariant : _numGenericArgsAndFlag & ~RuntimeMethodHandleConstants.IsAsyncVariant;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,8 @@ private unsafe bool TryGetMethodForOriginalLdFtnResult_InvokeMap_Inner(NativeFor
private static unsafe bool TryGetMethodForOriginalLdFtnResult_GenericMethodWithInstantiationArgument(IntPtr instantiationArgument, ref RuntimeTypeHandle declaringTypeHandle, out QMethodDefinition methodHandle, out RuntimeTypeHandle[] genericMethodTypeArgumentHandles)
{
MethodNameAndSignature nameAndSig;
bool success = TypeLoaderEnvironment.Instance.TryGetGenericMethodComponents(instantiationArgument, out declaringTypeHandle, out nameAndSig, out genericMethodTypeArgumentHandles);
bool success = TypeLoaderEnvironment.Instance.TryGetGenericMethodComponents(instantiationArgument, out declaringTypeHandle, out nameAndSig, out genericMethodTypeArgumentHandles, out bool isAsyncVariant);
Debug.Assert(!isAsyncVariant, "Async variants should not be visible to reflection");
if (success)
{
if (TypeLoaderEnvironment.Instance.TryGetMetadataForTypeMethodNameAndSignature(declaringTypeHandle, nameAndSig, out methodHandle))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,8 @@ internal override unsafe IntPtr Create(TypeBuilder builder)
RuntimeMethodHandle handle = TypeLoaderEnvironment.Instance.GetRuntimeMethodHandleForComponents(
builder.GetRuntimeTypeHandle(Method.OwningType),
Method.NameAndSignature.Handle,
genericArgHandles);
genericArgHandles,
Method.AsyncVariant);

return *(IntPtr*)&handle;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,17 +189,18 @@ internal MethodDesc GetMethod(ref NativeParser parser)
MethodNameAndSignature nameAndSignature = new MethodNameAndSignature(_module.MetadataReader, token.AsHandle().ToMethodHandle(_module.MetadataReader));

bool unboxingStub = (flags & MethodFlags.IsUnboxingStub) != 0;
bool asyncVariant = (flags & MethodFlags.IsAsyncVariant) != 0;

MethodDesc retVal;
if ((flags & MethodFlags.HasInstantiation) != 0)
{
TypeDesc[] typeArguments = GetTypeSequence(ref parser);
Debug.Assert(typeArguments.Length > 0);
retVal = this._typeSystemContext.ResolveGenericMethodInstantiation(unboxingStub, containingType, nameAndSignature, new Instantiation(typeArguments));
retVal = this._typeSystemContext.ResolveGenericMethodInstantiation(unboxingStub, asyncVariant, containingType, nameAndSignature, new Instantiation(typeArguments));
}
else
{
retVal = this._typeSystemContext.ResolveRuntimeMethod(unboxingStub, containingType, nameAndSignature);
retVal = this._typeSystemContext.ResolveRuntimeMethod(unboxingStub, asyncVariant, containingType, nameAndSignature);
}

if ((flags & MethodFlags.HasFunctionPointer) != 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ internal void ParseNativeLayoutInfo(InstantiatedMethod method)
if (!method.UnboxingStub && method.OwningType.IsValueType && !TypeLoaderEnvironment.IsStaticMethodSignature(method.NameAndSignature))
{
// Make it an unboxing stub, note the first parameter which is true
nonTemplateMethod = (InstantiatedMethod)method.Context.ResolveGenericMethodInstantiation(true, (DefType)method.OwningType, method.NameAndSignature, method.Instantiation);
nonTemplateMethod = (InstantiatedMethod)method.Context.ResolveGenericMethodInstantiation(true, method.AsyncVariant, (DefType)method.OwningType, method.NameAndSignature, method.Instantiation);
}

uint nativeLayoutInfoToken;
Expand Down Expand Up @@ -802,6 +802,7 @@ private void FinishRuntimeType(TypeDesc type)
_declaringTypeHandle = GetRuntimeTypeHandle(method.OwningType),
_genericMethodArgumentHandles = GetRuntimeTypeHandles(method.Instantiation),
_methodNameAndSignature = method.NameAndSignature,
_isAsyncVariant = method.AsyncVariant,
_methodDictionary = method.RuntimeMethodDictionary
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Reflection.Runtime.General;
using System.Threading;

using Internal.Metadata.NativeFormat;
using Internal.NativeFormat;
using Internal.Runtime.CompilerServices;
using Internal.TypeSystem;
Expand All @@ -19,6 +20,7 @@ internal class GenericMethodEntry
{
private int? _hashCode;
public bool _isRegisteredSuccessfully;
public bool _isAsyncVariant;
public IntPtr _methodDictionary;
public RuntimeTypeHandle _declaringTypeHandle;
public MethodNameAndSignature _methodNameAndSignature;
Expand All @@ -45,6 +47,9 @@ public virtual bool IsEqualToEntryByComponentsComparison(GenericMethodEntry othe
if (!other._declaringTypeHandle.Equals(_declaringTypeHandle))
return false;

if (_isAsyncVariant != other._isAsyncVariant)
return false;

if (!other._methodNameAndSignature.Equals(_methodNameAndSignature))
return false;

Expand Down Expand Up @@ -150,8 +155,14 @@ internal override bool MatchParsedEntry(ref NativeParser entryParser, ref Extern
if (_methodToLookup.OwningType != parsedDeclaringType)
return false;

// Hash table names / sigs are indirected through to the native layout info
MethodNameAndSignature nameAndSignature = TypeLoaderEnvironment.GetMethodNameAndSignatureFromToken(moduleHandle, entryParser.GetUnsigned());
int flagsAndToken = (int)entryParser.GetUnsigned();
bool isAsyncVariant = (flagsAndToken & GenericMethodsHashtableConstants.IsAsyncVariant) != 0;
if (_methodToLookup.AsyncVariant != isAsyncVariant)
return false;

int token = ((int)HandleType.Method << 25) | (flagsAndToken & ~GenericMethodsHashtableConstants.IsAsyncVariant);

MethodNameAndSignature nameAndSignature = TypeLoaderEnvironment.GetMethodNameAndSignatureFromToken(moduleHandle, (uint)token);
if (!_methodToLookup.NameAndSignature.Equals(nameAndSignature))
return false;

Expand All @@ -178,6 +189,9 @@ internal override bool MatchGenericMethodEntry(GenericMethodEntry entry)
if (_methodToLookup.OwningType != parsedDeclaringType)
return false;

if (_methodToLookup.AsyncVariant != entry._isAsyncVariant)
return false;

if (!_methodToLookup.NameAndSignature.Equals(entry._methodNameAndSignature))
return false;

Expand Down Expand Up @@ -208,11 +222,11 @@ internal bool TryLookupGenericMethodDictionary(GenericMethodLookupData lookupDat
return true;
}

public bool TryGetGenericMethodComponents(IntPtr methodDictionary, out RuntimeTypeHandle declaringType, out MethodNameAndSignature nameAndSignature, out RuntimeTypeHandle[] genericMethodArgumentHandles)
public bool TryGetGenericMethodComponents(IntPtr methodDictionary, out RuntimeTypeHandle declaringType, out MethodNameAndSignature nameAndSignature, out RuntimeTypeHandle[] genericMethodArgumentHandles, out bool isAsyncVariant)
{
if (!TryGetDynamicGenericMethodComponents(methodDictionary, out declaringType, out nameAndSignature, out genericMethodArgumentHandles))
if (!TryGetDynamicGenericMethodComponents(methodDictionary, out declaringType, out nameAndSignature, out genericMethodArgumentHandles, out isAsyncVariant))
{
if (!TryGetStaticGenericMethodComponents(methodDictionary, out declaringType, out nameAndSignature, out genericMethodArgumentHandles))
if (!TryGetStaticGenericMethodComponents(methodDictionary, out declaringType, out nameAndSignature, out genericMethodArgumentHandles, out isAsyncVariant))
return false;
}

Expand All @@ -222,8 +236,8 @@ public bool TryGetGenericMethodComponents(IntPtr methodDictionary, out RuntimeTy
public static bool TryGetGenericMethodComponents(IntPtr methodDictionary, out RuntimeTypeHandle declaringType, out RuntimeTypeHandle[] genericMethodArgumentHandles)
{
TypeLoaderEnvironment instance = TypeLoaderEnvironment.InstanceOrNull;
if (instance == null || !instance.TryGetDynamicGenericMethodComponents(methodDictionary, out declaringType, out _, out genericMethodArgumentHandles))
if (!TryGetStaticGenericMethodComponents(methodDictionary, out declaringType, out _, out genericMethodArgumentHandles))
if (instance == null || !instance.TryGetDynamicGenericMethodComponents(methodDictionary, out declaringType, out _, out genericMethodArgumentHandles, out _))
if (!TryGetStaticGenericMethodComponents(methodDictionary, out declaringType, out _, out genericMethodArgumentHandles, out _))
return false;

return true;
Expand Down Expand Up @@ -286,7 +300,7 @@ public bool TryGetGenericVirtualMethodPointer(InstantiatedMethod method, out Int
if (!method.UnboxingStub && method.OwningType.IsValueType && !IsStaticMethodSignature(method.NameAndSignature))
{
// Make it an unboxing stub, note the first parameter which is true
nonTemplateMethod = (InstantiatedMethod)method.Context.ResolveGenericMethodInstantiation(true, (DefType)method.OwningType, method.NameAndSignature, method.Instantiation);
nonTemplateMethod = (InstantiatedMethod)method.Context.ResolveGenericMethodInstantiation(true, method.AsyncVariant, (DefType)method.OwningType, method.NameAndSignature, method.Instantiation);
}

// If we cannot find an exact method entry point, look for an equivalent template and compute the generic dictionary
Expand Down Expand Up @@ -371,11 +385,12 @@ private static bool TryGetStaticGenericMethodDictionary(GenericMethodLookupData
return false;
}

private bool TryGetDynamicGenericMethodComponents(IntPtr methodDictionary, out RuntimeTypeHandle declaringType, out MethodNameAndSignature methodNameAndSignature, out RuntimeTypeHandle[] genericMethodArgumentHandles)
private bool TryGetDynamicGenericMethodComponents(IntPtr methodDictionary, out RuntimeTypeHandle declaringType, out MethodNameAndSignature methodNameAndSignature, out RuntimeTypeHandle[] genericMethodArgumentHandles, out bool isAsyncVariant)
{
declaringType = default(RuntimeTypeHandle);
methodNameAndSignature = null;
genericMethodArgumentHandles = null;
isAsyncVariant = false;

using (_dynamicGenericsLock.EnterScope())
{
Expand All @@ -389,10 +404,12 @@ private bool TryGetDynamicGenericMethodComponents(IntPtr methodDictionary, out R
declaringType = entry._declaringTypeHandle;
methodNameAndSignature = entry._methodNameAndSignature;
genericMethodArgumentHandles = entry._genericMethodArgumentHandles;
isAsyncVariant = entry._isAsyncVariant;
return true;
}
}
private static unsafe bool TryGetStaticGenericMethodComponents(IntPtr methodDictionary, out RuntimeTypeHandle declaringType, out MethodNameAndSignature nameAndSignature, out RuntimeTypeHandle[] genericMethodArgumentHandles)

private static unsafe bool TryGetStaticGenericMethodComponents(IntPtr methodDictionary, out RuntimeTypeHandle declaringType, out MethodNameAndSignature nameAndSignature, out RuntimeTypeHandle[] genericMethodArgumentHandles, out bool isAsyncVariant)
{
// Generic method dictionaries have a header that has the hash code in it. Locate the header
IntPtr dictionaryHeader = IntPtr.Subtract(methodDictionary, IntPtr.Size);
Expand Down Expand Up @@ -420,7 +437,12 @@ private static unsafe bool TryGetStaticGenericMethodComponents(IntPtr methodDict
// We have a match - fill in the results
declaringType = externalReferencesLookup.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());

int token = (int)entryParser.GetUnsigned();

int flagsAndToken = (int)entryParser.GetUnsigned();
isAsyncVariant = (flagsAndToken & GenericMethodsHashtableConstants.IsAsyncVariant) != 0;

int token = ((int)HandleType.Method << 25) | (flagsAndToken & ~GenericMethodsHashtableConstants.IsAsyncVariant);

nameAndSignature = new MethodNameAndSignature(module.MetadataReader, token.AsHandle().ToMethodHandle(module.MetadataReader));

uint arity = entryParser.GetSequenceCount();
Expand All @@ -438,6 +460,7 @@ private static unsafe bool TryGetStaticGenericMethodComponents(IntPtr methodDict
declaringType = default(RuntimeTypeHandle);
nameAndSignature = null;
genericMethodArgumentHandles = null;
isAsyncVariant = false;
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ private static InstantiatedMethod FindMatchingInterfaceSlot(NativeFormatModuleIn
Debug.Assert(interfaceImplType != null);
}

return (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, interfaceImplType, targetMethodNameAndSignature, slotMethod.Instantiation);
return (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, slotMethod.AsyncVariant, interfaceImplType, targetMethodNameAndSignature, slotMethod.Instantiation);
}
}
}
Expand Down Expand Up @@ -502,7 +502,7 @@ private static InstantiatedMethod ResolveGenericVirtualMethodTarget(DefType targ
Debug.Assert(targetMethodNameAndSignature != null);

TypeSystemContext context = slotMethod.Context;
return (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, targetType, targetMethodNameAndSignature, slotMethod.Instantiation);
return (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, slotMethod.AsyncVariant, targetType, targetMethodNameAndSignature, slotMethod.Instantiation);
}
}

Expand Down
Loading
Loading