// // Copyright (c) Microsoft Corporation. All rights reserved. // /*******************************************************************/ /* WARNING */ /* This file should be identical in the Bartok and Singularity */ /* depots. Master copy resides in Bartok Depot. Changes should be */ /* made to Bartok Depot and propagated to Singularity Depot. */ /*******************************************************************/ // Provides a number of "magic" casting functions needed by trusted components // of the runtime. namespace Microsoft.Bartok.Runtime { using System; using System.Runtime.CompilerServices; using System.Threading; internal sealed class Magic { // Returns the offset of the vtable from the base of an object. // The base is the beginning of the PostHeader. // Typically callers should access Object's vtable property directly, // but this is used by a few places that may be abusing the vtable slot // to hold values of type UIntPtr. internal static extern UIntPtr OffsetOfVTable { [NoHeapAllocation] [Intrinsic] get; } // Cast an object to a UIntPtr, equivalent to MSIL conv.u. [Intrinsic] [NoHeapAllocation] internal static extern UIntPtr addressOf(Object o); // The toPointer family of methods cast a managed pointer to T to an // unmanaged pointer to T. Exceptions are the Object and VTable // versions which return UIntPtr* instead since Object* and VTable* // are illegal. These are equivalent to MSIL conv.u. [Intrinsic] [NoHeapAllocation] internal static unsafe extern UIntPtr *toPointer(ref Object o); [Intrinsic] [NoHeapAllocation] internal static unsafe extern bool *toPointer(ref bool o); [Intrinsic] [NoHeapAllocation] internal static unsafe extern char *toPointer(ref char o); [Intrinsic] [NoHeapAllocation] internal static unsafe extern float *toPointer(ref float o); [Intrinsic] [NoHeapAllocation] internal static unsafe extern double *toPointer(ref double o); [Intrinsic] [NoHeapAllocation] internal static unsafe extern sbyte *toPointer(ref sbyte o); [Intrinsic] [NoHeapAllocation] internal static unsafe extern short *toPointer(ref short o); [Intrinsic] [NoHeapAllocation] internal static unsafe extern int *toPointer(ref int o); [Intrinsic] [NoHeapAllocation] internal static unsafe extern long *toPointer(ref long o); [Intrinsic] [NoHeapAllocation] internal static unsafe extern IntPtr *toPointer(ref IntPtr o); [Intrinsic] [NoHeapAllocation] internal static unsafe extern byte *toPointer(ref byte o); [Intrinsic] [NoHeapAllocation] internal static unsafe extern ushort *toPointer(ref ushort o); [Intrinsic] [NoHeapAllocation] internal static unsafe extern uint *toPointer(ref uint o); [Intrinsic] [NoHeapAllocation] internal static unsafe extern ulong *toPointer(ref ulong o); [Intrinsic] [NoHeapAllocation] internal static unsafe extern UIntPtr *toPointer(ref UIntPtr o); [Intrinsic] [NoHeapAllocation] internal static unsafe extern UIntPtr *toPointer(ref VTable o); // Cast a UIntPtr to an object. This has no MSIL instruction // equivalent. This is used, for example, at the birth point of an // object. [Intrinsic] [NoHeapAllocation] internal static extern Object fromAddress(UIntPtr v); // The various toXXX methods are unchecked (and therefore unsafe) // downcasts. They are used in places where vtables may be invalid (and // hence checked casts would fail). Uses as hand-optimizations should // be avoided when possible. [Intrinsic] [NoHeapAllocation] internal static extern Thread toThread(Object o); [Intrinsic] [NoHeapAllocation] internal static extern Monitor toMonitor(Object o); [Intrinsic] [NoHeapAllocation] internal static extern EMU toEMU(Object o); [Intrinsic] [NoHeapAllocation] internal static extern VTable toVTable(Object o); [Intrinsic] [NoHeapAllocation] internal static extern Array toArray(Object o); [Intrinsic] [NoHeapAllocation] internal static extern UIntPtr[] toUIntPtrVector(Array a); [Intrinsic] [NoHeapAllocation] internal static extern String toString(Object o); [Intrinsic] [NoHeapAllocation] internal static extern RuntimeType toRuntimeType(Object o); [Intrinsic] [NoHeapAllocation] internal static extern Type toType(Object o); [Intrinsic] [NoHeapAllocation] internal static extern uint[] toUIntArray(Object o); [Intrinsic] internal static extern WeakReference toWeakReference(Object o); // Performs an indirect call on the pointer 'p'. // This is equivalent to MSIL calli on the signature ()->void. [Intrinsic] internal static extern void calli(System.UIntPtr p); // Performs an indirect call on the pointer 'p' with argument 'v'. // This is equivalent to MSIL calli on the signature (UIntPtr)->void. [Intrinsic] internal static extern void calli(System.UIntPtr p, System.UIntPtr v); // Calls the Finalize method on an object. This is needed for the // finalizer implementation because C# will not allow direct calls to // finalizers. [Intrinsic] internal static extern void callFinalizer(Object o); // These are very dangerous utilties that essentially do // // [o + offset] = data // // They are currently used for undoing heap stores collected in the // tryall/atomic logs. Any other use should be cleared by at least the // Bartok team. [Intrinsic] internal static extern void SetAt(Object o, UIntPtr offset, UIntPtr data); [Intrinsic] internal static extern void SetAt(Object o, UIntPtr offset, Object data); } }