Пример #1
0
        static public 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);
        }
Пример #2
0
        public static void RhpReversePInvokeBadTransition()
        {
#if CORERT
            EH.FallbackFailFast(RhFailFastReason.IllegalNativeCallableEntry, null);
#else
            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.FallbackFailFast(RhFailFastReason.InternalError, null);
                throw EH.GetClasslibException(ExceptionIDs.Arithmetic, returnAddress);
            }
#endif
        }
Пример #3
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);
            }
        }
Пример #4
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);
            }
        }
Пример #5
0
        private static IntPtr RhpCidResolve(object pObject, IntPtr pCell)
        {
            try
            {
                EEType *pInterfaceType;
                ushort  slot;
                InternalCalls.RhpGetDispatchCellInfo(pCell, &pInterfaceType, &slot);
                IntPtr pTargetCode = RhResolveDispatchWorker(pObject, pInterfaceType, slot);
                if (pTargetCode != IntPtr.Zero)
                {
                    return(InternalCalls.RhpUpdateDispatchCellCache(pCell, pTargetCode, pObject.EEType));
                }
            }
            catch
            {
                // Exceptions are not permitted to escape from runtime->managed callbacks
                EH.FailFast(RhFailFastReason.InternalError, null);
            }

            // "Valid method implementation was not found."
            EH.FailFast(RhFailFastReason.InternalError, null);
            return(IntPtr.Zero);
        }
Пример #6
0
        internal static unsafe void AddToExistingCache <V>(CastableObjectCacheEntry <V>[] cache, IntPtr key, V value)
        {
            uint hashcode  = unchecked ((uint)key.ToInt64());
            uint cacheMask = (uint)cache.Length - 1;
            uint bucket    = hashcode & cacheMask;
            uint curbucket = bucket;

            // hash algorithm is open addressing with linear probing

            while (curbucket < cache.Length)
            {
                if (cache[curbucket].Key == default(IntPtr))
                {
                    cache[curbucket].Key   = key;
                    cache[curbucket].Value = value;
                    return;
                }
                curbucket++;
            }

            // Handle wrap-around case
            curbucket = 0;
            while (curbucket < bucket)
            {
                if (cache[curbucket].Key == default(IntPtr))
                {
                    cache[curbucket].Key   = key;
                    cache[curbucket].Value = value;
                    return;
                }
                curbucket++;
            }

            EH.FallbackFailFast(RhFailFastReason.InternalError, null);
            return;
        }
Пример #7
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);
            }
        }
Пример #8
0
        private static unsafe IntPtr RhResolveDispatchWorker(object pObject, void *cell, ref DispatchCellInfo cellInfo)
        {
            // Type of object we're dispatching on.
            EEType *pInstanceType = pObject.EEType;

            if (cellInfo.CellType == DispatchCellType.InterfaceAndSlot)
            {
                // Type whose DispatchMap is used. Usually the same as the above but for types which implement ICastable
                // we may repeat this process with an alternate type.
                EEType *pResolvingInstanceType = pInstanceType;

                IntPtr pTargetCode = DispatchResolve.FindInterfaceMethodImplementationTarget(pResolvingInstanceType,
                                                                                             cellInfo.InterfaceType.ToPointer(),
                                                                                             cellInfo.InterfaceSlot);

                if (pTargetCode == IntPtr.Zero && pInstanceType->IsICastable)
                {
                    // TODO!! BEGIN REMOVE THIS CODE WHEN WE REMOVE ICASTABLE
                    // Dispatch not resolved through normal dispatch map, try using the ICastable
                    // Call the ICastable.IsInstanceOfInterface method directly rather than via an interface
                    // dispatch since we know the method address statically. We ignore any cast error exception
                    // object passed back on failure (result == false) since IsInstanceOfInterface never throws.
                    IntPtr    pfnIsInstanceOfInterface = pInstanceType->ICastableIsInstanceOfInterfaceMethod;
                    Exception castError = null;
                    if (CalliIntrinsics.Call <bool>(pfnIsInstanceOfInterface, pObject, cellInfo.InterfaceType.ToPointer(), out castError))
                    {
                        IntPtr pfnGetImplTypeMethod = pInstanceType->ICastableGetImplTypeMethod;
                        pResolvingInstanceType = (EEType *)CalliIntrinsics.Call <IntPtr>(pfnGetImplTypeMethod, pObject, new IntPtr(cellInfo.InterfaceType.ToPointer()));
                        pTargetCode            = DispatchResolve.FindInterfaceMethodImplementationTarget(pResolvingInstanceType,
                                                                                                         cellInfo.InterfaceType.ToPointer(),
                                                                                                         cellInfo.InterfaceSlot);
                    }
                    else
                    // TODO!! END REMOVE THIS CODE WHEN WE REMOVE ICASTABLE
                    {
                        // Dispatch not resolved through normal dispatch map, using the CastableObject path
                        pTargetCode = InternalCalls.RhpGetCastableObjectDispatchHelper();
                    }
                }

                return(pTargetCode);
            }
            else if (cellInfo.CellType == DispatchCellType.VTableOffset)
            {
                // Dereference VTable
                return(*(IntPtr *)(((byte *)pInstanceType) + cellInfo.VTableOffset));
            }
            else
            {
#if SUPPORTS_NATIVE_METADATA_TYPE_LOADING
                // Attempt to convert dispatch cell to non-metadata form if we haven't acquired a cache for this cell yet
                if (cellInfo.HasCache == 0)
                {
                    cellInfo = InternalTypeLoaderCalls.ConvertMetadataTokenDispatch(InternalCalls.RhGetModuleFromPointer(cell), cellInfo);
                    if (cellInfo.CellType != DispatchCellType.MetadataToken)
                    {
                        return(RhResolveDispatchWorker(pObject, cell, ref cellInfo));
                    }
                }

                // If that failed, go down the metadata resolution path
                return(InternalTypeLoaderCalls.ResolveMetadataTokenDispatch(InternalCalls.RhGetModuleFromPointer(cell), (int)cellInfo.MetadataToken, new IntPtr(pInstanceType)));
#else
                EH.FallbackFailFast(RhFailFastReason.InternalError, null);
                return(IntPtr.Zero);
#endif
            }
        }
Пример #9
0
 internal extern static unsafe void RhpCopyContextFromExInfo(void* pOSContext, int cbOSContext, EH.PAL_LIMITED_CONTEXT* pPalContext);
Пример #10
0
 internal extern static unsafe IntPtr RhpCallCatchFunclet(
     object exceptionObj, byte* pHandlerIP, void* pvRegDisplay, ref EH.ExInfo exInfo);
Пример #11
0
 internal unsafe extern static void* RhpGetClasslibFunction(IntPtr address, EH.ClassLibFunctionId id);
Пример #12
0
 public static void DebugBreak()
 {
     EH.FallbackFailFast(RhFailFastReason.InternalError, null);
 }
Пример #13
0
 internal bool Init(EH.PAL_LIMITED_CONTEXT* pStackwalkCtx)
 {
     return InternalCalls.RhpSfiInit(ref this, pStackwalkCtx);
 }