Exemplo n.º 1
0
        static public /*internal*/ unsafe object CheckCastArray(Object obj, void *pvTargetEEType)
        {
            // a null value can be cast to anything
            if (obj == null)
            {
                return(null);
            }

            object result = IsInstanceOfArray(obj, pvTargetEEType);

            if (result == null)
            {
                // Throw the invalid cast exception defined by the classlib, using the input EEType*
                // to find the correct classlib.

                ExceptionIDs exID = ExceptionIDs.InvalidCast;

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

                BinderIntrinsics.TailCall_RhpThrowEx(e);
            }

            return(result);
        }
Exemplo n.º 2
0
        static public unsafe void *LdelemaRef(Object array, int index, IntPtr elementType)
        {
            Debug.Assert(array.EEType->IsArray, "second argument must be an array");

            EEType *elemType      = (EEType *)elementType;
            EEType *arrayElemType = array.EEType->RelatedParameterType;

            if (!AreTypesEquivalentInternal(elemType, arrayElemType))
            {
                // Throw the array type mismatch exception defined by the classlib, using the input array's EEType*
                // to find the correct classlib.

                IntPtr    addr = array.EEType->GetAssociatedModuleAddress();
                Exception e    = EH.GetClasslibException(ExceptionIDs.ArrayTypeMismatch, addr);

                BinderIntrinsics.TailCall_RhpThrowEx(e);
            }

            fixed(void *pArray = &array.m_pEEType)
            {
                // CORERT-TODO: This code has GC hole - the method return type should really be byref.
                // Requires byref returns in C# to fix cleanly (https://github.com/dotnet/roslyn/issues/118)
                return((IntPtr *)pArray + ArrayBaseIndex + index);
            }
        }
Exemplo n.º 3
0
        static public unsafe void CheckVectorElemAddr(void *pvElemType, object array)
        {
            if (array == null)
            {
                return;
            }

            Debug.Assert(array.EEType->IsArray, "second argument must be an array");

            EEType *elemType      = (EEType *)pvElemType;
            EEType *arrayElemType = array.EEType->RelatedParameterType;

            if (!AreTypesEquivalentInternal(elemType, arrayElemType)
                // In addition to the exactness check, add another check to allow non-exact matches through
                // if the element type is a ValueType. The issue here is Universal Generics. The Universal
                // Generic codegen will generate a call to this helper for all ldelema opcodes if the exact
                // type is not known, and this can include ValueTypes. For ValueTypes, the exact check is not
                // desireable as enum's are allowed to pass through this code if they are size matched.
                // While this check is overly broad and allows non-enum valuetypes to also skip the check
                // that is OK, because in the non-enum case the casting operations are sufficient to ensure
                // type safety.
                && !elemType->IsValueType)
            {
                // Throw the array type mismatch exception defined by the classlib, using the input array's EEType*
                // to find the correct classlib.
                ExceptionIDs exID = ExceptionIDs.ArrayTypeMismatch;

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

                BinderIntrinsics.TailCall_RhpThrowEx(e);
            }
        }
Exemplo n.º 4
0
        static public unsafe void StelemRef(Object array, int index, object obj)
        {
            // This is supported only on arrays
            Debug.Assert(array.EEType->IsArray, "first argument must be an array");

            if (index >= array.GetArrayLength())
            {
                IntPtr    addr = array.EEType->GetAssociatedModuleAddress();
                Exception e    = EH.GetClasslibException(ExceptionIDs.IndexOutOfRange, addr);
                throw e;
            }

            if (obj != null)
            {
                EEType *arrayElemType = array.EEType->RelatedParameterType;
                bool    compatible;
                if (arrayElemType->IsInterface)
                {
                    compatible = IsInstanceOfInterface(obj, arrayElemType) != null;
                }
                else if (arrayElemType->IsArray)
                {
                    compatible = IsInstanceOfArray(obj, arrayElemType) != null;
                }
                else
                {
                    compatible = IsInstanceOfClass(obj, arrayElemType) != null;
                }

                if (!compatible)
                {
                    // Throw the array type mismatch exception defined by the classlib, using the input array's EEType*
                    // to find the correct classlib.

                    IntPtr    addr = array.EEType->GetAssociatedModuleAddress();
                    Exception e    = EH.GetClasslibException(ExceptionIDs.ArrayTypeMismatch, addr);

                    BinderIntrinsics.TailCall_RhpThrowEx(e);
                }

                // Both bounds and type check are ok.
                fixed(void *pArray = &array.m_pEEType)
                {
                    RhpAssignRef((IntPtr *)pArray + ArrayBaseIndex + index, obj);
                }
            }
            else
            {
                fixed(void *pArray = &array.m_pEEType)
                {
                    // Storing null does not require write barrier
                    *((IntPtr *)pArray + ArrayBaseIndex + index) = default(IntPtr);
                }
            }
        }
