예제 #1
0
        private static unsafe bool UnboxAnyTypeCompare(EEType *pEEType, EEType *ptrUnboxToEEType)
        {
            if (TypeCast.AreTypesEquivalentInternal(pEEType, ptrUnboxToEEType))
            {
                return(true);
            }

            if (pEEType->CorElementType == ptrUnboxToEEType->CorElementType)
            {
                // Enum's and primitive types should pass the UnboxAny exception cases
                // if they have an exactly matching cor element type.
                switch (ptrUnboxToEEType->CorElementType)
                {
                case CorElementType.ELEMENT_TYPE_I1:
                case CorElementType.ELEMENT_TYPE_U1:
                case CorElementType.ELEMENT_TYPE_I2:
                case CorElementType.ELEMENT_TYPE_U2:
                case CorElementType.ELEMENT_TYPE_I4:
                case CorElementType.ELEMENT_TYPE_U4:
                case CorElementType.ELEMENT_TYPE_I8:
                case CorElementType.ELEMENT_TYPE_U8:
                case CorElementType.ELEMENT_TYPE_I:
                case CorElementType.ELEMENT_TYPE_U:
                    return(true);
                }
            }

            return(false);
        }
예제 #2
0
        private static unsafe bool UnboxAnyTypeCompare(EEType *pEEType, EEType *ptrUnboxToEEType)
        {
            if (TypeCast.AreTypesEquivalentInternal(pEEType, ptrUnboxToEEType))
            {
                return(true);
            }

            if (pEEType->ElementType == ptrUnboxToEEType->ElementType)
            {
                // Enum's and primitive types should pass the UnboxAny exception cases
                // if they have an exactly matching cor element type.
                switch (ptrUnboxToEEType->ElementType)
                {
                case EETypeElementType.Byte:
                case EETypeElementType.SByte:
                case EETypeElementType.Int16:
                case EETypeElementType.UInt16:
                case EETypeElementType.Int32:
                case EETypeElementType.UInt32:
                case EETypeElementType.Int64:
                case EETypeElementType.UInt64:
                case EETypeElementType.IntPtr:
                case EETypeElementType.UIntPtr:
                    return(true);
                }
            }

            return(false);
        }
예제 #3
0
        public static unsafe void RhUnboxNullable(ref byte data, EETypePtr pUnboxToEEType, Object obj)
        {
            EEType *ptrUnboxToEEType = (EEType *)pUnboxToEEType.ToPointer();

            if ((obj != null) && !TypeCast.AreTypesEquivalentInternal(obj.EEType, ptrUnboxToEEType->NullableType))
            {
                throw ptrUnboxToEEType->GetClasslibException(ExceptionIDs.InvalidCast);
            }
            InternalCalls.RhUnbox(obj, ref data, ptrUnboxToEEType);
        }
예제 #4
0
        public unsafe static void RhUnboxAny(object o, ref Hack_o_p data, EETypePtr pUnboxToEEType)
        {
            EEType *ptrUnboxToEEType = (EEType *)pUnboxToEEType.ToPointer();

            if (ptrUnboxToEEType->IsValueType)
            {
                // HACK: we would really want to take the address of o here,
                // but the rules of the C# language don't let us do that,
                // so we arrive at the same result by taking the address of p
                // and going back one pointer-sized unit
                fixed(IntPtr *pData = &data.p)
                {
                    bool isValid = false;

                    if (ptrUnboxToEEType->IsNullable)
                    {
                        isValid = (o == null) || TypeCast.AreTypesEquivalentInternal(o.EEType, ptrUnboxToEEType->GetNullableType());
                    }
                    else if (o != null)
                    {
                        isValid = UnboxAnyTypeCompare(o.EEType, ptrUnboxToEEType);
                    }

                    if (!isValid)
                    {
                        // Throw the invalid cast exception defined by the classlib, using the input unbox EEType*
                        // to find the correct classlib.

                        ExceptionIDs exID = o == null ? ExceptionIDs.NullReference : ExceptionIDs.InvalidCast;

                        IntPtr    addr = ptrUnboxToEEType->GetAssociatedModuleAddress();
                        Exception e    = EH.GetClasslibException(exID, addr);

                        BinderIntrinsics.TailCall_RhpThrowEx(e);
                    }
                    InternalCalls.RhUnbox(o, pData - 1, ptrUnboxToEEType);
                }
            }
            else
            {
                if (o == null || (TypeCast.IsInstanceOf(o, ptrUnboxToEEType) != null))
                {
                    data.o = o;
                }
                else
                {
                    IntPtr    addr = ptrUnboxToEEType->GetAssociatedModuleAddress();
                    Exception e    = EH.GetClasslibException(ExceptionIDs.InvalidCast, addr);

                    BinderIntrinsics.TailCall_RhpThrowEx(e);
                }
            }
        }
예제 #5
0
        public static unsafe void RhUnboxAny(object o, ref byte data, EETypePtr pUnboxToEEType)
        {
            EEType *ptrUnboxToEEType = (EEType *)pUnboxToEEType.ToPointer();

            if (ptrUnboxToEEType->IsValueType)
            {
                bool isValid = false;

                if (ptrUnboxToEEType->IsNullable)
                {
                    isValid = (o == null) || TypeCast.AreTypesEquivalentInternal(o.EEType, ptrUnboxToEEType->NullableType);
                }
                else
                {
                    isValid = (o != null) && UnboxAnyTypeCompare(o.EEType, ptrUnboxToEEType);
                }

                if (!isValid)
                {
                    // Throw the invalid cast exception defined by the classlib, using the input unbox EEType*
                    // to find the correct classlib.

                    ExceptionIDs exID = o == null ? ExceptionIDs.NullReference : ExceptionIDs.InvalidCast;

                    throw ptrUnboxToEEType->GetClasslibException(exID);
                }

                InternalCalls.RhUnbox(o, ref data, ptrUnboxToEEType);
            }
            else
            {
                if (o != null && (TypeCast.IsInstanceOf(o, ptrUnboxToEEType) == null))
                {
                    throw ptrUnboxToEEType->GetClasslibException(ExceptionIDs.InvalidCast);
                }

                Unsafe.As <byte, Object>(ref data) = o;
            }
        }