Beispiel #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>
        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());
        }
Beispiel #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, 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(factory.NameMangler));
                    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);
        }