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 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(); #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 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 RuntimeTypeHandle GetRelatedParameterTypeHandle(RuntimeTypeHandle parameterTypeHandle) { EETypePtr elementType = parameterTypeHandle.ToEETypePtr().ArrayElementType; return(new RuntimeTypeHandle(elementType)); }
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 void RhSetInterface(EETypePtr ptrEEType, int index, EETypePtr ptrInterfaceEEType) { EEType* pEEType = ptrEEType.ToPointer(); EEType* pInterfaceEEType = ptrInterfaceEEType.ToPointer(); pEEType->InterfaceMap[index].InterfaceType = pInterfaceEEType; }
public static unsafe EETypePtr RhGetNonArrayBaseType(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return new EETypePtr((IntPtr)pEEType->NonArrayBaseType); }
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); } }
private static unsafe IntPtr GVMLookupForSlotWorker(RuntimeTypeHandle type, RuntimeTypeHandle declaringType, RuntimeTypeHandle[] genericArguments, MethodNameAndSignature methodNameAndSignature) { bool slotChanged = false; IntPtr resolution = IntPtr.Zero; IntPtr functionPointer = IntPtr.Zero; IntPtr genericDictionary = IntPtr.Zero; bool lookForDefaultImplementations = false; again: // Walk parent hierarchy attempting to resolve EETypePtr eeType = type.ToEETypePtr(); while (!eeType.IsNull) { RuntimeTypeHandle handle = new RuntimeTypeHandle(eeType); string methodName = methodNameAndSignature.Name; RuntimeSignature methodSignature = methodNameAndSignature.Signature; if (RuntimeAugments.TypeLoaderCallbacks.TryGetGenericVirtualTargetForTypeAndSlot(handle, ref declaringType, genericArguments, ref methodName, ref methodSignature, lookForDefaultImplementations, out functionPointer, out genericDictionary, out slotChanged)) { methodNameAndSignature = new MethodNameAndSignature(methodName, methodSignature); if (!slotChanged) { resolution = FunctionPointerOps.GetGenericMethodFunctionPointer(functionPointer, genericDictionary); } break; } eeType = eeType.BaseType; } // If the current slot to examine has changed, restart the lookup. // This happens when there is an interface call. if (slotChanged) { return(GVMLookupForSlotWorker(type, declaringType, genericArguments, methodNameAndSignature)); } if (resolution == IntPtr.Zero && !lookForDefaultImplementations && declaringType.ToEETypePtr().IsInterface) { lookForDefaultImplementations = true; goto again; } if (resolution == IntPtr.Zero) { var sb = new System.Text.StringBuilder(); sb.AppendLine("Generic virtual method pointer lookup failure."); sb.AppendLine(); sb.AppendLine("Declaring type: " + declaringType.LastResortToString); sb.AppendLine("Target type: " + type.LastResortToString); sb.AppendLine("Method name: " + methodNameAndSignature.Name); sb.AppendLine("Instantiation:"); for (int i = 0; i < genericArguments.Length; i++) { sb.AppendLine(" Argument " + i.LowLevelToString() + ": " + genericArguments[i].LastResortToString); } Environment.FailFast(sb.ToString()); } return(resolution); }
internal RuntimeEEArrayType(EETypePtr eeType, int rank) : base(true, rank) { _runtimeTypeHandle = new RuntimeTypeHandle(eeType); }
internal RuntimeEEArrayType(EETypePtr eeType) : base(false, 1) { _runtimeTypeHandle = new RuntimeTypeHandle(eeType); }
public static RuntimeTypeHandle GetNullableType(RuntimeTypeHandle nullableType) { EETypePtr theT = nullableType.ToEETypePtr().NullableType; return(new RuntimeTypeHandle(theT)); }
public static bool IsAssignable(Object srcObject, RuntimeTypeHandle dstType) { EETypePtr srcEEType = srcObject.EETypePtr; return(RuntimeImports.AreTypesAssignable(srcEEType, dstType.ToEETypePtr())); }
public static RuntimeTypeHandle RuntimeTypeHandleOf <T>() { return(new RuntimeTypeHandle(EETypePtr.EETypePtrOf <T>())); }
public static RuntimeTypeHandle GetInterface(RuntimeTypeHandle typeHandle, int index) { EETypePtr eeInterface = typeHandle.ToEETypePtr().Interfaces[index]; return(CreateRuntimeTypeHandle(eeInterface)); }
public static int GetGCDescSize(RuntimeTypeHandle typeHandle) { EETypePtr eeType = CreateEETypePtr(typeHandle); return(RuntimeImports.RhGetGCDescSize(eeType)); }
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 EETypePtr RhGetRelatedParameterType(EETypePtr ptrEEType) { EEType *pEEType = ptrEEType.ToPointer(); return(new EETypePtr((IntPtr)pEEType->RelatedParameterType)); }
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 EETypePtr RhGetNonArrayBaseType(EETypePtr ptrEEType) { EEType *pEEType = ptrEEType.ToPointer(); return(new EETypePtr((IntPtr)pEEType->NonArrayBaseType)); }
public static unsafe uint RhGetNumInterfaces(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return (uint)pEEType->NumInterfaces; }
public static unsafe ushort RhGetComponentSize(EETypePtr ptrEEType) { EEType *pEEType = ptrEEType.ToPointer(); return(pEEType->ComponentSize); }
public static unsafe bool RhHasCctor(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return pEEType->HasCctor; }
public static unsafe uint RhGetNumInterfaces(EETypePtr ptrEEType) { EEType *pEEType = ptrEEType.ToPointer(); return((uint)pEEType->NumInterfaces); }
public static unsafe bool RhIsNullable(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return pEEType->IsNullable; }
public static unsafe bool RhIsDynamicType(EETypePtr ptrEEType) { EEType *pEEType = ptrEEType.ToPointer(); return(pEEType->IsDynamicType); }
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 bool RhHasCctor(EETypePtr ptrEEType) { EEType *pEEType = ptrEEType.ToPointer(); return(pEEType->HasCctor); }
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); } }
static unsafe public bool AreTypesEquivalent(EETypePtr pType1, EETypePtr pType2) { return (AreTypesEquivalentInternal(pType1.ToPointer(), pType2.ToPointer())); }
public static unsafe bool RhIsArray(EETypePtr ptrEEType) { EEType *pEEType = ptrEEType.ToPointer(); return(pEEType->IsArray); }
private static RuntimeTypeHandle CreateRuntimeTypeHandle(EETypePtr eeType) { return(new RuntimeTypeHandle(eeType)); }
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 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 RhGetNullableType(EETypePtr ptrEEType) { EEType *pEEType = ptrEEType.ToPointer(); return(new EETypePtr((IntPtr)pEEType->GetNullableType())); }
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 RhHasReferenceFields(EETypePtr ptrEEType) { EEType *pEEType = ptrEEType.ToPointer(); return(pEEType->HasReferenceFields); }
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 static unsafe EETypePtr RhGetRelatedParameterType(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return new EETypePtr((IntPtr)pEEType->RelatedParameterType); }
public static unsafe uint RhGetEETypeHash(EETypePtr ptrEEType) { EEType *pEEType = ptrEEType.ToPointer(); return(pEEType->HashCode); }
public static unsafe ushort RhGetComponentSize(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return pEEType->ComponentSize; }
public static bool IsGenericTypeDefinition(this RuntimeTypeHandle handle) { EETypePtr eeType = handle.ToEETypePtr(); return(eeType.IsGenericTypeDefinition); }
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); }
internal static extern object RhNewObject(EETypePtr pEEType);
public static unsafe bool RhIsDynamicType(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return pEEType->IsDynamicType; }
internal static extern Array RhNewArray(EETypePtr pEEType, int length);
public static unsafe bool RhIsInterface(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return pEEType->IsInterface; }
internal static extern String RhNewArrayAsString(EETypePtr pEEType, int length);
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; }
object ICastableObject.CastToInterface(EETypePtr interfaceType, bool produceCastErrorException, out Exception castError) { return(CastToInterface(new RuntimeTypeHandle(interfaceType), produceCastErrorException, out castError)); }
public static unsafe EETypePtr RhGetNullableType(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return new EETypePtr((IntPtr)pEEType->GetNullableType()); }
private static unsafe Action GetCompletionActionHelper( ref Action cachedMoveNextAction, ref byte stateMachineAddress, EETypePtr stateMachineType, Task taskIfDebuggingEnabled) { // Alert a listening debugger that we can't make forward progress unless it slips threads. // If we don't do this, and a method that uses "await foo;" is invoked through funceval, // we could end up hooking up a callback to push forward the async method's state machine, // the debugger would then abort the funceval after it takes too long, and then continuing // execution could result in another callback being hooked up. At that point we have // multiple callbacks registered to push the state machine, which could result in bad behavior. //Debugger.NotifyOfCrossThreadDependency(); MoveNextRunner runner; if (cachedMoveNextAction != null) { Debug.Assert(cachedMoveNextAction.Target is MoveNextRunner); runner = (MoveNextRunner)cachedMoveNextAction.Target; runner.m_executionContext = ExecutionContext.Capture(); return(cachedMoveNextAction); } runner = new MoveNextRunner(); runner.m_executionContext = ExecutionContext.Capture(); cachedMoveNextAction = runner.CallMoveNext; if (taskIfDebuggingEnabled != null) { runner.m_task = taskIfDebuggingEnabled; if (DebuggerSupport.LoggingOn) { IntPtr eeType = stateMachineType.RawValue; DebuggerSupport.TraceOperationCreation(CausalityTraceLevel.Required, taskIfDebuggingEnabled, "Async: " + eeType.ToString("x"), 0); } DebuggerSupport.AddToActiveTasks(taskIfDebuggingEnabled); } // // If the state machine is a value type, we need to box it now. // IAsyncStateMachine boxedStateMachine; if (stateMachineType.IsValueType) { object boxed = RuntimeImports.RhBox(stateMachineType, ref stateMachineAddress); Debug.Assert(boxed is IAsyncStateMachine); boxedStateMachine = Unsafe.As <IAsyncStateMachine>(boxed); } else { boxedStateMachine = Unsafe.As <byte, IAsyncStateMachine>(ref stateMachineAddress); } runner.m_stateMachine = boxedStateMachine; #if DEBUG // // In debug builds, we'll go ahead and call SetStateMachine, even though all of our initialization is done. // This way we'll keep forcing state machine implementations to keep the behavior needed by the CLR. // boxedStateMachine.SetStateMachine(boxedStateMachine); #endif // All done! return(cachedMoveNextAction); }
public static unsafe byte RhGetCorElementType(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return (byte)pEEType->CorElementType; }
public static RuntimeTypeHandle GetRelatedParameterTypeHandle(RuntimeTypeHandle parameterTypeHandle) { EETypePtr elementType = RuntimeImports.RhGetRelatedParameterType(parameterTypeHandle.ToEETypePtr()); return(new RuntimeTypeHandle(elementType)); }
public static unsafe uint RhGetEETypeHash(EETypePtr ptrEEType) { EEType* pEEType = ptrEEType.ToPointer(); return pEEType->HashCode; }
string // String RhNewArrayAsString(EETypePtr pEEType, int length);