Example #1
0
        private static void AddBaseType(IList <byte> d, TypeSpec ts, IBinaryFile of, ISection os, ref ulong offset, Target t,
                                        TysilaState s)
        {
            if (ts.other != null && ts.stype != TypeSpec.SpecialType.Boxed)
            {
                var bt = ts.other.Box;

                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 = bt.MangleType();

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

                s.r.VTableRequestor.Request(bt);
            }
            for (int i = 0; i < t.GetPointerSize(); i++, offset++)
            {
                d.Add(0);
            }
        }
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
        // TODO: Use ImplementInterface
        private static void OutputInterface(TypeSpec impl_ts,
                                            TypeSpec iface_ts, IBinaryFile of, ISection os,
                                            IList <byte> d, ref ulong offset, Target t,
                                            TysilaState s)
        {
            bool is_boxed = false;

            if (impl_ts.IsBoxed)
            {
                impl_ts  = impl_ts.Unbox;
                is_boxed = true;

                /* 'boxed' versions of each method should unbox the
                 * first parameter to a managed pointer then call
                 * the acutal method
                 */
            }
            /* Iterate through methods */
            var first_mdef = iface_ts.m.GetIntEntry(MetadataStream.tid_TypeDef,
                                                    iface_ts.tdrow, 5);
            var last_mdef = iface_ts.m.GetLastMethodDef(iface_ts.tdrow);

            for (uint mdef_row = first_mdef; mdef_row < last_mdef; mdef_row++)
            {
                MethodSpec iface_ms;
                MethodSpec impl_ms = null;
                iface_ts.m.GetMethodDefRow(MetadataStream.tid_MethodDef,
                                           (int)mdef_row, out iface_ms, iface_ts.gtparams, null);
                iface_ms.type = iface_ts;

                // First determine if there is a relevant MethodImpl entry
                for (int i = 1; i <= impl_ts.m.table_rows[MetadataStream.tid_MethodImpl]; i++)
                {
                    var Class = impl_ts.m.GetIntEntry(MetadataStream.tid_MethodImpl, i, 0);

                    if (Class == impl_ts.tdrow)
                    {
                        int mdecl_id, mdecl_row, mbody_id, mbody_row;
                        impl_ts.m.GetCodedIndexEntry(MetadataStream.tid_MethodImpl, i, 2,
                                                     impl_ts.m.MethodDefOrRef, out mdecl_id, out mdecl_row);
                        MethodSpec mdecl_ms;
                        impl_ts.m.GetMethodDefRow(mdecl_id, mdecl_row, out mdecl_ms, impl_ts.gtparams);

                        if (mdecl_ms.Equals(iface_ms))
                        {
                            impl_ts.m.GetCodedIndexEntry(MetadataStream.tid_MethodImpl, i, 1,
                                                         impl_ts.m.MethodDefOrRef, out mbody_id, out mbody_row);
                            impl_ts.m.GetMethodDefRow(mbody_id, mbody_row, out impl_ms, impl_ts.gtparams);
                            impl_ms.type = impl_ts;
                            break;
                        }
                    }
                }

                // Then iterate through all base classes looking for an implementation
                if (impl_ms == null)
                {
                    impl_ms = GetVirtualMethod(impl_ts, iface_ms, t, true);
                }

                if (iface_ms.MangleMethod().StartsWith("_ZW30System#2ECollections#2EGeneric13IEnumerable`1_G1") && impl_ts.stype == TypeSpec.SpecialType.SzArray)
                {
                    // Special case this so we get the generic IEnumerator<T> rather than the standard IEnumator from System.Array.GetEnumerator

                    // coreclr does something similar for _all_ T[] methods (see https://github.com/dotnet/coreclr/blob/release/2.0.0/src/mscorlib/src/System/Array.cs#L2577)
                    var szarrayhelper = iface_ms.m.GetTypeSpec("System", "SZArrayHelper");
                    var genum_ms      = iface_ms.m.GetMethodSpec(szarrayhelper, "GetEnumerator");
                    genum_ms.gmparams = new TypeSpec[] { impl_ts.other };
                    s.r.MethodRequestor.Request(genum_ms);
                    impl_ms = genum_ms;
                }

                // Vectors implement methods which we need to provide
                if (impl_ms == null && impl_ts.stype == TypeSpec.SpecialType.SzArray)
                {
                    // Build a new method that is based in the vector class
                    impl_ms      = iface_ms;
                    impl_ms.type = new TypeSpec
                    {
                        m        = impl_ts.m,
                        tdrow    = impl_ts.tdrow,
                        stype    = impl_ts.stype,
                        other    = impl_ts.other,
                        gtparams = iface_ms.type.gtparams
                    };
                }

                if (impl_ms != null)
                {
                    if (impl_ms.ReturnType != null && impl_ms.ReturnType.IsValueType && t.NeedsBoxRetType(impl_ms) && (iface_ms.ReturnType == null || (iface_ms.ReturnType != null && !iface_ms.ReturnType.IsValueType)))
                    {
                        impl_ms = impl_ms.Clone();
                        impl_ms.ret_type_needs_boxing = true;
                        s.r.BoxedMethodRequestor.Request(impl_ms);
                    }
                    else if (is_boxed)
                    {
                        impl_ms.is_boxed = true;
                        s.r.BoxedMethodRequestor.Request(impl_ms);
                    }
                    else
                    {
                        s.r.MethodRequestor.Request(impl_ms);
                    }
                }

                // Output reference
                string impl_target = (impl_ms == null) ? "__cxa_pure_virtual" : impl_ms.MangleMethod();
                //if(impl_ms == null)
                //{
                //    System.Diagnostics.Debugger.Break();
                //    var test = GetVirtualMethod(impl_ts, iface_ms, t, true);
                //}

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