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:: 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) */ }