예제 #1
0
        public static unsafe void RhSetNonArrayBaseType(EETypePtr ptrEEType, EETypePtr ptrBaseEEType)
        {
            EEType *pEEType     = ptrEEType.ToPointer();
            EEType *pBaseEEType = ptrBaseEEType.ToPointer();

            pEEType->BaseType = pBaseEEType;
        }
예제 #2
0
        public static unsafe void RhSetInterface(EETypePtr ptrEEType, int index, EETypePtr ptrInterfaceEEType)
        {
            EEType *pEEType          = ptrEEType.ToPointer();
            EEType *pInterfaceEEType = ptrInterfaceEEType.ToPointer();

            pEEType->InterfaceMap[index].InterfaceType = pInterfaceEEType;
        }
예제 #3
0
        public unsafe static object RhNewObject(EETypePtr pEEType)
        {
            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));
            }
        }
예제 #4
0
        public static unsafe bool RhIsString(EETypePtr ptrEEType)
        {
            EEType *pEEType = ptrEEType.ToPointer();

            // String is currently the only non-array type with a non-zero component size.
            return((pEEType->ComponentSize == sizeof(char)) && !pEEType->IsArray);
        }
예제 #5
0
        public static unsafe RhEETypeClassification RhGetEETypeClassification(EETypePtr ptrEEType)
        {
            EEType *pEEType = ptrEEType.ToPointer();

            if (pEEType->IsArray)
            {
                return(RhEETypeClassification.Array);
            }

            if (pEEType->IsGeneric)
            {
                return(RhEETypeClassification.Generic);
            }

            if (pEEType->IsGenericTypeDefinition)
            {
                return(RhEETypeClassification.GenericTypeDefinition);
            }

            if (pEEType->IsPointerTypeDefinition)
            {
                return(RhEETypeClassification.UnmanagedPointer);
            }

            return(RhEETypeClassification.Regular);
        }
예제 #6
0
        public static unsafe object RhBox(EETypePtr pEEType, ref byte data)
        {
            EEType *ptrEEType  = (EEType *)pEEType.ToPointer();
            int     dataOffset = 0;
            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 (data == 0)
                {
                    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.
                dataOffset = ptrEEType->NullableValueOffset;
                ptrEEType  = ptrEEType->NullableType;
            }

#if FEATURE_64BIT_ALIGNMENT
            if (ptrEEType->RequiresAlign8)
            {
                result = InternalCalls.RhpNewFastMisalign(ptrEEType);
            }
            else
#endif // FEATURE_64BIT_ALIGNMENT
            {
                result = InternalCalls.RhpNewFast(ptrEEType);
            }
            InternalCalls.RhpBox(result, ref Unsafe.Add(ref data, dataOffset));
            return(result);
        }
예제 #7
0
        public unsafe static object RhBox(EETypePtr pEEType, ref byte data)
        {
            EEType* ptrEEType = (EEType*)pEEType.ToPointer();
            int dataOffset = 0;
            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 (data == 0)
                    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.
                dataOffset = ptrEEType->NullableValueOffset;
                ptrEEType = ptrEEType->NullableType;
            }

#if FEATURE_64BIT_ALIGNMENT
            if (ptrEEType->RequiresAlign8)
            {
                result = InternalCalls.RhpNewFastMisalign(ptrEEType);
            }
            else
#endif // FEATURE_64BIT_ALIGNMENT
            {
                result = InternalCalls.RhpNewFast(ptrEEType);
            }
            InternalCalls.RhpBox(result, ref Unsafe.Add(ref data, dataOffset));
            return result;
        }
예제 #8
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);
        }
예제 #9
0
        public static void FailedAllocation(EETypePtr pEEType, bool fIsOverflow)
        {
            ExceptionIDs exID = fIsOverflow ? ExceptionIDs.Overflow : ExceptionIDs.OutOfMemory;

            // Throw the out of memory exception defined by the classlib, using the input MethodTable*
            // to find the correct classlib.

            throw pEEType.ToPointer()->GetClasslibException(exID);
        }
예제 #10
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);
        }
예제 #11
0
        public static void FailedAllocation(EETypePtr pEEType, bool fIsOverflow)
        {
            ExceptionIDs exID = fIsOverflow ? ExceptionIDs.Overflow : ExceptionIDs.OutOfMemory;

            // Throw the out of memory exception defined by the classlib, using the input EEType*
            // to find the correct classlib.

            Exception e = pEEType.ToPointer()->GetClasslibException(exID);

            BinderIntrinsics.TailCall_RhpThrowEx(e);
        }
예제 #12
0
        public static unsafe ref byte RhUnbox2(EETypePtr pUnboxToEEType, Object obj)
        {
            EEType *ptrUnboxToEEType = (EEType *)pUnboxToEEType.ToPointer();

            if ((obj == null) || !UnboxAnyTypeCompare(obj.EEType, ptrUnboxToEEType))
            {
                ExceptionIDs exID = obj == null ? ExceptionIDs.NullReference : ExceptionIDs.InvalidCast;
                throw ptrUnboxToEEType->GetClasslibException(exID);
            }
            return(ref obj.GetRawData());
        }
예제 #13
0
        //
        // Helper to create an array from a newobj instruction
        //
        public static unsafe Array NewObjArray(RuntimeTypeHandle typeHandleForArrayType, int[] arguments)
        {
            EETypePtr eeTypePtr = typeHandleForArrayType.ToEETypePtr();

            Debug.Assert(eeTypePtr.IsArray);

            fixed(int *pArguments = arguments)
            {
                return(ArrayHelpers.NewObjArray((IntPtr)eeTypePtr.ToPointer(), arguments.Length, pArguments));
            }
        }
예제 #14
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);
                }
            }
        }
예제 #15
0
        private static IntPtr RhResolveDispatchOnType(EETypePtr instanceType, EETypePtr interfaceType, ushort slot)
        {
            // Type of object we're dispatching on.
            EEType *pInstanceType = instanceType.ToPointer();

            // Type of interface
            EEType *pInterfaceType = interfaceType.ToPointer();

            return(DispatchResolve.FindInterfaceMethodImplementationTarget(pInstanceType,
                                                                           pInterfaceType,
                                                                           slot));
        }
예제 #16
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;
            }
        }
예제 #17
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;
            }
        }
예제 #18
0
        public static unsafe object RhBoxAny(ref byte data, EETypePtr pEEType)
        {
            EEType *ptrEEType = (EEType *)pEEType.ToPointer();

            if (ptrEEType->IsValueType)
            {
                return(RhBox(pEEType, ref data));
            }
            else
            {
                return(Unsafe.As <byte, Object>(ref data));
            }
        }
예제 #19
0
        static public unsafe bool RhBoxAndNullCheck(ref Hack_o_p data, EETypePtr pEEType)
        {
            EEType *ptrEEType = (EEType *)pEEType.ToPointer();

            if (ptrEEType->IsValueType)
            {
                return(true);
            }
            else
            {
                return(data.o != null);
            }
        }
예제 #20
0
        public unsafe static object RhAllocLocal(EETypePtr pEEType)
        {
            EEType *ptrEEType = (EEType *)pEEType.ToPointer();

            if (ptrEEType->IsValueType)
            {
                return(RhNewObject(pEEType));
            }
            else
            {
                return(new Wrapper());
            }
        }
예제 #21
0
        public static unsafe bool RhBoxAndNullCheck(ref byte data, EETypePtr pEEType)
        {
            EEType *ptrEEType = (EEType *)pEEType.ToPointer();

            if (ptrEEType->IsValueType)
            {
                return(true);
            }
            else
            {
                return(Unsafe.As <byte, Object>(ref data) != null);
            }
        }
예제 #22
0
        public static unsafe EETypePtr RhGetInterface(EETypePtr ptrEEType, uint index)
        {
            EEType *pEEType = ptrEEType.ToPointer();

            // The convoluted pointer arithmetic into the interface map below (rather than a simply array
            // dereference) is because C# will generate a 64-bit multiply for the lookup by default. This
            // causes us a problem on x86 because it uses a helper that's mapped directly into the CRT via
            // import magic and that technique doesn't work with the way we link this code into the runtime
            // image. Since we don't need a 64-bit multiply here (the classlib is trusted code) we manually
            // perform the calculation.
            EEInterfaceInfo *pInfo = (EEInterfaceInfo *)((byte *)pEEType->InterfaceMap + (index * (uint)sizeof(EEInterfaceInfo)));

            return(new EETypePtr((IntPtr)pInfo->InterfaceType));
        }
