131 lines · c
1/*===-- executionengine_ocaml.c - LLVM OCaml Glue ---------------*- C++ -*-===*\2|* *|3|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|4|* Exceptions. *|5|* See https://llvm.org/LICENSE.txt for license information. *|6|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|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 "caml/alloc.h"19#include "caml/callback.h"20#include "caml/custom.h"21#include "caml/fail.h"22#include "caml/memory.h"23#include "llvm_ocaml.h"24#include "llvm-c/Core.h"25#include "llvm-c/ExecutionEngine.h"26#include "llvm-c/Target.h"27#include <assert.h>28#include <string.h>29 30#define ExecutionEngine_val(v) ((LLVMExecutionEngineRef)from_val(v))31 32void llvm_raise(value Prototype, char *Message);33 34/* unit -> bool */35value llvm_ee_initialize(value Unit) {36 LLVMLinkInMCJIT();37 38 return Val_bool(!LLVMInitializeNativeTarget() &&39 !LLVMInitializeNativeAsmParser() &&40 !LLVMInitializeNativeAsmPrinter());41}42 43/* llcompileroption -> llmodule -> ExecutionEngine.t */44value llvm_ee_create(value OptRecordOpt, value M) {45 LLVMExecutionEngineRef MCJIT;46 char *Error;47 struct LLVMMCJITCompilerOptions Options;48 49 LLVMInitializeMCJITCompilerOptions(&Options, sizeof(Options));50 if (OptRecordOpt != Val_int(0)) {51 value OptRecord = Field(OptRecordOpt, 0);52 Options.OptLevel = Int_val(Field(OptRecord, 0));53 Options.CodeModel = Int_val(Field(OptRecord, 1));54 Options.NoFramePointerElim = Int_val(Field(OptRecord, 2));55 Options.EnableFastISel = Int_val(Field(OptRecord, 3));56 Options.MCJMM = NULL;57 }58 59 if (LLVMCreateMCJITCompilerForModule(&MCJIT, Module_val(M), &Options,60 sizeof(Options), &Error))61 llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error);62 return to_val(MCJIT);63}64 65/* ExecutionEngine.t -> unit */66value llvm_ee_dispose(value EE) {67 LLVMDisposeExecutionEngine(ExecutionEngine_val(EE));68 return Val_unit;69}70 71/* llmodule -> ExecutionEngine.t -> unit */72value llvm_ee_add_module(value M, value EE) {73 LLVMAddModule(ExecutionEngine_val(EE), Module_val(M));74 return Val_unit;75}76 77/* llmodule -> ExecutionEngine.t -> llmodule */78value llvm_ee_remove_module(value M, value EE) {79 LLVMModuleRef RemovedModule;80 char *Error;81 if (LLVMRemoveModule(ExecutionEngine_val(EE), Module_val(M), &RemovedModule,82 &Error))83 llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error);84 return Val_unit;85}86 87/* ExecutionEngine.t -> unit */88value llvm_ee_run_static_ctors(value EE) {89 LLVMRunStaticConstructors(ExecutionEngine_val(EE));90 return Val_unit;91}92 93/* ExecutionEngine.t -> unit */94value llvm_ee_run_static_dtors(value EE) {95 LLVMRunStaticDestructors(ExecutionEngine_val(EE));96 return Val_unit;97}98 99extern value llvm_alloc_data_layout(LLVMTargetDataRef TargetData);100 101/* ExecutionEngine.t -> Llvm_target.DataLayout.t */102value llvm_ee_get_data_layout(value EE) {103 value DataLayout;104 LLVMTargetDataRef OrigDataLayout;105 char *TargetDataCStr;106 107 OrigDataLayout = LLVMGetExecutionEngineTargetData(ExecutionEngine_val(EE));108 TargetDataCStr = LLVMCopyStringRepOfTargetData(OrigDataLayout);109 DataLayout = llvm_alloc_data_layout(LLVMCreateTargetData(TargetDataCStr));110 LLVMDisposeMessage(TargetDataCStr);111 112 return DataLayout;113}114 115/* Llvm.llvalue -> int64 -> llexecutionengine -> unit */116value llvm_ee_add_global_mapping(value Global, value Ptr, value EE) {117 LLVMAddGlobalMapping(ExecutionEngine_val(EE), Value_val(Global),118 (void *)(Int64_val(Ptr)));119 return Val_unit;120}121 122value llvm_ee_get_global_value_address(value Name, value EE) {123 return caml_copy_int64((int64_t)LLVMGetGlobalValueAddress(124 ExecutionEngine_val(EE), String_val(Name)));125}126 127value llvm_ee_get_function_address(value Name, value EE) {128 return caml_copy_int64((int64_t)LLVMGetFunctionAddress(129 ExecutionEngine_val(EE), String_val(Name)));130}131