6 个版本
0.2.2 | 2020 年 8 月 22 日 |
---|---|
0.2.1 | 2020 年 5 月 9 日 |
0.2.0 | 2019 年 8 月 17 日 |
0.1.2 | 2019 年 8 月 14 日 |
0.1.0 | 2019 年 7 月 21 日 |
#3 in #lightning
3MB
94K SLoC
包含 (不为人知的 autoconf 代码,9KB) vendor/gnu-lightning/configure.ac
lightning-sys
Rust 的安全 GNU lightning 绑定
GNU lightning 版本
此 crate 明确链接到其自己的 lightning-2.1.3 版本的副本。
MSRV
最低支持的 Rust 版本是 1.39。
示例
一个将数字增加 1 的函数
use lightning_sys::{Jit, Reg, JitPointer, JitWord};
let mut jit = Jit::new();
let mut 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);
对 printf
的简单函数调用
extern crate libc;
use std::ffi::CString;
use lightning_sys::{Jit, JitWord, Reg, JitPointer};
use std::convert::TryInto;
fn main() {
let mut jit = Jit::new();
let mut 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();
}
斐波那契数列
use lightning_sys::{Jit, JitWord, Reg, JitPointer, NULL};
fn main() {
let mut jit = Jit::new();
let mut 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(0));
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));
}
尾调用优化的阶乘
use lightning_sys::{Jit, JitWord, Reg, NULL};
fn main() {
let mut jit = Jit::new();
let mut js = jit.new_state();
let fact = js.forward();
js.prolog();
let inarg = js.arg();
js.getarg(Reg::R(0), &inarg);
js.prepare();
js.pushargi(1);
js.pushargr(Reg::R(0));
let call = js.finishi(NULL);
js.patch_at(&call, &fact);
js.retval(Reg::R(0));
js.retr(Reg::R(0));
js.epilog();
js.link(&fact);
js.prolog();
js.frame(16);
let f_ent = js.label(); // TCO entry point
let ac = js.arg();
let ina = js.arg();
js.getarg(Reg::R(0), &ac);
js.getarg(Reg::R(1), &ina);
let f_out = js.blei(Reg::R(1), 1);
js.mulr(Reg::R(0), Reg::R(0), Reg::R(1));
js.putargr(Reg::R(0), &ac);
js.subi(Reg::R(1), Reg::R(1), 1);
js.putargr(Reg::R(1), &ina);
let jump = js.jmpi(); // tail call optimiation
js.patch_at(&jump, &f_ent);
js.patch(&f_out);
js.retr(Reg::R(0));
let factorial = unsafe{ js.emit::<extern fn(JitWord) -> JitWord>() };
js.clear();
println!("factorial({}) = {}", 5, factorial(5));
}
依赖项
~0.1–2.7MB
~42K SLoC