Exemple #1
0
        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));
        }
Exemple #2
0
        static unsafe void Monitor_exit(byte *obj)
        {
            var tid = System.Threading.Thread.CurrentThread.ManagedThreadId;
            var mla = obj + ClassOperations.GetMutexLockOffset();

            release(mla, tid);
        }
Exemple #3
0
        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;
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        /* 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));
        }
Exemple #6
0
        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);
            }
        }