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
6 changes: 3 additions & 3 deletions src/coreclr/vm/genericdict.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1382,11 +1382,11 @@ Dictionary::PopulateEntry(
}
_ASSERTE(!constraintType.IsNull());

MethodDesc *pResolvedMD = constraintType.GetMethodTable()->TryResolveConstraintMethodApprox(ownerType, pMethod);
MethodDesc *pResolvedMD = constraintType.GetMethodTable()->TryResolveConstraintMethodApprox(ownerType, pMethod, !pMethod->IsStatic());

// All such calls should be resolvable. If not then for now just throw an error.
_ASSERTE(pResolvedMD);
INDEBUG(if (!pResolvedMD) constraintType.GetMethodTable()->TryResolveConstraintMethodApprox(ownerType, pMethod);)
INDEBUG(if (!pResolvedMD) constraintType.GetMethodTable()->TryResolveConstraintMethodApprox(ownerType, pMethod, !pMethod->IsStatic());)
if (!pResolvedMD)
COMPlusThrowHR(COR_E_BADIMAGEFORMAT);

Expand All @@ -1396,7 +1396,7 @@ Dictionary::PopulateEntry(
// In such case we would need to box the value type before we can dispatch to the implementation.
// This would require us to make a "boxing stub". For now we leave the boxing stubs unimplemented.
// It's not clear if anyone would need them and the implementation complexity is not worth it at this time.
if (!pResolvedMD->GetMethodTable()->IsValueType() && constraintType.GetMethodTable()->IsValueType())
if (pResolvedMD->IsStatic() && !pResolvedMD->GetMethodTable()->IsValueType() && constraintType.GetMethodTable()->IsValueType())
{
SString assemblyName;

Expand Down
18 changes: 15 additions & 3 deletions src/coreclr/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5183,6 +5183,7 @@ void CEEInfo::getCallInfo(
MethodDesc * directMethod = constrainedType.GetMethodTable()->TryResolveConstraintMethodApprox(
exactType,
pMD,
TRUE, /* allowInstParam, At compile time the exact destination cannot reliably be known */
&fForceUseRuntimeLookup);
if (directMethod
#ifdef FEATURE_DEFAULT_INTERFACES
Expand Down Expand Up @@ -5395,9 +5396,20 @@ void CEEInfo::getCallInfo(
{
pResult->kind = CORINFO_CALL_CODE_POINTER;

// For reference types, the constrained type does not affect method resolution
DictionaryEntryKind entryKind = (!constrainedType.IsNull() && constrainedType.IsValueType()) ? ConstrainedMethodEntrySlot : MethodEntrySlot;

DictionaryEntryKind entryKind;
if (constrainedType.IsNull() || ((flags & CORINFO_CALLINFO_CALLVIRT) && !constrainedType.IsValueType()))
{
// For reference types, the constrained type does not affect method resolution on a callvirt, and if there is no
// constraint, it doesn't effect it either
entryKind = MethodEntrySlot;
}
else
{
// constrained. callvirt case where the constraint type is a valuetype
// OR
// constrained. call or constrained. ldftn case
entryKind = ConstrainedMethodEntrySlot;
}
ComputeRuntimeLookupForSharedGenericToken(entryKind,
pResolvedToken,
pConstrainedResolvedToken,
Expand Down
11 changes: 6 additions & 5 deletions src/coreclr/vm/methodtable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9173,11 +9173,11 @@ MethodDesc *MethodTable::GetDefaultConstructor(BOOL forceBoxedEntryPoint /* = FA
//==========================================================================================
// Finds the (non-unboxing) MethodDesc that implements the interface virtual static method pInterfaceMD.
MethodDesc *
MethodTable::ResolveVirtualStaticMethod(MethodDesc* pInterfaceMD)
MethodTable::ResolveVirtualStaticMethod(MethodDesc* pInterfaceMD, BOOL allowInstParam)
{
for (MethodTable* pMT = this; pMT != nullptr; pMT = pMT->GetParentMethodTable())
{
MethodDesc* pMD = pMT->TryResolveVirtualStaticMethodOnThisType(pInterfaceMD);
MethodDesc* pMD = pMT->TryResolveVirtualStaticMethodOnThisType(pInterfaceMD, allowInstParam);
if (pMD != nullptr)
{
return pMD;
Expand All @@ -9190,7 +9190,7 @@ MethodTable::ResolveVirtualStaticMethod(MethodDesc* pInterfaceMD)
// Try to locate the appropriate MethodImpl matching a given interface static virtual method.
// Returns nullptr on failure.
MethodDesc*
MethodTable::TryResolveVirtualStaticMethodOnThisType(MethodDesc* pInterfaceMD)
MethodTable::TryResolveVirtualStaticMethodOnThisType(MethodDesc* pInterfaceMD, BOOL allowInstParam)
{
HRESULT hr = S_OK;
IMDInternalImport* pMDInternalImport = GetMDImport();
Expand Down Expand Up @@ -9263,7 +9263,7 @@ MethodTable::TryResolveVirtualStaticMethodOnThisType(MethodDesc* pInterfaceMD)

if (pInterfaceMD->HasMethodInstantiation() || pMethodImpl->HasMethodInstantiation() || HasInstantiation())
{
return pMethodImpl->FindOrCreateAssociatedMethodDesc(pMethodImpl, this, FALSE, pInterfaceMD->GetMethodInstantiation(), TRUE);
return pMethodImpl->FindOrCreateAssociatedMethodDesc(pMethodImpl, this, FALSE, pInterfaceMD->GetMethodInstantiation(), allowInstParam);
}
else
{
Expand All @@ -9286,6 +9286,7 @@ MethodDesc *
MethodTable::TryResolveConstraintMethodApprox(
TypeHandle thInterfaceType,
MethodDesc * pInterfaceMD,
BOOL allowInstParam,
BOOL * pfForceUseRuntimeLookup) // = NULL
{
CONTRACTL {
Expand All @@ -9295,7 +9296,7 @@ MethodTable::TryResolveConstraintMethodApprox(

if (pInterfaceMD->IsStatic())
{
return ResolveVirtualStaticMethod(pInterfaceMD);
return ResolveVirtualStaticMethod(pInterfaceMD, allowInstParam);
}

// We can't resolve constraint calls effectively for reference types, and there's
Expand Down
5 changes: 3 additions & 2 deletions src/coreclr/vm/methodtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -2280,7 +2280,7 @@ class MethodTable


// Resolve virtual static interface method pInterfaceMD on this type.
MethodDesc *ResolveVirtualStaticMethod(MethodDesc* pInterfaceMD);
MethodDesc *ResolveVirtualStaticMethod(MethodDesc* pInterfaceMD, BOOL allowInstParam);

// Try a partial resolve of the constraint call, up to generic code sharing.
//
Expand All @@ -2297,6 +2297,7 @@ class MethodTable
MethodDesc * TryResolveConstraintMethodApprox(
TypeHandle ownerType,
MethodDesc * pMD,
BOOL fExactResolution = FALSE,
BOOL * pfForceUseRuntimeLookup = NULL);

//-------------------------------------------------------------------
Expand Down Expand Up @@ -2397,7 +2398,7 @@ class MethodTable

// Try to resolve a given static virtual method override on this type. Return nullptr
// when not found.
MethodDesc *TryResolveVirtualStaticMethodOnThisType(MethodDesc* pInterfaceMD);
MethodDesc *TryResolveVirtualStaticMethodOnThisType(MethodDesc* pInterfaceMD, BOOL allowInstParam);

public:
static MethodDesc *MapMethodDeclToMethodImpl(MethodDesc *pMDDecl);
Expand Down