public static unsafe void RhSetNonArrayBaseType(EETypePtr ptrEEType, EETypePtr ptrBaseEEType) { EEType *pEEType = ptrEEType.ToPointer(); EEType *pBaseEEType = ptrBaseEEType.ToPointer(); pEEType->BaseType = pBaseEEType; }
public static unsafe void RhSetInterface(EETypePtr ptrEEType, int index, EETypePtr ptrInterfaceEEType) { EEType *pEEType = ptrEEType.ToPointer(); EEType *pInterfaceEEType = ptrInterfaceEEType.ToPointer(); pEEType->InterfaceMap[index].InterfaceType = pInterfaceEEType; }
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)); } }
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); }
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); }
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); }
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; }
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); }
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); }
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); }
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); }
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()); }
// // 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)); } }
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); } } }
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)); }
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; } }
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; } }
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)); } }
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); } }
public unsafe static object RhAllocLocal(EETypePtr pEEType) { EEType *ptrEEType = (EEType *)pEEType.ToPointer(); if (ptrEEType->IsValueType) { return(RhNewObject(pEEType)); } else { return(new Wrapper()); } }
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); } }
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)); }
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); }
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()); }
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); } }
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)); } }
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); } }
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); } }
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)); } }
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()); } }
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()); } }
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); } }
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); } }
static unsafe public bool AreTypesEquivalent(EETypePtr pType1, EETypePtr pType2) { return (AreTypesEquivalentInternal(pType1.ToPointer(), pType2.ToPointer())); }
public static unsafe ushort RhGetComponentSize(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return pEEType->ComponentSize; }
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; }
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); }
public static unsafe bool RhIsNullable(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return pEEType->IsNullable; }
public static unsafe bool RhHasReferenceFields(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return pEEType->HasReferenceFields; }
public static unsafe bool RhIsArray(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return pEEType->IsArray; }
public static unsafe bool RhHasCctor(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return pEEType->HasCctor; }
public static unsafe void RhSetInterface(EETypePtr ptrEEType, int index, EETypePtr ptrInterfaceEEType) { EEType* pEEType = ptrEEType.ToPointer(); EEType* pInterfaceEEType = ptrInterfaceEEType.ToPointer(); pEEType->InterfaceMap[index].InterfaceType = pInterfaceEEType; }
public static unsafe uint RhGetNumInterfaces(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return (uint)pEEType->NumInterfaces; }
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; }
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); }
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); } }
public static unsafe bool RhIsDynamicType(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return pEEType->IsDynamicType; }
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; }
public static unsafe bool RhIsInterface(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return pEEType->IsInterface; }
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; } }
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; }
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); } }
public static unsafe EETypePtr RhGetNullableType(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return new EETypePtr((IntPtr)pEEType->GetNullableType()); }
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; }
public static unsafe byte RhGetCorElementType(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return (byte)pEEType->CorElementType; }
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(); }
public static unsafe uint RhGetEETypeHash(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return pEEType->HashCode; }
public static unsafe EETypePtr RhGetRelatedParameterType(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return new EETypePtr((IntPtr)pEEType->RelatedParameterType); }
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; }
public static unsafe EETypePtr RhGetNonArrayBaseType(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return new EETypePtr((IntPtr)pEEType->NonArrayBaseType); }