Mercurial > projects > ldc
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)); +}