Example #1
0
        public static int GetTypeSize(metadata.TypeSpec ts,
                                      target.Target t, bool is_static = false)
        {
            switch (ts.stype)
            {
            case TypeSpec.SpecialType.None:
                if (ts.Equals(ts.m.SystemRuntimeTypeHandle) ||
                    ts.Equals(ts.m.SystemRuntimeMethodHandle) ||
                    ts.Equals(ts.m.SystemRuntimeFieldHandle))
                {
                    return(is_static ? 0 : (t.GetPointerSize()));
                }
                if (ts.m.classlayouts[ts.tdrow] != 0 && ts.IsGeneric == false && ts.IsGenericTemplate == false)
                {
                    var size = ts.m.GetIntEntry(metadata.MetadataStream.tid_ClassLayout,
                                                ts.m.classlayouts[ts.tdrow],
                                                1);
                    if (size != 0)
                    {
                        return((int)size);
                    }
                }
                return(GetFieldOffset(ts, (string)null, t, out var is_tls, is_static));

            case TypeSpec.SpecialType.SzArray:
            case TypeSpec.SpecialType.Array:
                if (is_static)
                {
                    return(0);
                }
                return(GetArrayObjectSize(t));

            case TypeSpec.SpecialType.Boxed:
                if (is_static)
                {
                    return(0);
                }
                return(GetTypeSize(ts.m.SystemObject, t) +
                       GetTypeSize(ts.Unbox, t));

            default:
                throw new NotImplementedException();
            }
        }
Example #2
0
        private static void OutputVirtualMethods(TypeSpec decl_ts,
                                                 IBinaryFile of, ISection os,
                                                 IList <byte> d, ref ulong offset, target.Target t,
                                                 TysilaState s)
        {
            var vmeths = GetVirtualMethodDeclarations(decl_ts);

            ImplementVirtualMethods(decl_ts, vmeths);

            foreach (var vmeth in vmeths)
            {
                var    impl_ms     = vmeth.impl_meth;
                string impl_target = (impl_ms == null) ? "__cxa_pure_virtual" : impl_ms.MethodReferenceAlias;

                var impl_sym = of.CreateSymbol();
                impl_sym.Name       = impl_target;
                impl_sym.ObjectType = SymbolObjectType.Function;

                var impl_reloc = of.CreateRelocation();
                impl_reloc.Addend     = 0;
                impl_reloc.DefinedIn  = os;
                impl_reloc.Offset     = offset;
                impl_reloc.References = impl_sym;
                impl_reloc.Type       = t.GetDataToCodeReloc();
                of.AddRelocation(impl_reloc);

                for (int i = 0; i < t.GetPointerSize(); i++, offset++)
                {
                    d.Add(0);
                }

                if (impl_ms != null)
                {
                    s.r.MethodRequestor.Request(impl_ms);
                }
            }
        }
Example #3
0
        internal static target.Target.Reg DoAllocation(Code c, int ct, target.Target t, ref long alloced, ref int cur_stack)
        {
            // rationalise thread-local addresses to use the same registers as normal ones
            if (ct == Opcode.ct_tls_int32)
            {
                ct = Opcode.ct_int32;
            }
            else if (ct == Opcode.ct_tls_int64)
            {
                ct = Opcode.ct_int64;
            }
            else if (ct == Opcode.ct_tls_intptr)
            {
                ct = Opcode.ct_intptr;
            }

            long avail = t.ct_regs[ct] & ~alloced;

            if (avail != 0)
            {
                // We have a valid allocation to use
                int idx = 0;
                while ((avail & 0x1) == 0)
                {
                    idx++;
                    avail >>= 1;
                }
                var reg = t.regs[idx];
                alloced |= (1L << idx);
                return(reg);
            }
            else
            {
                return(t.AllocateStackLocation(c, t.GetCTSize(ct), ref cur_stack));
            }
        }
Example #4
0
        static int get_conv_pushtype(Opcode n, target.Target t)
        {
            var dt = n.uses[1].v;

            switch (dt)
            {
            case 1:
            case 2:
            case 4:
            case -1:
            case -2:
            case -4:
                return(ct_int32);

            case 8:
            case -8:
                return(ct_int64);

            case 14:
            case 18:
                return(ct_float);
            }
            throw new NotSupportedException("Invalid opcode: " + n.ToString());
        }
