1 (* RUN: %ocamlopt -warn-error A llvm.cmxa llvm_target.cmxa llvm_executionengine.cmxa %s -o %t 2 * RUN: %t 3 * XFAIL: vg_leak 4 *) 5 6 open Llvm 7 open Llvm_executionengine 8 open Llvm_target 9 10 (* Note that this takes a moment to link, so it's best to keep the number of 11 individual tests low. *) 12 13 let context = global_context () 14 let i8_type = Llvm.i8_type context 15 let i32_type = Llvm.i32_type context 16 let i64_type = Llvm.i64_type context 17 let double_type = Llvm.double_type context 18 19 let bomb msg = 20 prerr_endline msg; 21 exit 2 22 23 let define_main_fn m retval = 24 let fn = 25 let str_arr_type = pointer_type (pointer_type i8_type) in 26 define_function "main" (function_type i32_type [| i32_type; 27 str_arr_type; 28 str_arr_type |]) m in 29 let b = builder_at_end (global_context ()) (entry_block fn) in 30 ignore (build_ret (const_int i32_type retval) b); 31 fn 32 33 let define_plus m = 34 let fn = define_function "plus" (function_type i32_type [| i32_type; 35 i32_type |]) m in 36 let b = builder_at_end (global_context ()) (entry_block fn) in 37 let add = build_add (param fn 0) (param fn 1) "sum" b in 38 ignore (build_ret add b) 39 40 let test_genericvalue () = 41 let tu = (1, 2) in 42 let ptrgv = GenericValue.of_pointer tu in 43 assert (tu = GenericValue.as_pointer ptrgv); 44 45 let fpgv = GenericValue.of_float double_type 2. in 46 assert (2. = GenericValue.as_float double_type fpgv); 47 48 let intgv = GenericValue.of_int i32_type 3 in 49 assert (3 = GenericValue.as_int intgv); 50 51 let i32gv = GenericValue.of_int32 i32_type (Int32.of_int 4) in 52 assert ((Int32.of_int 4) = GenericValue.as_int32 i32gv); 53 54 let nigv = GenericValue.of_nativeint i32_type (Nativeint.of_int 5) in 55 assert ((Nativeint.of_int 5) = GenericValue.as_nativeint nigv); 56 57 let i64gv = GenericValue.of_int64 i64_type (Int64.of_int 6) in 58 assert ((Int64.of_int 6) = GenericValue.as_int64 i64gv) 59 60 let test_executionengine () = 61 (* create *) 62 let m = create_module (global_context ()) "test_module" in 63 let main = define_main_fn m 42 in 64 65 let m2 = create_module (global_context ()) "test_module2" in 66 define_plus m2; 67 68 let ee = ExecutionEngine.create m in 69 ExecutionEngine.add_module m2 ee; 70 71 (* run_static_ctors *) 72 ExecutionEngine.run_static_ctors ee; 73 74 (* run_function_as_main *) 75 let res = ExecutionEngine.run_function_as_main main [|"test"|] [||] ee in 76 if 42 != res then bomb "main did not return 42"; 77 78 (* free_machine_code *) 79 ExecutionEngine.free_machine_code main ee; 80 81 (* find_function *) 82 match ExecutionEngine.find_function "dne" ee with 83 | Some _ -> raise (Failure "find_function 'dne' failed") 84 | None -> 85 86 match ExecutionEngine.find_function "plus" ee with 87 | None -> raise (Failure "find_function 'plus' failed") 88 | Some plus -> 89 90 (* run_function *) 91 let res = ExecutionEngine.run_function plus 92 [| GenericValue.of_int i32_type 2; 93 GenericValue.of_int i32_type 2 |] 94 ee in 95 if 4 != GenericValue.as_int res then bomb "plus did not work"; 96 97 (* remove_module *) 98 Llvm.dispose_module (ExecutionEngine.remove_module m2 ee); 99 100 (* run_static_dtors *) 101 ExecutionEngine.run_static_dtors ee; 102 103 (* Show that the target data binding links and runs.*) 104 let td = ExecutionEngine.target_data ee in 105 106 (* Demonstrate that a garbage pointer wasn't returned. *) 107 let ty = intptr_type td in 108 if ty != i32_type && ty != i64_type then bomb "target_data did not work"; 109 110 (* dispose *) 111 ExecutionEngine.dispose ee 112 113 let _ = 114 test_genericvalue (); 115 test_executionengine () 116