BuildMethodTableThrowException(IDS_CLASSLOAD_BADFORMAT);
}
- // Signature validation
- if (!bmtProp->fNoSanityChecks)
- {
- hr = validateTokenSig(tok,pMemberSignature,cMemberSignature,dwMemberAttrs,pMDInternalImport);
- if (FAILED(hr))
- {
- BuildMethodTableThrowException(hr, BFA_BAD_SIGNATURE, mdMethodDefNil);
- }
- }
+ bool isVtblGap = false;
if (IsMdRTSpecialName(dwMemberAttrs) || IsMdVirtual(dwMemberAttrs) || IsDelegate())
{
if (FAILED(pMDInternalImport->GetNameOfMethodDef(tok, (LPCSTR *)&strMethodName)))
{
BuildMethodTableThrowException(BFA_METHOD_NAME_TOO_LONG);
}
+
+ isVtblGap = IsMdRTSpecialName(dwMemberAttrs) && strncmp(strMethodName, "_VtblGap", 8) == 0;
}
else
{
strMethodName = NULL;
}
+ // Signature validation
+ if (!bmtProp->fNoSanityChecks && !isVtblGap)
+ {
+ hr = validateTokenSig(tok,pMemberSignature,cMemberSignature,dwMemberAttrs,pMDInternalImport);
+ if (FAILED(hr))
+ {
+ BuildMethodTableThrowException(hr, BFA_BAD_SIGNATURE, mdMethodDefNil);
+ }
+ }
+
DWORD numGenericMethodArgs = 0;
{
// single empty slot).
//
- if (IsMdRTSpecialName(dwMemberAttrs))
+ if (isVtblGap)
{
- PREFIX_ASSUME(strMethodName != NULL); // if we've gotten here we've called GetNameOfMethodDef
-
- // The slot is special, but it might not be a vtable spacer. To
- // determine that we must look at the name.
- if (strncmp(strMethodName, "_VtblGap", 8) == 0)
- {
- //
- // This slot doesn't really exist, don't add it to the method
- // table. Instead it represents one or more empty slots, encoded
- // in the method name. Locate the beginning of the count in the
- // name. There are these points to consider:
- // There may be no count present at all (in which case the
- // count is taken as one).
- // There may be an additional count just after Gap but before
- // the '_'. We ignore this.
- //
+ //
+ // This slot doesn't really exist, don't add it to the method
+ // table. Instead it represents one or more empty slots, encoded
+ // in the method name. Locate the beginning of the count in the
+ // name. There are these points to consider:
+ // There may be no count present at all (in which case the
+ // count is taken as one).
+ // There may be an additional count just after Gap but before
+ // the '_'. We ignore this.
+ //
- LPCSTR pos = strMethodName + 8;
+ LPCSTR pos = strMethodName + 8;
- // Skip optional number.
- while (IS_DIGIT(*pos))
- pos++;
+ // Skip optional number.
+ while (IS_DIGIT(*pos))
+ pos++;
- WORD n = 0;
+ WORD n = 0;
- // Check for presence of count.
- if (*pos == '\0')
- n = 1;
- else
+ // Check for presence of count.
+ if (*pos == '\0')
+ {
+ n = 1;
+ }
+ else
+ {
+ if (*pos != '_')
{
- if (*pos != '_')
- {
- BuildMethodTableThrowException(COR_E_BADIMAGEFORMAT,
- IDS_CLASSLOAD_BADSPECIALMETHOD,
- tok);
- }
+ BuildMethodTableThrowException(COR_E_BADIMAGEFORMAT,
+ IDS_CLASSLOAD_BADSPECIALMETHOD,
+ tok);
+ }
- // Skip '_'.
- pos++;
+ // Skip '_'.
+ pos++;
- // Read count.
- bool fReadAtLeastOneDigit = false;
- while (IS_DIGIT(*pos))
- {
- _ASSERTE(n < 6552);
- n *= 10;
- n += DIGIT_TO_INT(*pos);
- pos++;
- fReadAtLeastOneDigit = true;
- }
+ // Read count.
+ bool fReadAtLeastOneDigit = false;
+ while (IS_DIGIT(*pos))
+ {
+ _ASSERTE(n < 6552);
+ n *= 10;
+ n += DIGIT_TO_INT(*pos);
+ pos++;
+ fReadAtLeastOneDigit = true;
+ }
- // Check for end of name.
- if (*pos != '\0' || !fReadAtLeastOneDigit)
- {
- BuildMethodTableThrowException(COR_E_BADIMAGEFORMAT,
- IDS_CLASSLOAD_BADSPECIALMETHOD,
- tok);
- }
+ // Check for end of name.
+ if (*pos != '\0' || !fReadAtLeastOneDigit)
+ {
+ BuildMethodTableThrowException(COR_E_BADIMAGEFORMAT,
+ IDS_CLASSLOAD_BADSPECIALMETHOD,
+ tok);
}
+ }
#ifdef FEATURE_COMINTEROP
- // Record vtable gap in mapping list. The map is an optional field, so ensure we've allocated
- // these fields first.
- EnsureOptionalFieldsAreAllocated(GetHalfBakedClass(), m_pAllocMemTracker, GetLoaderAllocator()->GetLowFrequencyHeap());
- if (GetHalfBakedClass()->GetSparseCOMInteropVTableMap() == NULL)
- GetHalfBakedClass()->SetSparseCOMInteropVTableMap(new SparseVTableMap());
+ // Record vtable gap in mapping list. The map is an optional field, so ensure we've allocated
+ // these fields first.
+ EnsureOptionalFieldsAreAllocated(GetHalfBakedClass(), m_pAllocMemTracker, GetLoaderAllocator()->GetLowFrequencyHeap());
+ if (GetHalfBakedClass()->GetSparseCOMInteropVTableMap() == NULL)
+ GetHalfBakedClass()->SetSparseCOMInteropVTableMap(new SparseVTableMap());
- GetHalfBakedClass()->GetSparseCOMInteropVTableMap()->RecordGap((WORD)NumDeclaredMethods(), n);
+ GetHalfBakedClass()->GetSparseCOMInteropVTableMap()->RecordGap((WORD)NumDeclaredMethods(), n);
- bmtProp->fSparse = true;
+ bmtProp->fSparse = true;
#endif // FEATURE_COMINTEROP
- continue;
- }
-
+ continue;
}
-
//
// This is a real method so add it to the enumeration of methods. We now need to retrieve
// information on the method and store it for later use.