Skip to content

Commit

Permalink
Handle marker types with more than 1 generic argument correctly when …
Browse files Browse the repository at this point in the history
…they must be materialized into full types (#54875)
  • Loading branch information
davidwrighton authored Jun 29, 2021
1 parent 6f7f30e commit 9fb6e81
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 4 deletions.
8 changes: 6 additions & 2 deletions src/coreclr/vm/methodtable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9820,8 +9820,12 @@ PTR_MethodTable MethodTable::InterfaceMapIterator::GetInterface(MethodTable* pMT
MethodTable *pResult = m_pMap->GetMethodTable();
if (pResult->IsSpecialMarkerTypeForGenericCasting())
{
TypeHandle ownerAsInst(pMTOwner);
Instantiation inst(&ownerAsInst, 1);
TypeHandle ownerAsInst[MaxGenericParametersForSpecialMarkerType];
for (DWORD i = 0; i < MaxGenericParametersForSpecialMarkerType; i++)
ownerAsInst[i] = pMTOwner;

_ASSERTE(pResult->GetInstantiation().GetNumArgs() <= MaxGenericParametersForSpecialMarkerType);
Instantiation inst(ownerAsInst, pResult->GetInstantiation().GetNumArgs());
pResult = ClassLoader::LoadGenericInstantiationThrowing(pResult->GetModule(), pResult->GetCl(), inst, ClassLoader::LoadTypes, loadLevel).AsMethodTable();
if (pResult->IsFullyLoaded())
SetInterface(pResult);
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/vm/methodtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -1254,6 +1254,8 @@ class MethodTable
return IsGenericTypeDefinition();
}

static const DWORD MaxGenericParametersForSpecialMarkerType = 8;

static BOOL ComputeContainsGenericVariables(Instantiation inst);

inline void SetContainsGenericVariables()
Expand Down
5 changes: 3 additions & 2 deletions src/coreclr/vm/methodtablebuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9147,8 +9147,9 @@ MethodTableBuilder::LoadExactInterfaceMap(MethodTable *pMT)
if (uninstGenericCase && pItfPossiblyApprox->HasInstantiation() && pItfPossiblyApprox->ContainsGenericVariables())
{
// We allow a limited set of interface generic shapes with type variables. In particular, we require the
// instantiations to be exactly simple type variables
if (InstantiationIsAllTypeVariables(pItfPossiblyApprox->GetInstantiation()))
// instantiations to be exactly simple type variables, and to have a relatively small number of generic arguments
// so that the fallback instantiating logic works efficiently
if (InstantiationIsAllTypeVariables(pItfPossiblyApprox->GetInstantiation()) && pItfPossiblyApprox->GetInstantiation().GetNumArgs() <= MethodTable::MaxGenericParametersForSpecialMarkerType)
{
pItfPossiblyApprox = ClassLoader::LoadTypeDefThrowing(pItfPossiblyApprox->GetModule(), pItfPossiblyApprox->GetCl(), ClassLoader::ThrowIfNotFound, ClassLoader::PermitUninstDefOrRef, 0, CLASS_LOAD_EXACTPARENTS).AsMethodTable();
}
Expand Down

0 comments on commit 9fb6e81

Please sign in to comment.