20
20
#include " llvm/Transforms/Scalar.h"
21
21
#include " llvm/Transforms/IPO.h"
22
22
#include " llvm/ADT/Triple.h"
23
+ #include " llvm/ADT/DenseSet.h"
23
24
#include " llvm/Assembly/Parser.h"
24
25
#include " llvm/Assembly/PrintModulePass.h"
25
26
#include " llvm/Support/FormattedStream.h"
42
43
#include " llvm-c/Core.h"
43
44
#include " llvm-c/BitReader.h"
44
45
#include " llvm-c/Object.h"
45
- #include < cstdlib>
46
46
47
47
// Used by RustMCJITMemoryManager::getPointerToNamedFunction()
48
48
// to get around glibc issues. See the function for more information.
53
53
#endif
54
54
55
55
using namespace llvm ;
56
+ using namespace llvm ::sys;
56
57
57
58
static const char *LLVMRustError;
58
59
@@ -100,18 +101,6 @@ void LLVMRustInitializeTargets() {
100
101
LLVMInitializeX86AsmParser ();
101
102
}
102
103
103
- extern " C" bool
104
- LLVMRustLoadLibrary (const char * file) {
105
- std::string err;
106
-
107
- if (llvm::sys::DynamicLibrary::LoadLibraryPermanently (file, &err)) {
108
- LLVMRustError = err.c_str ();
109
- return false ;
110
- }
111
-
112
- return true ;
113
- }
114
-
115
104
// Custom memory manager for MCJITting. It needs special features
116
105
// that the generic JIT memory manager doesn't entail. Based on
117
106
// code from LLI, change where needed for Rust.
@@ -121,10 +110,13 @@ class RustMCJITMemoryManager : public JITMemoryManager {
121
110
SmallVector<sys::MemoryBlock, 16 > AllocatedCodeMem;
122
111
SmallVector<sys::MemoryBlock, 16 > FreeCodeMem;
123
112
void * __morestack;
113
+ DenseSet<DynamicLibrary*> crates;
124
114
125
115
RustMCJITMemoryManager (void * sym) : __morestack(sym) { }
126
116
~RustMCJITMemoryManager ();
127
117
118
+ bool loadCrate (const char *, std::string*);
119
+
128
120
virtual uint8_t *allocateCodeSection (uintptr_t Size, unsigned Alignment,
129
121
unsigned SectionID);
130
122
@@ -197,6 +189,19 @@ class RustMCJITMemoryManager : public JITMemoryManager {
197
189
}
198
190
};
199
191
192
+ bool RustMCJITMemoryManager::loadCrate (const char * file, std::string* err) {
193
+ DynamicLibrary crate = DynamicLibrary::getPermanentLibrary (file,
194
+ err);
195
+
196
+ if (crate.isValid ()) {
197
+ crates.insert (&crate);
198
+
199
+ return true ;
200
+ }
201
+
202
+ return false ;
203
+ }
204
+
200
205
uint8_t *RustMCJITMemoryManager::allocateDataSection (uintptr_t Size,
201
206
unsigned Alignment,
202
207
unsigned SectionID) {
@@ -276,6 +281,9 @@ void *RustMCJITMemoryManager::getPointerToNamedFunction(const std::string &Name,
276
281
if (Name == " __morestack" ) return &__morestack;
277
282
278
283
const char *NameStr = Name.c_str ();
284
+
285
+ // Look through loaded crates and main for symbols.
286
+
279
287
void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol (NameStr);
280
288
if (Ptr) return Ptr;
281
289
@@ -293,21 +301,49 @@ RustMCJITMemoryManager::~RustMCJITMemoryManager() {
293
301
}
294
302
295
303
extern " C" void *
296
- LLVMRustJIT (void * __morestack,
297
- LLVMPassManagerRef PMR,
298
- LLVMModuleRef M,
299
- CodeGenOpt::Level OptLevel,
300
- bool EnableSegmentedStacks) {
304
+ LLVMRustPrepareJIT (void * __morestack) {
305
+ // An execution engine will take ownership of this later
306
+ // and clean it up for us.
307
+
308
+ return (void *) new RustMCJITMemoryManager (__morestack);
309
+ }
310
+
311
+ extern " C" bool
312
+ LLVMRustLoadCrate (void * mem, const char * crate) {
313
+ RustMCJITMemoryManager* manager = (RustMCJITMemoryManager*) mem;
314
+ std::string Err;
315
+
316
+ assert (manager);
317
+
318
+ if (!manager->loadCrate (crate, &Err)) {
319
+ LLVMRustError = Err.c_str ();
320
+ return false ;
321
+ }
322
+
323
+ return true ;
324
+ }
325
+
326
+ extern " C" void *
327
+ LLVMRustExecuteJIT (void * mem,
328
+ LLVMPassManagerRef PMR,
329
+ LLVMModuleRef M,
330
+ CodeGenOpt::Level OptLevel,
331
+ bool EnableSegmentedStacks) {
301
332
302
333
InitializeNativeTarget ();
303
334
InitializeNativeTargetAsmPrinter ();
335
+ InitializeNativeTargetAsmParser ();
304
336
305
337
std::string Err;
306
338
TargetOptions Options;
339
+ Options.JITExceptionHandling = true ;
307
340
Options.JITEmitDebugInfo = true ;
308
341
Options.NoFramePointerElim = true ;
309
342
Options.EnableSegmentedStacks = EnableSegmentedStacks;
310
343
PassManager *PM = unwrap<PassManager>(PMR);
344
+ RustMCJITMemoryManager* MM = (RustMCJITMemoryManager*) mem;
345
+
346
+ assert (MM);
311
347
312
348
PM->add (createBasicAliasAnalysisPass ());
313
349
PM->add (createInstructionCombiningPass ());
@@ -318,8 +354,8 @@ LLVMRustJIT(void* __morestack,
318
354
PM->add (createPromoteMemoryToRegisterPass ());
319
355
PM->run (*unwrap (M));
320
356
321
- RustMCJITMemoryManager* MM = new RustMCJITMemoryManager (__morestack);
322
357
ExecutionEngine* EE = EngineBuilder (unwrap (M))
358
+ .setErrorStr (&Err)
323
359
.setTargetOptions (Options)
324
360
.setJITMemoryManager (MM)
325
361
.setOptLevel (OptLevel)
0 commit comments