/*===-- executionengine_ocaml.c - LLVM OCaml Glue ---------------*- C++ -*-===*\ |* *| |* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| |* Exceptions. *| |* See https://llvm.org/LICENSE.txt for license information. *| |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| |* *| |*===----------------------------------------------------------------------===*| |* *| |* This file glues LLVM's OCaml interface to its C interface. These functions *| |* are by and large transparent wrappers to the corresponding C functions. *| |* *| |* Note that these functions intentionally take liberties with the CAMLparamX *| |* macros, since most of the parameters are not GC heap objects. *| |* *| \*===----------------------------------------------------------------------===*/ #include "caml/alloc.h" #include "caml/callback.h" #include "caml/custom.h" #include "caml/fail.h" #include "caml/memory.h" #include "llvm_ocaml.h" #include "llvm-c/Core.h" #include "llvm-c/ExecutionEngine.h" #include "llvm-c/Target.h" #include #include #define ExecutionEngine_val(v) ((LLVMExecutionEngineRef)from_val(v)) void llvm_raise(value Prototype, char *Message); /* unit -> bool */ value llvm_ee_initialize(value Unit) { LLVMLinkInMCJIT(); return Val_bool(!LLVMInitializeNativeTarget() && !LLVMInitializeNativeAsmParser() && !LLVMInitializeNativeAsmPrinter()); } /* llcompileroption -> llmodule -> ExecutionEngine.t */ value llvm_ee_create(value OptRecordOpt, value M) { LLVMExecutionEngineRef MCJIT; char *Error; struct LLVMMCJITCompilerOptions Options; LLVMInitializeMCJITCompilerOptions(&Options, sizeof(Options)); if (OptRecordOpt != Val_int(0)) { value OptRecord = Field(OptRecordOpt, 0); Options.OptLevel = Int_val(Field(OptRecord, 0)); Options.CodeModel = Int_val(Field(OptRecord, 1)); Options.NoFramePointerElim = Int_val(Field(OptRecord, 2)); Options.EnableFastISel = Int_val(Field(OptRecord, 3)); Options.MCJMM = NULL; } if (LLVMCreateMCJITCompilerForModule(&MCJIT, Module_val(M), &Options, sizeof(Options), &Error)) llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error); return to_val(MCJIT); } /* ExecutionEngine.t -> unit */ value llvm_ee_dispose(value EE) { LLVMDisposeExecutionEngine(ExecutionEngine_val(EE)); return Val_unit; } /* llmodule -> ExecutionEngine.t -> unit */ value llvm_ee_add_module(value M, value EE) { LLVMAddModule(ExecutionEngine_val(EE), Module_val(M)); return Val_unit; } /* llmodule -> ExecutionEngine.t -> llmodule */ value llvm_ee_remove_module(value M, value EE) { LLVMModuleRef RemovedModule; char *Error; if (LLVMRemoveModule(ExecutionEngine_val(EE), Module_val(M), &RemovedModule, &Error)) llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error); return Val_unit; } /* ExecutionEngine.t -> unit */ value llvm_ee_run_static_ctors(value EE) { LLVMRunStaticConstructors(ExecutionEngine_val(EE)); return Val_unit; } /* ExecutionEngine.t -> unit */ value llvm_ee_run_static_dtors(value EE) { LLVMRunStaticDestructors(ExecutionEngine_val(EE)); return Val_unit; } extern value llvm_alloc_data_layout(LLVMTargetDataRef TargetData); /* ExecutionEngine.t -> Llvm_target.DataLayout.t */ value llvm_ee_get_data_layout(value EE) { value DataLayout; LLVMTargetDataRef OrigDataLayout; char *TargetDataCStr; OrigDataLayout = LLVMGetExecutionEngineTargetData(ExecutionEngine_val(EE)); TargetDataCStr = LLVMCopyStringRepOfTargetData(OrigDataLayout); DataLayout = llvm_alloc_data_layout(LLVMCreateTargetData(TargetDataCStr)); LLVMDisposeMessage(TargetDataCStr); return DataLayout; } /* Llvm.llvalue -> int64 -> llexecutionengine -> unit */ value llvm_ee_add_global_mapping(value Global, value Ptr, value EE) { LLVMAddGlobalMapping(ExecutionEngine_val(EE), Value_val(Global), (void *)(Int64_val(Ptr))); return Val_unit; } value llvm_ee_get_global_value_address(value Name, value EE) { return caml_copy_int64((int64_t)LLVMGetGlobalValueAddress( ExecutionEngine_val(EE), String_val(Name))); } value llvm_ee_get_function_address(value Name, value EE) { return caml_copy_int64((int64_t)LLVMGetFunctionAddress( ExecutionEngine_val(EE), String_val(Name))); }