1
|
1 #include <cassert>
|
|
2
|
|
3 #include "llvm/Module.h"
|
|
4 #include "llvm/Bitcode/ReaderWriter.h"
|
|
5 #include "llvm/Support/MemoryBuffer.h"
|
|
6
|
|
7 #include "runtime.h"
|
|
8 #include "logger.h"
|
|
9
|
|
10 #include "root.h"
|
|
11 #include "mars.h"
|
|
12
|
|
13 static llvm::Module* M = NULL;
|
|
14 static bool runtime_failed = false;
|
|
15
|
|
16 bool LLVM_D_InitRuntime()
|
|
17 {
|
|
18 Logger::println("*** Loading D runtime ***");
|
|
19 LOG_SCOPE;
|
|
20
|
|
21 std::string filename(global.params.runtimeImppath);
|
|
22 filename.append("/llvmdcore.bc");
|
|
23 llvm::MemoryBuffer* buffer = llvm::MemoryBuffer::getFile(filename.c_str(), filename.length());
|
|
24 if (!buffer) {
|
|
25 Logger::println("Failed to load runtime library from disk");
|
|
26 runtime_failed = true;
|
|
27 return false;
|
|
28 }
|
|
29
|
|
30 std::string errstr;
|
|
31 bool retval = false;
|
|
32 M = llvm::ParseBitcodeFile(buffer, &errstr);
|
|
33 if (M) {
|
|
34 retval = true;
|
|
35 }
|
|
36 else {
|
|
37 Logger::println("Failed to load runtime: %s", errstr.c_str());
|
|
38 runtime_failed = true;
|
|
39 }
|
|
40
|
|
41 delete buffer;
|
|
42 return retval;
|
|
43 }
|
|
44
|
|
45 void LLVM_D_FreeRuntime()
|
|
46 {
|
|
47 if (M) {
|
|
48 Logger::println("*** Freeing D runtime ***");
|
|
49 delete M;
|
|
50 }
|
|
51 }
|
|
52
|
|
53 llvm::Function* LLVM_D_GetRuntimeFunction(llvm::Module* target, const char* name)
|
|
54 {
|
|
55 // TODO maybe check the target module first, to allow overriding the runtime on a pre module basis?
|
|
56 // could be done and seems like it could be neat too :)
|
|
57
|
|
58 if (global.params.noruntime) {
|
|
59 error("No implicit runtime calls allowed with -noruntime option enabled");
|
|
60 fatal();
|
|
61 }
|
|
62
|
|
63 if (!M) {
|
|
64 assert(!runtime_failed);
|
|
65 LLVM_D_InitRuntime();
|
|
66 }
|
|
67
|
|
68 llvm::Function* fn = M->getFunction(name);
|
|
69 if (!fn)
|
|
70 return NULL;
|
|
71
|
|
72 const llvm::FunctionType* fnty = fn->getFunctionType();
|
|
73 return llvm::cast<llvm::Function>(target->getOrInsertFunction(name, fnty));
|
|
74 }
|