1*9880d681SAndroid Build Coastguard Worker(* RUN: cp %s %T/executionengine.ml 2*9880d681SAndroid Build Coastguard Worker * RUN: %ocamlc -g -w +A -package llvm.executionengine -linkpkg %T/executionengine.ml -o %t 3*9880d681SAndroid Build Coastguard Worker * RUN: %t 4*9880d681SAndroid Build Coastguard Worker * RUN: %ocamlopt -g -w +A -package llvm.executionengine -linkpkg %T/executionengine.ml -o %t 5*9880d681SAndroid Build Coastguard Worker * RUN: %t 6*9880d681SAndroid Build Coastguard Worker * REQUIRES: native, object-emission 7*9880d681SAndroid Build Coastguard Worker * XFAIL: vg_leak 8*9880d681SAndroid Build Coastguard Worker *) 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Workeropen Llvm 11*9880d681SAndroid Build Coastguard Workeropen Llvm_executionengine 12*9880d681SAndroid Build Coastguard Workeropen Llvm_target 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Worker(* Note that this takes a moment to link, so it's best to keep the number of 15*9880d681SAndroid Build Coastguard Worker individual tests low. *) 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Workerlet context = global_context () 18*9880d681SAndroid Build Coastguard Workerlet i8_type = Llvm.i8_type context 19*9880d681SAndroid Build Coastguard Workerlet i32_type = Llvm.i32_type context 20*9880d681SAndroid Build Coastguard Workerlet i64_type = Llvm.i64_type context 21*9880d681SAndroid Build Coastguard Workerlet double_type = Llvm.double_type context 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Workerlet () = 24*9880d681SAndroid Build Coastguard Worker assert (Llvm_executionengine.initialize ()) 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Workerlet bomb msg = 27*9880d681SAndroid Build Coastguard Worker prerr_endline msg; 28*9880d681SAndroid Build Coastguard Worker exit 2 29*9880d681SAndroid Build Coastguard Worker 30*9880d681SAndroid Build Coastguard Workerlet define_getglobal m pg = 31*9880d681SAndroid Build Coastguard Worker let fn = define_function "getglobal" (function_type i32_type [||]) m in 32*9880d681SAndroid Build Coastguard Worker let b = builder_at_end (global_context ()) (entry_block fn) in 33*9880d681SAndroid Build Coastguard Worker let g = build_call pg [||] "" b in 34*9880d681SAndroid Build Coastguard Worker ignore (build_ret g b); 35*9880d681SAndroid Build Coastguard Worker fn 36*9880d681SAndroid Build Coastguard Worker 37*9880d681SAndroid Build Coastguard Workerlet define_plus m = 38*9880d681SAndroid Build Coastguard Worker let fn = define_function "plus" (function_type i32_type [| i32_type; 39*9880d681SAndroid Build Coastguard Worker i32_type |]) m in 40*9880d681SAndroid Build Coastguard Worker let b = builder_at_end (global_context ()) (entry_block fn) in 41*9880d681SAndroid Build Coastguard Worker let add = build_add (param fn 0) (param fn 1) "sum" b in 42*9880d681SAndroid Build Coastguard Worker ignore (build_ret add b); 43*9880d681SAndroid Build Coastguard Worker fn 44*9880d681SAndroid Build Coastguard Worker 45*9880d681SAndroid Build Coastguard Workerlet test_executionengine () = 46*9880d681SAndroid Build Coastguard Worker let open Ctypes in 47*9880d681SAndroid Build Coastguard Worker 48*9880d681SAndroid Build Coastguard Worker (* create *) 49*9880d681SAndroid Build Coastguard Worker let m = create_module (global_context ()) "test_module" in 50*9880d681SAndroid Build Coastguard Worker let ee = create m in 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Worker (* add plus *) 53*9880d681SAndroid Build Coastguard Worker ignore (define_plus m); 54*9880d681SAndroid Build Coastguard Worker 55*9880d681SAndroid Build Coastguard Worker (* declare global variable *) 56*9880d681SAndroid Build Coastguard Worker ignore (define_global "globvar" (const_int i32_type 23) m); 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Worker (* add module *) 59*9880d681SAndroid Build Coastguard Worker let m2 = create_module (global_context ()) "test_module2" in 60*9880d681SAndroid Build Coastguard Worker add_module m2 ee; 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Worker (* add global mapping *) 63*9880d681SAndroid Build Coastguard Worker (* BROKEN: see PR20656 *) 64*9880d681SAndroid Build Coastguard Worker (* let g = declare_function "g" (function_type i32_type [||]) m2 in 65*9880d681SAndroid Build Coastguard Worker let cg = coerce (Foreign.funptr (void @-> returning int32_t)) (ptr void) 66*9880d681SAndroid Build Coastguard Worker (fun () -> 42l) in 67*9880d681SAndroid Build Coastguard Worker add_global_mapping g cg ee; 68*9880d681SAndroid Build Coastguard Worker 69*9880d681SAndroid Build Coastguard Worker (* check g *) 70*9880d681SAndroid Build Coastguard Worker let cg' = get_pointer_to_global g (ptr void) ee in 71*9880d681SAndroid Build Coastguard Worker if 0 <> ptr_compare cg cg' then bomb "int pointers to g differ"; 72*9880d681SAndroid Build Coastguard Worker 73*9880d681SAndroid Build Coastguard Worker (* add getglobal *) 74*9880d681SAndroid Build Coastguard Worker let getglobal = define_getglobal m2 g in*) 75*9880d681SAndroid Build Coastguard Worker 76*9880d681SAndroid Build Coastguard Worker (* run_static_ctors *) 77*9880d681SAndroid Build Coastguard Worker run_static_ctors ee; 78*9880d681SAndroid Build Coastguard Worker 79*9880d681SAndroid Build Coastguard Worker (* get a handle on globvar *) 80*9880d681SAndroid Build Coastguard Worker let varh = get_global_value_address "globvar" int32_t ee in 81*9880d681SAndroid Build Coastguard Worker if 23l <> varh then bomb "get_global_value_address didn't work"; 82*9880d681SAndroid Build Coastguard Worker 83*9880d681SAndroid Build Coastguard Worker (* call plus *) 84*9880d681SAndroid Build Coastguard Worker let cplusty = Foreign.funptr (int32_t @-> int32_t @-> returning int32_t) in 85*9880d681SAndroid Build Coastguard Worker let cplus = get_function_address "plus" cplusty ee in 86*9880d681SAndroid Build Coastguard Worker if 4l <> cplus 2l 2l then bomb "plus didn't work"; 87*9880d681SAndroid Build Coastguard Worker 88*9880d681SAndroid Build Coastguard Worker (* call getglobal *) 89*9880d681SAndroid Build Coastguard Worker (* let cgetglobalty = Foreign.funptr (void @-> returning int32_t) in 90*9880d681SAndroid Build Coastguard Worker let cgetglobal = get_pointer_to_global getglobal cgetglobalty ee in 91*9880d681SAndroid Build Coastguard Worker if 42l <> cgetglobal () then bomb "getglobal didn't work"; *) 92*9880d681SAndroid Build Coastguard Worker 93*9880d681SAndroid Build Coastguard Worker (* remove_module *) 94*9880d681SAndroid Build Coastguard Worker remove_module m2 ee; 95*9880d681SAndroid Build Coastguard Worker dispose_module m2; 96*9880d681SAndroid Build Coastguard Worker 97*9880d681SAndroid Build Coastguard Worker (* run_static_dtors *) 98*9880d681SAndroid Build Coastguard Worker run_static_dtors ee; 99*9880d681SAndroid Build Coastguard Worker 100*9880d681SAndroid Build Coastguard Worker (* Show that the data layout binding links and runs.*) 101*9880d681SAndroid Build Coastguard Worker let dl = data_layout ee in 102*9880d681SAndroid Build Coastguard Worker 103*9880d681SAndroid Build Coastguard Worker (* Demonstrate that a garbage pointer wasn't returned. *) 104*9880d681SAndroid Build Coastguard Worker let ty = DataLayout.intptr_type context dl in 105*9880d681SAndroid Build Coastguard Worker if ty != i32_type && ty != i64_type then bomb "target_data did not work"; 106*9880d681SAndroid Build Coastguard Worker 107*9880d681SAndroid Build Coastguard Worker (* dispose *) 108*9880d681SAndroid Build Coastguard Worker dispose ee 109*9880d681SAndroid Build Coastguard Worker 110*9880d681SAndroid Build Coastguard Workerlet () = 111*9880d681SAndroid Build Coastguard Worker test_executionengine (); 112*9880d681SAndroid Build Coastguard Worker Gc.compact () 113