예제 #1
0
        private LinkerSymbol CreateMethodDefinition(MosaMethod method)
        {
            // Emit method name
            var methodNameSymbol = EmitStringWithLength(method.FullName + Metadata.NameString, method.FullName);

            // Emit method table
            var methodTableSymbol = Linker.CreateSymbol(method.FullName + Metadata.MethodDefinition, SectionKind.ROData, TypeLayout.NativePointerAlignment, 0);
            var writer1           = new EndianAwareBinaryWriter(methodTableSymbol.Stream, Architecture.Endianness);

            // 1. Pointer to Name
            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, (int)writer1.Position, 0, methodNameSymbol, 0);
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 2. Pointer to Custom Attributes
            if (method.CustomAttributes.Count > 0)
            {
                var customAttributeListSymbol = CreateCustomAttributesTable(method);
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, (int)writer1.Position, 0, customAttributeListSymbol, 0);
            }
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 3. Attributes
            writer1.Write((uint)method.MethodAttributes, TypeLayout.NativePointerSize);

            // 4. Local Stack Size (16 Bits) && Parameter Stack Size (16 Bits)
            int value = TypeLayout.GetMethodStackSize(method) | (TypeLayout.GetMethodParameterStackSize(method) << 16);

            writer1.Write(value, TypeLayout.NativePointerSize);

            // 5. Pointer to Method
            if (!method.IsAbstract)
            {
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, (int)writer1.Position, 0, method.FullName, SectionKind.Text, 0);
            }
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 6. Pointer to return type
            Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, (int)writer1.Position, 0, method.Signature.ReturnType.FullName + Metadata.TypeDefinition, SectionKind.ROData, 0);
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 7. Pointer to Exception Handler Table
            if (method.ExceptionHandlers.Count != 0)
            {
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, (int)writer1.Position, 0, method.FullName + Metadata.ProtectedRegionTable, SectionKind.ROData, 0);
            }
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 8. Pointer to GC Tracking information
            // TODO: This has yet to be designed.
            writer1.WriteZeroBytes(TypeLayout.NativePointerSize);

            // 9. Number of Parameters
            writer1.Write((uint)method.Signature.Parameters.Count, TypeLayout.NativePointerSize);

            // 10. Pointers to Parameter Definitions
            foreach (var parameter in method.Signature.Parameters)
            {
                // Create definition and get the symbol
                var parameterDefinitionSymbol = CreateParameterDefinition(parameter);

                // Link
                Linker.Link(LinkType.AbsoluteAddress, NativePatchType, methodTableSymbol, (int)writer1.Position, 0, parameterDefinitionSymbol, 0);
                writer1.WriteZeroBytes(TypeLayout.NativePointerSize);
            }

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