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
        public unsafe override System.Reflection.ParameterInfo[] GetParameters()
        {
            if (_Params == null)
            {
                var pc     = mspec.m.GetMethodDefSigParamCount(mspec.msig);
                var rt_idx = mspec.m.GetMethodDefSigRetTypeIndex(mspec.msig);
                mspec.m.GetTypeSpec(ref rt_idx, mspec.gtparams, mspec.gmparams);

                var _params = new TysosParameterInfo[pc];
                var _ptypes = new TysosType[pc];

                for (int i = 0; i < pc; i++)
                {
                    var       tspec = mspec.m.GetTypeSpec(ref rt_idx, mspec.gtparams, mspec.gmparams);
                    TysosType tt    = tspec;
                    _ptypes[i] = tt;

                    TysosParameterInfo tpi = new TysosParameterInfo(tt, i, this);
                    _params[i] = tpi;
                }

                if (System.Threading.Interlocked.CompareExchange(ref _Params, _params, null) == null)
                {
                    _ParamTypes = _ptypes;
                }
            }

            return(_Params);
        }
Exemple #3
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 #4
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 #5
0
 internal ConstructorInfo(TysosMethod meth, TysosType type)
 {
     if (meth == null)
     {
         throw new Exception("libsupcs.ConstructorInfo constructor called with meth as null");
     }
     if (type == null)
     {
         throw new Exception("libsupcs.ConstructorInfo constructor called with type as null");
     }
     _meth = meth; _type = type;
 }
Exemple #6
0
        static unsafe void get_enum_values_and_names(TysosType enum_type, HandleOnStack values_ptr, HandleOnStack names_ptr, bool getNames)
        {
            //System.Diagnostics.Debugger.Log(0, "libsupcs", "get_enum_values_and_names: enum_type: " + ((ulong)enum_vtbl).ToString("X16"));
            //var enum_type = TysosType.internal_from_vtbl(enum_vtbl);
            MonoEnumInfo info;

            get_enum_info(enum_type, out info);

            ulong[] values = new ulong[info.values.Length];
            int[]   v      = info.values as int[];
            for (int i = 0; i < info.values.Length; i++)
            {
                values[i] = (ulong)v[i];
            }
            *values_ptr.ptr = CastOperations.ReinterpretAsPointer(values);

            if (getNames)
            {
                *names_ptr.ptr = CastOperations.ReinterpretAsPointer(info.names);
            }
        }
Exemple #7
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 #8
0
        internal static unsafe metadata.TypeSpec GetTypeSpec(TysosType t)
        {
            void **impl_ptr = t.GetImplOffset();

            return(GetTypeSpec(*impl_ptr));
        }
Exemple #9
0
        static internal unsafe TysosType GetUnderlyingEnumType(TysosType enum_type)
        {
            void *e_type_vtbl = *enum_type.GetImplOffset();

            return(TysosType.internal_from_vtbl(GetUnderlyingEnumTypeVtbl(*(void **)e_type_vtbl)));
        }