Exemplo n.º 5
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);
                }
            }
        }
Exemplo n.º 6
0
        static public /*internal*/ unsafe object CheckCastInterface(Object obj, void *pvTargetEEType)
        {
            // a null value can be cast to anything
            if (obj == null)
            {
                return(null);
            }

            EEType *pTargetType = (EEType *)pvTargetEEType;
            EEType *pObjType    = obj.EEType;

            if (ImplementsInterface(pObjType, pTargetType))
            {
                return(obj);
            }

            Exception castError = null;

            // If object type implements ICastable then there's one more way to check whether it implements
            // the interface.
            if (pObjType->IsICastable)
            {
                // Call the ICastable.IsInstanceOfInterface method directly rather than via an interface
                // dispatch since we know the method address statically.
                IntPtr pfnIsInstanceOfInterface = pObjType->ICastableIsInstanceOfInterfaceMethod;
                if (CalliIntrinsics.Call <bool>(pfnIsInstanceOfInterface, obj, pTargetType, out castError))
                {
                    return(obj);
                }
            }

            // Throw the invalid cast exception defined by the classlib, using the input EEType* to find the
            // correct classlib unless ICastable.IsInstanceOfInterface returned a more specific exception for
            // us to use.

            IntPtr addr = ((EEType *)pvTargetEEType)->GetAssociatedModuleAddress();

            if (castError == null)
            {
                castError = EH.GetClasslibException(ExceptionIDs.InvalidCast, addr);
            }

            BinderIntrinsics.TailCall_RhpThrowEx(castError);
            throw castError;
        }
Exemplo n.º 7
0
        public unsafe static object RhBox(EETypePtr pEEType, void *pData)
        {
            EEType *ptrEEType = (EEType *)pEEType.ToPointer();
            object  result;

            // If we're boxing a Nullable<T> then either box the underlying T or return null (if the
            // nullable's value is empty).
            if (ptrEEType->IsNullable)
            {
                // The boolean which indicates whether the value is null comes first in the Nullable struct.
                if (!*(bool *)pData)
                {
                    return(null);
                }

                // Switch type we're going to box to the Nullable<T> target type and advance the data pointer
                // to the value embedded within the nullable.
                pData     = (byte *)pData + ptrEEType->GetNullableValueOffset();
                ptrEEType = ptrEEType->GetNullableType();
            }

#if FEATURE_64BIT_ALIGNMENT
            if (ptrEEType->RequiresAlign8)
            {
                result = InternalCalls.RhpNewFastMisalign(ptrEEType);
            }
            else
#endif // FEATURE_64BIT_ALIGNMENT
            {
                result = InternalCalls.RhpNewFast(ptrEEType);
            }
            if (result == null)
            {
                // Throw the out of memory exception defined by the classlib, using the input EEType*
                // to find the correct classlib.

                ExceptionIDs exID = ExceptionIDs.OutOfMemory;

                IntPtr    addr = pEEType.ToPointer()->GetAssociatedModuleAddress();
                Exception e    = EH.GetClasslibException(exID, addr);
                throw e;
            }
            InternalCalls.RhpBox(result, pData);
            return(result);
        }
Exemplo n.º 8
0
        public static IntPtr RhHandleAllocVariable(object value, uint type)
        {
            IntPtr h = InternalCalls.RhpHandleAllocVariable(value, type);

            if (h == IntPtr.Zero)
            {
                // Throw the out of memory exception defined by the classlib, using the return address of this method
                // to find the correct classlib.

                ExceptionIDs exID = ExceptionIDs.OutOfMemory;

                IntPtr    returnAddr = BinderIntrinsics.GetReturnAddress();
                Exception e          = EH.GetClasslibException(exID, returnAddr);
                throw e;
            }

            return(h);
        }
