Beispiel #1
0
// 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;
}