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 @@ -55,6 +55,19 @@ public override bool Equals(object? compare)
&& thisMethod.Name.Equals(otherMethod.Name);
}

public bool ReturnTypeHasInstantiation
{
get
{
Method method = Reader.GetMethod(Handle);
Handle returnType = method.Signature.GetMethodSignature(Reader).ReturnType;
if (returnType.HandleType != HandleType.TypeSpecification)
return false;
Handle inner = returnType.ToTypeSpecificationHandle(Reader).GetTypeSpecification(Reader).Signature;
return inner.HandleType == HandleType.TypeInstantiationSignature;
}
}

public override int GetHashCode()
{
Method method = Reader.GetMethod(Handle);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,17 +190,18 @@ internal MethodDesc GetMethod(ref NativeParser parser)

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

MethodDesc retVal;
if ((flags & MethodFlags.HasInstantiation) != 0)
{
TypeDesc[] typeArguments = GetTypeSequence(ref parser);
Debug.Assert(typeArguments.Length > 0);
retVal = this._typeSystemContext.ResolveGenericMethodInstantiation(unboxingStub, asyncVariant, containingType, nameAndSignature, new Instantiation(typeArguments));
retVal = this._typeSystemContext.ResolveGenericMethodInstantiation(unboxingStub, asyncVariant, returnDroppingAsyncThunk, containingType, nameAndSignature, new Instantiation(typeArguments));
}
else
{
retVal = this._typeSystemContext.ResolveRuntimeMethod(unboxingStub, asyncVariant, containingType, nameAndSignature);
retVal = this._typeSystemContext.ResolveRuntimeMethod(unboxingStub, asyncVariant, returnDroppingAsyncThunk, 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, method.AsyncVariant, (DefType)method.OwningType, method.NameAndSignature, method.Instantiation);
nonTemplateMethod = (InstantiatedMethod)method.Context.ResolveGenericMethodInstantiation(true, method.AsyncVariant, method.ReturnDroppingAsyncThunk, (DefType)method.OwningType, method.NameAndSignature, method.Instantiation);
}

uint nativeLayoutInfoToken;
Expand Down Expand Up @@ -803,6 +803,7 @@ private void FinishRuntimeType(TypeDesc type)
_genericMethodArgumentHandles = GetRuntimeTypeHandles(method.Instantiation),
_methodNameAndSignature = method.NameAndSignature,
_isAsyncVariant = method.AsyncVariant,
_isReturnDroppingAsyncThunk = method.ReturnDroppingAsyncThunk,
_methodDictionary = method.RuntimeMethodDictionary
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ internal class GenericMethodEntry
private int? _hashCode;
public bool _isRegisteredSuccessfully;
public bool _isAsyncVariant;
public bool _isReturnDroppingAsyncThunk;
public IntPtr _methodDictionary;
public RuntimeTypeHandle _declaringTypeHandle;
public MethodNameAndSignature _methodNameAndSignature;
Expand Down Expand Up @@ -50,6 +51,9 @@ public virtual bool IsEqualToEntryByComponentsComparison(GenericMethodEntry othe
if (_isAsyncVariant != other._isAsyncVariant)
return false;

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

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

Expand Down Expand Up @@ -157,10 +161,13 @@ internal override bool MatchParsedEntry(ref NativeParser entryParser, ref Extern

int flagsAndToken = (int)entryParser.GetUnsigned();
bool isAsyncVariant = (flagsAndToken & GenericMethodsHashtableConstants.IsAsyncVariant) != 0;
bool isReturnDroppingAsyncThunk = (flagsAndToken & GenericMethodsHashtableConstants.IsReturnDroppingAsyncThunk) != 0;
if (_methodToLookup.AsyncVariant != isAsyncVariant)
return false;
if (_methodToLookup.ReturnDroppingAsyncThunk != isReturnDroppingAsyncThunk)
return false;

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

MethodNameAndSignature nameAndSignature = TypeLoaderEnvironment.GetMethodNameAndSignatureFromToken(moduleHandle, (uint)token);
if (!_methodToLookup.NameAndSignature.Equals(nameAndSignature))
Expand Down Expand Up @@ -192,6 +199,9 @@ internal override bool MatchGenericMethodEntry(GenericMethodEntry entry)
if (_methodToLookup.AsyncVariant != entry._isAsyncVariant)
return false;

if (_methodToLookup.ReturnDroppingAsyncThunk != entry._isReturnDroppingAsyncThunk)
return false;

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

Expand Down Expand Up @@ -300,7 +310,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, method.AsyncVariant, (DefType)method.OwningType, method.NameAndSignature, method.Instantiation);
nonTemplateMethod = (InstantiatedMethod)method.Context.ResolveGenericMethodInstantiation(true, method.AsyncVariant, method.ReturnDroppingAsyncThunk, (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 @@ -441,7 +451,7 @@ private static unsafe bool TryGetStaticGenericMethodComponents(IntPtr methodDict
int flagsAndToken = (int)entryParser.GetUnsigned();
isAsyncVariant = (flagsAndToken & GenericMethodsHashtableConstants.IsAsyncVariant) != 0;

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

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

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

return (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, slotMethod.AsyncVariant, interfaceImplType, targetMethodNameAndSignature, slotMethod.Instantiation);
bool returnDroppingAsyncThunk = slotMethod.AsyncVariant
&& !slotMethod.NameAndSignature.ReturnTypeHasInstantiation
&& targetMethodNameAndSignature.ReturnTypeHasInstantiation;
bool asyncVariant = slotMethod.AsyncVariant && !returnDroppingAsyncThunk;

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

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

bool returnDroppingAsyncThunk = slotMethod.AsyncVariant
&& !slotMethod.NameAndSignature.ReturnTypeHasInstantiation
&& targetMethodNameAndSignature.ReturnTypeHasInstantiation;
bool asyncVariant = slotMethod.AsyncVariant && !returnDroppingAsyncThunk;

return (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, asyncVariant, returnDroppingAsyncThunk, targetType, targetMethodNameAndSignature, slotMethod.Instantiation);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,10 @@ public MethodDesc GetMethodDescForRuntimeMethodHandle(TypeSystemContext context,
if (genericMethodArgs != null)
{
Instantiation methodInst = context.ResolveRuntimeTypeHandles(genericMethodArgs);
return context.ResolveGenericMethodInstantiation(unboxingStub: false, isAsyncVariant, type, nameAndSignature, methodInst);
return context.ResolveGenericMethodInstantiation(unboxingStub: false, isAsyncVariant, returnDroppingAsyncThunk: false, type, nameAndSignature, methodInst);
}

return context.ResolveRuntimeMethod(unboxingStub: false, isAsyncVariant, type, nameAndSignature);
return context.ResolveRuntimeMethod(unboxingStub: false, isAsyncVariant, returnDroppingAsyncThunk: false, type, nameAndSignature);
}

public unsafe bool TryGetRuntimeMethodHandleComponents(RuntimeMethodHandle runtimeMethodHandle, out RuntimeTypeHandle declaringTypeHandle, out QMethodDefinition handle, out RuntimeTypeHandle[] genericMethodArgs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ public bool TryGetGenericMethodDictionaryForComponents(RuntimeTypeHandle declari
TypeSystemContext context = TypeSystemContextFactory.Create();

DefType declaringType = (DefType)context.ResolveRuntimeTypeHandle(declaringTypeHandle);
InstantiatedMethod methodBeingLoaded = (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, asyncVariant: false, declaringType, nameAndSignature, context.ResolveRuntimeTypeHandles(genericMethodArgHandles));
InstantiatedMethod methodBeingLoaded = (InstantiatedMethod)context.ResolveGenericMethodInstantiation(false, asyncVariant: false, returnDroppingAsyncThunk: false, declaringType, nameAndSignature, context.ResolveRuntimeTypeHandles(genericMethodArgHandles));

if (TryLookupGenericMethodDictionary(new MethodDescBasedGenericMethodLookup(methodBeingLoaded), out methodDictionary))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ public override bool AsyncVariant
}
}

public override bool ReturnDroppingAsyncThunk
{
get
{
return _methodDef.ReturnDroppingAsyncThunk;
}
}

#if DEBUG
public override string ToString()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,13 @@ public virtual bool AsyncVariant
return false;
}
}

public virtual bool ReturnDroppingAsyncThunk
{
get
{
return false;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public override MethodDesc GetCanonMethodTarget(CanonicalFormKind kind)
if (canonicalizedTypeOfTargetMethod == OwningType)
return this;

return Context.ResolveRuntimeMethod(this.UnboxingStub, this.AsyncVariant, canonicalizedTypeOfTargetMethod, this.NameAndSignature);
return Context.ResolveRuntimeMethod(this.UnboxingStub, this.AsyncVariant, this.ReturnDroppingAsyncThunk, canonicalizedTypeOfTargetMethod, this.NameAndSignature);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ namespace Internal.TypeSystem.NoMetadata
/// </summary>
internal sealed partial class RuntimeMethodDesc : NoMetadataMethodDesc
{
public RuntimeMethodDesc(bool unboxingStub, bool asyncVariant, DefType owningType,
public RuntimeMethodDesc(bool unboxingStub, bool asyncVariant, bool returnDroppingAsyncThunk, DefType owningType,
MethodNameAndSignature nameAndSignature, int hashcode)
{
_owningType = owningType;
_nameAndSignature = nameAndSignature;
_unboxingStub = unboxingStub;
_asyncVariant = asyncVariant;
_returnDroppingAsyncThunk = returnDroppingAsyncThunk;
SetHashCode(hashcode);

#if DEBUG
Expand Down Expand Up @@ -116,6 +117,15 @@ public override bool AsyncVariant
}
}

private bool _returnDroppingAsyncThunk;
public override bool ReturnDroppingAsyncThunk
{
get
{
return _returnDroppingAsyncThunk;
}
}

public override MethodDesc GetTypicalMethodDefinition()
{
TypeDesc owningTypeDefinition = OwningType.GetTypeDefinition();
Expand All @@ -127,7 +137,7 @@ public override MethodDesc GetTypicalMethodDefinition()
}

// Otherwise, find its equivalent on the type definition of the owning type
return Context.ResolveRuntimeMethod(UnboxingStub, AsyncVariant, (DefType)owningTypeDefinition, _nameAndSignature);
return Context.ResolveRuntimeMethod(UnboxingStub, AsyncVariant, ReturnDroppingAsyncThunk, (DefType)owningTypeDefinition, _nameAndSignature);
}

public override MethodDesc InstantiateSignature(Instantiation typeInstantiation, Instantiation methodInstantiation)
Expand All @@ -137,7 +147,7 @@ public override MethodDesc InstantiateSignature(Instantiation typeInstantiation,
TypeDesc owningType = method.OwningType;
TypeDesc instantiatedOwningType = owningType.InstantiateSignature(typeInstantiation, methodInstantiation);
if (owningType != instantiatedOwningType)
method = instantiatedOwningType.Context.ResolveRuntimeMethod(UnboxingStub, AsyncVariant, (DefType)instantiatedOwningType, _nameAndSignature);
method = instantiatedOwningType.Context.ResolveRuntimeMethod(UnboxingStub, AsyncVariant, ReturnDroppingAsyncThunk, (DefType)instantiatedOwningType, _nameAndSignature);

Instantiation instantiation = method.Instantiation;
TypeDesc[] clone = null;
Expand Down
Loading
Loading