mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-27 21:40:34 +02:00
Update documentation on jit_frame and jit_tramp
* doc/body.texi: Reorder documentation, making jit_frame and jit_tramp the lightning response to the need of trampolines, continuations and tail call optimizations. A pseudo code example of a factorial function was added. Also added a section for description of the available predicates. * doc/fact.c: New file, implementing a simple example of a translation of a trivial, recursive, tail call optimization into lightning calls. This is the conversion to functional C code of the example in doc/body.texi. * doc/Makefile.am: Update for the next test case.
This commit is contained in:
parent
c8b6c36971
commit
894a02412c
4 changed files with 258 additions and 43 deletions
75
doc/fact.c
Normal file
75
doc/fact.c
Normal file
|
@ -0,0 +1,75 @@
|
|||
#include <stdio.h>
|
||||
#include <lightning.h>
|
||||
|
||||
static jit_state_t *_jit;
|
||||
|
||||
typedef long (*pwfw_t)(long); /* Pointer to Long Function of Long */
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
pwfw_t factorial;
|
||||
long arg;
|
||||
jit_node_t *ac; /* Accumulator */
|
||||
jit_node_t *in; /* Argument */
|
||||
jit_node_t *call;
|
||||
jit_node_t *fact;
|
||||
jit_node_t *jump;
|
||||
jit_node_t *fact_entry;
|
||||
jit_node_t *fact_out;
|
||||
|
||||
init_jit(argv[0]);
|
||||
_jit = jit_new_state();
|
||||
|
||||
/* declare a forward label */
|
||||
fact = jit_forward();
|
||||
|
||||
jit_prolog(); /* Entry point of the factorial function */
|
||||
in = jit_arg(); /* Receive an integer argument */
|
||||
jit_getarg(JIT_R0, in); /* Move argument to RO */
|
||||
jit_prepare();
|
||||
jit_pushargi(1); /* This is the accumulator */
|
||||
jit_pushargr(JIT_R0); /* This is the argument */
|
||||
call = jit_finishi(NULL); /* Call the tail call optimized function */
|
||||
jit_patch_at(call, fact); /* Patch call to forward defined function */
|
||||
/* the above could have been written as:
|
||||
* jit_patch_at(jit_finishi(NULL), fact);
|
||||
*/
|
||||
jit_retval(JIT_R0); /* Fetch the result */
|
||||
jit_retr(JIT_R0); /* Return it */
|
||||
jit_epilog(); /* Epilog *before* label before prolog */
|
||||
|
||||
/* define the forward label */
|
||||
jit_link(fact); /* Entry point of the helper function */
|
||||
jit_prolog();
|
||||
jit_frame(16); /* Reserve 16 bytes in the stack */
|
||||
fact_entry = jit_label(); /* This is the tail call entry point */
|
||||
ac = jit_arg(); /* The accumulator is the first argument */
|
||||
in = jit_arg(); /* The factorial argument */
|
||||
jit_getarg(JIT_R0, ac); /* Move the accumulator to R0 */
|
||||
jit_getarg(JIT_R1, in); /* Move the argument to R1 */
|
||||
fact_out = jit_blei(JIT_R1, 1); /* Done if argument is one or less */
|
||||
jit_mulr(JIT_R0, JIT_R0, JIT_R1); /* accumulator *= argument */
|
||||
jit_putargr(JIT_R0, ac); /* Update the accumulator */
|
||||
jit_subi(JIT_R1, JIT_R1, 1); /* argument -= 1 */
|
||||
jit_putargr(JIT_R1, in); /* Update the argument */
|
||||
jump = jit_jmpi();
|
||||
jit_patch_at(jump, fact_entry); /* Tail Call Optimize it! */
|
||||
jit_patch(fact_out);
|
||||
jit_retr(JIT_R0); /* Return the accumulator */
|
||||
|
||||
factorial = jit_emit();
|
||||
/* no need to query information about resolved addresses */
|
||||
jit_clear_state();
|
||||
|
||||
if (argc == 2)
|
||||
arg = atoi(argv[1]);
|
||||
else
|
||||
arg = 5;
|
||||
|
||||
/* call the generated code */
|
||||
printf("factorial(%ld) = %ld\n", arg, factorial(arg));
|
||||
/* release all memory associated with the _jit identifier */
|
||||
jit_destroy_state();
|
||||
finish_jit();
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue