1/*===-- executionengine_ocaml.c - LLVM OCaml Glue ---------------*- C++ -*-===*\ 2|* *| 3|* The LLVM Compiler Infrastructure *| 4|* *| 5|* This file is distributed under the University of Illinois Open Source *| 6|* License. See LICENSE.TXT for details. *| 7|* *| 8|*===----------------------------------------------------------------------===*| 9|* *| 10|* This file glues LLVM's OCaml interface to its C interface. These functions *| 11|* are by and large transparent wrappers to the corresponding C functions. *| 12|* *| 13|* Note that these functions intentionally take liberties with the CAMLparamX *| 14|* macros, since most of the parameters are not GC heap objects. *| 15|* *| 16\*===----------------------------------------------------------------------===*/ 17 18#include <string.h> 19#include <assert.h> 20#include "llvm-c/Core.h" 21#include "llvm-c/ExecutionEngine.h" 22#include "llvm-c/Target.h" 23#include "caml/alloc.h" 24#include "caml/custom.h" 25#include "caml/fail.h" 26#include "caml/memory.h" 27#include "caml/callback.h" 28 29void llvm_raise(value Prototype, char *Message); 30 31/* unit -> bool */ 32CAMLprim value llvm_ee_initialize(value Unit) { 33 LLVMLinkInMCJIT(); 34 35 return Val_bool(!LLVMInitializeNativeTarget() && 36 !LLVMInitializeNativeAsmParser() && 37 !LLVMInitializeNativeAsmPrinter()); 38} 39 40/* llmodule -> llcompileroption -> ExecutionEngine.t */ 41CAMLprim LLVMExecutionEngineRef llvm_ee_create(value OptRecordOpt, LLVMModuleRef M) { 42 value OptRecord; 43 LLVMExecutionEngineRef MCJIT; 44 char *Error; 45 struct LLVMMCJITCompilerOptions Options; 46 47 LLVMInitializeMCJITCompilerOptions(&Options, sizeof(Options)); 48 if (OptRecordOpt != Val_int(0)) { 49 OptRecord = Field(OptRecordOpt, 0); 50 Options.OptLevel = Int_val(Field(OptRecord, 0)); 51 Options.CodeModel = Int_val(Field(OptRecord, 1)); 52 Options.NoFramePointerElim = Int_val(Field(OptRecord, 2)); 53 Options.EnableFastISel = Int_val(Field(OptRecord, 3)); 54 Options.MCJMM = NULL; 55 } 56 57 if (LLVMCreateMCJITCompilerForModule(&MCJIT, M, &Options, 58 sizeof(Options), &Error)) 59 llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error); 60 return MCJIT; 61} 62 63/* ExecutionEngine.t -> unit */ 64CAMLprim value llvm_ee_dispose(LLVMExecutionEngineRef EE) { 65 LLVMDisposeExecutionEngine(EE); 66 return Val_unit; 67} 68 69/* llmodule -> ExecutionEngine.t -> unit */ 70CAMLprim value llvm_ee_add_module(LLVMModuleRef M, LLVMExecutionEngineRef EE) { 71 LLVMAddModule(EE, M); 72 return Val_unit; 73} 74 75/* llmodule -> ExecutionEngine.t -> llmodule */ 76CAMLprim value llvm_ee_remove_module(LLVMModuleRef M, LLVMExecutionEngineRef EE) { 77 LLVMModuleRef RemovedModule; 78 char *Error; 79 if (LLVMRemoveModule(EE, M, &RemovedModule, &Error)) 80 llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error); 81 return Val_unit; 82} 83 84/* ExecutionEngine.t -> unit */ 85CAMLprim value llvm_ee_run_static_ctors(LLVMExecutionEngineRef EE) { 86 LLVMRunStaticConstructors(EE); 87 return Val_unit; 88} 89 90/* ExecutionEngine.t -> unit */ 91CAMLprim value llvm_ee_run_static_dtors(LLVMExecutionEngineRef EE) { 92 LLVMRunStaticDestructors(EE); 93 return Val_unit; 94} 95 96extern value llvm_alloc_data_layout(LLVMTargetDataRef TargetData); 97 98/* ExecutionEngine.t -> Llvm_target.DataLayout.t */ 99CAMLprim value llvm_ee_get_data_layout(LLVMExecutionEngineRef EE) { 100 value DataLayout; 101 LLVMTargetDataRef OrigDataLayout; 102 char* TargetDataCStr; 103 104 OrigDataLayout = LLVMGetExecutionEngineTargetData(EE); 105 TargetDataCStr = LLVMCopyStringRepOfTargetData(OrigDataLayout); 106 DataLayout = llvm_alloc_data_layout(LLVMCreateTargetData(TargetDataCStr)); 107 LLVMDisposeMessage(TargetDataCStr); 108 109 return DataLayout; 110} 111 112/* Llvm.llvalue -> int64 -> llexecutionengine -> unit */ 113CAMLprim value llvm_ee_add_global_mapping(LLVMValueRef Global, value Ptr, 114 LLVMExecutionEngineRef EE) { 115 LLVMAddGlobalMapping(EE, Global, (void*) (Int64_val(Ptr))); 116 return Val_unit; 117} 118 119CAMLprim value llvm_ee_get_global_value_address(value Name, 120 LLVMExecutionEngineRef EE) { 121 return caml_copy_int64((int64_t) LLVMGetGlobalValueAddress(EE, String_val(Name))); 122} 123 124CAMLprim value llvm_ee_get_function_address(value Name, 125 LLVMExecutionEngineRef EE) { 126 return caml_copy_int64((int64_t) LLVMGetFunctionAddress(EE, String_val(Name))); 127} 128