예제 #23
0
        public static void FailedAllocation(EETypePtr pEEType, bool fIsOverflow)
        {
            // Throw the out of memory or overflow exception defined by the classlib, using the return address from this helper
            // to find the correct classlib.

            ExceptionIDs exID = fIsOverflow ? ExceptionIDs.Overflow : ExceptionIDs.OutOfMemory;

            // Throw the out of memory exception defined by the classlib, using the input EEType*
            // to find the correct classlib.
            IntPtr    addr = pEEType.ToPointer()->GetAssociatedModuleAddress();
            Exception e    = GetClasslibException(exID, addr);

            BinderIntrinsics.TailCall_RhpThrowEx(e);
        }
예제 #24
0
        static public unsafe ref byte 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)
                {
                    throw ptrUnboxToEEType->GetClasslibException(ExceptionIDs.InvalidCast);
                }
            }
            return(ref obj.GetRawData());
        }
예제 #25
0
        public unsafe static object RhNewArray(EETypePtr pEEType, int length)
        {
            EEType* ptrEEType = (EEType*)pEEType.ToPointer();
#if FEATURE_64BIT_ALIGNMENT
            if (ptrEEType->RequiresAlign8)
            {
                return InternalCalls.RhpNewArrayAlign8(ptrEEType, length);
            }
            else
#endif // FEATURE_64BIT_ALIGNMENT
            {
                return InternalCalls.RhpNewArray(ptrEEType, length);
            }
        }
예제 #26
0
        public unsafe static object RhNewArray(EETypePtr pEEType, int length)
        {
            EEType *ptrEEType = (EEType *)pEEType.ToPointer();

#if FEATURE_64BIT_ALIGNMENT
            if (ptrEEType->RequiresAlign8)
            {
                return(InternalCalls.RhpNewArrayAlign8(ptrEEType, length));
            }
            else
#endif // FEATURE_64BIT_ALIGNMENT
            {
                return(InternalCalls.RhpNewArray(ptrEEType, length));
            }
        }
예제 #27
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->NullableType))
                {
                    throw ptrUnboxToEEType->GetClasslibException(ExceptionIDs.InvalidCast);
                }
                InternalCalls.RhUnbox(obj, pData - 1, ptrUnboxToEEType);
            }
        }
예제 #28
0
        public unsafe static object RhBoxAny(ref Hack_o_p data, EETypePtr pEEType)
        {
            EEType *ptrEEType = (EEType *)pEEType.ToPointer();

            if (ptrEEType->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)
                return(RhBox(pEEType, pData - 1));
            }
            else
            {
                return(data.o);
            }
        }
예제 #29
0
        public static unsafe object RhNewObject(EETypePtr pEEType)
        {
            EEType *ptrEEType = (EEType *)pEEType.ToPointer();

            // This is structured in a funny way because at the present state of things in CoreRT, the Debug.Assert
            // below will call into the assert defined in the class library (and not the MRT version of it). The one
            // in the class library is not low level enough to be callable when GC statics are not initialized yet.
            // Feel free to restructure once that's not a problem.
#if DEBUG
            bool isValid = !ptrEEType->IsGenericTypeDefinition &&
                           !ptrEEType->IsInterface &&
                           !ptrEEType->IsArray &&
                           !ptrEEType->IsString &&
                           !ptrEEType->IsByRefLike;
            if (!isValid)
            {
                Debug.Assert(false);
            }
#endif

#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));
            }
        }
예제 #30
0
        public unsafe static object RhAllocLocal(EETypePtr pEEType)
        {
            EEType *ptrEEType = (EEType *)pEEType.ToPointer();

            if (ptrEEType->IsValueType)
            {
#if FEATURE_64BIT_ALIGNMENT
                if (ptrEEType->RequiresAlign8)
                {
                    return(InternalCalls.RhpNewFastMisalign(ptrEEType));
                }
#endif
                return(InternalCalls.RhpNewFast(ptrEEType));
            }
            else
            {
                return(new Wrapper());
            }
        }
예제 #31
0
        public static unsafe ref byte RhAllocLocal2(EETypePtr pEEType)
        {
            EEType *ptrEEType = (EEType *)pEEType.ToPointer();

            if (ptrEEType->IsValueType)
            {
#if FEATURE_64BIT_ALIGNMENT
                if (ptrEEType->RequiresAlign8)
                {
                    return(ref InternalCalls.RhpNewFastMisalign(ptrEEType).GetRawData());
                }
#endif
                return(ref InternalCalls.RhpNewFast(ptrEEType).GetRawData());
            }
            else
            {
                return(ref new Wrapper().GetRawData());
            }
        }