Example #5
0
        static int get_call_rettype(Opcode n, target.Target t)
        {
            // Determine the return type from the method signature
            var cs = n.uses[0];

            var ms = cs.ms;

            if (ms == null)
            {
                throw new NotSupportedException();
            }

            var msig   = ms.msig;
            var rt_idx = ms.m.GetMethodDefSigRetTypeIndex(msig);

            throw new NotImplementedException();

            /*var ret_ts = ms.m.GetTypeSpec(ref rt_idx,
             *  n.n.g.ms.gtparams, n.n.g.ms.gmparams);
             *
             * var ct = GetCTFromType(ret_ts);
             *
             * return ct;*/
        }
Example #6
0
        /* Vtable:
         *
         *  TIPtr (just to a glorified TypeSpec)
         *  IFacePtr (to list of implemented interfaces)
         *  Extends (to base classes for quick castclassex)
         *  TypeSize (to allow MemberwiseClone to work without full Reflection)
         *  Any target-specific data
         *  Method 0
         *  ...
         *
         *  IFaceList TODO
         *
         *
         */

        public static void OutputVTable(TypeSpec ts,
                                        target.Target t, binary_library.IBinaryFile of,
                                        TysilaState s,
                                        MetadataStream base_m = null,
                                        ISection os           = null,
                                        ISection data_sect    = null)
        {
            // Don't compile if not for this architecture
            if (!t.IsTypeValid(ts))
            {
                return;
            }

            /* New signature table */
            s.sigt = new SignatureTable(ts.MangleType());

            // If its a delegate type we also need to output its methods
            if (ts.IsDelegate && !ts.IsGenericTemplate)
            {
                s.r.DelegateRequestor.Request(ts);
            }

            if (os == null)
            {
                os = of.GetRDataSection();
            }
            var d        = os.Data;
            var ptr_size = t.GetCTSize(ir.Opcode.ct_object);

            os.Align(ptr_size);

            ulong offset = (ulong)os.Data.Count;

            /* Symbol */
            var sym = of.CreateSymbol();

            sym.Name       = ts.MangleType();
            sym.ObjectType = binary_library.SymbolObjectType.Object;
            sym.Offset     = offset;
            sym.Type       = binary_library.SymbolType.Global;
            os.AddSymbol(sym);

            if (base_m != null && ts.m != base_m)
            {
                sym.Type = SymbolType.Weak;
            }

            /* TIPtr */
            var tiptr_offset = s.sigt.GetSignatureAddress(ts.Signature, t, s);

            var ti_reloc = of.CreateRelocation();

            ti_reloc.Addend          = tiptr_offset;
            ti_reloc.DefinedIn       = os;
            ti_reloc.Offset          = offset;
            ti_reloc.Type            = t.GetDataToDataReloc();
            ti_reloc.References      = of.CreateSymbol();
            ti_reloc.References.Name = s.sigt.GetStringTableName();
            of.AddRelocation(ti_reloc);

            for (int i = 0; i < ptr_size; i++, offset++)
            {
                d.Add(0);
            }

            /* IFacePtr */
            IRelocation if_reloc = null;

            if (!ts.IsGenericTemplate && !ts.IsInterface && ts.stype != TypeSpec.SpecialType.Ptr && ts.stype != TypeSpec.SpecialType.MPtr)
            {
                if_reloc            = of.CreateRelocation();
                if_reloc.DefinedIn  = os;
                if_reloc.Offset     = offset;
                if_reloc.Type       = t.GetDataToDataReloc();
                if_reloc.References = sym;
                of.AddRelocation(if_reloc);
            }

            for (int i = 0; i < ptr_size; i++, offset++)
            {
                d.Add(0);
            }

            /* Extends */
            var ts_extends = ts.GetExtends();

            if (ts_extends != null)
            {
                var ext_reloc = of.CreateRelocation();
                ext_reloc.Addend    = 0;
                ext_reloc.DefinedIn = os;
                ext_reloc.Offset    = offset;
                ext_reloc.Type      = t.GetDataToDataReloc();

                var ext_sym = of.CreateSymbol();
                ext_sym.Name = ts_extends.MangleType();

                ext_reloc.References = ext_sym;
                of.AddRelocation(ext_reloc);

                s.r.VTableRequestor.Request(ts_extends);
            }
            for (int i = 0; i < ptr_size; i++, offset++)
            {
                d.Add(0);
            }

            if (ts.IsInterface || ts.IsGenericTemplate || ts.stype == TypeSpec.SpecialType.MPtr || ts.stype == TypeSpec.SpecialType.Ptr)
            {
                /* Type size is zero for somethinh we cannot
                 * instantiate */
                for (int i = 0; i < ptr_size; i++, offset++)
                {
                    d.Add(0);
                }

                /* Flags */
                AddFlags(d, ts, ref offset, t);

                /* BaseType */
                AddBaseType(d, ts, of, os, ref offset, t, s);

                // Target-specific information
                t.AddExtraVTableFields(ts, d, ref offset);
            }
            else
            {
                /* Type size */
                var tsize = t.IntPtrArray(BitConverter.GetBytes(GetTypeSize(ts, t)));
                foreach (var b in tsize)
                {
                    d.Add(b);
                    offset++;
                }

                /* Flags */
                AddFlags(d, ts, ref offset, t);

                /* BaseType */
                AddBaseType(d, ts, of, os, ref offset, t, s);

                // Target specific information
                t.AddExtraVTableFields(ts, d, ref offset);

                /* Virtual methods */
                OutputVirtualMethods(ts, of, os,
                                     d, ref offset, t, s);

                /* Interface implementations */

                // build list of implemented interfaces
                var ii = ts.ImplementedInterfaces;

                // first, add all interface implementations
                List <ulong> ii_offsets = new List <ulong>();

                for (int i = 0; i < ii.Count; i++)
                {
                    ii_offsets.Add(offset - sym.Offset);
                    OutputInterface(ts, ii[i],
                                    of, os, d, ref offset, t, s);
                    s.r.VTableRequestor.Request(ii[i]);
                }

                // point iface ptr here
                if_reloc.Addend = (long)offset - (long)sym.Offset;
                for (int i = 0; i < ii.Count; i++)
                {
                    // list is pointer to interface declaration, then implementation
                    var id_ptr_sym = of.CreateSymbol();
                    id_ptr_sym.Name = ii[i].MangleType();

                    var id_ptr_reloc = of.CreateRelocation();
                    id_ptr_reloc.Addend     = 0;
                    id_ptr_reloc.DefinedIn  = os;
                    id_ptr_reloc.Offset     = offset;
                    id_ptr_reloc.References = id_ptr_sym;
                    id_ptr_reloc.Type       = t.GetDataToDataReloc();
                    of.AddRelocation(id_ptr_reloc);

                    for (int j = 0; j < ptr_size; j++, offset++)
                    {
                        d.Add(0);
                    }

                    // implementation
                    var ii_ptr_reloc = of.CreateRelocation();
                    ii_ptr_reloc.Addend     = (long)ii_offsets[i];
                    ii_ptr_reloc.DefinedIn  = os;
                    ii_ptr_reloc.Offset     = offset;
                    ii_ptr_reloc.References = sym;
                    ii_ptr_reloc.Type       = t.GetDataToDataReloc();
                    of.AddRelocation(ii_ptr_reloc);

                    for (int j = 0; j < ptr_size; j++, offset++)
                    {
                        d.Add(0);
                    }
                }

                // null terminate the list
                for (int j = 0; j < ptr_size; j++, offset++)
                {
                    d.Add(0);
                }
            }

            sym.Size = (long)(offset - sym.Offset);

            /* Output signature table if any */
            if (data_sect == null)
            {
                data_sect = of.GetDataSection();
            }
            s.sigt.WriteToOutput(of, base_m, t, data_sect);
        }
Example #7
0
        public static void OutputStaticFields(metadata.TypeSpec ts,
                                              target.Target t, binary_library.IBinaryFile of,
                                              MetadataStream base_m         = null,
                                              binary_library.ISection os    = null,
                                              binary_library.ISection tlsos = null)
        {
            // Don't compile if not for this architecture
            if (!t.IsTypeValid(ts))
            {
                return;
            }

            int align = 1;

            if (ts.SimpleType == 0)
            {
                align = GetTypeAlignment(ts, t, true);
            }

            if (os == null)
            {
                os = of.GetDataSection();
            }
            os.Align(t.GetPointerSize());
            os.Align(align);

            ulong offset    = (ulong)os.Data.Count;
            ulong tl_offset = 0;

            if (tlsos != null)
            {
                tl_offset = (ulong)tlsos.Data.Count;
            }

            int cur_offset   = 0;
            int cur_tloffset = 0;

            /* is_initialized */
            for (int i = 0; i < t.psize; i++)
            {
                os.Data.Add(0);
            }
            cur_offset += t.psize;

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

            for (uint fdef_row = first_fdef; fdef_row < last_fdef; fdef_row++)
            {
                // Ensure field is static or not as required
                var flags = ts.m.GetIntEntry(MetadataStream.tid_Field,
                                             (int)fdef_row, 0);
                if ((flags & 0x10) == 0x10)
                {
                    // Increment by type size
                    var fsig = (int)ts.m.GetIntEntry(MetadataStream.tid_Field,
                                                     (int)fdef_row, 2);

                    var ft      = ts.m.GetFieldType(ref fsig, ts.gtparams, null);
                    var ft_size = t.GetSize(ft);

                    ft_size = util.util.align(ft_size, align);

                    bool     is_tls = ts.m.thread_local_fields[(int)fdef_row];
                    ISection cur_os = os;
                    if (is_tls)
                    {
                        if (tlsos == null)
                        {
                            throw new NotSupportedException("No thread-local section provided");
                        }
                        cur_os = tlsos;
                    }

                    /* See if there is any data defined as an rva */
                    var rva = ts.m.fieldrvas[(int)fdef_row];
                    if (rva != 0)
                    {
                        var rrva = (int)ts.m.ResolveRVA(rva);
                        for (int i = 0; i < ft_size; i++)
                        {
                            cur_os.Data.Add(ts.m.file.ReadByte(rrva++));
                        }
                    }
                    else
                    {
                        for (int i = 0; i < ft_size; i++)
                        {
                            cur_os.Data.Add(0);
                        }
                    }

                    /* Output any additional defined symbols */
                    foreach (var alias in ts.m.GetFieldAliases((int)fdef_row))
                    {
                        var asym = of.CreateSymbol();
                        asym.Name       = alias;
                        asym.Offset     = offset + (ulong)cur_offset;
                        asym.Type       = binary_library.SymbolType.Global;
                        asym.ObjectType = binary_library.SymbolObjectType.Object;
                        cur_os.AddSymbol(asym);

                        asym.Size = ft_size;

                        if (base_m != null && ts.m != base_m)
                        {
                            asym.Type = binary_library.SymbolType.Weak;
                        }
                    }

                    if (is_tls)
                    {
                        cur_tloffset += ft_size;
                    }
                    else
                    {
                        cur_offset += ft_size;
                    }
                }
            }

            if (cur_offset > 0)
            {
                /* Add symbol */

                var sym = of.CreateSymbol();
                sym.Name       = ts.m.MangleType(ts) + "S";
                sym.Offset     = offset;
                sym.Type       = binary_library.SymbolType.Global;
                sym.ObjectType = binary_library.SymbolObjectType.Object;
                os.AddSymbol(sym);

                sym.Size = os.Data.Count - (int)offset;

                if (base_m != null && ts.m != base_m)
                {
                    sym.Type = binary_library.SymbolType.Weak;
                }
            }
            if (cur_tloffset > 0)
            {
                /* Add thread local symbol */
                var sym = of.CreateSymbol();
                sym.Name       = ts.m.MangleType(ts) + "ST";
                sym.Offset     = tl_offset;
                sym.Type       = binary_library.SymbolType.Global;
                sym.ObjectType = binary_library.SymbolObjectType.Object;
                tlsos.AddSymbol(sym);

                sym.Size = tlsos.Data.Count - (int)tl_offset;

                if (base_m != null && ts.m != base_m)
                {
                    sym.Type = binary_library.SymbolType.Weak;
                }
            }
        }
