diff options
Diffstat (limited to 'src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs')
-rw-r--r-- | src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs | 150 |
1 files changed, 86 insertions, 64 deletions
diff --git a/src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs b/src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs index ef08550b7..c813492bf 100644 --- a/src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs +++ b/src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs @@ -15,6 +15,8 @@ using Internal.Text; using Internal.TypeSystem; using Internal.TypeSystem.Ecma; +using Debug = System.Diagnostics.Debug; + namespace ILCompiler.CppCodeGen { internal class CppWriter @@ -586,17 +588,17 @@ namespace ILCompiler.CppCodeGen if (explicitLayout || hasSize) { - if (classLayoutMetadata.Size > 0) + if (!explicitLayout) { + sb.Exdent(); sb.AppendLine(); - sb.Append("struct { char __sizePadding[" + classLayoutMetadata.Size + "]; };"); + sb.Append("};"); } - if (!explicitLayout) + if (classLayoutMetadata.Size > 0) { - sb.Exdent(); sb.AppendLine(); - sb.Append("};"); + sb.Append("struct { char __sizePadding[" + classLayoutMetadata.Size + "]; };"); } sb.Exdent(); @@ -797,42 +799,61 @@ namespace ILCompiler.CppCodeGen } } } + + bool generateMethod = !(node is BlobNode); + string pointerType = node is EETypeNode ? "MethodTable * " : "void* "; - nodeCode.Append(pointerType); - if (node is EETypeNode) + if (generateMethod) { - nodeCode.Append(GetCppMethodDeclarationName((node as EETypeNode).Type, "__getMethodTable")); + nodeCode.Append(pointerType); + if (node is EETypeNode) + { + nodeCode.Append(GetCppMethodDeclarationName((node as EETypeNode).Type, "__getMethodTable")); + } + else + { + string mangledName = ((ISymbolNode)node).GetMangledName(factory.NameMangler); + + // Rename generic composition and optional fields nodes to avoid name clash with types + bool shouldReplaceNamespaceQualifier = node is GenericCompositionNode || node is EETypeOptionalFieldsNode || node is SealedVTableNode; + nodeCode.Append(shouldReplaceNamespaceQualifier ? mangledName.Replace("::", "_") : mangledName); + } + nodeCode.Append("()"); + nodeCode.AppendLine(); + nodeCode.Append("{"); + nodeCode.Indent(); + nodeCode.AppendLine(); + nodeCode.Append("static "); } else { - string mangledName = ((ISymbolNode)node).GetMangledName(factory.NameMangler); - - // Rename generic composition and optional fields nodes to avoid name clash with types - bool shouldReplaceNamespaceQualifier = node is GenericCompositionNode || node is EETypeOptionalFieldsNode; - nodeCode.Append(shouldReplaceNamespaceQualifier ? mangledName.Replace("::", "_") : mangledName); + nodeCode.Append("extern \"C\" "); } - nodeCode.Append("()"); - nodeCode.AppendLine(); - nodeCode.Append("{"); - nodeCode.Indent(); - nodeCode.AppendLine(); - nodeCode.Append("static struct {"); + nodeCode.Append("struct {"); nodeCode.AppendLine(); nodeCode.Append(GetCodeForNodeStruct(nodeDataSections, node)); nodeCode.AppendLine(); - nodeCode.Append("} mt = {"); + + if (generateMethod) + nodeCode.Append("} mt = {"); + else + nodeCode.Append(" } " + ((ISymbolNode)node).GetMangledName(factory.NameMangler) + " = {"); nodeCode.Append(GetCodeForNodeData(nodeDataSections, relocs, nodeData.Data, node, offset, factory)); nodeCode.Append("};"); - nodeCode.AppendLine(); - nodeCode.Append("return ( "); - nodeCode.Append(pointerType); - nodeCode.Append(")&mt;"); - nodeCode.Exdent(); - nodeCode.AppendLine(); - nodeCode.Append("}"); + + if (generateMethod) + { + nodeCode.AppendLine(); + nodeCode.Append("return ( "); + nodeCode.Append(pointerType); + nodeCode.Append(")&mt;"); + nodeCode.Exdent(); + nodeCode.AppendLine(); + nodeCode.Append("}"); + } nodeCode.AppendLine(); return nodeCode.ToString(); } @@ -882,10 +903,15 @@ namespace ILCompiler.CppCodeGen relocCode.Append("()"); } // Node is either an non-emitted type or a generic composition - both are ignored for CPP codegen - else if ((reloc.Target is TypeManagerIndirectionNode || reloc.Target is InterfaceDispatchMapNode || reloc.Target is EETypeOptionalFieldsNode || reloc.Target is GenericCompositionNode) && !(reloc.Target as ObjectNode).ShouldSkipEmittingObjectNode(factory)) + else if ((reloc.Target is TypeManagerIndirectionNode || + reloc.Target is InterfaceDispatchMapNode || + reloc.Target is EETypeOptionalFieldsNode || + reloc.Target is GenericCompositionNode || + reloc.Target is SealedVTableNode + ) && !(reloc.Target as ObjectNode).ShouldSkipEmittingObjectNode(factory)) { string mangledTargetName = reloc.Target.GetMangledName(factory.NameMangler); - bool shouldReplaceNamespaceQualifier = reloc.Target is GenericCompositionNode || reloc.Target is EETypeOptionalFieldsNode; + bool shouldReplaceNamespaceQualifier = reloc.Target is GenericCompositionNode || reloc.Target is EETypeOptionalFieldsNode || reloc.Target is SealedVTableNode; relocCode.Append(shouldReplaceNamespaceQualifier ? mangledTargetName.Replace("::", "_") : mangledTargetName); relocCode.Append("()"); } @@ -894,12 +920,12 @@ namespace ILCompiler.CppCodeGen { relocCode.Append("dispatchMapModule"); } - else if(reloc.Target is UnboxingStubNode) + else if(reloc.Target is CppUnboxingStubNode) { - var method = reloc.Target as UnboxingStubNode; + var method = reloc.Target as CppUnboxingStubNode; relocCode.Append("(void*)&"); - relocCode.Append(GetCppMethodDeclarationName(method.Method.OwningType, UnboxingStubNode.GetMangledName(factory.NameMangler, method.Method), false)); + relocCode.Append(GetCppMethodDeclarationName(method.Method.OwningType, method.GetMangledName(factory.NameMangler), false)); } else { @@ -1011,26 +1037,30 @@ namespace ILCompiler.CppCodeGen //RTR header needs to be declared after all modules have already been output string rtrHeader = string.Empty; - // GetData stabilizes the indices of the embedded objects. This must be done manually - // for C++ codegen since we don't currently emit the DispatchMapTable node directly. - factory.DispatchMapTable.GetData(factory, false); - // Iterate through nodes foreach (var node in nodeIterator.GetNodes()) { if (node is EETypeNode) OutputTypeNode(node as EETypeNode, factory, typeDefinitions, methodTables); - else if ((node is EETypeOptionalFieldsNode || node is TypeManagerIndirectionNode || node is GenericCompositionNode) && !(node as ObjectNode).ShouldSkipEmittingObjectNode(factory)) + else if ((node is EETypeOptionalFieldsNode || + node is TypeManagerIndirectionNode || + node is GenericCompositionNode || + node is BlobNode || + node is SealedVTableNode) && !(node as ObjectNode).ShouldSkipEmittingObjectNode(factory)) additionalNodes.Append(GetCodeForObjectNode(node as ObjectNode, factory)); - else if (node is InterfaceDispatchMapNode) + else if (node is ArrayOfEmbeddedPointersNode<InterfaceDispatchMapNode> dispatchMap) { - dispatchPointers.Append("(void *)"); - dispatchPointers.Append(((ISymbolNode)node).GetMangledName(factory.NameMangler)); - dispatchPointers.Append("(),"); - dispatchPointers.AppendLine(); - dispatchMapCount++; - additionalNodes.Append(GetCodeForObjectNode(node as ObjectNode, factory)); - + var dispatchMapData = dispatchMap.GetData(factory, false); + Debug.Assert(dispatchMapData.Relocs.Length == dispatchMapData.Data.Length / factory.Target.PointerSize); + foreach (Relocation reloc in dispatchMapData.Relocs) + { + dispatchPointers.Append("(void *)"); + dispatchPointers.Append(reloc.Target.GetMangledName(factory.NameMangler)); + dispatchPointers.Append("(),"); + dispatchPointers.AppendLine(); + dispatchMapCount++; + additionalNodes.Append(GetCodeForObjectNode(reloc.Target as ObjectNode, factory)); + } } else if (node is ReadyToRunHeaderNode) rtrHeader = GetCodeForReadyToRunHeader(node as ReadyToRunHeaderNode, factory); @@ -1202,23 +1232,15 @@ namespace ILCompiler.CppCodeGen if (typeNode is ConstructedEETypeNode) { - IReadOnlyList<MethodDesc> virtualSlots = _compilation.NodeFactory.VTable(nodeType.GetClosestDefType()).Slots; + DefType closestDefType = nodeType.GetClosestDefType(); - int baseSlots = 0; - var baseType = nodeType.BaseType; - while (baseType != null) - { - IReadOnlyList<MethodDesc> baseVirtualSlots = _compilation.NodeFactory.VTable(baseType).Slots; - if (baseVirtualSlots != null) - baseSlots += baseVirtualSlots.Count; - baseType = baseType.BaseType; - } + IReadOnlyList<MethodDesc> virtualSlots = _compilation.NodeFactory.VTable(closestDefType).Slots; - for (int slot = 0; slot < virtualSlots.Count; slot++) + foreach (MethodDesc slot in virtualSlots) { - MethodDesc virtualMethod = virtualSlots[slot]; typeDefinitions.AppendLine(); - typeDefinitions.Append(GetCodeForVirtualMethod(virtualMethod, baseSlots + slot)); + int slotNumber = VirtualMethodSlotHelper.GetVirtualMethodSlot(_compilation.NodeFactory, slot, closestDefType); + typeDefinitions.Append(GetCodeForVirtualMethod(slot, slotNumber)); } if (nodeType.IsDelegate) @@ -1242,7 +1264,7 @@ namespace ILCompiler.CppCodeGen typeDefinitions.AppendLine(); AppendCppMethodDeclaration(typeDefinitions, m, false); typeDefinitions.AppendLine(); - AppendCppMethodDeclaration(typeDefinitions, m, false, null, null, UnboxingStubNode.GetMangledName(factory.NameMangler, m)); + AppendCppMethodDeclaration(typeDefinitions, m, false, null, null, CppUnboxingStubNode.GetMangledName(factory.NameMangler, m)); } } @@ -1274,7 +1296,7 @@ namespace ILCompiler.CppCodeGen rtrHeader.Append(GetCodeForObjectNode(headerNode, factory)); rtrHeader.AppendLine(); - rtrHeader.Append("void* RtRHeaderWrapper() {"); + rtrHeader.Append("extern \"C\" void* RtRHeaderWrapper() {"); rtrHeader.Indent(); rtrHeader.AppendLine(); rtrHeader.Append("static struct {"); @@ -1342,13 +1364,13 @@ namespace ILCompiler.CppCodeGen /// </summary> /// <param name="unboxingStubNode">The unboxing stub node to be output</param> /// <param name="methodImplementations">The buffer in which to write out the C++ code</param> - private void OutputUnboxingStubNode(UnboxingStubNode unboxingStubNode) + private void OutputUnboxingStubNode(CppUnboxingStubNode unboxingStubNode) { Out.WriteLine(); CppGenerationBuffer sb = new CppGenerationBuffer(); sb.AppendLine(); - AppendCppMethodDeclaration(sb, unboxingStubNode.Method, true, null, null, UnboxingStubNode.GetMangledName(_compilation.NameMangler, unboxingStubNode.Method)); + AppendCppMethodDeclaration(sb, unboxingStubNode.Method, true, null, null, unboxingStubNode.GetMangledName(_compilation.NameMangler)); sb.AppendLine(); sb.Append("{"); sb.Indent(); @@ -1405,8 +1427,8 @@ namespace ILCompiler.CppCodeGen { if (node is CppMethodCodeNode) OutputMethodNode(node as CppMethodCodeNode); - else if (node is UnboxingStubNode) - OutputUnboxingStubNode(node as UnboxingStubNode); + else if (node is CppUnboxingStubNode) + OutputUnboxingStubNode(node as CppUnboxingStubNode); } Out.Dispose(); |