diff gen/runtime.c @ 1:c53b6e3fe49a trunk

[svn r5] Initial commit. Most things are very rough.
author lindquist
date Sat, 01 Sep 2007 21:43:27 +0200
parents
children e116aa1488e6
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gen/runtime.c	Sat Sep 01 21:43:27 2007 +0200
@@ -0,0 +1,74 @@
+#include <cassert>
+
+#include "llvm/Module.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+#include "runtime.h"
+#include "logger.h"
+
+#include "root.h"
+#include "mars.h"
+
+static llvm::Module* M = NULL;
+static bool runtime_failed = false;
+
+bool LLVM_D_InitRuntime()
+{
+    Logger::println("*** Loading D runtime ***");
+    LOG_SCOPE;
+
+    std::string filename(global.params.runtimeImppath);
+    filename.append("/llvmdcore.bc");
+    llvm::MemoryBuffer* buffer = llvm::MemoryBuffer::getFile(filename.c_str(), filename.length());
+    if (!buffer) {
+        Logger::println("Failed to load runtime library from disk");
+        runtime_failed = true;
+        return false;
+    }
+
+    std::string errstr;
+    bool retval = false;
+    M = llvm::ParseBitcodeFile(buffer, &errstr);
+    if (M) {
+        retval = true;
+    }
+    else {
+        Logger::println("Failed to load runtime: %s", errstr.c_str());
+        runtime_failed = true;
+    }
+    
+    delete buffer;
+    return retval;
+}
+
+void LLVM_D_FreeRuntime()
+{
+    if (M) {
+        Logger::println("*** Freeing D runtime ***");
+        delete M;
+    }
+}
+
+llvm::Function* LLVM_D_GetRuntimeFunction(llvm::Module* target, const char* name)
+{
+    // TODO maybe check the target module first, to allow overriding the runtime on a pre module basis?
+    // could be done and seems like it could be neat too :)
+
+    if (global.params.noruntime) {
+        error("No implicit runtime calls allowed with -noruntime option enabled");
+        fatal();
+    }
+    
+    if (!M) {
+        assert(!runtime_failed);
+        LLVM_D_InitRuntime();
+    }
+    
+    llvm::Function* fn = M->getFunction(name);
+    if (!fn)
+        return NULL;
+    
+    const llvm::FunctionType* fnty = fn->getFunctionType();
+    return llvm::cast<llvm::Function>(target->getOrInsertFunction(name, fnty));
+}