Fix a missing-root error in interp.c:perform_tail_call().
This commit is contained in:
parent
9f351abd86
commit
885a1ebdbb
30
interp.c
30
interp.c
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue