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;