static unsafe object to_object(TysosType enum_type, object value) { /* Convert value (of an integral type) to an enum of type 'enum_type' * and return its boxed value */ if (enum_type == null) { throw new ArgumentNullException("enumType"); } if (value == null) { throw new ArgumentException("value"); } /* The incoming value type 'value' is already boxed. * * We can therefore just copy its data to a new enum object */ void *value_obj = CastOperations.ReinterpretAsPointer(value); void *value_vtbl = *(void **)value_obj; int value_csize = *(int *)((byte *)value_vtbl + ClassOperations.GetVtblTypeSizeOffset()); void *ret_obj = MemoryOperations.GcMalloc(value_csize); MemoryOperations.MemCpy(ret_obj, value_obj, value_csize); void *ret_vtbl = *(void **)((byte *)CastOperations.ReinterpretAsPointer(enum_type) + ClassOperations.GetSystemTypeImplOffset()); *(void **)ret_obj = ret_vtbl; *(void **)((byte *)ret_obj + ClassOperations.GetMutexLockOffset()) = null; return(CastOperations.ReinterpretAsObject(ret_obj)); }
static unsafe void Monitor_exit(byte *obj) { var tid = System.Threading.Thread.CurrentThread.ManagedThreadId; var mla = obj + ClassOperations.GetMutexLockOffset(); release(mla, tid); }
static unsafe void ReliableEnter(byte *obj, ref bool success) { var tid = System.Threading.Thread.CurrentThread.ManagedThreadId; var mla = obj + ClassOperations.GetMutexLockOffset(); while (try_acquire(mla, tid) != 1) { ; } success = true; }
static unsafe void *get_value(void *obj) { /* we can copy the entire enum object to an instance * of the underlying type and just change the * vtbl */ byte *enum_vtbl = *(byte **)obj; int enum_size = *(int *)(enum_vtbl + ClassOperations.GetVtblTypeSizeOffset()); void **enum_ti = *(void ***)enum_vtbl; void * ut_vtbl = *(enum_ti + 1); void *new_obj = MemoryOperations.GcMalloc(enum_size); MemoryOperations.MemCpy(new_obj, obj, enum_size); *(void **)new_obj = ut_vtbl; *(void **)((byte *)new_obj + ClassOperations.GetMutexLockOffset()) = null; return(new_obj); }
/* Build an array of a particular type */ public static unsafe T[] CreateSZArray <T>(int nitems, void *data_addr) { TysosType arrtt = (TysosType)typeof(T[]); TysosType elemtt = (TysosType)typeof(T); int elemsize; if (elemtt.IsValueType) { elemsize = elemtt.GetClassSize() - ClassOperations.GetBoxedTypeDataOffset(); } else { elemsize = OtherOperations.GetPointerSize(); } if (data_addr == null) { data_addr = MemoryOperations.GcMalloc(elemsize * nitems); } byte *ret = (byte *)MemoryOperations.GcMalloc(ArrayOperations.GetArrayClassSize() + 8); // extra space for lobounds and length array void *vtbl = *(void **)((byte *)CastOperations.ReinterpretAsPointer(arrtt) + ClassOperations.GetSystemTypeImplOffset()); *(void **)(ret + ClassOperations.GetVtblFieldOffset()) = vtbl; *(ulong *)(ret + ClassOperations.GetMutexLockOffset()) = 0; *(void **)(ret + ArrayOperations.GetElemTypeOffset()) = *(void **)((byte *)CastOperations.ReinterpretAsPointer(elemtt) + ClassOperations.GetSystemTypeImplOffset()); *(int *)(ret + ArrayOperations.GetElemSizeOffset()) = elemsize; *(void **)(ret + ArrayOperations.GetInnerArrayOffset()) = data_addr; *(void **)(ret + ArrayOperations.GetLoboundsOffset()) = ret + ArrayOperations.GetArrayClassSize(); *(void **)(ret + ArrayOperations.GetSizesOffset()) = ret + ArrayOperations.GetArrayClassSize() + 4; *(int *)(ret + ArrayOperations.GetRankOffset()) = 1; *(int *)(ret + ArrayOperations.GetArrayClassSize()) = 0; // lobounds[0] *(int *)(ret + ArrayOperations.GetArrayClassSize() + 4) = nitems; // sizes[0] return((T[])CastOperations.ReinterpretAsObject(ret)); }
static unsafe void *GetValueImpl(void *arr, int pos) { /* Get the element type of the array */ void *et = *(void **)((byte *)arr + ArrayOperations.GetElemTypeOffset()); /* Get a pointer to the source data */ var elem_size = *(int *)((byte *)arr + ArrayOperations.GetElemSizeOffset()); void *ia = *(void **)((byte *)arr + ArrayOperations.GetInnerArrayOffset()); void *sptr = (void *)((byte *)ia + pos * elem_size); /* Is this a value type? In which case we need to return a boxed value */ void *extends = *(void **)((byte *)et + ClassOperations.GetVtblExtendsVtblPtrOffset()); if (extends == OtherOperations.GetStaticObjectAddress("_Zu1L") || extends == OtherOperations.GetStaticObjectAddress("_ZW6System4Enum")) { /* This is a value type. We need to read the size of the element, * create a new object of the appropriate size and copy the data * into it */ byte *ret = (byte *)MemoryOperations.GcMalloc(elem_size + ClassOperations.GetBoxedTypeDataOffset()); *(void **)(ret + ClassOperations.GetVtblFieldOffset()) = et; *(ulong *)(ret + ClassOperations.GetMutexLockOffset()) = 0; /* Avoid calls to memcpy if possible */ switch (elem_size) { case 1: *(byte *)(ret + ClassOperations.GetBoxedTypeDataOffset()) = *(byte *)sptr; return(ret); case 2: *(ushort *)(ret + ClassOperations.GetBoxedTypeDataOffset()) = *(ushort *)sptr; return(ret); case 4: *(uint *)(ret + ClassOperations.GetBoxedTypeDataOffset()) = *(uint *)sptr; return(ret); case 8: if (OtherOperations.GetPointerSize() >= 8) { *(ulong *)(ret + ClassOperations.GetBoxedTypeDataOffset()) = *(ulong *)sptr; return(ret); } else { *(uint *)(ret + ClassOperations.GetBoxedTypeDataOffset()) = *(uint *)sptr; *(uint *)(ret + ClassOperations.GetBoxedTypeDataOffset() + 4) = *(uint *)((byte *)sptr + 4); return(ret); } case 16: if (OtherOperations.GetPointerSize() >= 8) { *(ulong *)(ret + ClassOperations.GetBoxedTypeDataOffset()) = *(ulong *)sptr; *(ulong *)(ret + ClassOperations.GetBoxedTypeDataOffset() + 8) = *(ulong *)((byte *)sptr + 8); return(ret); } else { *(uint *)(ret + ClassOperations.GetBoxedTypeDataOffset()) = *(uint *)sptr; *(uint *)(ret + ClassOperations.GetBoxedTypeDataOffset() + 4) = *(uint *)((byte *)sptr + 4); *(uint *)(ret + ClassOperations.GetBoxedTypeDataOffset() + 8) = *(uint *)((byte *)sptr + 8); *(uint *)(ret + ClassOperations.GetBoxedTypeDataOffset() + 12) = *(uint *)((byte *)sptr + 12); return(ret); } } /* Do data copy via memcpy */ MemoryOperations.MemCpy(ret + ClassOperations.GetBoxedTypeDataOffset(), sptr, elem_size); return(ret); } else { /* Its a reference type, so just return the pointer */ return(*(void **)sptr); } }