@@ -6210,22 +6210,26 @@ MethodTable::FindDispatchImpl(
62106210
62116211 // Try exact match first
62126212 MethodDesc *pDefaultMethod = NULL ;
6213+
6214+ FindDefaultInterfaceImplementationFlags flags = FindDefaultInterfaceImplementationFlags::InstantiateFoundMethodDesc;
6215+ if (throwOnConflict)
6216+ flags = flags | FindDefaultInterfaceImplementationFlags::ThrowOnConflict;
6217+
62136218 BOOL foundDefaultInterfaceImplementation = FindDefaultInterfaceImplementation (
62146219 pIfcMD, // the interface method being resolved
62156220 pIfcMT, // the interface being resolved
62166221 &pDefaultMethod,
6217- FALSE , // allowVariance
6218- throwOnConflict);
6222+ flags);
62196223
62206224 // If there's no exact match, try a variant match
62216225 if (!foundDefaultInterfaceImplementation && pIfcMT->HasVariance ())
62226226 {
6227+ flags = flags | FindDefaultInterfaceImplementationFlags::AllowVariance;
62236228 foundDefaultInterfaceImplementation = FindDefaultInterfaceImplementation (
62246229 pIfcMD, // the interface method being resolved
62256230 pIfcMT, // the interface being resolved
62266231 &pDefaultMethod,
6227- TRUE , // allowVariance
6228- throwOnConflict);
6232+ flags);
62296233 }
62306234
62316235 if (foundDefaultInterfaceImplementation)
@@ -6324,10 +6328,13 @@ namespace
63246328 MethodTable *pMT,
63256329 MethodDesc *interfaceMD,
63266330 MethodTable *interfaceMT,
6327- BOOL allowVariance ,
6331+ FindDefaultInterfaceImplementationFlags findDefaultImplementationFlags ,
63286332 MethodDesc **candidateMD,
63296333 ClassLoadLevel level)
63306334 {
6335+ bool allowVariance = (findDefaultImplementationFlags & FindDefaultInterfaceImplementationFlags::AllowVariance) != FindDefaultInterfaceImplementationFlags::None;
6336+ bool instantiateMethodInstantiation = (findDefaultImplementationFlags & FindDefaultInterfaceImplementationFlags::InstantiateFoundMethodDesc) != FindDefaultInterfaceImplementationFlags::None;
6337+
63316338 *candidateMD = NULL ;
63326339
63336340 MethodDesc *candidateMaybe = NULL ;
@@ -6418,11 +6425,20 @@ namespace
64186425 else
64196426 {
64206427 // Static virtual methods don't record MethodImpl slots so they need special handling
6428+ ResolveVirtualStaticMethodFlags resolveVirtualStaticMethodFlags = ResolveVirtualStaticMethodFlags::None;
6429+ if (allowVariance)
6430+ {
6431+ resolveVirtualStaticMethodFlags |= ResolveVirtualStaticMethodFlags::AllowVariantMatches;
6432+ }
6433+ if (instantiateMethodInstantiation)
6434+ {
6435+ resolveVirtualStaticMethodFlags |= ResolveVirtualStaticMethodFlags::InstantiateResultOverFinalMethodDesc;
6436+ }
6437+
64216438 candidateMaybe = pMT->TryResolveVirtualStaticMethodOnThisType (
64226439 interfaceMT,
64236440 interfaceMD,
6424- /* verifyImplemented */ FALSE ,
6425- /* allowVariance */ allowVariance,
6441+ resolveVirtualStaticMethodFlags,
64266442 /* level */ level);
64276443 }
64286444 }
@@ -6461,8 +6477,7 @@ BOOL MethodTable::FindDefaultInterfaceImplementation(
64616477 MethodDesc *pInterfaceMD,
64626478 MethodTable *pInterfaceMT,
64636479 MethodDesc **ppDefaultMethod,
6464- BOOL allowVariance,
6465- BOOL throwOnConflict,
6480+ FindDefaultInterfaceImplementationFlags findDefaultImplementationFlags,
64666481 ClassLoadLevel level
64676482)
64686483{
@@ -6478,12 +6493,13 @@ BOOL MethodTable::FindDefaultInterfaceImplementation(
64786493 } CONTRACT_END;
64796494
64806495#ifdef FEATURE_DEFAULT_INTERFACES
6496+ bool allowVariance = (findDefaultImplementationFlags & FindDefaultInterfaceImplementationFlags::AllowVariance) != FindDefaultInterfaceImplementationFlags::None;
64816497 CQuickArray<MatchCandidate> candidates;
64826498 unsigned candidatesCount = 0 ;
64836499
64846500 // Check the current method table itself
64856501 MethodDesc *candidateMaybe = NULL ;
6486- if (IsInterface () && TryGetCandidateImplementation (this , pInterfaceMD, pInterfaceMT, allowVariance , &candidateMaybe, level))
6502+ if (IsInterface () && TryGetCandidateImplementation (this , pInterfaceMD, pInterfaceMT, findDefaultImplementationFlags , &candidateMaybe, level))
64876503 {
64886504 _ASSERTE (candidateMaybe != NULL );
64896505
@@ -6523,7 +6539,7 @@ BOOL MethodTable::FindDefaultInterfaceImplementation(
65236539 MethodTable *pCurMT = it.GetInterface (pMT, level);
65246540
65256541 MethodDesc *pCurMD = NULL ;
6526- if (TryGetCandidateImplementation (pCurMT, pInterfaceMD, pInterfaceMT, allowVariance , &pCurMD, level))
6542+ if (TryGetCandidateImplementation (pCurMT, pInterfaceMD, pInterfaceMT, findDefaultImplementationFlags , &pCurMD, level))
65276543 {
65286544 //
65296545 // Found a match. But is it a more specific match (we want most specific interfaces)
@@ -6619,6 +6635,8 @@ BOOL MethodTable::FindDefaultInterfaceImplementation(
66196635 }
66206636 else if (pBestCandidateMT != candidates[i].pMT )
66216637 {
6638+ bool throwOnConflict = (findDefaultImplementationFlags & FindDefaultInterfaceImplementationFlags::ThrowOnConflict) != FindDefaultInterfaceImplementationFlags::None;
6639+
66226640 if (throwOnConflict)
66236641 ThrowExceptionForConflictingOverride (this , pInterfaceMT, pInterfaceMD);
66246642
@@ -8875,12 +8893,15 @@ MethodDesc *
88758893MethodTable::ResolveVirtualStaticMethod (
88768894 MethodTable* pInterfaceType,
88778895 MethodDesc* pInterfaceMD,
8878- BOOL allowNullResult,
8879- BOOL verifyImplemented,
8880- BOOL allowVariantMatches,
8896+ ResolveVirtualStaticMethodFlags resolveVirtualStaticMethodFlags,
88818897 BOOL* uniqueResolution,
88828898 ClassLoadLevel level)
88838899{
8900+ bool verifyImplemented = (resolveVirtualStaticMethodFlags & ResolveVirtualStaticMethodFlags::VerifyImplemented) != ResolveVirtualStaticMethodFlags::None;
8901+ bool allowVariantMatches = (resolveVirtualStaticMethodFlags & ResolveVirtualStaticMethodFlags::AllowVariantMatches) != ResolveVirtualStaticMethodFlags::None;
8902+ bool instantiateMethodParameters = (resolveVirtualStaticMethodFlags & ResolveVirtualStaticMethodFlags::InstantiateResultOverFinalMethodDesc) != ResolveVirtualStaticMethodFlags::None;
8903+ bool allowNullResult = (resolveVirtualStaticMethodFlags & ResolveVirtualStaticMethodFlags::AllowNullResult) != ResolveVirtualStaticMethodFlags::None;
8904+
88848905 if (uniqueResolution != nullptr )
88858906 {
88868907 *uniqueResolution = TRUE ;
@@ -8912,7 +8933,7 @@ MethodTable::ResolveVirtualStaticMethod(
89128933 // Search for match on a per-level in the type hierarchy
89138934 for (MethodTable* pMT = this ; pMT != nullptr ; pMT = pMT->GetParentMethodTable ())
89148935 {
8915- MethodDesc* pMD = pMT->TryResolveVirtualStaticMethodOnThisType (pInterfaceType, pInterfaceMD, verifyImplemented, /* allowVariance */ FALSE , level);
8936+ MethodDesc* pMD = pMT->TryResolveVirtualStaticMethodOnThisType (pInterfaceType, pInterfaceMD, resolveVirtualStaticMethodFlags & ~ResolveVirtualStaticMethodFlags::AllowVariantMatches , level);
89168937 if (pMD != nullptr )
89178938 {
89188939 return pMD;
@@ -8956,7 +8977,7 @@ MethodTable::ResolveVirtualStaticMethod(
89568977 {
89578978 // Variant or equivalent matching interface found
89588979 // Attempt to resolve on variance matched interface
8959- pMD = pMT->TryResolveVirtualStaticMethodOnThisType (pItfInMap, pInterfaceMD, verifyImplemented, /* allowVariance */ FALSE , level);
8980+ pMD = pMT->TryResolveVirtualStaticMethodOnThisType (pItfInMap, pInterfaceMD, resolveVirtualStaticMethodFlags & ~ResolveVirtualStaticMethodFlags::AllowVariantMatches , level);
89608981 if (pMD != nullptr )
89618982 {
89628983 return pMD;
@@ -8970,12 +8991,25 @@ MethodTable::ResolveVirtualStaticMethod(
89708991 BOOL allowVariantMatchInDefaultImplementationLookup = FALSE ;
89718992 do
89728993 {
8994+ FindDefaultInterfaceImplementationFlags findDefaultImplementationFlags = FindDefaultInterfaceImplementationFlags::None;
8995+ if (allowVariantMatchInDefaultImplementationLookup)
8996+ {
8997+ findDefaultImplementationFlags |= FindDefaultInterfaceImplementationFlags::AllowVariance;
8998+ }
8999+ if (uniqueResolution == nullptr )
9000+ {
9001+ findDefaultImplementationFlags |= FindDefaultInterfaceImplementationFlags::ThrowOnConflict;
9002+ }
9003+ if (instantiateMethodParameters)
9004+ {
9005+ findDefaultImplementationFlags |= FindDefaultInterfaceImplementationFlags::InstantiateFoundMethodDesc;
9006+ }
9007+
89739008 BOOL haveUniqueDefaultImplementation = FindDefaultInterfaceImplementation (
89749009 pInterfaceMD,
89759010 pInterfaceType,
89769011 &pMDDefaultImpl,
8977- /* allowVariance */ allowVariantMatchInDefaultImplementationLookup,
8978- /* throwOnConflict */ uniqueResolution == nullptr ,
9012+ findDefaultImplementationFlags,
89799013 level);
89809014 if (haveUniqueDefaultImplementation || (pMDDefaultImpl != nullptr && (verifyImplemented || uniqueResolution != nullptr )))
89819015 {
@@ -9018,8 +9052,12 @@ MethodTable::ResolveVirtualStaticMethod(
90189052// Try to locate the appropriate MethodImpl matching a given interface static virtual method.
90199053// Returns nullptr on failure.
90209054MethodDesc*
9021- MethodTable::TryResolveVirtualStaticMethodOnThisType (MethodTable* pInterfaceType, MethodDesc* pInterfaceMD, BOOL verifyImplemented, BOOL allowVariance , ClassLoadLevel level)
9055+ MethodTable::TryResolveVirtualStaticMethodOnThisType (MethodTable* pInterfaceType, MethodDesc* pInterfaceMD, ResolveVirtualStaticMethodFlags resolveVirtualStaticMethodFlags , ClassLoadLevel level)
90229056{
9057+ bool instantiateMethodParameters = (resolveVirtualStaticMethodFlags & ResolveVirtualStaticMethodFlags::InstantiateResultOverFinalMethodDesc) != ResolveVirtualStaticMethodFlags::None;
9058+ bool allowVariance = (resolveVirtualStaticMethodFlags & ResolveVirtualStaticMethodFlags::AllowVariantMatches) != ResolveVirtualStaticMethodFlags::None;
9059+ bool verifyImplemented = (resolveVirtualStaticMethodFlags & ResolveVirtualStaticMethodFlags::VerifyImplemented) != ResolveVirtualStaticMethodFlags::None;
9060+
90239061 HRESULT hr = S_OK;
90249062 IMDInternalImport* pMDInternalImport = GetMDImport ();
90259063 HENUMInternalMethodImplHolder hEnumMethodImpl (pMDInternalImport);
@@ -9148,7 +9186,7 @@ MethodTable::TryResolveVirtualStaticMethodOnThisType(MethodTable* pInterfaceType
91489186 COMPlusThrow (kTypeLoadException , E_FAIL);
91499187 }
91509188
9151- if (!verifyImplemented)
9189+ if (!verifyImplemented && instantiateMethodParameters )
91529190 {
91539191 pMethodImpl = pMethodImpl->FindOrCreateAssociatedMethodDesc (
91549192 pMethodImpl,
@@ -9202,9 +9240,7 @@ MethodTable::VerifyThatAllVirtualStaticMethodsAreImplemented()
92029240 !ResolveVirtualStaticMethod (
92039241 pInterfaceMT,
92049242 pMD,
9205- /* allowNullResult */ TRUE ,
9206- /* verifyImplemented */ TRUE ,
9207- /* allowVariantMatches */ FALSE ,
9243+ ResolveVirtualStaticMethodFlags::AllowNullResult | ResolveVirtualStaticMethodFlags::VerifyImplemented,
92089244 /* uniqueResolution */ &uniqueResolution,
92099245 /* level */ CLASS_LOAD_EXACTPARENTS)))
92109246 {
@@ -9240,12 +9276,18 @@ MethodTable::TryResolveConstraintMethodApprox(
92409276 _ASSERTE (!thInterfaceType.IsTypeDesc ());
92419277 _ASSERTE (thInterfaceType.IsInterface ());
92429278 BOOL uniqueResolution;
9279+
9280+ ResolveVirtualStaticMethodFlags flags = ResolveVirtualStaticMethodFlags::AllowVariantMatches
9281+ | ResolveVirtualStaticMethodFlags::InstantiateResultOverFinalMethodDesc;
9282+ if (pfForceUseRuntimeLookup != NULL )
9283+ {
9284+ flags |= ResolveVirtualStaticMethodFlags::AllowNullResult;
9285+ }
9286+
92439287 MethodDesc *result = ResolveVirtualStaticMethod (
92449288 thInterfaceType.GetMethodTable (),
92459289 pInterfaceMD,
9246- /* allowNullResult */ pfForceUseRuntimeLookup != NULL ,
9247- /* verifyImplemented */ FALSE ,
9248- /* allowVariantMatches */ TRUE ,
9290+ flags,
92499291 &uniqueResolution);
92509292 if (result == NULL || !uniqueResolution)
92519293 {
0 commit comments