Пример #1
0
        private String GetCodeForObjectNode(ObjectNode node, NodeFactory factory)
        {
            // virtual slots
            var nodeData = node.GetData(factory, false);

            CppGenerationBuffer nodeCode = new CppGenerationBuffer();

            /* Create list of byte data. Used to divide contents between reloc and byte data
          * First val - isReloc
          * Second val - size of byte data if first value of tuple is false
          */

            List<NodeDataSection> nodeDataSections = new List<NodeDataSection>();
            byte[] actualData = new byte[nodeData.Data.Length];
            Relocation[] relocs = nodeData.Relocs;

            int nextRelocOffset = -1;
            int nextRelocIndex = -1;
            int lastByteIndex = 0;

            if (relocs.Length > 0)
            {
                nextRelocOffset = relocs[0].Offset;
                nextRelocIndex = 0;
            }

            int i = 0;
            int offset = 0;
            CppGenerationBuffer nodeDataDecl = new CppGenerationBuffer();

            if (node is ISymbolNode)
            {
                offset = (node as ISymbolNode).Offset;
                i = offset;
                lastByteIndex = offset;
            }
            while (i < nodeData.Data.Length)
            {
                if (i == nextRelocOffset)
                {
                    Relocation reloc = relocs[nextRelocIndex];

                    int size = _compilation.TypeSystemContext.Target.PointerSize;
                    // Make sure we've gotten the correct size for the reloc
                    System.Diagnostics.Debug.Assert(reloc.RelocType == (size == 8 ? RelocType.IMAGE_REL_BASED_DIR64 : RelocType.IMAGE_REL_BASED_HIGHLOW));

                    // Update nextRelocIndex/Offset
                    if (++nextRelocIndex < relocs.Length)
                    {
                        nextRelocOffset = relocs[nextRelocIndex].Offset;
                    }
                    nodeDataSections.Add(new NodeDataSection(NodeDataSectionType.Relocation, size));
                    i += size;
                    lastByteIndex = i;
                }
                else
                {
                    i++;
                    if (i + 1 == nextRelocOffset || i + 1 == nodeData.Data.Length)
                    {
                        nodeDataSections.Add(new NodeDataSection(NodeDataSectionType.ByteData, (i + 1) - lastByteIndex));
                    }
                }
            }

            nodeCode.Append("MethodTable * ");
            if (node is EETypeNode)
            {
                nodeCode.Append(GetCppMethodDeclarationName((node as EETypeNode).Type, "__getMethodTable"));
            }
            else
            {
                nodeCode.Append(node.GetName());
            }
            nodeCode.Append("()");
            nodeCode.AppendLine();
            nodeCode.Append("{");
            nodeCode.Indent();
            nodeCode.AppendLine();
            nodeCode.Append("static struct {");

            nodeCode.AppendLine();
            nodeCode.Append(GetCodeForNodeStruct(nodeDataSections, node));

            nodeCode.AppendLine();
            nodeCode.Append("} mt = {");
            nodeCode.Append(GetCodeForNodeData(nodeDataSections, relocs, nodeData.Data, node, offset));

            nodeCode.Append("};");
            nodeCode.AppendLine();
            nodeCode.Append("return (MethodTable *)&mt;");
            nodeCode.Exdent();
            nodeCode.AppendLine();
            nodeCode.Append("}");

            return nodeCode.ToString();
        }
Пример #2
0
        private String GetCodeForObjectNode(ObjectNode node, NodeFactory factory)
        {
            // virtual slots
            var nodeData = node.GetData(factory, false);

            CppGenerationBuffer nodeCode = new CppGenerationBuffer();

            /* Create list of byte data. Used to divide contents between reloc and byte data
             * First val - isReloc
             * Second val - size of byte data if first value of tuple is false
             */

            List <NodeDataSection> nodeDataSections = new List <NodeDataSection>();

            byte[]       actualData = new byte[nodeData.Data.Length];
            Relocation[] relocs     = nodeData.Relocs;

            int nextRelocOffset = -1;
            int nextRelocIndex  = -1;
            int lastByteIndex   = 0;

            if (relocs.Length > 0)
            {
                nextRelocOffset = relocs[0].Offset;
                nextRelocIndex  = 0;
            }

            int i      = 0;
            int offset = 0;
            CppGenerationBuffer nodeDataDecl = new CppGenerationBuffer();

            if (node is ISymbolNode)
            {
                offset        = (node as ISymbolNode).Offset;
                i             = offset;
                lastByteIndex = offset;
            }
            while (i < nodeData.Data.Length)
            {
                if (i == nextRelocOffset)
                {
                    Relocation reloc = relocs[nextRelocIndex];

                    int size = _compilation.TypeSystemContext.Target.PointerSize;
                    // Make sure we've gotten the correct size for the reloc
                    System.Diagnostics.Debug.Assert(reloc.RelocType == (size == 8 ? RelocType.IMAGE_REL_BASED_DIR64 : RelocType.IMAGE_REL_BASED_HIGHLOW));

                    // Update nextRelocIndex/Offset
                    if (++nextRelocIndex < relocs.Length)
                    {
                        nextRelocOffset = relocs[nextRelocIndex].Offset;
                    }
                    nodeDataSections.Add(new NodeDataSection(NodeDataSectionType.Relocation, size));
                    i            += size;
                    lastByteIndex = i;
                }
                else
                {
                    i++;
                    if (i + 1 == nextRelocOffset || i + 1 == nodeData.Data.Length)
                    {
                        nodeDataSections.Add(new NodeDataSection(NodeDataSectionType.ByteData, (i + 1) - lastByteIndex));
                    }
                }
            }

            nodeCode.Append("MethodTable * ");
            if (node is EETypeNode)
            {
                nodeCode.Append(GetCppMethodDeclarationName((node as EETypeNode).Type, "__getMethodTable"));
            }
            else
            {
                nodeCode.Append(node.GetName());
            }
            nodeCode.Append("()");
            nodeCode.AppendLine();
            nodeCode.Append("{");
            nodeCode.Indent();
            nodeCode.AppendLine();
            nodeCode.Append("static struct {");

            nodeCode.AppendLine();
            nodeCode.Append(GetCodeForNodeStruct(nodeDataSections, node));

            nodeCode.AppendLine();
            nodeCode.Append("} mt = {");
            nodeCode.Append(GetCodeForNodeData(nodeDataSections, relocs, nodeData.Data, node, offset));

            nodeCode.Append("};");
            nodeCode.AppendLine();
            nodeCode.Append("return (MethodTable *)&mt;");
            nodeCode.Exdent();
            nodeCode.AppendLine();
            nodeCode.Append("}");

            return(nodeCode.ToString());
        }