/// <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); }
/// <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(); }
/// <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()); }
/// <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()); }