]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | // Copyright 2014 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
11 | #include "rustllvm.h" | |
12 | ||
13 | #include "llvm/ExecutionEngine/SectionMemoryManager.h" | |
14 | ||
15 | using namespace llvm; | |
16 | using namespace llvm::sys; | |
17 | using namespace llvm::object; | |
18 | ||
19 | class RustJITMemoryManager : public SectionMemoryManager | |
20 | { | |
21 | typedef SectionMemoryManager Base; | |
22 | ||
1a4d82fc JJ |
23 | public: |
24 | ||
62682a34 | 25 | RustJITMemoryManager() {} |
1a4d82fc JJ |
26 | |
27 | uint64_t getSymbolAddress(const std::string &Name) override | |
28 | { | |
1a4d82fc JJ |
29 | return Base::getSymbolAddress(Name); |
30 | } | |
31 | }; | |
32 | ||
33 | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(RustJITMemoryManager, LLVMRustJITMemoryManagerRef) | |
34 | ||
1a4d82fc JJ |
35 | extern "C" LLVMBool LLVMRustLoadDynamicLibrary(const char *path) |
36 | { | |
37 | std::string err; | |
38 | DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(path, &err); | |
39 | ||
40 | if (!lib.isValid()) | |
41 | LLVMRustSetLastError(err.c_str()); | |
42 | ||
43 | return lib.isValid(); | |
44 | } | |
45 | ||
46 | // Calls LLVMAddModule; | |
47 | // exists for consistency with LLVMExecutionEngineRemoveModule | |
48 | extern "C" void LLVMExecutionEngineAddModule( | |
49 | LLVMExecutionEngineRef eeref, LLVMModuleRef mref) | |
50 | { | |
62682a34 SL |
51 | #ifdef _WIN32 |
52 | // On Windows, MCJIT must generate ELF objects | |
53 | std::string target = getProcessTriple(); | |
54 | target += "-elf"; | |
55 | target = Triple::normalize(target); | |
56 | unwrap(mref)->setTargetTriple(target); | |
57 | #endif | |
1a4d82fc JJ |
58 | LLVMAddModule(eeref, mref); |
59 | } | |
60 | ||
61 | // LLVMRemoveModule exists in LLVM's C bindings, | |
62 | // but it requires pointless parameters | |
63 | extern "C" LLVMBool LLVMExecutionEngineRemoveModule( | |
64 | LLVMExecutionEngineRef eeref, LLVMModuleRef mref) | |
65 | { | |
66 | ExecutionEngine *ee = unwrap(eeref); | |
67 | Module *m = unwrap(mref); | |
68 | ||
69 | return ee->removeModule(m); | |
70 | } | |
71 | ||
62682a34 | 72 | extern "C" LLVMExecutionEngineRef LLVMBuildExecutionEngine(LLVMModuleRef mod) |
1a4d82fc JJ |
73 | { |
74 | // These are necessary for code generation to work properly. | |
75 | InitializeNativeTarget(); | |
76 | InitializeNativeTargetAsmPrinter(); | |
77 | InitializeNativeTargetAsmParser(); | |
78 | ||
62682a34 SL |
79 | #ifdef _WIN32 |
80 | // On Windows, MCJIT must generate ELF objects | |
81 | std::string target = getProcessTriple(); | |
82 | target += "-elf"; | |
83 | target = Triple::normalize(target); | |
84 | unwrap(mod)->setTargetTriple(target); | |
85 | #endif | |
86 | ||
1a4d82fc JJ |
87 | std::string error_str; |
88 | TargetOptions options; | |
89 | ||
62682a34 | 90 | RustJITMemoryManager *mm = new RustJITMemoryManager; |
1a4d82fc | 91 | |
85aaf69f | 92 | ExecutionEngine *ee = |
d9579d0f | 93 | #if LLVM_VERSION_MINOR >= 6 |
85aaf69f | 94 | EngineBuilder(std::unique_ptr<Module>(unwrap(mod))) |
62682a34 | 95 | .setMCJITMemoryManager(std::unique_ptr<RustJITMemoryManager>(mm)) |
d9579d0f AL |
96 | #else |
97 | EngineBuilder(unwrap(mod)) | |
62682a34 | 98 | .setMCJITMemoryManager(mm) |
85aaf69f SL |
99 | #endif |
100 | .setEngineKind(EngineKind::JIT) | |
101 | .setErrorStr(&error_str) | |
102 | .setTargetOptions(options) | |
103 | .create(); | |
1a4d82fc JJ |
104 | |
105 | if (!ee) | |
106 | LLVMRustSetLastError(error_str.c_str()); | |
107 | ||
108 | return wrap(ee); | |
109 | } | |
110 | ||
111 | extern "C" void LLVMExecutionEngineFinalizeObject(LLVMExecutionEngineRef eeref) | |
112 | { | |
113 | ExecutionEngine *ee = unwrap(eeref); | |
114 | ||
115 | ee->finalizeObject(); | |
116 | } |