Esempio n. 1
0
        static unsafe void InitializeArray(void *arr, void *fld_handle)
        {
            System.Diagnostics.Debugger.Log(0, "libsupcs", "InitializeArray: arr: " + ((ulong)arr).ToString("X16") + ", fld_handle: " + ((ulong)fld_handle).ToString("X16"));
            void *dst = *(void **)((byte *)arr + ArrayOperations.GetInnerArrayOffset());

            /* Get total number of elements, and hence data size */
            int *sizes = *(int **)((byte *)arr + ArrayOperations.GetSizesOffset());
            int  rank  = *(int *)((byte *)arr + ArrayOperations.GetRankOffset());

            if (rank == 0)
            {
                return;
            }

            int size = sizes[0];

            for (int i = 1; i < rank; i++)
            {
                size *= sizes[i];
            }

            int len = size * *(int *)((byte *)arr + ArrayOperations.GetElemSizeOffset());

            /* Field Typeinfos hava a pointer to the stored data as their third element */
            void *src = ((void **)fld_handle)[2];

            System.Diagnostics.Debugger.Log(0, "libsupcs", "InitializeArray: src: " + ((ulong)src).ToString("X16") +
                                            ", dest: " + ((ulong)dst).ToString("X16") + ", len: " + len.ToString());

            MemoryOperations.MemCpy(dst, src, len);
        }
Esempio n. 2
0
        static unsafe int GetLength(void *arr)
        {
            int  arrRank = *(int *)((byte *)arr + ArrayOperations.GetRankOffset());
            int *szPtr   = *(int **)((byte *)arr + ArrayOperations.GetSizesOffset());

            int ret = 1;

            for (int i = 0; i < arrRank; i++)
            {
                ret = ret * *(szPtr + i);
            }
            return(ret);
        }
Esempio n. 3
0
        static unsafe int GetLength(void *arr, int rank)
        {
            if (arr == null)
            {
                System.Diagnostics.Debugger.Break();
                throw new ArgumentNullException();
            }
            int arrRank = *(int *)((byte *)arr + ArrayOperations.GetRankOffset());

            if (rank < 0 || rank >= arrRank)
            {
                System.Diagnostics.Debugger.Break();
                throw new IndexOutOfRangeException();
            }

            int *szPtr = *(int **)((byte *)arr + ArrayOperations.GetSizesOffset());

            return(*(szPtr + rank));
        }
Esempio n. 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));
        }
Esempio n. 5
0
        static unsafe void InternalGetReference(void *arr, System.TypedReference *typedref, int ranks, int *rank_indices)
        {
            // idx = rightmost-index + 2nd-right * rightmost-size + 3rd-right * 2nd-right-size * right-size + ...

            // rank checking is done by System.Array members in coreclr
            int *lovals = *(int **)((byte *)arr + ArrayOperations.GetLoboundsOffset());
            int *sizes  = *(int **)((byte *)arr + ArrayOperations.GetSizesOffset());

            // first get index of first rank
            if (rank_indices[0] > sizes[0])
            {
                throw new IndexOutOfRangeException();
            }
            int index = rank_indices[0] - lovals[0];

            // now repeat mul rank size; add rank index; rank-1 times
            for (int rank = 1; rank < ranks; rank++)
            {
                if (rank_indices[rank] > sizes[rank])
                {
                    throw new IndexOutOfRangeException();
                }

                index *= sizes[rank];
                index += rank_indices[rank];
            }

            // get pointer to actual data
            int   et_size = *(int *)((byte *)arr + ArrayOperations.GetElemSizeOffset());
            void *ptr     = *(byte **)((byte *)arr + ArrayOperations.GetInnerArrayOffset()) + index * et_size;

            // store to the typed reference
            *(void **)((byte *)typedref + ClassOperations.GetTypedReferenceValueOffset()) = ptr;
            *(void **)((byte *)typedref + ClassOperations.GetTypedReferenceTypeOffset())  =
                *(void **)((byte *)arr + ArrayOperations.GetElemTypeOffset());
        }
Esempio n. 6
0
        static unsafe bool FastCopy(void *srcArr, int srcIndex, void *dstArr, int dstIndex, int length)
        {
            /* This is often called with length == 0 when the
             * first item is added to a List<T> as the default
             * array within the list has length 0.
             */

            if (length == 0)
            {
                return(true);
            }

            // Ensure both arrays are of rank 1
            int srcRank = *(int *)((byte *)srcArr + ArrayOperations.GetRankOffset());
            int dstRank = *(int *)((byte *)dstArr + ArrayOperations.GetRankOffset());

            if (srcRank != 1)
            {
                return(false);
            }
            if (dstRank != 1)
            {
                return(false);
            }

            // Ensure srcIndex is valid
            int srcLobound = **(int **)((byte *)srcArr + ArrayOperations.GetLoboundsOffset());
            int srcSize    = **(int **)((byte *)srcArr + ArrayOperations.GetSizesOffset());

            srcIndex -= srcLobound;
            if (srcIndex + length > srcSize)
            {
                return(false);
            }

            // Ensure destIndex is valid
            int dstLobound = **(int **)((byte *)dstArr + ArrayOperations.GetLoboundsOffset());
            int dstSize    = **(int **)((byte *)dstArr + ArrayOperations.GetSizesOffset());

            dstIndex -= dstLobound;
            if (dstIndex + length > dstSize)
            {
                return(false);
            }

            // Ensure both have same element type
            void *srcET = *(void **)((byte *)srcArr + ArrayOperations.GetElemTypeOffset());
            void *dstET = *(void **)((byte *)dstArr + ArrayOperations.GetElemTypeOffset());

            if (srcET != dstET)
            {
                return(false);
            }

            // Get element size
            int elemSize = *(int *)((byte *)srcArr + ArrayOperations.GetElemSizeOffset());

            srcIndex *= elemSize;
            dstIndex *= elemSize;

            byte *srcAddr = *(byte **)((byte *)srcArr + ArrayOperations.GetInnerArrayOffset()) + srcIndex;
            byte *dstAddr = *(byte **)((byte *)dstArr + ArrayOperations.GetInnerArrayOffset()) + dstIndex;

            length *= elemSize;

            MemoryOperations.MemMove(dstAddr, srcAddr, length);

            return(true);
        }