예제 #32
0
        public unsafe static object RhNewObject(EETypePtr pEEType)
        {
            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);
            }
        }
예제 #33
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)
                {
                    throw ptrUnboxToEEType->GetClasslibException(ExceptionIDs.InvalidCast);
                }
            }

            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);
            }
        }
예제 #34
0
 static unsafe public bool AreTypesEquivalent(EETypePtr pType1, EETypePtr pType2)
 {
     return (AreTypesEquivalentInternal(pType1.ToPointer(), pType2.ToPointer()));
 }
예제 #35
0
 public static unsafe ushort RhGetComponentSize(EETypePtr ptrEEType)
 {
     EEType* pEEType = ptrEEType.ToPointer();
     return pEEType->ComponentSize;
 }
예제 #36
0
        public static unsafe RhEETypeClassification RhGetEETypeClassification(EETypePtr ptrEEType)
        {
            EEType* pEEType = ptrEEType.ToPointer();

            if (pEEType->IsArray)
                return RhEETypeClassification.Array;

            if (pEEType->IsGeneric)
                return RhEETypeClassification.Generic;

            if (pEEType->IsGenericTypeDefinition)
                return RhEETypeClassification.GenericTypeDefinition;

            if (pEEType->IsPointerTypeDefinition)
                return RhEETypeClassification.UnmanagedPointer;

            return RhEETypeClassification.Regular;
        }
예제 #37
0
        public static void FailedAllocation(EETypePtr pEEType, bool fIsOverflow)
        {
            ExceptionIDs exID = fIsOverflow ? ExceptionIDs.Overflow : ExceptionIDs.OutOfMemory;

            // Throw the out of memory exception defined by the classlib, using the input EEType* 
            // to find the correct classlib.

            throw pEEType.ToPointer()->GetClasslibException(exID);
        }
예제 #38
0
 public static unsafe bool RhIsNullable(EETypePtr ptrEEType)
 {
     EEType* pEEType = ptrEEType.ToPointer();
     return pEEType->IsNullable;
 }
예제 #39
0
 public static unsafe bool RhHasReferenceFields(EETypePtr ptrEEType)
 {
     EEType* pEEType = ptrEEType.ToPointer();
     return pEEType->HasReferenceFields;
 }
예제 #40
0
 public static unsafe bool RhIsArray(EETypePtr ptrEEType)
 {
     EEType* pEEType = ptrEEType.ToPointer();
     return pEEType->IsArray;
 }
예제 #41
0
 public static unsafe bool RhHasCctor(EETypePtr ptrEEType)
 {
     EEType* pEEType = ptrEEType.ToPointer();
     return pEEType->HasCctor;
 }
예제 #42
0
 public static unsafe void RhSetInterface(EETypePtr ptrEEType, int index, EETypePtr ptrInterfaceEEType)
 {
     EEType* pEEType = ptrEEType.ToPointer();
     EEType* pInterfaceEEType = ptrInterfaceEEType.ToPointer();
     pEEType->InterfaceMap[index].InterfaceType = pInterfaceEEType;
 }
예제 #43
0
 public static unsafe uint RhGetNumInterfaces(EETypePtr ptrEEType)
 {
     EEType* pEEType = ptrEEType.ToPointer();
     return (uint)pEEType->NumInterfaces;
 }
예제 #44
0
 static public unsafe bool RhBoxAndNullCheck(ref byte data, EETypePtr pEEType)
 {
     EEType* ptrEEType = (EEType*)pEEType.ToPointer();
     if (ptrEEType->IsValueType)
         return true;
     else
         return Unsafe.As<byte, Object>(ref data) != null;
 }
예제 #45
0
        public static unsafe EETypePtr RhGetInterface(EETypePtr ptrEEType, uint index)
        {
            EEType* pEEType = ptrEEType.ToPointer();

            // The convoluted pointer arithmetic into the interface map below (rather than a simply array
            // dereference) is because C# will generate a 64-bit multiply for the lookup by default. This
            // causes us a problem on x86 because it uses a helper that's mapped directly into the CRT via
            // import magic and that technique doesn't work with the way we link this code into the runtime
            // image. Since we don't need a 64-bit multiply here (the classlib is trusted code) we manually
            // perform the calculation.
            EEInterfaceInfo* pInfo = (EEInterfaceInfo*)((byte*)pEEType->InterfaceMap + (index * (uint)sizeof(EEInterfaceInfo)));

            return new EETypePtr((IntPtr)pInfo->InterfaceType);
        }