Example #8
0
        public static int GetTypeAlignment(metadata.TypeSpec ts,
                                           target.Target t, bool is_static)
        {
            if (ts.m.classlayouts[ts.tdrow] != 0 && ts.IsGeneric == false && ts.IsGenericTemplate == false)
            {
                // see if there is a packing specified
                var pack = ts.m.GetIntEntry(metadata.MetadataStream.tid_ClassLayout,
                                            ts.m.classlayouts[ts.tdrow],
                                            0);
                if (pack != 0)
                {
                    return((int)pack);
                }
            }
            if (ts.stype != TypeSpec.SpecialType.None)
            {
                return(t.psize);
            }

            // types always align on their most strictly aligned type
            int cur_align = 1;

            if (ts.SimpleType != 0)
            {
                // simple types larger than a pointer (e.g. object/string)
                //  still aling to pointer size;
                var ret = GetTypeSize(ts, t, is_static);
                if (ret < t.psize)
                {
                    return(ret);
                }
                return(t.psize);
            }

            // reference types will always have a pointer and int64 in them
            if (is_static == false && !ts.IsValueType)
            {
                cur_align = t.psize;
                cur_align = util.util.align(cur_align, t.GetCTSize(ir.Opcode.ct_int64));
            }
            // and static will always have an 'is_initialized'
            else if (is_static)
            {
                cur_align = t.psize;
            }

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

            for (uint fdef_row = first_fdef; fdef_row < last_fdef; fdef_row++)
            {
                // Ensure field is static if requested
                var flags = ts.m.GetIntEntry(MetadataStream.tid_Field,
                                             (int)fdef_row, 0);
                if (((flags & 0x10) == 0x10 && is_static == true) ||
                    ((flags & 0x10) == 0 && is_static == false))
                {
                    // Get alignment of underlying type
                    var fsig = (int)ts.m.GetIntEntry(MetadataStream.tid_Field,
                                                     (int)fdef_row, 2);

                    var ft = ts.m.GetFieldType(ref fsig, ts.gtparams, null);

                    int ft_align;
                    if (ft.IsValueType)
                    {
                        ft_align = GetTypeAlignment(ft, t, false);
                    }
                    else
                    {
                        ft_align = t.psize;
                    }

                    if (ft_align > cur_align)
                    {
                        cur_align = ft_align;
                    }
                }
            }

            return(cur_align);
        }