Exemplo n.º 9
0
        public static IntPtr RhHandleAllocDependent(object primary, object secondary)
        {
            IntPtr h = InternalCalls.RhpHandleAllocDependent(primary, secondary);

            if (h == IntPtr.Zero)
            {
                // Throw the out of memory exception defined by the classlib, using the return address of this method
                // to find the correct classlib.

                ExceptionIDs exID = ExceptionIDs.OutOfMemory;

                IntPtr    returnAddr = BinderIntrinsics.GetReturnAddress();
                Exception e          = EH.GetClasslibException(exID, returnAddr);
                throw e;
            }

            return(h);
        }
Exemplo n.º 10
0
        public static void RhpReversePInvokeBadTransition()
        {
            IntPtr returnAddress = BinderIntrinsics.GetReturnAddress();

            if (returnAddress != IntPtr.Zero)
            {
                EH.FailFastViaClasslib(
                    RhFailFastReason.IllegalNativeCallableEntry,
                    null,
                    returnAddress);
            }
            else
            {
                // @HACKHACK: we need to force the method to have an EBP frame so that we can use the
                // GetReturnAddress() intrinsic above.  This seems to be the smallest way to do this.
                EH.FailFast(RhFailFastReason.InternalError, null);
                throw EH.GetClasslibException(ExceptionIDs.Arithmetic, returnAddress);
            }
        }
Exemplo n.º 11
0
        static public unsafe void RhUnboxNullable(ref Hack_o_p data, EETypePtr pUnboxToEEType, Object obj)
        {
            EEType *ptrUnboxToEEType = (EEType *)pUnboxToEEType.ToPointer();

            // 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)
            {
                if ((obj != null) && (obj.EEType != ptrUnboxToEEType->GetNullableType()))
                {
                    IntPtr    addr = ptrUnboxToEEType->GetAssociatedModuleAddress();
                    Exception e    = EH.GetClasslibException(ExceptionIDs.InvalidCast, addr);

                    BinderIntrinsics.TailCall_RhpThrowEx(e);
                }
                InternalCalls.RhUnbox(obj, pData - 1, ptrUnboxToEEType);
            }
        }
Exemplo n.º 12
0
        public unsafe static object RhNewObject(EETypePtr pEEType)
        {
            try
            {
                EEType *ptrEEType = (EEType *)pEEType.ToPointer();
#if FEATURE_64BIT_ALIGNMENT
                if (ptrEEType->RequiresAlign8)
                {
                    if (ptrEEType->IsValueType)
                    {
                        return(InternalCalls.RhpNewFastMisalign(ptrEEType));
                    }
                    if (ptrEEType->IsFinalizable)
                    {
                        return(InternalCalls.RhpNewFinalizableAlign8(ptrEEType));
                    }
                    return(InternalCalls.RhpNewFastAlign8(ptrEEType));
                }
                else
#endif // FEATURE_64BIT_ALIGNMENT
                {
                    if (ptrEEType->IsFinalizable)
                    {
                        return(InternalCalls.RhpNewFinalizable(ptrEEType));
                    }
                    return(InternalCalls.RhpNewFast(ptrEEType));
                }
            }
            catch (OutOfMemoryException)
            {
                // Throw the out of memory exception defined by the classlib, using the input EEType*
                // to find the correct classlib.

                ExceptionIDs exID = ExceptionIDs.OutOfMemory;

                IntPtr    addr = pEEType.ToPointer()->GetAssociatedModuleAddress();
                Exception e    = EH.GetClasslibException(exID, addr);
                throw e;
            }
        }