예제 #46
0
 public unsafe static object RhBoxAny(ref byte data, EETypePtr pEEType)
 {
     EEType* ptrEEType = (EEType*)pEEType.ToPointer();
     if (ptrEEType->IsValueType)
     {
         return RhBox(pEEType, ref data);
     }
     else
     {
         return Unsafe.As<byte, Object>(ref data);
     }
 }
예제 #47
0
 public static unsafe bool RhIsDynamicType(EETypePtr ptrEEType)
 {
     EEType* pEEType = ptrEEType.ToPointer();
     return pEEType->IsDynamicType;
 }
예제 #48
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) || (o.EEType == ptrUnboxToEEType->GetNullableType());
                    else
                        isValid = (o != null && o.EEType->CorElementType == ptrUnboxToEEType->CorElementType && TypeCast.IsInstanceOfClass(o, ptrUnboxToEEType) != null);

                    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
                data.o = o;
        }
예제 #49
0
 public static unsafe bool RhIsInterface(EETypePtr ptrEEType)
 {
     EEType* pEEType = ptrEEType.ToPointer();
     return pEEType->IsInterface;
 }
예제 #50
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;
            }
        }
예제 #51
0
 public static unsafe bool RhIsString(EETypePtr ptrEEType)
 {
     EEType* pEEType = ptrEEType.ToPointer();
     // String is currently the only non-array type with a non-zero component size.
     return (pEEType->ComponentSize == sizeof(char)) && !pEEType->IsArray;
 }
예제 #52
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);
            }
        }
예제 #53
0
 public static unsafe EETypePtr RhGetNullableType(EETypePtr ptrEEType)
 {
     EEType* pEEType = ptrEEType.ToPointer();
     return new EETypePtr((IntPtr)pEEType->GetNullableType());
 }
예제 #54
0
 static public unsafe bool RhBoxAndNullCheck(ref Hack_o_p data, EETypePtr pEEType)
 {
     EEType* ptrEEType = (EEType*)pEEType.ToPointer();
     if (ptrEEType->IsValueType)
         return true;
     else
         return data.o != null;
 }
예제 #55
0
 public static unsafe byte RhGetCorElementType(EETypePtr ptrEEType)
 {
     EEType* pEEType = ptrEEType.ToPointer();
     return (byte)pEEType->CorElementType;
 }
예제 #56
0
        public unsafe static object RhAllocLocal(EETypePtr pEEType)
        {
            EEType* ptrEEType = (EEType*)pEEType.ToPointer();
            if (ptrEEType->IsValueType)
            {
#if FEATURE_64BIT_ALIGNMENT
                if (ptrEEType->RequiresAlign8)
                    return InternalCalls.RhpNewFastMisalign(ptrEEType);
#endif
                return InternalCalls.RhpNewFast(ptrEEType);
            }
            else
                return new Wrapper();
        }
예제 #57
0
 public static unsafe uint RhGetEETypeHash(EETypePtr ptrEEType)
 {
     EEType* pEEType = ptrEEType.ToPointer();
     return pEEType->HashCode;
 }
예제 #58
0
 public static unsafe EETypePtr RhGetRelatedParameterType(EETypePtr ptrEEType)
 {
     EEType* pEEType = ptrEEType.ToPointer();
     return new EETypePtr((IntPtr)pEEType->RelatedParameterType);
 }
예제 #59
0
 public unsafe static object RhBoxAny(ref Hack_o_p data, EETypePtr pEEType)
 {
     EEType* ptrEEType = (EEType*)pEEType.ToPointer();
     if (ptrEEType->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)
             return RhBox(pEEType, pData - 1);
     }
     else
         return data.o;
 }
예제 #60
0
 public static unsafe EETypePtr RhGetNonArrayBaseType(EETypePtr ptrEEType)
 {
     EEType* pEEType = ptrEEType.ToPointer();
     return new EETypePtr((IntPtr)pEEType->NonArrayBaseType);
 }