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 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 #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
        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);
        }