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); }
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 }
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); } }
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); } }
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); }
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; }
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); } }
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 } }
internal extern static unsafe void RhpCopyContextFromExInfo(void* pOSContext, int cbOSContext, EH.PAL_LIMITED_CONTEXT* pPalContext);
internal extern static unsafe IntPtr RhpCallCatchFunclet( object exceptionObj, byte* pHandlerIP, void* pvRegDisplay, ref EH.ExInfo exInfo);
internal unsafe extern static void* RhpGetClasslibFunction(IntPtr address, EH.ClassLibFunctionId id);
public static void DebugBreak() { EH.FallbackFailFast(RhFailFastReason.InternalError, null); }
internal bool Init(EH.PAL_LIMITED_CONTEXT* pStackwalkCtx) { return InternalCalls.RhpSfiInit(ref this, pStackwalkCtx); }