Exemplo n.º 13
0
        public unsafe static object RhNewArray(EETypePtr pEEType, int length)
        {
            EEType *ptrEEType = (EEType *)pEEType.ToPointer();

            try
            {
#if FEATURE_64BIT_ALIGNMENT
                if (ptrEEType->RequiresAlign8)
                {
                    return(InternalCalls.RhpNewArrayAlign8(ptrEEType, length));
                }
                else
#endif // FEATURE_64BIT_ALIGNMENT
                {
                    return(InternalCalls.RhpNewArray(ptrEEType, length));
                }
            }
            catch (OutOfMemoryException)
            {
                // Throw the out of memory exception defined by the classlib, using the input EEType*
                // to find the correct classlib.

                ExceptionIDs exID = ExceptionIDs.OutOfMemory;

                IntPtr    addr = pEEType.ToPointer()->GetAssociatedModuleAddress();
                Exception e    = EH.GetClasslibException(exID, addr);
                throw e;
            }
            catch (OverflowException)
            {
                // Throw the overflow exception defined by the classlib, using the input EEType*
                // to find the correct classlib.

                ExceptionIDs exID = ExceptionIDs.Overflow;

                IntPtr    addr = pEEType.ToPointer()->GetAssociatedModuleAddress();
                Exception e    = EH.GetClasslibException(exID, addr);
                throw e;
            }
        }
Exemplo n.º 14
0
        static public /*internal*/ unsafe void CheckUnbox(Object obj, byte expectedCorElementType)
        {
            if (obj == null)
            {
                return;
            }

            if (obj.EEType->CorElementType == (CorElementType)expectedCorElementType)
            {
                return;
            }

            // Throw the invalid cast exception defined by the classlib, using the input object's EEType*
            // to find the correct classlib.

            ExceptionIDs exID = ExceptionIDs.InvalidCast;

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

            BinderIntrinsics.TailCall_RhpThrowEx(e);
        }
Exemplo n.º 15
0
        static public /*internal*/ unsafe void CheckArrayStore(object array, object obj)
        {
            if (array == null || obj == null)
            {
                return;
            }

            Debug.Assert(array.EEType->IsArray, "first argument must be an array");

            EEType *arrayElemType = array.EEType->RelatedParameterType;
            bool    compatible;

            if (arrayElemType->IsInterface)
            {
                compatible = IsInstanceOfInterface(obj, arrayElemType) != null;
            }
            else if (arrayElemType->IsArray)
            {
                compatible = IsInstanceOfArray(obj, arrayElemType) != null;
            }
            else
            {
                compatible = IsInstanceOfClass(obj, arrayElemType) != null;
            }

            if (!compatible)
            {
                // Throw the array type mismatch exception defined by the classlib, using the input array's EEType*
                // to find the correct classlib.

                ExceptionIDs exID = ExceptionIDs.ArrayTypeMismatch;

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

                BinderIntrinsics.TailCall_RhpThrowEx(e);
            }
        }
Exemplo n.º 16
0
        static public unsafe void *RhUnbox2(EETypePtr pUnboxToEEType, Object obj)
        {
            EEType *ptrUnboxToEEType = (EEType *)pUnboxToEEType.ToPointer();

            if (obj.EEType != ptrUnboxToEEType)
            {
                // We allow enums and their primtive type to be interchangable
                if (obj.EEType->CorElementType != ptrUnboxToEEType->CorElementType)
                {
                    IntPtr    addr = ptrUnboxToEEType->GetAssociatedModuleAddress();
                    Exception e    = EH.GetClasslibException(ExceptionIDs.InvalidCast, addr);

                    BinderIntrinsics.TailCall_RhpThrowEx(e);
                }
            }

            fixed(void *pObject = &obj.m_pEEType)
            {
                // CORERT-TODO: This code has GC hole - the method return type should really be byref.
                // Requires byref returns in C# to fix cleanly (https://github.com/dotnet/roslyn/issues/118)
                return((IntPtr *)pObject + 1);
            }
        }
Exemplo n.º 17
0
        static public /*internal*/ unsafe void CheckVectorElemAddr(void *pvElemType, object array)
        {
            if (array == null)
            {
                return;
            }

            Debug.Assert(array.EEType->IsArray, "second argument must be an array");

            EEType *elemType      = (EEType *)pvElemType;
            EEType *arrayElemType = array.EEType->RelatedParameterType;

            if (!AreTypesEquivalentInternal(elemType, arrayElemType))
            {
                // Throw the array type mismatch exception defined by the classlib, using the input array's EEType*
                // to find the correct classlib.
                ExceptionIDs exID = ExceptionIDs.ArrayTypeMismatch;

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

                BinderIntrinsics.TailCall_RhpThrowEx(e);
            }
        }