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)
|
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)
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue