commit 26f445bbbff6aa1df91bcc20b7d4250eabac7f1b
parent 57cd4aa9819801558b14d8ae0c5d51f353d07396
Author: Andres Navarro <canavarro82@gmail.com>
Date: Sat, 16 Apr 2011 21:46:55 -0300
Bugfix: unbalanced push/pop in gc rooting.
Diffstat:
2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/src/krepl.c b/src/krepl.c
@@ -68,9 +68,10 @@ void eval_cfn(klisp_State *K, TValue *xparams, TValue obj)
void loop_fn(klisp_State *K, TValue *xparams, TValue obj);
/* this is called from both loop_fn and error_fn */
-/* GC: assumes denv is rooted */
+/* GC: assumes denv is NOT rooted */
inline void create_loop(klisp_State *K, TValue denv)
{
+ krooted_tvs_push(K, denv);
TValue loop_cont =
kmake_continuation(K, K->root_cont, &loop_fn, 1, denv);
krooted_tvs_push(K, loop_cont);
@@ -78,8 +79,9 @@ inline void create_loop(klisp_State *K, TValue denv)
krooted_tvs_pop(K); /* in eval cont */
krooted_tvs_push(K, eval_cont);
TValue read_cont = kmake_continuation(K, eval_cont, &read_fn, 0);
- krooted_tvs_pop(K);
kset_cc(K, read_cont);
+ krooted_tvs_pop(K);
+ krooted_tvs_pop(K);
kapply_cc(K, KINERT);
}
@@ -144,8 +146,8 @@ void kinit_repl(klisp_State *K)
krooted_tvs_pop(K);
krooted_tvs_pop(K);
+ krooted_tvs_pop(K);
- /* don't yet pop std_env */
+ /* GC: create_loop will root std_env */
create_loop(K, std_env);
- krooted_tvs_pop(K);
}
diff --git a/src/kstate.h b/src/kstate.h
@@ -34,7 +34,7 @@ typedef struct {
int32_t saved_col;
} ksource_info_t;
-#define GC_PROTECT_SIZE 32
+#define GC_PROTECT_SIZE 6 /* XXX was 32 */
/* NOTE: when adding TValues here, remember to add them to
markroot in kgc.c!! */
@@ -341,6 +341,9 @@ typedef void (*klisp_Ofunc) (klisp_State *K, TValue *ud, TValue ptree,
*/
inline void klispS_apply_cc(klisp_State *K, TValue val)
{
+ klisp_assert(K->rooted_tvs_top == 0);
+ klisp_assert(K->rooted_vars_top == 0);
+
K->next_obj = K->curr_cont; /* save it from GC */
Continuation *cont = tv2cont(K->curr_cont);
K->next_func = cont->fn;
@@ -370,6 +373,9 @@ inline void klispS_set_cc(klisp_State *K, TValue new_cont)
inline void klispS_tail_call(klisp_State *K, TValue top, TValue ptree,
TValue env)
{
+ klisp_assert(K->rooted_tvs_top == 0);
+ klisp_assert(K->rooted_vars_top == 0);
+
K->next_obj = top; /* save it from GC */
Operative *op = tv2op(top);
K->next_func = op->fn;