Mercurial > projects > ldc
view tools/binding/llvm/executionengine.d @ 1404:11b122f92136
Now that templates instantiations are no longer emitted for all modules that
even blink at them they seem to break due to being linkonce (if compiled with
any optimization level > 0), so let's give them weak linkage instead.
The difference is that unreferenced linkonce symbols can be deleted, while
weak symbols need to be preserved.
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Thu, 21 May 2009 15:23:28 +0200 |
parents | 4ff9ab0d472c |
children |
line wrap: on
line source
// Written in the D programming language by Frits van Bommel 2008 // Binding of llvm.c.ExecutionEngine for D. // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // module llvm.executionengine; import llvm.c.Core; import llvm.c.ExecutionEngine; import llvm.llvm; import llvm.util; /// class GenericValue { /// private LLVMGenericValueRef value; /// private this(LLVMGenericValueRef v) { value = v; } /// void dispose() { LLVMDisposeGenericValue(value); value = null; } /// ~this() { dispose(); // safe because value isn't on the GC heap and isn't exposed. } /// static GenericValue GetS(IntegerType ty, long N) { return new GenericValue(LLVMCreateGenericValueOfInt(ty.ll, N, true)); } /// static GenericValue GetU(IntegerType ty, ulong N) { return new GenericValue(LLVMCreateGenericValueOfInt(ty.ll, N, false)); } /// static GenericValue GetP(void* P) { return new GenericValue(LLVMCreateGenericValueOfPointer(P)); } /// static GenericValue GetF(RealType ty, double N) { return new GenericValue(LLVMCreateGenericValueOfFloat(ty.ll, N)); } /// uint intWidth() { return LLVMGenericValueIntWidth(value); } /// ulong toUInt() { return LLVMGenericValueToInt(value, false); } /// long toSInt() { return LLVMGenericValueToInt(value, true); } /// void* toPointer() { return LLVMGenericValueToPointer(value); } /// double toFloat(RealType ty) { return LLVMGenericValueToFloat(ty.ll, value); } } /// class ExecutionEngine { /// private LLVMExecutionEngineRef ee; /// private this(LLVMExecutionEngineRef ee) { this.ee = ee; } /// static ExecutionEngine Create(ModuleProvider mp) { LLVMExecutionEngineRef ee; char* err; if (LLVMCreateExecutionEngine(&ee, mp.ll, &err)) { auto errmsg = from_stringz(err).dup; LLVMDisposeMessage(err); if (errmsg.length == 0) errmsg = "Error creating execution engine"; throw new LLVMException(errmsg); } return new ExecutionEngine(ee); } /// static ExecutionEngine CreateInterpreter(ModuleProvider mp) { LLVMExecutionEngineRef ee; char* err; if (LLVMCreateInterpreter(&ee, mp.ll, &err)) { auto errmsg = from_stringz(err).dup; LLVMDisposeMessage(err); if (errmsg.length == 0) errmsg = "Error creating interpreter"; throw new LLVMException(errmsg); } return new ExecutionEngine(ee); } /// static ExecutionEngine CreateJIT(ModuleProvider mp) { LLVMExecutionEngineRef ee; char* err; if (LLVMCreateJITCompiler(&ee, mp.ll, &err)) { auto errmsg = from_stringz(err).dup; LLVMDisposeMessage(err); if (errmsg.length == 0) errmsg = "Error creating JIT"; throw new LLVMException(errmsg); } return new ExecutionEngine(ee); } /// void dispose() { LLVMDisposeExecutionEngine(ee); ee = null; } /// ~this() { dispose(); // safe because ee isn't on the GC heap and isn't exposed. } /// void runStaticConstructors() { LLVMRunStaticConstructors(ee); } /// void runStaticDestructors() { LLVMRunStaticDestructors(ee); } /// int runAsMain(Function f, char[][] args = null, char[][] env = null) { auto argv = new char*[args.length]; foreach (size_t idx, ref arg; args) { argv[idx] = to_stringz(arg); } auto envp = new char*[env.length + 1]; foreach (size_t idx, ref envvar ; env) { envp[idx] = to_stringz(envvar); } envp[$-1] = null; return LLVMRunFunctionAsMain(ee, f.value, argv.length, argv.ptr, envp.ptr); } /// GenericValue run(Function f, GenericValue[] args = null) { auto cargs = new LLVMGenericValueRef[args.length]; foreach (size_t idx, ref arg ; args) { cargs[idx] = arg.value; } auto result = LLVMRunFunction(ee, f.value, cargs.length, cargs.ptr); return new GenericValue(result); } /// void freeMachineCodeForFunction(Function f) { LLVMFreeMachineCodeForFunction(ee, f.value); } /// void addModuleProvider(ModuleProvider mp) { LLVMAddModuleProvider(ee, mp.ll); } /// Module removeModuleProvider(ModuleProvider mp) { LLVMModuleRef mod; char* err; if (LLVMRemoveModuleProvider(ee, mp.ll, &mod, &err)) { auto errmsg = from_stringz(err).dup; LLVMDisposeMessage(err); if (errmsg.length == 0) errmsg = "Error removing ModuleProvider from ExecutionEngine"; throw new LLVMException(errmsg); } return Module.GetExisting(mod); } /// Function findFunction(char[] name) { LLVMValueRef fn; if (LLVMFindFunction(ee, to_stringz(name), &fn)) { return null; } return new Function(fn, getTypeOf(fn)); } }