diff options
author | Jan Kotas <jkotas@microsoft.com> | 2015-12-01 10:12:23 +0300 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2015-12-18 01:31:34 +0300 |
commit | 5323536d0b3dfbe8ea28b9adc1812677317d8392 (patch) | |
tree | 98f21149a5f11031f8367f92953eb0c8cf72073f /src/ILCompiler.Compiler | |
parent | 48eb9926db083dadb98fc0e676449ffa3e9465a6 (diff) |
Native compilation of Runtime.Base
- For now - until we have the proper multifile compilation in place, link the Runtime.Base .cs files into System.Private.CoreLib. The proper factoring of Runtime.Base is still guaranteed by building Runtime.Base as separate .dll.
- Remove many stubbed out helpers since the proper implementation is comming from Runtime.Base now.
- Fix CppCodeGen to deal with same RuntimeImport being used with different signatures (e.g. RpNewArray is imported under two different signatures in System.Private.CoreLib)
Diffstat (limited to 'src/ILCompiler.Compiler')
-rw-r--r-- | src/ILCompiler.Compiler/src/Compiler/Compilation.cs | 23 | ||||
-rw-r--r-- | src/ILCompiler.Compiler/src/CppCodeGen/CppWriter.cs | 101 | ||||
-rw-r--r-- | src/ILCompiler.Compiler/src/CppCodeGen/ILToCppImporter.cs | 3 |
3 files changed, 98 insertions, 29 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/Compilation.cs b/src/ILCompiler.Compiler/src/Compiler/Compilation.cs index 0147987dc..a858aa207 100644 --- a/src/ILCompiler.Compiler/src/Compiler/Compilation.cs +++ b/src/ILCompiler.Compiler/src/Compiler/Compilation.cs @@ -200,20 +200,27 @@ namespace ILCompiler foreach (var inputFile in _typeSystemContext.InputFilePaths) { var module = _typeSystemContext.GetModuleFromPath(inputFile.Value); - foreach (var type in module.GetAllTypes()) + AddCompilationRootsForRuntimeExports(module); + } + + AddCompilationRootsForRuntimeExports((EcmaModule)_typeSystemContext.SystemModule); + } + + private void AddCompilationRootsForRuntimeExports(EcmaModule module) + { + foreach (var type in module.GetAllTypes()) + { + foreach (var method in type.GetMethods()) { - foreach (var method in type.GetMethods()) + if (method.HasCustomAttribute("System.Runtime", "RuntimeExportAttribute")) { - if (method.HasCustomAttribute("System.Runtime", "RuntimeExportAttribute")) - { - string exportName = ((EcmaMethod)method).GetAttributeStringValue("System.Runtime", "RuntimeExportAttribute"); - AddCompilationRoot(method, "Runtime export", exportName); - } + string exportName = ((EcmaMethod)method).GetAttributeStringValue("System.Runtime", "RuntimeExportAttribute"); + AddCompilationRoot(method, "Runtime export", exportName); } } } } - + private void AddCompilationRoot(MethodDesc method, string reason, string exportName = null) { var methodEntryPoint = _nodeFactory.MethodEntrypoint(method); diff --git a/src/ILCompiler.Compiler/src/CppCodeGen/CppWriter.cs b/src/ILCompiler.Compiler/src/CppCodeGen/CppWriter.cs index 7c8ba7350..83757638c 100644 --- a/src/ILCompiler.Compiler/src/CppCodeGen/CppWriter.cs +++ b/src/ILCompiler.Compiler/src/CppCodeGen/CppWriter.cs @@ -47,6 +47,8 @@ namespace ILCompiler.CppCodeGen SetWellKnownTypeSignatureName(WellKnownType.UIntPtr, "uintptr_t"); SetWellKnownTypeSignatureName(WellKnownType.Single, "float"); SetWellKnownTypeSignatureName(WellKnownType.Double, "double"); + + BuildExternCSignatureMap(); } private Dictionary<TypeDesc, string> _cppSignatureNames = new Dictionary<TypeDesc, string>(); @@ -71,36 +73,51 @@ namespace ILCompiler.CppCodeGen return mangledName; } - public string GetCppMethodDeclaration(MethodDesc method, bool implementation, string externalMethodName = null) + // extern "C" methods are sometimes referenced via different signatures. + // _externCSignatureMap contains the canonical signature of the extern "C" import. References + // via other signatures are required to use casts. + private Dictionary<string, MethodSignature> _externCSignatureMap = new Dictionary<string, MethodSignature>(); + + private void BuildExternCSignatureMap() + { + foreach (var nodeAlias in _compilation.NodeFactory.NodeAliases) + { + var methodNode = (CppMethodCodeNode)nodeAlias.Key; + _externCSignatureMap.Add(nodeAlias.Value, methodNode.Method.Signature); + } + } + + public string GetCppMethodDeclaration(MethodDesc method, bool implementation, string externalMethodName = null, MethodSignature methodSignature = null) { StringBuilder sb = new StringBuilder(); - var methodSignature = method.Signature; + if (methodSignature == null) + methodSignature = method.Signature; - if (!implementation) + if (externalMethodName != null) { - if (externalMethodName != null) - { - sb.Append("extern \"C\" "); - } - else + sb.Append("extern \"C\" "); + } + else + { + if (!implementation) { sb.Append("static "); } } sb.Append(GetCppSignatureTypeName(methodSignature.ReturnType)); sb.Append(" "); - if (implementation) - { - sb.Append(GetCppTypeName(method.OwningType)); - sb.Append("::"); - } if (externalMethodName != null) { sb.Append(externalMethodName); } else { + if (implementation) + { + sb.Append(GetCppTypeName(method.OwningType)); + sb.Append("::"); + } sb.Append(GetCppMethodName(method)); } sb.Append("("); @@ -265,30 +282,53 @@ namespace ILCompiler.CppCodeGen if (importName == null) importName = method.Name; + MethodSignature methodSignature = method.Signature; + bool slotCastRequired = false; + + MethodSignature externCSignature; + if (_externCSignatureMap.TryGetValue(importName, out externCSignature)) + { + slotCastRequired = !externCSignature.Equals(method.Signature); + } + else + { + externCSignature = methodSignature; + } + // TODO: hacky special-case if (importName != "memmove" && importName != "malloc") // some methods are already declared by the CRT headers { - builder.AppendLine(GetCppMethodDeclaration(method, false, importName)); + builder.AppendLine(GetCppMethodDeclaration(method, false, importName, externCSignature)); } builder.AppendLine(GetCppMethodDeclaration(method, true)); builder.AppendLine("{"); - builder.Append(" "); - if (GetCppSignatureTypeName(method.Signature.ReturnType) != "void") + + if (slotCastRequired) + { + AppendSlotTypeDef(builder, method); + } + + if (!method.Signature.ReturnType.IsVoid) { builder.Append("return "); } - builder.AppendLine("::" + importName + "(" + GetCppMethodCallParamList(method) + ");"); + if (slotCastRequired) + builder.Append("((__slot__" + GetCppMethodName(method) + ")"); + builder.Append("::"); + builder.Append(importName); + if (slotCastRequired) + builder.Append(")"); + + builder.Append("("); + builder.Append(GetCppMethodCallParamList(method)); + builder.AppendLine(");"); builder.AppendLine("}"); return builder.ToString(); } default: - // TODO: hacky special-case - if (method.Name == "BlockCopy") - return null; - return GetCppMethodDeclaration(method, true) + " { throw 0xC000C000; }" + Environment.NewLine; } } @@ -894,6 +934,25 @@ namespace ILCompiler.CppCodeGen { var methodCodeNode = (CppMethodCodeNode)_compilation.NodeFactory.MethodEntrypoint(m); Out.WriteLine(methodCodeNode.CppCode); + + var alternateName = _compilation.NodeFactory.GetSymbolAlternateName(methodCodeNode); + if (alternateName != null) + { + Out.WriteLine(GetCppMethodDeclaration(m, true, alternateName)); + Out.WriteLine("{"); + Out.Write(" "); + if (!m.Signature.ReturnType.IsVoid) + { + Out.Write("return "); + } + Out.Write(GetCppTypeName(m.OwningType)); + Out.Write("::"); + Out.Write(GetCppMethodName(m)); + Out.Write("("); + Out.Write(GetCppMethodCallParamList(m)); + Out.WriteLine(");"); + Out.WriteLine("}"); + } } } } diff --git a/src/ILCompiler.Compiler/src/CppCodeGen/ILToCppImporter.cs b/src/ILCompiler.Compiler/src/CppCodeGen/ILToCppImporter.cs index f3b5ccdf6..5a2f940d9 100644 --- a/src/ILCompiler.Compiler/src/CppCodeGen/ILToCppImporter.cs +++ b/src/ILCompiler.Compiler/src/CppCodeGen/ILToCppImporter.cs @@ -2064,6 +2064,9 @@ namespace Internal.IL { var type = ResolveTypeToken(token); + // TODO: Remove + _writer.GetCppSignatureTypeName(type); + Push(StackValueKind.Int32, new Value("sizeof(" + _writer.GetCppTypeName(type) + ")")); } |