Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs')
-rw-r--r--src/ILCompiler.CppCodeGen/src/CppCodeGen/CppWriter.cs150
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();