lightning-sys 0.2.2

GNU lightning bindings for rust
Documentation
use lightning_sys::{Jit, JitWord, Reg, NULL};

// Create constants with the same names as in the original example, to ease
// comparison between the Rust and C versions.
const JIT_R0: Reg = Reg::R(0);
const JIT_R1: Reg = Reg::R(1);

#[allow(clippy::print_literal)]
fn main() {
    let mut j = Jit::new();
    let mut js = j.new_state();

    /* declare a forward label */
    let fact = js.forward();

    js.prolog();                        /* Entry point of the factorial function */
    let inp = js.arg();                 /* Receive an integer argument */
    js.getarg(JIT_R0, &inp);            /* Move argument to RO */
    js.prepare();
    js.pushargi(1);                     /* This is the accumulator */
    js.pushargr(JIT_R0);                /* This is the argument */
    let call = js.finishi(NULL);        /* Call the tail call optimized function */
    js.patch_at(&call, &fact);          /* Patch call to forward defined function */
    /* the above could have been written as:
     *          js.patch_at(js.finishi(NULL), fact);
     */
    js.retval(JIT_R0);                  /* Fetch the result */
    js.retr(JIT_R0);                    /* Return it */
    js.epilog();                        /* Epilog *before* label before prolog */

    /* define the forward label */
    js.link(&fact);                     /* Entry point of the helper function */
    js.prolog();
    js.frame(16);                       /* Reserve 16 bytes in the stack */
    let fact_entry = js.label();        /* This is the tail call entry point */
    let ac = js.arg();                  /* The accumulator is the first argument */
    let inp = js.arg();                 /* The factorial argument */
    js.getarg(JIT_R0, &ac);             /* Move the accumulator to R0 */
    js.getarg(JIT_R1, &inp);            /* Move the argument to R1 */
    let fact_out = js.blei(JIT_R1, 1);  /* Done if argument is one or less */
    js.mulr(JIT_R0, JIT_R0, JIT_R1);    /* accumulator *= argument */
    js.putargr(JIT_R0, &ac);            /* Update the accumulator */
    js.subi(JIT_R1, JIT_R1, 1);         /* argument -= 1 */
    js.putargr(JIT_R1, &inp);           /* Update the argument */
    let jump = js.jmpi();
    js.patch_at(&jump, &fact_entry);    /* Tail Call Optimize it! */
    js.patch(&fact_out);
    js.retr(JIT_R0);                    /* Return the accumulator */

    let factorial = unsafe{ js.emit::<extern fn(JitWord) -> JitWord>() };
    /* no need to query information about resolved addresses */
    js.clear();

    let arg = std::env::args().nth(1).map(|x| x.parse().unwrap_or(0)).unwrap_or(5);

    /* call the generated code */
    println!("factorial({}) = {}", arg, factorial(arg));
    /* release all memory associated with the _jit identifier */
    /* (this happens automatically with Drop in the Rust version) */
}