@@ -2945,7 +2945,15 @@ MethodTableBuilder::EnumerateClassMethods()
29452945 }
29462946 if (IsMdStatic (dwMemberAttrs))
29472947 {
2948- BuildMethodTableThrowException (BFA_VIRTUAL_STATIC_METHOD );
2948+ if (fIsClassInterface )
2949+ {
2950+ bmtProp->fHasVirtualStaticMethods = TRUE ;
2951+ }
2952+ else
2953+ {
2954+ // Static virtual methods are only allowed to exist in interfaces
2955+ BuildMethodTableThrowException (BFA_VIRTUAL_STATIC_METHOD );
2956+ }
29492957 }
29502958 if (strMethodName && (0 ==strcmp (strMethodName, COR_CTOR_METHOD_NAME )))
29512959 {
@@ -5021,14 +5029,16 @@ MethodTableBuilder::ValidateMethods()
50215029
50225030 if (it.IsMethodImpl ())
50235031 {
5024- if (!IsMdVirtual (it.Attrs ()))
5025- { // Non-virtual methods cannot participate in a methodImpl pair.
5032+ if (!IsMdVirtual (it.Attrs ()) && !IsMdStatic (it.Attrs ()))
5033+ {
5034+ // Non-virtual methods may only participate in a methodImpl pair when
5035+ // they are static and they implement a virtual static interface method.
50265036 BuildMethodTableThrowException (IDS_CLASSLOAD_MI_MUSTBEVIRTUAL , it.Token ());
50275037 }
50285038 }
50295039
50305040 // Virtual static methods are not allowed.
5031- if (IsMdStatic (it.Attrs ()) && IsMdVirtual (it.Attrs ()))
5041+ if (IsMdStatic (it.Attrs ()) && IsMdVirtual (it.Attrs ()) && ! IsInterface () )
50325042 {
50335043 BuildMethodTableThrowException (IDS_CLASSLOAD_STATICVIRTUAL , it.Token ());
50345044 }
@@ -5297,8 +5307,8 @@ MethodTableBuilder::PlaceVirtualMethods()
52975307 DeclaredMethodIterator it (*this );
52985308 while (it.Next ())
52995309 {
5300- if (!IsMdVirtual (it.Attrs ()))
5301- { // Only processing declared virtual methods
5310+ if (!IsMdVirtual (it.Attrs ()) || IsMdStatic (it. Attrs ()) )
5311+ { // Only processing declared virtual instance methods
53025312 continue ;
53035313 }
53045314
@@ -5613,12 +5623,11 @@ MethodTableBuilder::ProcessMethodImpls()
56135623 DeclaredMethodIterator it (*this );
56145624 while (it.Next ())
56155625 {
5616- // Non-virtual methods cannot be classified as methodImpl - we should have thrown an
5617- // error before reaching this point.
5618- CONSISTENCY_CHECK (!(!IsMdVirtual (it.Attrs ()) && it.IsMethodImpl ()));
5619-
5620- if (!IsMdVirtual (it.Attrs ()))
5621- { // Only virtual methods can participate in methodImpls
5626+ if (!IsMdVirtual (it.Attrs ()) && it.IsMethodImpl ())
5627+ {
5628+ // Non-virtual methods can only be classified as methodImpl when implementing
5629+ // static virtual methods.
5630+ CONSISTENCY_CHECK (IsMdStatic (it.Attrs ()));
56225631 continue ;
56235632 }
56245633
@@ -6263,75 +6272,80 @@ MethodTableBuilder::PlaceMethodImpls()
62636272 // Get the declaration part of the method impl. It will either be a token
62646273 // (declaration is on this type) or a method desc.
62656274 bmtMethodHandle hDeclMethod = bmtMethodImpl->GetDeclarationMethod (iEntry);
6266- if (hDeclMethod.IsMDMethod ())
6267- {
6268- // The declaration is on the type being built
6269- bmtMDMethod * pCurDeclMethod = hDeclMethod.AsMDMethod ();
6270-
6271- mdToken mdef = pCurDeclMethod->GetMethodSignature ().GetToken ();
6272- if (bmtMethodImpl->IsBody (mdef))
6273- { // A method declared on this class cannot be both a decl and an impl
6274- BuildMethodTableThrowException (IDS_CLASSLOAD_MI_MULTIPLEOVERRIDES , mdef);
6275- }
62766275
6277- if (IsInterface ())
6278- {
6279- // Throws
6280- PlaceInterfaceDeclarationOnInterface (
6281- hDeclMethod,
6282- pCurImplMethod,
6283- slots, // Adds override to the slot and replaced arrays.
6284- replaced,
6285- &slotIndex,
6286- dwMaxSlotSize); // Increments count
6287- }
6288- else
6289- {
6290- // Throws
6291- PlaceLocalDeclarationOnClass (
6292- pCurDeclMethod,
6293- pCurImplMethod,
6294- slots, // Adds override to the slot and replaced arrays.
6295- replaced,
6296- &slotIndex,
6297- dwMaxSlotSize); // Increments count
6298- }
6299- }
6300- else
6276+ // Don't place static virtual method overrides in the vtable
6277+ if (!IsMdStatic (hDeclMethod.GetDeclAttrs ()))
63016278 {
6302- bmtRTMethod * pCurDeclMethod = hDeclMethod.AsRTMethod ();
6303-
6304- if (IsInterface ())
6305- {
6306- // Throws
6307- PlaceInterfaceDeclarationOnInterface (
6308- hDeclMethod,
6309- pCurImplMethod,
6310- slots, // Adds override to the slot and replaced arrays.
6311- replaced,
6312- &slotIndex,
6313- dwMaxSlotSize); // Increments count
6314- }
6315- else
6279+ if (hDeclMethod.IsMDMethod ())
63166280 {
6317- // Do not use pDecl->IsInterface here as that asks the method table and the MT may not yet be set up.
6318- if (pCurDeclMethod->GetOwningType ()->IsInterface ())
6281+ // The declaration is on the type being built
6282+ bmtMDMethod * pCurDeclMethod = hDeclMethod.AsMDMethod ();
6283+
6284+ mdToken mdef = pCurDeclMethod->GetMethodSignature ().GetToken ();
6285+ if (bmtMethodImpl->IsBody (mdef))
6286+ { // A method declared on this class cannot be both a decl and an impl
6287+ BuildMethodTableThrowException (IDS_CLASSLOAD_MI_MULTIPLEOVERRIDES , mdef);
6288+ }
6289+
6290+ if (IsInterface ())
63196291 {
63206292 // Throws
6321- PlaceInterfaceDeclarationOnClass (
6322- pCurDeclMethod,
6323- pCurImplMethod);
6293+ PlaceInterfaceDeclarationOnInterface (
6294+ hDeclMethod,
6295+ pCurImplMethod,
6296+ slots, // Adds override to the slot and replaced arrays.
6297+ replaced,
6298+ &slotIndex,
6299+ dwMaxSlotSize); // Increments count
63246300 }
63256301 else
63266302 {
63276303 // Throws
6328- PlaceParentDeclarationOnClass (
6304+ PlaceLocalDeclarationOnClass (
63296305 pCurDeclMethod,
63306306 pCurImplMethod,
6331- slots,
6307+ slots, // Adds override to the slot and replaced arrays.
6308+ replaced,
6309+ &slotIndex,
6310+ dwMaxSlotSize); // Increments count
6311+ }
6312+ }
6313+ else
6314+ {
6315+ bmtRTMethod * pCurDeclMethod = hDeclMethod.AsRTMethod ();
6316+
6317+ if (IsInterface ())
6318+ {
6319+ // Throws
6320+ PlaceInterfaceDeclarationOnInterface (
6321+ hDeclMethod,
6322+ pCurImplMethod,
6323+ slots, // Adds override to the slot and replaced arrays.
63326324 replaced,
63336325 &slotIndex,
6334- dwMaxSlotSize); // Increments count
6326+ dwMaxSlotSize); // Increments count
6327+ }
6328+ else
6329+ {
6330+ // Do not use pDecl->IsInterface here as that asks the method table and the MT may not yet be set up.
6331+ if (pCurDeclMethod->GetOwningType ()->IsInterface ())
6332+ {
6333+ // Throws
6334+ PlaceInterfaceDeclarationOnClass (
6335+ pCurDeclMethod,
6336+ pCurImplMethod);
6337+ }
6338+ else
6339+ {
6340+ // Throws
6341+ PlaceParentDeclarationOnClass (
6342+ pCurDeclMethod,
6343+ pCurImplMethod,
6344+ slots,
6345+ replaced,
6346+ &slotIndex,
6347+ dwMaxSlotSize); // Increments count
6348+ }
63356349 }
63366350 }
63376351 }
@@ -9783,7 +9797,8 @@ MethodTable * MethodTableBuilder::AllocateNewMT(
97839797 LoaderAllocator *pAllocator,
97849798 BOOL isInterface,
97859799 BOOL fDynamicStatics ,
9786- BOOL fHasGenericsStaticsInfo
9800+ BOOL fHasGenericsStaticsInfo ,
9801+ BOOL fHasVirtualStaticMethods
97879802#ifdef FEATURE_COMINTEROP
97889803 , BOOL fHasDynamicInterfaceMap
97899804#endif
@@ -9926,6 +9941,10 @@ MethodTable * MethodTableBuilder::AllocateNewMT(
99269941
99279942 // initialize the total number of slots
99289943 pMT->SetNumVirtuals (static_cast <WORD >(dwVirtuals));
9944+ if (fHasVirtualStaticMethods )
9945+ {
9946+ pMT->SetHasVirtualStaticMethods ();
9947+ }
99299948
99309949 pMT->SetParentMethodTable (pMTParent);
99319950
@@ -10103,6 +10122,7 @@ MethodTableBuilder::SetupMethodTable2(
1010310122 IsInterface (),
1010410123 bmtProp->fDynamicStatics ,
1010510124 bmtProp->fGenericsStatics ,
10125+ bmtProp->fHasVirtualStaticMethods ,
1010610126#ifdef FEATURE_COMINTEROP
1010710127 fHasDynamicInterfaceMap ,
1010810128#endif
0 commit comments