Esempio n. 1
0
        /// <summary>
        /// Output C++ code via a given dependency graph
        /// </summary>
        /// <param name="nodes">A set of dependency nodes</param>
        /// <param name="entrypoint">Code entrypoint</param>
        /// <param name="factory">Associated NodeFactory instance</param>
        /// <param name="definitions">Text buffer in which the type and method definitions will be written</param>
        /// <param name="implementation">Text buffer in which the method implementations will be written</param>
        public void OutputNodes(IEnumerable<DependencyNode> nodes, NodeFactory factory)
        {
            CppGenerationBuffer dispatchPointers = new CppGenerationBuffer();
            CppGenerationBuffer forwardDefinitions = new CppGenerationBuffer();
            CppGenerationBuffer typeDefinitions = new CppGenerationBuffer();
            CppGenerationBuffer methodTables = new CppGenerationBuffer();
            CppGenerationBuffer additionalNodes = new CppGenerationBuffer();
            DependencyNodeIterator nodeIterator = new DependencyNodeIterator(nodes);

            // Number of InterfaceDispatchMapNodes needs to be declared explicitly for Ubuntu and OSX
            int dispatchMapCount = 0;
            dispatchPointers.AppendLine();
            dispatchPointers.Indent();

            //RTR header needs to be declared after all modules have already been output
            string rtrHeader = string.Empty;

            // Iterate through nodes
            foreach (var node in nodeIterator.GetNodes())
            {
                if (node is EETypeNode)
                    OutputTypeNode(node as EETypeNode, factory, forwardDefinitions, typeDefinitions, methodTables);
                else if ((node is EETypeOptionalFieldsNode || node is TypeManagerIndirectionNode || node is GenericCompositionNode) && !(node as ObjectNode).ShouldSkipEmittingObjectNode(factory))
                    additionalNodes.Append(GetCodeForObjectNode(node as ObjectNode, factory));
                else if (node is InterfaceDispatchMapNode)
                {
                    dispatchPointers.Append("(void *)");
                    dispatchPointers.Append(((ISymbolNode)node).GetMangledName());
                    dispatchPointers.Append("(),");
                    dispatchPointers.AppendLine();
                    dispatchMapCount++;
                    additionalNodes.Append(GetCodeForObjectNode(node as ObjectNode, factory));

                }
                else if (node is ReadyToRunHeaderNode)
                    rtrHeader = GetCodeForReadyToRunHeader(node as ReadyToRunHeaderNode, factory);
            }

            dispatchPointers.AppendLine();
            dispatchPointers.Exdent();

            Out.Write(forwardDefinitions.ToString());

            Out.Write(typeDefinitions.ToString());

            Out.Write(additionalNodes.ToString());

            Out.Write(methodTables.ToString());

            // Emit pointers to dispatch map nodes, to be used in interface dispatch
            Out.Write("void * dispatchMapModule[");
            Out.Write(dispatchMapCount);
            Out.Write("] = {");
            Out.Write(dispatchPointers.ToString());
            Out.Write("};");

            Out.Write(rtrHeader);
        }
Esempio n. 2
0
        /// <summary>
        /// Output C++ code via a given dependency graph
        /// </summary>
        /// <param name="nodes">A set of dependency nodes</param>
        /// <param name="entrypoint">Code entrypoint</param>
        /// <param name="factory">Associated NodeFactory instance</param>
        /// <param name="definitions">Text buffer in which the type and method definitions will be written</param>
        /// <param name="implementation">Text buffer in which the method implementations will be written</param>
        public void OutputNodes(IEnumerable<DependencyNode> nodes, MethodDesc entrypoint, NodeFactory factory, CppGenerationBuffer definitions, CppGenerationBuffer implementation)
        {
            CppGenerationBuffer forwardDefinitions = new CppGenerationBuffer();
            CppGenerationBuffer typeDefinitions = new CppGenerationBuffer();
            CppGenerationBuffer methodTables = new CppGenerationBuffer();
            CppGenerationBuffer optionalFields = new CppGenerationBuffer();
            DependencyNodeIterator nodeIterator = new DependencyNodeIterator(nodes);
            // Output well-known types to avoid build errors

            if (_wellKnownTypeNodes != null)
            {
                foreach (var wellKnownTypeNode in _wellKnownTypeNodes)
                {
                    OutputTypeNode(wellKnownTypeNode, factory, forwardDefinitions, typeDefinitions, methodTables);
                }
            }
            // Iterate through nodes
            foreach (var node in nodeIterator.GetNodes())
            {
                if (node is EETypeNode && !_emittedTypes.Contains(((EETypeNode)node).Type))
                    OutputTypeNode(node as EETypeNode, factory, forwardDefinitions, typeDefinitions, methodTables);

                else if (node is CppMethodCodeNode)
                    OutputMethodNode(node as CppMethodCodeNode, implementation);

                else if (node is EETypeOptionalFieldsNode)
                    optionalFields.Append(GetCodeForObjectNode(node as EETypeOptionalFieldsNode, factory));
            }

            definitions.Append(forwardDefinitions.ToString());
            forwardDefinitions.Clear();
            definitions.Append(typeDefinitions.ToString());
            typeDefinitions.Clear();
            definitions.Append(methodTables.ToString());
            methodTables.Clear();
            definitions.Append(optionalFields.ToString());
            optionalFields.Clear();
        }
