1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
//! lightning-sys aims provides safe (as safe as a jit can be) rust bindings to GNU Lightning //! //! ## Examples: //! ### a function that increments a number by one //! ``` //! use lightning_sys::{Jit, Reg, JitPointer, JitWord}; //! //! let jit = Jit::new(); //! let js = jit.new_state(); //! //! js.prolog(); //! let inarg = js.arg(); //! js.getarg(Reg::R(0), &inarg); //! js.addi(Reg::R(0), Reg::R(0), 1); //! js.retr(Reg::R(0)); //! //! let incr = unsafe { js.emit::<extern fn(JitWord) -> JitWord>() }; //! js.clear(); //! //! assert_eq!(incr(5), 6); //! assert_eq!(incr(6), 7); //! //! ``` //! //! ### A simple function call to `printf` //! ``` //! extern crate libc; //! //! use std::ffi::CString; //! use lightning_sys::{Jit, JitWord, Reg, JitPointer}; //! use std::convert::TryInto; //! //! fn main() { //! let jit = Jit::new(); //! let js = jit.new_state(); //! //! // make sure this outlives any calls //! let cs = CString::new("generated %d bytes\n").unwrap(); //! //! let start = js.note(file!(), line!()); //! js.prolog(); //! let inarg = js.arg(); //! js.getarg(Reg::R(1), &inarg); //! js.prepare(); //! js.pushargi(cs.as_ptr() as JitWord); //! js.ellipsis(); //! js.pushargr(Reg::R(1)); //! js.finishi(libc::printf as JitPointer); //! js.ret(); //! js.epilog(); //! let end = js.note(file!(), line!()); //! //! let my_function = unsafe{ js.emit::<extern fn(JitWord)>() }; //! /* call the generated code, passing its size as argument */ //! my_function((js.address(&end) as u64 - js.address(&start) as u64).try_into().unwrap()); //! js.clear(); //! //! // TODO: dissasembly has not been implemented yet //! // js.dissasemble(); //! } //! //! ``` //! ### Fibonacci numbers //! ``` //! use lightning_sys::{Jit, JitWord, Reg, JitPointer, NULL}; //! //! fn main() { //! let jit = Jit::new(); //! let js = jit.new_state(); //! //! let label = js.label(); //! js.prolog(); //! let inarg = js.arg(); //! js.getarg(Reg::R(0), &inarg); //! let zero = js.beqi(Reg::R(0), 0); //! js.movr(Reg::V(0), Reg::R(0)); //! js.movi(Reg::R(0), 1); //! let refr = js.blei(Reg::V(0), 2); //! js.subi(Reg::V(1), Reg::V(0), 1); //! js.subi(Reg::V(2), Reg::V(0), 2); //! js.prepare(); //! js.pushargr(Reg::V(1)); //! let call = js.finishi(NULL); //! js.patch_at(&call, &label); //! js.retval(Reg::V(1)); //! js.prepare(); //! js.pushargr(Reg::V(2)); //! let call2 = js.finishi(NULL); //! js.patch_at(&call2, &label); //! js.retval(Reg::R(1)); //! js.addr(Reg::R(0), Reg::R(0), Reg::V(1)); //! //! js.patch(&refr); //! js.patch(&zero); //! js.retr(Reg::R(0)); //! js.epilog(); //! //! let fib = unsafe{ js.emit::<extern fn(JitWord) -> JitWord>() }; //! js.clear(); //! //! println!("fib({})={}", 32, fib(32)); //! assert_eq!(0, fib(0)); //! assert_eq!(1, fib(1)); //! assert_eq!(1, fib(2)); //! assert_eq!(2178309, fib(32)); //! } //! ``` #[allow(non_upper_case_globals)] #[allow(non_camel_case_types)] #[allow(non_snake_case)] #[allow(dead_code)] mod bindings; #[macro_use] extern crate mashup; extern crate num_traits; pub mod jit; pub use jit::Jit; pub mod jitstate; pub use jitstate::JitState; pub mod types; pub use types::NULL; pub use types::Reg; pub use types::JitNode; pub use types::{JitWord, JitUword, JitPointer}; pub(crate) use types::ToFFI;