Exemple #1
0
        static unsafe bool Equals(void *a, void *b)
        {
            /* a is guaranteed to be a System.Enum, therefore just ensuring b
             * is the same type ensures b is an enum */
            void *avtbl = *(void **)a;
            void *bvtbl = *(void **)b;

            if (avtbl != bvtbl)
            {
                return(false);
            }

            /* Get size of data to compare */
            var  tsize = *(int *)((byte *)avtbl + ClassOperations.GetVtblTypeSizeOffset()) - ClassOperations.GetBoxedTypeDataOffset();
            int *adata = (int *)((byte *)a + ClassOperations.GetBoxedTypeDataOffset());
            int *bdata = (int *)((byte *)b + ClassOperations.GetBoxedTypeDataOffset());

            /* Use lowest common denominator of int32s for comparison (most enums are int32s) */
            for (int i = 0; i < tsize; i += 4, adata++, bdata++)
            {
                if (*adata != *bdata)
                {
                    return(false);
                }
            }
            return(true);
        }
Exemple #2
0
        static unsafe void InternalSetValue(void *typedref, void *objval)
        {
            // get the type from the typed reference to see if we need to unbox the object
            //  or store as a reference type

            void *et  = *(void **)((byte *)typedref + ClassOperations.GetTypedReferenceTypeOffset());
            void *ptr = *(void **)((byte *)typedref + ClassOperations.GetTypedReferenceValueOffset());

            void *etextends = *(void **)((byte *)et + ClassOperations.GetVtblExtendsVtblPtrOffset());

            if (etextends == OtherOperations.GetStaticObjectAddress("_Zu1L") ||
                etextends == OtherOperations.GetStaticObjectAddress("_ZW6System4Enum"))
            {
                // this is a boxed value type.  Get its size
                var vt_size = TysosType.GetValueTypeSize(et);

                // src ptr
                void *src = *(void **)((byte *)objval + ClassOperations.GetBoxedTypeDataOffset());

                CopyMem((byte *)ptr, (byte *)src, vt_size);
            }
            else
            {
                // simply copy the reference
                *(void **)ptr = objval;
            }
        }
Exemple #3
0
        static unsafe void *InternalToObject(void *typedref)
        {
            // get the type from the typed reference to see if we need to box the object
            //  or simply return the address as a reference type

            void *et  = *(void **)((byte *)typedref + ClassOperations.GetTypedReferenceTypeOffset());
            void *src = *(void **)((byte *)typedref + ClassOperations.GetTypedReferenceValueOffset());

            void *etextends = *(void **)((byte *)et + ClassOperations.GetVtblExtendsVtblPtrOffset());

            if (etextends == OtherOperations.GetStaticObjectAddress("_Zu1L") ||
                etextends == OtherOperations.GetStaticObjectAddress("_ZW6System4Enum"))
            {
                // this is a boxed value type.  Get its size
                var vt_size = TysosType.GetValueTypeSize(et);

                // build a new boxed type
                var ret = MemoryOperations.GcMalloc(*(int *)((byte *)et + ClassOperations.GetVtblTypeSizeOffset()));

                // dst ptr
                var dst = (byte *)ret + ClassOperations.GetBoxedTypeDataOffset();

                CopyMem(dst, (byte *)src, vt_size);

                return(ret);
            }
            else
            {
                // simply copy the reference
                return(*(void **)src);
            }
        }
Exemple #4
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 #5
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);
            }
        }