Esempio n. 3
0
        /// <summary>
        /// Output C++ code via a given dependency graph
        /// </summary>
        /// <param name="nodes">A set of dependency nodes</param>
        /// <param name="entrypoint">Code entrypoint</param>
        /// <param name="factory">Associated NodeFactory instance</param>
        private void OutputNodes(IEnumerable<DependencyNode> nodes, NodeFactory factory)
        {
            CppGenerationBuffer forwardDefinitions = new CppGenerationBuffer();
            CppGenerationBuffer typeDefinitions = new CppGenerationBuffer();
            CppGenerationBuffer methodTables = new CppGenerationBuffer();
            CppGenerationBuffer optionalFields = new CppGenerationBuffer();
            DependencyNodeIterator nodeIterator = new DependencyNodeIterator(nodes, factory);

            // Output well-known types to avoid build errors
            if (_wellKnownTypeNodes != null)
            {
                foreach (var wellKnownTypeNode in _wellKnownTypeNodes)
                {
                    OutputTypeNode(wellKnownTypeNode, factory, forwardDefinitions, typeDefinitions, methodTables);
                }
            }

            // Iterate through nodes
            foreach (var node in nodeIterator.GetNodes())
            {
                if (node is EETypeNode && !_emittedTypes.Contains(((EETypeNode)node).Type))
                    OutputTypeNode(node as EETypeNode, factory, forwardDefinitions, typeDefinitions, methodTables);

                else if (node is EETypeOptionalFieldsNode)
                    optionalFields.Append(GetCodeForObjectNode(node as EETypeOptionalFieldsNode, factory));
            }

            Out.Write(forwardDefinitions.ToString());
            Out.Write(typeDefinitions.ToString());
            Out.Write(methodTables.ToString());
            Out.Write(optionalFields.ToString());
        }
Esempio n. 4
0
        /// <summary>
        /// Output C++ code via a given dependency graph
        /// </summary>
        /// <param name="nodes">A set of dependency nodes</param>
        /// <param name="entrypoint">Code entrypoint</param>
        /// <param name="factory">Associated NodeFactory instance</param>
        private void OutputNodes(IEnumerable<DependencyNode> nodes, NodeFactory factory)
        {
            CppGenerationBuffer forwardDefinitions = new CppGenerationBuffer();
            CppGenerationBuffer typeDefinitions = new CppGenerationBuffer();
            CppGenerationBuffer methodTables = new CppGenerationBuffer();
            CppGenerationBuffer optionalFields = new CppGenerationBuffer();
            DependencyNodeIterator nodeIterator = new DependencyNodeIterator(nodes, factory);

            // Output well-known types to avoid build errors
            if (_wellKnownTypeNodes != null)
            {
                foreach (var wellKnownTypeNode in _wellKnownTypeNodes)
                {
                    OutputTypeNode(wellKnownTypeNode, factory, forwardDefinitions, typeDefinitions, methodTables);
                }
            }

            // Iterate through nodes
            foreach (var node in nodeIterator.GetNodes())
            {
                if (node is EETypeNode && !_emittedTypes.Contains(((EETypeNode)node).Type))
                    OutputTypeNode(node as EETypeNode, factory, forwardDefinitions, typeDefinitions, methodTables);

                // TODO: Remove the need for the skip check
                // https://github.com/dotnet/corert/issues/1826
                else if (node is EETypeOptionalFieldsNode && (node as ObjectNode).ShouldSkipEmittingObjectNode(factory))
                    optionalFields.Append(GetCodeForObjectNode(node as EETypeOptionalFieldsNode, factory));
            }

            Out.Write(forwardDefinitions.ToString());
            Out.Write(typeDefinitions.ToString());
            Out.Write(methodTables.ToString());
            Out.Write(optionalFields.ToString());
        }