// Validate an EEType extracted from an object. bool EEType::Validate(bool assertOnFail /* default: true */) { #define REPORT_FAILURE() do { if (assertOnFail) { ASSERT_UNCONDITIONALLY("EEType::Validate check failed"); } return false; } while (false) // Deal with the most common case of a bad pointer without an exception. if (this == NULL) REPORT_FAILURE(); // EEType structures should be at least pointer aligned. if (dac_cast<TADDR>(this) & (sizeof(TADDR)-1)) REPORT_FAILURE(); // Verify object size is bigger than min_obj_size size_t minObjSize = get_BaseSize(); if (get_ComponentSize() != 0) { // If it is an array, we will align the size to the nearest pointer alignment, even if there are // zero elements. Our strings take advantage of this. minObjSize = (size_t)ALIGN_UP(minObjSize, sizeof(TADDR)); } if (minObjSize < (3 * sizeof(TADDR))) REPORT_FAILURE(); switch (get_Kind()) { case CanonicalEEType: { // If the parent type is NULL this had better look like Object. if (!IsInterface() && (m_RelatedType.m_pBaseType == NULL)) { if (IsRelatedTypeViaIAT() || get_IsValueType() || HasFinalizer() || HasReferenceFields() || HasGenericVariance()) { REPORT_FAILURE(); } } break; } case ClonedEEType: { // Cloned types must have a related type. if (m_RelatedType.m_ppCanonicalTypeViaIAT == NULL) REPORT_FAILURE(); // Either we're dealing with a clone of String or a generic type. We can tell the difference based // on the component size. switch (get_ComponentSize()) { case 0: { // Cloned generic type. if (!IsRelatedTypeViaIAT()) { REPORT_FAILURE(); } break; } case 2: { // Cloned string. if (get_IsValueType() || HasFinalizer() || HasReferenceFields() || HasGenericVariance()) { REPORT_FAILURE(); } break; } default: // Apart from cloned strings we don't expected cloned types to have a component size. REPORT_FAILURE(); } break; } case ParameterizedEEType: { // The only parameter EETypes that can exist on the heap are arrays // Array types must have a related type. if (m_RelatedType.m_pRelatedParameterType == NULL) REPORT_FAILURE(); // Component size cannot be zero in this case. if (get_ComponentSize() == 0) REPORT_FAILURE(); if (get_IsValueType() || HasFinalizer() || HasGenericVariance()) { REPORT_FAILURE(); } break; } case GenericTypeDefEEType: { // We should never see uninstantiated generic type definitions here // since we should never construct an object instance around them. REPORT_FAILURE(); } default: // Should be unreachable. REPORT_FAILURE(); } #undef REPORT_FAILURE return true; }
bool PrimitiveType::IsOfType(Type* pType) const { Type_type othertype = pType->get_Kind(); switch (get_Kind()) { case type_bool: { return othertype == type_bool; } break; case type_char: { return othertype == type_char; } break; case type_wchar_t: { switch (othertype) { case type_char: return true; case type_wchar_t: return true; } } break; case type_uchar16: { switch (othertype) { case type_uchar16: return true; } } break; case type_uchar32: { switch (othertype) { case type_uchar16: return true; case type_uchar32: return true; } } break; case type_short: { switch (othertype) { case type_short: return true; case type_signed_char: return true; case type_unsigned_char: return true; } } break; case type_int: { switch (othertype) { case type_int: return true; case type_short: return true; case type_unsigned_short: return true; case type_signed_char: return true; case type_unsigned_char: return true; } } break; case type_unsigned_int: { switch (othertype) { case type_unsigned_int: return true; case type_unsigned_short: return true; case type_unsigned_char: return true; } } break; case type_long_long: { switch (othertype) { case type_long_long: return true; case type_long: return true; case type_int: return true; case type_unsigned_int: return true; case type_short: return true; case type_unsigned_short: return true; case type_signed_char: return true; case type_unsigned_char: return true; } } break; case type_unsigned_long_long: { switch (othertype) { case type_unsigned_char: return true; case type_unsigned_short: return true; case type_unsigned_int: return true; case type_unsigned_long: return true; case type_unsigned_long_long: return true; } } break; case type_float: { return othertype == type_float; } break; case type_double: { return othertype == type_double || othertype == type_float; } break; case type_long_double: { return othertype == type_long_double || othertype == type_double || othertype == type_float; } break; case type_float80: { return othertype == type_float80 || othertype == type_long_double || othertype == type_double || othertype == type_float; } break; default: ASSERT(0); } return false; }