about summary refs log tree commit diff
path: root/src/rustllvm/ExecutionEngineWrapper.cpp
diff options
context:
space:
mode:
authorMurarth <murarth@gmail.com>2015-05-19 16:00:59 -0700
committerMurarth <murarth@gmail.com>2015-06-08 16:54:50 -0700
commit021e48326db304559a74f2f338d511f9674d0da7 (patch)
tree95a987c78c2e1a24bea1f19ce62bcc88d15285d7 /src/rustllvm/ExecutionEngineWrapper.cpp
parentaca207a65c82d7581076772846ef424f1a64449b (diff)
downloadrust-021e48326db304559a74f2f338d511f9674d0da7.tar.gz
rust-021e48326db304559a74f2f338d511f9674d0da7.zip
Changes to LLVM `ExecutionEngine` wrapper
* Removes `RustJITMemoryManager` from public API.
  This was really sort of an implementation detail to begin with.
* `__morestack` is linked to C++ wrapper code and this pointer
  is used when resolving the symbol for `ExecutionEngine` code.
* `__morestack_addr` is also resolved for `ExecutionEngine` code.
  This function is sometimes referenced in LLVM-generated code,
  but was not able to be resolved on Mac OS systems.
* Added Windows support to `ExecutionEngine` API.
* Added a test for basic `ExecutionEngine` functionality.
Diffstat (limited to 'src/rustllvm/ExecutionEngineWrapper.cpp')
-rw-r--r--src/rustllvm/ExecutionEngineWrapper.cpp50
1 files changed, 35 insertions, 15 deletions
diff --git a/src/rustllvm/ExecutionEngineWrapper.cpp b/src/rustllvm/ExecutionEngineWrapper.cpp
index 7e0630fd242..e37ede82bb5 100644
--- a/src/rustllvm/ExecutionEngineWrapper.cpp
+++ b/src/rustllvm/ExecutionEngineWrapper.cpp
@@ -16,22 +16,31 @@ using namespace llvm;
 using namespace llvm::sys;
 using namespace llvm::object;
 
+// libmorestack is not used on Windows
+#ifndef _WIN32
+extern "C" void __morestack(void);
+
+static void* morestack_addr() {
+    return reinterpret_cast<void*>(__morestack);
+}
+#endif
+
 class RustJITMemoryManager : public SectionMemoryManager
 {
     typedef SectionMemoryManager Base;
 
-    const void *morestack;
-
     public:
 
-    RustJITMemoryManager(const void *morestack_ptr)
-        : morestack(morestack_ptr)
-        {}
+    RustJITMemoryManager() {}
 
     uint64_t getSymbolAddress(const std::string &Name) override
     {
+#ifndef _WIN32
         if (Name == "__morestack" || Name == "___morestack")
-            return reinterpret_cast<uint64_t>(morestack);
+            return reinterpret_cast<uint64_t>(__morestack);
+        if (Name == "__morestack_addr" || Name == "___morestack_addr")
+            return reinterpret_cast<uint64_t>(morestack_addr);
+#endif
 
         return Base::getSymbolAddress(Name);
     }
@@ -39,11 +48,6 @@ class RustJITMemoryManager : public SectionMemoryManager
 
 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(RustJITMemoryManager, LLVMRustJITMemoryManagerRef)
 
-extern "C" LLVMRustJITMemoryManagerRef LLVMRustCreateJITMemoryManager(void *morestack)
-{
-    return wrap(new RustJITMemoryManager(morestack));
-}
-
 extern "C" LLVMBool LLVMRustLoadDynamicLibrary(const char *path)
 {
     std::string err;
@@ -60,6 +64,13 @@ extern "C" LLVMBool LLVMRustLoadDynamicLibrary(const char *path)
 extern "C" void LLVMExecutionEngineAddModule(
     LLVMExecutionEngineRef eeref, LLVMModuleRef mref)
 {
+#ifdef _WIN32
+    // On Windows, MCJIT must generate ELF objects
+    std::string target = getProcessTriple();
+    target += "-elf";
+    target = Triple::normalize(target);
+    unwrap(mref)->setTargetTriple(target);
+#endif
     LLVMAddModule(eeref, mref);
 }
 
@@ -74,27 +85,36 @@ extern "C" LLVMBool LLVMExecutionEngineRemoveModule(
     return ee->removeModule(m);
 }
 
-extern "C" LLVMExecutionEngineRef LLVMBuildExecutionEngine(
-    LLVMModuleRef mod, LLVMRustJITMemoryManagerRef mref)
+extern "C" LLVMExecutionEngineRef LLVMBuildExecutionEngine(LLVMModuleRef mod)
 {
     // These are necessary for code generation to work properly.
     InitializeNativeTarget();
     InitializeNativeTargetAsmPrinter();
     InitializeNativeTargetAsmParser();
 
+#ifdef _WIN32
+    // On Windows, MCJIT must generate ELF objects
+    std::string target = getProcessTriple();
+    target += "-elf";
+    target = Triple::normalize(target);
+    unwrap(mod)->setTargetTriple(target);
+#endif
+
     std::string error_str;
     TargetOptions options;
 
     options.JITEmitDebugInfo = true;
     options.NoFramePointerElim = true;
 
+    RustJITMemoryManager *mm = new RustJITMemoryManager;
+
     ExecutionEngine *ee =
     #if LLVM_VERSION_MINOR >= 6
         EngineBuilder(std::unique_ptr<Module>(unwrap(mod)))
-            .setMCJITMemoryManager(std::unique_ptr<RustJITMemoryManager>(unwrap(mref)))
+            .setMCJITMemoryManager(std::unique_ptr<RustJITMemoryManager>(mm))
     #else
         EngineBuilder(unwrap(mod))
-            .setMCJITMemoryManager(unwrap(mref))
+            .setMCJITMemoryManager(mm)
     #endif
             .setEngineKind(EngineKind::JIT)
             .setErrorStr(&error_str)