1 /*===-- executionengine_ocaml.c - LLVM OCaml Glue ---------------*- C++ -*-===*\
3 |* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
5 |* See https://llvm.org/LICENSE.txt for license information. *|
6 |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
8 |*===----------------------------------------------------------------------===*|
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. *|
13 |* Note that these functions intentionally take liberties with the CAMLparamX *|
14 |* macros, since most of the parameters are not GC heap objects. *|
16 \*===----------------------------------------------------------------------===*/
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"
30 #define ExecutionEngine_val(v) ((LLVMExecutionEngineRef)from_val(v))
32 void llvm_raise(value Prototype
, char *Message
);
35 value
llvm_ee_initialize(value Unit
) {
38 return Val_bool(!LLVMInitializeNativeTarget() &&
39 !LLVMInitializeNativeAsmParser() &&
40 !LLVMInitializeNativeAsmPrinter());
43 /* llcompileroption -> llmodule -> ExecutionEngine.t */
44 value
llvm_ee_create(value OptRecordOpt
, value M
) {
45 LLVMExecutionEngineRef MCJIT
;
47 struct LLVMMCJITCompilerOptions Options
;
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));
59 if (LLVMCreateMCJITCompilerForModule(&MCJIT
, Module_val(M
), &Options
,
60 sizeof(Options
), &Error
))
61 llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error
);
65 /* ExecutionEngine.t -> unit */
66 value
llvm_ee_dispose(value EE
) {
67 LLVMDisposeExecutionEngine(ExecutionEngine_val(EE
));
71 /* llmodule -> ExecutionEngine.t -> unit */
72 value
llvm_ee_add_module(value M
, value EE
) {
73 LLVMAddModule(ExecutionEngine_val(EE
), Module_val(M
));
77 /* llmodule -> ExecutionEngine.t -> llmodule */
78 value
llvm_ee_remove_module(value M
, value EE
) {
79 LLVMModuleRef RemovedModule
;
81 if (LLVMRemoveModule(ExecutionEngine_val(EE
), Module_val(M
), &RemovedModule
,
83 llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error
);
87 /* ExecutionEngine.t -> unit */
88 value
llvm_ee_run_static_ctors(value EE
) {
89 LLVMRunStaticConstructors(ExecutionEngine_val(EE
));
93 /* ExecutionEngine.t -> unit */
94 value
llvm_ee_run_static_dtors(value EE
) {
95 LLVMRunStaticDestructors(ExecutionEngine_val(EE
));
99 extern value
llvm_alloc_data_layout(LLVMTargetDataRef TargetData
);
101 /* ExecutionEngine.t -> Llvm_target.DataLayout.t */
102 value
llvm_ee_get_data_layout(value EE
) {
104 LLVMTargetDataRef OrigDataLayout
;
105 char *TargetDataCStr
;
107 OrigDataLayout
= LLVMGetExecutionEngineTargetData(ExecutionEngine_val(EE
));
108 TargetDataCStr
= LLVMCopyStringRepOfTargetData(OrigDataLayout
);
109 DataLayout
= llvm_alloc_data_layout(LLVMCreateTargetData(TargetDataCStr
));
110 LLVMDisposeMessage(TargetDataCStr
);
115 /* Llvm.llvalue -> int64 -> llexecutionengine -> unit */
116 value
llvm_ee_add_global_mapping(value Global
, value Ptr
, value EE
) {
117 LLVMAddGlobalMapping(ExecutionEngine_val(EE
), Value_val(Global
),
118 (void *)(Int64_val(Ptr
)));
122 value
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
)));
127 value
llvm_ee_get_function_address(value Name
, value EE
) {
128 return caml_copy_int64((int64_t)LLVMGetFunctionAddress(
129 ExecutionEngine_val(EE
), String_val(Name
)));