@@ -6210,22 +6210,26 @@ MethodTable::FindDispatchImpl(
6210
6210
6211
6211
// Try exact match first
6212
6212
MethodDesc *pDefaultMethod = NULL ;
6213
+
6214
+ FindDefaultInterfaceImplementationFlags flags = FindDefaultInterfaceImplementationFlags::InstantiateFoundMethodDesc;
6215
+ if (throwOnConflict)
6216
+ flags = flags | FindDefaultInterfaceImplementationFlags::ThrowOnConflict;
6217
+
6213
6218
BOOL foundDefaultInterfaceImplementation = FindDefaultInterfaceImplementation (
6214
6219
pIfcMD, // the interface method being resolved
6215
6220
pIfcMT, // the interface being resolved
6216
6221
&pDefaultMethod,
6217
- FALSE , // allowVariance
6218
- throwOnConflict);
6222
+ flags);
6219
6223
6220
6224
// If there's no exact match, try a variant match
6221
6225
if (!foundDefaultInterfaceImplementation && pIfcMT->HasVariance ())
6222
6226
{
6227
+ flags = flags | FindDefaultInterfaceImplementationFlags::AllowVariance;
6223
6228
foundDefaultInterfaceImplementation = FindDefaultInterfaceImplementation (
6224
6229
pIfcMD, // the interface method being resolved
6225
6230
pIfcMT, // the interface being resolved
6226
6231
&pDefaultMethod,
6227
- TRUE , // allowVariance
6228
- throwOnConflict);
6232
+ flags);
6229
6233
}
6230
6234
6231
6235
if (foundDefaultInterfaceImplementation)
@@ -6324,10 +6328,13 @@ namespace
6324
6328
MethodTable *pMT,
6325
6329
MethodDesc *interfaceMD,
6326
6330
MethodTable *interfaceMT,
6327
- BOOL allowVariance ,
6331
+ FindDefaultInterfaceImplementationFlags findDefaultImplementationFlags ,
6328
6332
MethodDesc **candidateMD,
6329
6333
ClassLoadLevel level)
6330
6334
{
6335
+ bool allowVariance = (findDefaultImplementationFlags & FindDefaultInterfaceImplementationFlags::AllowVariance) != FindDefaultInterfaceImplementationFlags::None;
6336
+ bool instantiateMethodInstantiation = (findDefaultImplementationFlags & FindDefaultInterfaceImplementationFlags::InstantiateFoundMethodDesc) != FindDefaultInterfaceImplementationFlags::None;
6337
+
6331
6338
*candidateMD = NULL ;
6332
6339
6333
6340
MethodDesc *candidateMaybe = NULL ;
@@ -6418,11 +6425,20 @@ namespace
6418
6425
else
6419
6426
{
6420
6427
// 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
+
6421
6438
candidateMaybe = pMT->TryResolveVirtualStaticMethodOnThisType (
6422
6439
interfaceMT,
6423
6440
interfaceMD,
6424
- /* verifyImplemented */ FALSE ,
6425
- /* allowVariance */ allowVariance,
6441
+ resolveVirtualStaticMethodFlags,
6426
6442
/* level */ level);
6427
6443
}
6428
6444
}
@@ -6461,8 +6477,7 @@ BOOL MethodTable::FindDefaultInterfaceImplementation(
6461
6477
MethodDesc *pInterfaceMD,
6462
6478
MethodTable *pInterfaceMT,
6463
6479
MethodDesc **ppDefaultMethod,
6464
- BOOL allowVariance,
6465
- BOOL throwOnConflict,
6480
+ FindDefaultInterfaceImplementationFlags findDefaultImplementationFlags,
6466
6481
ClassLoadLevel level
6467
6482
)
6468
6483
{
@@ -6478,12 +6493,13 @@ BOOL MethodTable::FindDefaultInterfaceImplementation(
6478
6493
} CONTRACT_END;
6479
6494
6480
6495
#ifdef FEATURE_DEFAULT_INTERFACES
6496
+ bool allowVariance = (findDefaultImplementationFlags & FindDefaultInterfaceImplementationFlags::AllowVariance) != FindDefaultInterfaceImplementationFlags::None;
6481
6497
CQuickArray<MatchCandidate> candidates;
6482
6498
unsigned candidatesCount = 0 ;
6483
6499
6484
6500
// Check the current method table itself
6485
6501
MethodDesc *candidateMaybe = NULL ;
6486
- if (IsInterface () && TryGetCandidateImplementation (this , pInterfaceMD, pInterfaceMT, allowVariance , &candidateMaybe, level))
6502
+ if (IsInterface () && TryGetCandidateImplementation (this , pInterfaceMD, pInterfaceMT, findDefaultImplementationFlags , &candidateMaybe, level))
6487
6503
{
6488
6504
_ASSERTE (candidateMaybe != NULL );
6489
6505
@@ -6523,7 +6539,7 @@ BOOL MethodTable::FindDefaultInterfaceImplementation(
6523
6539
MethodTable *pCurMT = it.GetInterface (pMT, level);
6524
6540
6525
6541
MethodDesc *pCurMD = NULL ;
6526
- if (TryGetCandidateImplementation (pCurMT, pInterfaceMD, pInterfaceMT, allowVariance , &pCurMD, level))
6542
+ if (TryGetCandidateImplementation (pCurMT, pInterfaceMD, pInterfaceMT, findDefaultImplementationFlags , &pCurMD, level))
6527
6543
{
6528
6544
//
6529
6545
// Found a match. But is it a more specific match (we want most specific interfaces)
@@ -6619,6 +6635,8 @@ BOOL MethodTable::FindDefaultInterfaceImplementation(
6619
6635
}
6620
6636
else if (pBestCandidateMT != candidates[i].pMT )
6621
6637
{
6638
+ bool throwOnConflict = (findDefaultImplementationFlags & FindDefaultInterfaceImplementationFlags::ThrowOnConflict) != FindDefaultInterfaceImplementationFlags::None;
6639
+
6622
6640
if (throwOnConflict)
6623
6641
ThrowExceptionForConflictingOverride (this , pInterfaceMT, pInterfaceMD);
6624
6642
@@ -8875,12 +8893,15 @@ MethodDesc *
8875
8893
MethodTable::ResolveVirtualStaticMethod (
8876
8894
MethodTable* pInterfaceType,
8877
8895
MethodDesc* pInterfaceMD,
8878
- BOOL allowNullResult,
8879
- BOOL verifyImplemented,
8880
- BOOL allowVariantMatches,
8896
+ ResolveVirtualStaticMethodFlags resolveVirtualStaticMethodFlags,
8881
8897
BOOL* uniqueResolution,
8882
8898
ClassLoadLevel level)
8883
8899
{
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
+
8884
8905
if (uniqueResolution != nullptr )
8885
8906
{
8886
8907
*uniqueResolution = TRUE ;
@@ -8912,7 +8933,7 @@ MethodTable::ResolveVirtualStaticMethod(
8912
8933
// Search for match on a per-level in the type hierarchy
8913
8934
for (MethodTable* pMT = this ; pMT != nullptr ; pMT = pMT->GetParentMethodTable ())
8914
8935
{
8915
- MethodDesc* pMD = pMT->TryResolveVirtualStaticMethodOnThisType (pInterfaceType, pInterfaceMD, verifyImplemented, /* allowVariance */ FALSE , level);
8936
+ MethodDesc* pMD = pMT->TryResolveVirtualStaticMethodOnThisType (pInterfaceType, pInterfaceMD, resolveVirtualStaticMethodFlags & ~ResolveVirtualStaticMethodFlags::AllowVariantMatches , level);
8916
8937
if (pMD != nullptr )
8917
8938
{
8918
8939
return pMD;
@@ -8956,7 +8977,7 @@ MethodTable::ResolveVirtualStaticMethod(
8956
8977
{
8957
8978
// Variant or equivalent matching interface found
8958
8979
// 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);
8960
8981
if (pMD != nullptr )
8961
8982
{
8962
8983
return pMD;
@@ -8970,12 +8991,25 @@ MethodTable::ResolveVirtualStaticMethod(
8970
8991
BOOL allowVariantMatchInDefaultImplementationLookup = FALSE ;
8971
8992
do
8972
8993
{
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
+
8973
9008
BOOL haveUniqueDefaultImplementation = FindDefaultInterfaceImplementation (
8974
9009
pInterfaceMD,
8975
9010
pInterfaceType,
8976
9011
&pMDDefaultImpl,
8977
- /* allowVariance */ allowVariantMatchInDefaultImplementationLookup,
8978
- /* throwOnConflict */ uniqueResolution == nullptr ,
9012
+ findDefaultImplementationFlags,
8979
9013
level);
8980
9014
if (haveUniqueDefaultImplementation || (pMDDefaultImpl != nullptr && (verifyImplemented || uniqueResolution != nullptr )))
8981
9015
{
@@ -9018,8 +9052,12 @@ MethodTable::ResolveVirtualStaticMethod(
9018
9052
// Try to locate the appropriate MethodImpl matching a given interface static virtual method.
9019
9053
// Returns nullptr on failure.
9020
9054
MethodDesc*
9021
- MethodTable::TryResolveVirtualStaticMethodOnThisType (MethodTable* pInterfaceType, MethodDesc* pInterfaceMD, BOOL verifyImplemented, BOOL allowVariance , ClassLoadLevel level)
9055
+ MethodTable::TryResolveVirtualStaticMethodOnThisType (MethodTable* pInterfaceType, MethodDesc* pInterfaceMD, ResolveVirtualStaticMethodFlags resolveVirtualStaticMethodFlags , ClassLoadLevel level)
9022
9056
{
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
+
9023
9061
HRESULT hr = S_OK;
9024
9062
IMDInternalImport* pMDInternalImport = GetMDImport ();
9025
9063
HENUMInternalMethodImplHolder hEnumMethodImpl (pMDInternalImport);
@@ -9148,7 +9186,7 @@ MethodTable::TryResolveVirtualStaticMethodOnThisType(MethodTable* pInterfaceType
9148
9186
COMPlusThrow (kTypeLoadException , E_FAIL);
9149
9187
}
9150
9188
9151
- if (!verifyImplemented)
9189
+ if (!verifyImplemented && instantiateMethodParameters )
9152
9190
{
9153
9191
pMethodImpl = pMethodImpl->FindOrCreateAssociatedMethodDesc (
9154
9192
pMethodImpl,
@@ -9202,9 +9240,7 @@ MethodTable::VerifyThatAllVirtualStaticMethodsAreImplemented()
9202
9240
!ResolveVirtualStaticMethod (
9203
9241
pInterfaceMT,
9204
9242
pMD,
9205
- /* allowNullResult */ TRUE ,
9206
- /* verifyImplemented */ TRUE ,
9207
- /* allowVariantMatches */ FALSE ,
9243
+ ResolveVirtualStaticMethodFlags::AllowNullResult | ResolveVirtualStaticMethodFlags::VerifyImplemented,
9208
9244
/* uniqueResolution */ &uniqueResolution,
9209
9245
/* level */ CLASS_LOAD_EXACTPARENTS)))
9210
9246
{
@@ -9240,12 +9276,18 @@ MethodTable::TryResolveConstraintMethodApprox(
9240
9276
_ASSERTE (!thInterfaceType.IsTypeDesc ());
9241
9277
_ASSERTE (thInterfaceType.IsInterface ());
9242
9278
BOOL uniqueResolution;
9279
+
9280
+ ResolveVirtualStaticMethodFlags flags = ResolveVirtualStaticMethodFlags::AllowVariantMatches
9281
+ | ResolveVirtualStaticMethodFlags::InstantiateResultOverFinalMethodDesc;
9282
+ if (pfForceUseRuntimeLookup != NULL )
9283
+ {
9284
+ flags |= ResolveVirtualStaticMethodFlags::AllowNullResult;
9285
+ }
9286
+
9243
9287
MethodDesc *result = ResolveVirtualStaticMethod (
9244
9288
thInterfaceType.GetMethodTable (),
9245
9289
pInterfaceMD,
9246
- /* allowNullResult */ pfForceUseRuntimeLookup != NULL ,
9247
- /* verifyImplemented */ FALSE ,
9248
- /* allowVariantMatches */ TRUE ,
9290
+ flags,
9249
9291
&uniqueResolution);
9250
9292
if (result == NULL || !uniqueResolution)
9251
9293
{
0 commit comments