Fix a missing-root error in interp.c:perform_tail_call().

This commit is contained in:
Jesse D. McDonald 2010-04-12 21:38:22 -05:00
parent 9f351abd86
commit 885a1ebdbb
3 changed files with 24 additions and 18 deletions

View File

@ -328,21 +328,27 @@ break_for_loop:
static void perform_tail_call(interp_state_t *state)
{
value_t new_lambda, new_argv, new_ctx, new_k;
gc_root_t new_lambda, new_argv, new_ctx, new_k;
new_lambda = get_input(state, get_fixnum(_LAMBDA_SLOT(state->lambda.value, TAIL_CALL)));
new_argv = get_input(state, get_fixnum(_LAMBDA_SLOT(state->lambda.value, ARG_LIST)));
new_ctx = get_input(state, get_fixnum(_LAMBDA_SLOT(state->lambda.value, CONTEXT)));
new_k = get_input(state, get_fixnum(_LAMBDA_SLOT(state->lambda.value, CONTINUATION)));
register_gc_root(&new_lambda, get_input(state, get_fixnum(_LAMBDA_SLOT(state->lambda.value, TAIL_CALL))));
register_gc_root(&new_argv, get_input(state, get_fixnum(_LAMBDA_SLOT(state->lambda.value, ARG_LIST))));
register_gc_root(&new_ctx, get_input(state, get_fixnum(_LAMBDA_SLOT(state->lambda.value, CONTEXT))));
register_gc_root(&new_k, get_input(state, get_fixnum(_LAMBDA_SLOT(state->lambda.value, CONTINUATION))));
/* If new lambda or continuation is a template, instantiate it here. */
new_lambda = make_lambda(state, new_lambda);
new_k = make_lambda(state, new_k);
/* If new lambda or continuation is a template, instantiate it here */
new_lambda.value = make_lambda(state, new_lambda.value);
new_k.value = make_lambda(state, new_k.value);
state->lambda.value = new_lambda;
state->argv.value = new_argv;
state->ctx.value = new_ctx;
state->k.value = new_k;
/* Transfer control to new function */
state->lambda.value = new_lambda.value;
state->argv.value = new_argv.value;
state->ctx.value = new_ctx.value;
state->k.value = new_k.value;
unregister_gc_root(&new_lambda);
unregister_gc_root(&new_argv);
unregister_gc_root(&new_ctx);
unregister_gc_root(&new_k);
}
static value_t eval_expression(interp_state_t *state, uint8_t code, uint8_t in1, uint8_t in2)

View File

@ -10,6 +10,7 @@
; (lambda () (string->number number-string))
; (lambda (n) (k (fact n))))))
#(
#="string->number"
#S(#="template"
; (let/cc k
; (lambda (n)
@ -25,14 +26,13 @@
0x40 ; i0
0x41 ; i1
)
#="string->number" ; g2
)
#()
1
"\x00\x80\x1b\x01"; (set! f0 (lambda g1))
0x02 ; g2
0
""
0x01 ; g1
0xfd ; argv
0xfe ; ctx
0x80 ; f0
0x02 ; g2
)
; vim:set syntax= sw=2 expandtab:

View File

@ -50,7 +50,7 @@
#=0 ; fact
)
"\x80"
2
1
"\x09\x80\x40\x01\; (set! f0 (fix- i0 g1))
\x02\x80\x80\x00"; (set! f0 (cons f0 nil))
0x03 ; g3