Exemple #10
0
        static unsafe void get_enum_info(TysosType enumType, out MonoEnumInfo info)
        {
            MonoEnumInfo ret = new MonoEnumInfo();

            ret.utype = GetUnderlyingEnumType(enumType);

            if (!ret.utype.Equals(typeof(int)))
            {
                throw new Exception("get_enum_info: currently only enums with an underlying type of int are supported");
            }

            var ets = enumType.tspec;

            /* Iterate through methods looking for requested
             *    one */
            var first_fdef = ets.m.GetIntEntry(metadata.MetadataStream.tid_TypeDef,
                                               ets.tdrow, 4);
            var last_fdef = ets.m.GetLastFieldDef(ets.tdrow);

            // First iterate to get number of satic fields
            int static_fields = 0;

            for (uint fdef_row = first_fdef; fdef_row < last_fdef; fdef_row++)
            {
                var flags = ets.m.GetIntEntry(metadata.MetadataStream.tid_Field,
                                              (int)fdef_row, 0);
                if ((flags & 0x10) == 0x10)
                {
                    static_fields++;
                }
            }

            ret.names = new string[static_fields];
            int[] values = new int[static_fields];

            System.Diagnostics.Debugger.Log(0, "libsupcs", "Enum.get_enum_info: found " + static_fields.ToString() + " entries");

            static_fields = 0;
            // Iterate again to get the details
            for (uint fdef_row = first_fdef; fdef_row < last_fdef; fdef_row++)
            {
                var flags = ets.m.GetIntEntry(metadata.MetadataStream.tid_Field,
                                              (int)fdef_row, 0);
                if ((flags & 0x10) == 0x10)
                {
                    var name = ets.m.GetStringEntry(metadata.MetadataStream.tid_Field,
                                                    (int)fdef_row, 1);
                    ret.names[static_fields] = name;

                    System.Diagnostics.Debugger.Log(0, "libsupcs", "Enum.get_enum_info: field: " + name);

                    var const_row = ets.m.const_field_owners[fdef_row];
                    if (const_row != 0)
                    {
                        var const_offset = (int)ets.m.GetIntEntry(metadata.MetadataStream.tid_Constant,
                                                                  const_row, 2);

                        ets.m.SigReadUSCompressed(ref const_offset);
                        var const_val = ets.m.sh_blob.di.ReadInt(const_offset);
                        values[static_fields] = const_val;

                        System.Diagnostics.Debugger.Log(0, "libsupcs", "Enum.get_enum_info: value: " + const_val.ToString());
                    }

                    static_fields++;
                }
            }

            ret.values = values;
            info       = ret;
        }
Exemple #11
0
 public TysosMethod(metadata.MethodSpec ms, TysosType owning_type)
 {
     mspec      = ms;
     OwningType = owning_type;
 }
Exemple #12
0
        public override object Invoke(object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] parameters, System.Globalization.CultureInfo culture)
        {
            uint flags = 0;

            if (MethodAddress == null)
            {
                var mangled_name = mspec.MangleMethod();
                System.Diagnostics.Debugger.Log(0, "libsupcs", "TysosMethod.Invoke: requesting run-time address for " + mangled_name);
                MethodAddress = JitOperations.GetAddressOfObject(mspec.MangleMethod());
                if (MethodAddress == null)
                {
                    System.Diagnostics.Debugger.Log(0, "libsupcs", "TysosMethod.Invoke: jit compiling method");
                    MethodAddress = JitOperations.JitCompile(this.mspec);
                }
            }
            if (MethodAddress == null)
            {
                throw new System.Reflection.TargetException("Method does not have a defined implementation (" + OwningType.FullName + "." + Name + "())");
            }
            if (!IsStatic && (obj == null))
            {
                throw new System.Reflection.TargetException("Instance method and obj is null (" + OwningType.FullName + "." + Name + "())");
            }

            // TODO: check number and type of parameters is what the method expects

            // Get total number of parameters
            int p_length = 0;

            if (parameters != null)
            {
                p_length = parameters.Length;
            }
            if (!IsStatic)
            {
                p_length++;
            }

            // See InternalStrCpy for the rationale here
            int     max_stack_alloc = p_length > 512 ? 512 : p_length;
            IntPtr *pstack          = stackalloc IntPtr[max_stack_alloc];
            IntPtr *tstack          = stackalloc IntPtr[max_stack_alloc];

            void **ps, ts;

            if (max_stack_alloc <= 512)
            {
                ps = (void **)pstack;
                ts = (void **)tstack;
            }
            else
            {
                ps = (void **)MemoryOperations.GcMalloc(p_length * sizeof(void *));
                ts = (void **)MemoryOperations.GcMalloc(p_length * sizeof(void *));
            }

            // Build a new params array to include obj if necessary, and a tysos type array
            int curptr = 0;

            if (!IsStatic)
            {
                ps[0] = CastOperations.ReinterpretAsPointer(obj);
                ts[0] = OtherOperations.GetStaticObjectAddress("_Zu1O");
                curptr++;
            }
            if (parameters != null)
            {
                for (int i = 0; i < parameters.Length; i++, curptr++)
                {
                    var cp = CastOperations.ReinterpretAsPointer(parameters[i]);
                    ps[curptr] = cp;
                    ts[curptr] = *(void **)cp;
                }
            }

            if (!IsStatic)
            {
                flags |= invoke_flag_instance;
            }
            if (OwningType.IsValueType)
            {
                flags |= invoke_flag_vt;
            }
            if (ReturnType != null && ReturnType.IsValueType)
            {
                flags |= invoke_flag_vt_ret;
            }

            return(CastOperations.ReinterpretAsObject(InternalInvoke(MethodAddress, p_length, ps, ts,
                                                                     (ReturnType != null) ? TysosType.ReinterpretAsType(ReturnType)._impl : null, flags)));
        }
Exemple #13
0
        static unsafe void Copy(void *srcArr, int srcIndex, void *dstArr, int dstIndex, int length,
                                bool reliable)
        {
            /* Ensure arrays are valid */
            if (srcArr == null || dstArr == null)
            {
                throw new ArgumentNullException();
            }

            /* Ensure length is valid */
            if (length < 0)
            {
                throw new ArgumentOutOfRangeException();
            }

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

            if (srcRank != dstRank)
            {
                throw new RankException();
            }

            /* Get source and dest element types */
            var srcET = *(void **)((byte *)srcArr + ArrayOperations.GetElemTypeOffset());
            var dstET = *(void **)((byte *)dstArr + ArrayOperations.GetElemTypeOffset());

            /* See if we can do a quick copy */
            bool can_quick_copy = false;

            if (srcET == dstET)
            {
                can_quick_copy = true;
            }
            else if (TysosType.CanCast(srcET, dstET))
            {
                can_quick_copy = true;
            }
            else if (reliable)
            {
                throw new ArrayTypeMismatchException();   /* ConstrainedCopy requires types to be the same or derived */
            }
            else
            {
                can_quick_copy = false;
            }

            /* For now we don't handle arrays with lobounds != 0 */
            var srcLobounds = *(int **)((byte *)srcArr + ArrayOperations.GetLoboundsOffset());
            var dstLobounds = *(int **)((byte *)dstArr + ArrayOperations.GetLoboundsOffset());

            for (int i = 0; i < srcRank; i++)
            {
                if (srcLobounds[i] != 0)
                {
                    throw new NotImplementedException("srcLobounds != 0");
                }
                if (dstLobounds[i] != 0)
                {
                    throw new NotImplementedException("dstLobounds != 0");
                }
            }
            if (srcIndex < 0 || dstIndex < 0)
            {
                throw new ArgumentOutOfRangeException();
            }

            /* Ensure we don't overflow */
            var src_len = GetLength(srcArr);
            var dst_len = GetLength(dstArr);

            if (srcIndex + length > src_len)
            {
                System.Diagnostics.Debugger.Log(0, "libsupcs", "Array.Copy srcIndex/length out of range");
                System.Diagnostics.Debugger.Log(length, "libsupcs", "length");
                System.Diagnostics.Debugger.Log(srcIndex, "libsupcs", "srcIndex");
                System.Diagnostics.Debugger.Log(src_len, "libsupcs", "src_len");
                throw new ArgumentOutOfRangeException();
            }
            if (dstIndex + length > dst_len)
            {
                System.Diagnostics.Debugger.Log(0, "libsupcs", "Array.Copy dstIndex/length out of range");
                System.Diagnostics.Debugger.Log(length, "libsupcs", "length");
                System.Diagnostics.Debugger.Log(dstIndex, "libsupcs", "dstIndex");
                System.Diagnostics.Debugger.Log(dst_len, "libsupcs", "dst_len");
                throw new ArgumentOutOfRangeException();
            }

            if (can_quick_copy)
            {
                /* Elem size of both arrays is guaranteed to be the same and we can do a shallow copy */
                var e_size = *(int *)((byte *)srcArr + ArrayOperations.GetElemSizeOffset());

                var src_ia = *(byte **)((byte *)srcArr + ArrayOperations.GetInnerArrayOffset());
                var dst_ia = *(byte **)((byte *)dstArr + ArrayOperations.GetInnerArrayOffset());

                MemoryOperations.MemMove(dst_ia + dstIndex * e_size, src_ia + srcIndex * e_size, length * e_size);
            }
            else
            {
                /* TODO: implement as per System.Array.Copy() semantics */
                throw new NotImplementedException("Cannot quick copy " + ((ulong)srcET).ToString("X") +
                                                  " to " + ((ulong)dstET).ToString("X"));
            }
        }