Example #9
0
        public static int GetFieldOffset(metadata.TypeSpec ts,
                                         string fname, target.Target t, out bool is_tls, bool is_static = false,
                                         List <TypeSpec> field_types = null, List <string> field_names = null,
                                         List <int> field_offsets    = null)
        {
            int align = 1;

            is_tls = false;
            if (ts.SimpleType == 0) // class
            {
                align = GetTypeAlignment(ts, t, is_static);
            }
            if (ts.SimpleType == 0xe && !is_static) // string
            {
                align = t.GetPointerSize();
            }

            if (ts.Equals(ts.m.SystemString) && !is_static)
            {
                /* System.String has a special layout in dotnet clr because the fields
                 * length and firstchar are reversed */

                if (field_names != null)
                {
                    field_names.Add("__vtbl");
                    field_names.Add("__mutex_lock");
                    field_names.Add("m_stringLength");
                    field_names.Add("m_firstChar");
                }
                if (field_types != null)
                {
                    field_types.Add(ts.m.SystemIntPtr);
                    field_types.Add(ts.m.SystemInt64);
                    field_types.Add(ts.m.SystemInt32);
                    field_types.Add(ts.m.SystemChar);
                }
                if (field_offsets != null)
                {
                    field_offsets.Add(0);
                    field_offsets.Add(GetArrayFieldOffset(ArrayField.MutexLock, t));
                    field_offsets.Add(GetTypeSize(ts.m.SystemObject, t));
                    field_offsets.Add(GetTypeSize(ts.m.SystemObject, t) + t.GetPointerSize());
                }

                if (fname == null)
                {
                    // size = sizeof(Object) + sizeof(int length), aligned to pointer size
                    return(GetTypeSize(ts.m.SystemObject, t) + t.GetPointerSize());
                }
                else
                {
                    if (fname == "length" || fname == "m_stringLength")
                    {
                        return(GetTypeSize(ts.m.SystemObject, t));
                    }
                    else if (fname == "start_char" || fname == "m_firstChar")
                    {
                        return(GetTypeSize(ts.m.SystemObject, t) + t.GetPointerSize());
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                }
            }

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

            int cur_offset    = 0;
            int cur_tl_offset = 0;

            if (is_static == false && !ts.IsValueType)
            {
                if (ts.GetExtends() == null)
                {
                    // Add a vtable entry
                    if (field_offsets != null)
                    {
                        field_offsets.Add(cur_offset);
                    }
                    cur_offset += t.GetCTSize(ir.Opcode.ct_object);
                    cur_offset  = util.util.align(cur_offset, align);

                    if (field_types != null)
                    {
                        field_types.Add(ts.m.SystemIntPtr);
                    }
                    if (field_names != null)
                    {
                        field_names.Add("__vtbl");
                    }

                    // Add a mutex lock entry
                    if (field_offsets != null)
                    {
                        field_offsets.Add(cur_offset);
                    }
                    cur_offset += t.GetCTSize(ir.Opcode.ct_int64);
                    cur_offset  = util.util.align(cur_offset, align);

                    if (field_types != null)
                    {
                        field_types.Add(ts.m.SystemInt64);
                    }
                    if (field_names != null)
                    {
                        field_names.Add("__mutex_lock");
                    }
                }
                else
                {
                    cur_offset = GetFieldOffset(ts.GetExtends(), (string)null, t,
                                                out is_tls,
                                                is_static, field_types, field_names, field_offsets);
                    cur_offset = util.util.align(cur_offset, align);
                }
            }
            else if (is_static)
            {
                // Add an is_initalized field
                cur_offset += t.GetCTSize(ir.Opcode.ct_intptr);
                cur_offset  = util.util.align(cur_offset, align);
            }

            for (uint fdef_row = first_fdef; fdef_row < last_fdef; fdef_row++)
            {
                // Ensure field is static if requested
                var flags = ts.m.GetIntEntry(MetadataStream.tid_Field,
                                             (int)fdef_row, 0);
                if (((flags & 0x10) == 0x10 && is_static == true) ||
                    ((flags & 0x10) == 0 && is_static == false))
                {
                    // Check on name if we are looking for a particular field
                    bool f_is_tls = ts.m.thread_local_fields[fdef_row];
                    if (fname != null)
                    {
                        var ffname = ts.m.GetIntEntry(MetadataStream.tid_Field,
                                                      (int)fdef_row, 1);
                        if (MetadataStream.CompareString(ts.m, ffname, fname))
                        {
                            if (f_is_tls)
                            {
                                is_tls = true;
                                return(cur_tl_offset);
                            }
                            else
                            {
                                is_tls = false;
                                return(cur_offset);
                            }
                        }
                    }

                    // Increment by type size
                    var fsig = (int)ts.m.GetIntEntry(MetadataStream.tid_Field,
                                                     (int)fdef_row, 2);

                    var ft      = ts.m.GetFieldType(ref fsig, ts.gtparams, null);
                    var ft_size = t.GetSize(ft);

                    if (field_types != null)
                    {
                        field_types.Add(ft);
                    }
                    if (field_names != null)
                    {
                        var cur_fname = ts.m.GetStringEntry(MetadataStream.tid_Field,
                                                            (int)fdef_row, 1);
                        field_names.Add(cur_fname);
                    }
                    if (field_offsets != null)
                    {
                        if (f_is_tls)
                        {
                            field_offsets.Add(cur_tl_offset);
                        }
                        else
                        {
                            field_offsets.Add(cur_offset);
                        }
                    }

                    if (f_is_tls)
                    {
                        cur_tl_offset += ft_size;
                        cur_tl_offset  = util.util.align(cur_tl_offset, align);
                    }
                    else
                    {
                        cur_offset += ft_size;
                        cur_offset  = util.util.align(cur_offset, align);
                    }
                }
            }

            // Shouldn't get here if looking for a specific field
            if (fname != null)
            {
                throw new MissingFieldException();
            }

            // Else return size of complete type
            return(cur_offset);
        }
Example #10
0
        public static int GetFieldOffset(metadata.TypeSpec ts,
                                         metadata.MethodSpec fs, target.Target t, out bool is_tls, bool is_static = false)
        {
            int align = 1;

            is_tls = false;
            if (ts.SimpleType == 0 || ts.SimpleType == 0xe)      // class or string
            {
                align = GetTypeAlignment(ts, t, is_static);
            }

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

            uint search_field_name = 0;

            if (fs != null)
            {
                search_field_name = fs.m.GetIntEntry(MetadataStream.tid_Field,
                                                     fs.mdrow, 1);
            }

            int cur_offset    = 0;
            int cur_tl_offset = 0;

            if (is_static == false && !ts.IsValueType)
            {
                if (ts.GetExtends() == null)
                {
                    // Add a vtable entry
                    cur_offset += t.GetCTSize(ir.Opcode.ct_object);
                    cur_offset  = util.util.align(cur_offset, align);

                    // Add a mutex lock entry
                    cur_offset += t.GetCTSize(ir.Opcode.ct_int64);
                    cur_offset  = util.util.align(cur_offset, align);
                }
                else
                {
                    cur_offset = GetFieldOffset(ts.GetExtends(), (string)null, t, out is_tls);
                    cur_offset = util.util.align(cur_offset, align);
                }
            }
            else if (is_static)
            {
                // Add an is_initalized field
                cur_offset += t.GetCTSize(ir.Opcode.ct_intptr);
                cur_offset  = util.util.align(cur_offset, align);
            }

            for (uint fdef_row = first_fdef; fdef_row < last_fdef; fdef_row++)
            {
                // Ensure field is static if requested
                var flags = ts.m.GetIntEntry(MetadataStream.tid_Field,
                                             (int)fdef_row, 0);
                if (((flags & 0x10) == 0x10 && is_static == true) ||
                    ((flags & 0x10) == 0 && is_static == false))
                {
                    // Check on name if we are looking for a particular field
                    bool f_is_tls = ts.m.thread_local_fields[fdef_row];
                    if (search_field_name != 0)
                    {
                        var fname = ts.m.GetIntEntry(MetadataStream.tid_Field,
                                                     (int)fdef_row, 1);
                        if (MetadataStream.CompareString(ts.m, fname,
                                                         fs.m, search_field_name))
                        {
                            if (f_is_tls)
                            {
                                is_tls = true;
                                return(cur_tl_offset);
                            }
                            else
                            {
                                is_tls = false;
                                return(cur_offset);
                            }
                        }
                    }

                    // Increment by type size
                    var fsig = (int)ts.m.GetIntEntry(MetadataStream.tid_Field,
                                                     (int)fdef_row, 2);

                    var ft      = ts.m.GetFieldType(ref fsig, ts.gtparams, null);
                    var ft_size = t.GetSize(ft);

                    if (f_is_tls)
                    {
                        cur_tl_offset += ft_size;
                        cur_tl_offset  = util.util.align(cur_tl_offset, align);
                    }
                    else
                    {
                        cur_offset += ft_size;
                        cur_offset  = util.util.align(cur_offset, align);
                    }
                }
            }

            // Shouldn't get here if looking for a specific field
            if (search_field_name != 0)
            {
                throw new MissingFieldException();
            }

            // Else return size of complete type
            return(cur_offset);
        }
Example #11
0
 public static int GetArrayObjectSize(target.Target t)
 {
     // round up to 8x intptr size so size is aligned to word size
     return(8 * t.GetPointerSize());
 }
Example #12
0
 protected static target.Target.Reg DoAllocation(Code c, StackItem si, target.Target t, ref long alloced, ref int cur_stack)
 {
     si.reg = DoAllocation(c, si.ct, t, ref alloced, ref cur_stack);
     return(si.reg);
 }
Example #13
0
 static int get_object_pushtype(Opcode n, target.Target t)
 {
     return(ct_intptr);
 }
Example #14
0
        static int get_binnumop_pushtype(Opcode n, target.Target t)
        {
            var a = n.uses[0].ct;
            var b = n.uses[1].ct;

            switch (a)
            {
            case ct_int32:
                switch (b)
                {
                case ct_int32:
                    return(ct_int32);

                case ct_intptr:
                    return(ct_intptr);

                case ct_ref:
                    if (n.oc == oc_add)
                    {
                        return(ct_ref);
                    }
                    break;
                }
                break;

            case ct_int64:
                switch (b)
                {
                case ct_int64:
                    return(ct_int64);
                }
                break;

            case ct_intptr:
                switch (b)
                {
                case ct_int32:
                    return(ct_intptr);

                case ct_intptr:
                    return(ct_intptr);

                case ct_ref:
                    if (n.oc == oc_add)
                    {
                        return(ct_ref);
                    }
                    break;
                }
                break;

            case ct_float:
                switch (b)
                {
                case ct_float:
                    return(ct_float);
                }
                break;

            case ct_ref:
                switch (b)
                {
                case ct_int32:
                    if (n.oc == oc_add || n.oc == oc_sub)
                    {
                        return(ct_ref);
                    }
                    break;

                case ct_intptr:
                    if (n.oc == oc_add || n.oc == oc_sub)
                    {
                        return(ct_ref);
                    }
                    break;

                case ct_ref:
                    if (n.oc == oc_sub)
                    {
                        return(ct_intptr);
                    }
                    break;
                }
                break;
            }
            throw new NotSupportedException("Invalid opcode:" + n.ToString());
        }