Exemple #1
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 #2
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 #3
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);
            }
        }