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) 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))); register_gc_root(&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))); register_gc_root(&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))); register_gc_root(&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_k, get_input(state, get_fixnum(_LAMBDA_SLOT(state->lambda.value, CONTINUATION))));
/* If new lambda or continuation is a template, instantiate it here. */ /* If new lambda or continuation is a template, instantiate it here */
new_lambda = make_lambda(state, new_lambda); new_lambda.value = make_lambda(state, new_lambda.value);
new_k = make_lambda(state, new_k); new_k.value = make_lambda(state, new_k.value);
state->lambda.value = new_lambda; /* Transfer control to new function */
state->argv.value = new_argv; state->lambda.value = new_lambda.value;
state->ctx.value = new_ctx; state->argv.value = new_argv.value;
state->k.value = new_k; 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) 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 () (string->number number-string))
; (lambda (n) (k (fact n)))))) ; (lambda (n) (k (fact n))))))
#( #(
#="string->number"
#S(#="template" #S(#="template"
; (let/cc k ; (let/cc k
; (lambda (n) ; (lambda (n)
@ -25,14 +26,13 @@
0x40 ; i0 0x40 ; i0
0x41 ; i1 0x41 ; i1
) )
#="string->number" ; g2
) )
#() #()
1 0
"\x00\x80\x1b\x01"; (set! f0 (lambda g1)) ""
0x02 ; g2 0x01 ; g1
0xfd ; argv 0xfd ; argv
0xfe ; ctx 0xfe ; ctx
0x80 ; f0 0x02 ; g2
) )
; vim:set syntax= sw=2 expandtab: ; vim:set syntax= sw=2 expandtab:

View File

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