protected override void RunPostCompile()
        {
            foreach (var type in TypeSystem.AllTypes)
            {
                foreach (var field in type.Fields)
                {
                    if (!field.IsStatic)
                    {
                        continue;
                    }

                    if (!Compiler.MethodScanner.IsFieldAccessed(field))
                    {
                        continue;
                    }

                    var section = field.Data != null ? SectionKind.ROData : SectionKind.BSS;
                    int size    = TypeLayout.GetFieldSize(field);

                    var symbol = Compiler.Linker.DefineSymbol(field.FullName, section, Architecture.NativeAlignment, size);

                    if (field.Data != null)
                    {
                        symbol.Stream.Write(field.Data, 0, size);
                    }
                }
            }
        }
Example #2
0
        private LinkerSymbol CreateFieldDefinitions(MosaType type)
        {
            // Emit fields table
            var fieldsTableSymbol = Linker.CreateSymbol(type.FullName + Metadata.FieldsTable, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
            var writer1           = new EndianAwareBinaryWriter(fieldsTableSymbol.Stream, Architecture.Endianness);

            // 1. Number of Fields
            writer1.Write((uint)type.Fields.Count, TypeLayout.NativePointerSize);

            // 2. Pointers to Field Definitions
            foreach (MosaField field in type.Fields)
            {
                // Emit field name
                var fieldNameSymbol = EmitStringWithLength(field.FullName + Metadata.NameString, field.Name);

                // Emit field definition
                var fieldDefSymbol = Linker.CreateSymbol(field.FullName + Metadata.FieldDefinition, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
                var writer2        = new EndianAwareBinaryWriter(fieldDefSymbol.Stream, Architecture.Endianness);

                // 1. Name
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldDefSymbol, (int)writer2.Position, 0, fieldNameSymbol, 0);
                writer2.WriteZeroBytes(TypeLayout.NativePointerSize);

                // 2. Pointer to Custom Attributes
                if (field.CustomAttributes.Count > 0)
                {
                    var customAttributesTableSymbol = CreateCustomAttributesTable(field);
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldDefSymbol, (int)writer2.Position, 0, customAttributesTableSymbol, 0);
                }
                writer2.WriteZeroBytes(TypeLayout.NativePointerSize);

                // 3. Attributes
                writer2.Write((uint)field.FieldAttributes, TypeLayout.NativePointerSize);

                // 4. Pointer to Field Type
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldDefSymbol, (int)writer2.Position, 0, field.FieldType.FullName + Metadata.TypeDefinition, SectionKind.ROData, 0);
                writer2.WriteZeroBytes(TypeLayout.NativePointerSize);

                // 5 & 6. Offset / Address + Size
                if (field.IsStatic && !field.IsLiteral)
                {
                    var section = (field.Data != null) ? SectionKind.ROData : SectionKind.BSS;
                    Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldDefSymbol, (int)writer2.Position, 0, field.FullName, section, 0);
                    writer2.WriteZeroBytes(TypeLayout.NativePointerSize);
                    writer2.Write((field.Data != null) ? field.Data.Length : 0, TypeLayout.NativePointerSize);
                }
                else
                {
                    writer2.WriteZeroBytes(TypeLayout.NativePointerSize);
                    writer2.Write(TypeLayout.GetFieldOffset(field), TypeLayout.NativePointerSize);
                }

                // Create another symbol with field data if any
                if (field.IsStatic)
                {
                    // Assign a memory slot to the static & initialize it, if there's initial data set
                    // Determine the size of the type & alignment requirements
                    int size, alignment;
                    Architecture.GetTypeRequirements(TypeLayout, field.FieldType, out size, out alignment);

                    size = TypeLayout.GetFieldSize(field);

                    // The linker section to move this field into
                    SectionKind section = field.Data != null ? section = SectionKind.ROData : section = SectionKind.BSS;

                    var symbol = Compiler.Linker.CreateSymbol(field.FullName, section, alignment, size);

                    if (field.Data != null)
                    {
                        symbol.Stream.Write(field.Data, 0, size);
                    }
                }

                // Add pointer to field list
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, fieldsTableSymbol, (int)writer1.Position, 0, fieldDefSymbol, 0);
                writer1.WriteZeroBytes(TypeLayout.NativePointerSize);
            }

            // Return fieldsTableSymbol for linker usage
            return(fieldsTableSymbol);
        }