klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

commit 0af0483146e78e873be4820124965773f54dce9f
parent c6c298863a93e9ecab8cf737457bfe6804b79c2c
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Sat, 16 Apr 2011 12:10:47 -0300

Added gc rooting kgenvironments

Diffstat:
Msrc/kgenvironments.c | 166++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 136 insertions(+), 30 deletions(-)

diff --git a/src/kgenvironments.c b/src/kgenvironments.c @@ -88,13 +88,12 @@ void make_environment(klisp_State *K, TValue *xparams, TValue ptree, ** If bindings is not finite (or not a list) an error is signaled. */ +/* GC: assume bindings is rooted, uses dummys 1 & 2 */ TValue split_check_let_bindings(klisp_State *K, char *name, TValue bindings, TValue *exprs, bool starp) { - TValue dummy_cars = kcons(K, KNIL, KNIL); - TValue last_car_pair = dummy_cars; - TValue dummy_cadrs = kcons(K, KNIL, KNIL); - TValue last_cadr_pair = dummy_cadrs; + TValue last_car_pair = kget_dummy1(K); + TValue last_cadr_pair = kget_dummy2(K); TValue tail = bindings; @@ -104,6 +103,8 @@ TValue split_check_let_bindings(klisp_State *K, char *name, TValue bindings, if (!ttispair(first) || !ttispair(kcdr(first)) || !ttisnil(kcddr(first))) { unmark_list(K, bindings); + UNUSED(kcutoff_dummy1(K)); + UNUSED(kcutoff_dummy2(K)); klispE_throw_extra(K, name, ": bad structure in bindings"); return KNIL; } @@ -120,6 +121,9 @@ TValue split_check_let_bindings(klisp_State *K, char *name, TValue bindings, unmark_list(K, bindings); + TValue cars = kcutoff_dummy1(K); + TValue cadrs = kcutoff_dummy2(K); + if (!ttispair(tail) && !ttisnil(tail)) { klispE_throw_extra(K, name, ": expected list"); return KNIL; @@ -127,24 +131,29 @@ TValue split_check_let_bindings(klisp_State *K, char *name, TValue bindings, klispE_throw_extra(K, name , ": expected finite list"); return KNIL; } else { - *exprs = kcdr(dummy_cadrs); - TValue res; + /* check copy list could throw an error + and leave the dummys full, use tvs_push instead */ + krooted_tvs_push(K, cars); + krooted_tvs_push(K, cadrs); + + *exprs = cadrs; if (starp) { /* all bindings are consider individual ptrees in these 'let's, replace each ptree with its copy (after checking of course) */ - tail = kcdr(dummy_cars); + tail = cars; while(!ttisnil(tail)) { TValue first = kcar(tail); TValue copy = check_copy_ptree(K, name, first, KIGNORE); kset_car(tail, copy); tail = kcdr(tail); } - res = kcdr(dummy_cars); } else { /* all bindings are consider one ptree in these 'let's */ - res = check_copy_ptree(K, name, kcdr(dummy_cars), KIGNORE); + cars = check_copy_ptree(K, name, cars, KIGNORE); } - return res; + krooted_tvs_pop(K); + krooted_tvs_pop(K); + return cars; } } @@ -191,10 +200,12 @@ void do_let(klisp_State *K, TValue *xparams, TValue obj) } } else { TValue new_env = kmake_environment(K, env); + krooted_tvs_push(K, new_env); TValue new_cont = kmake_continuation(K, kget_cc(K), KNIL, KNIL, do_let, 7, sname, kcar(bindings), kcdr(bindings), kcdr(exprs), new_env, b2tv(false), body); + krooted_tvs_pop(K); kset_cc(K, new_cont); ktail_eval(K, kcar(exprs), recp? new_env : env); } @@ -213,16 +224,28 @@ void Slet(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) TValue exprs; TValue bptree = split_check_let_bindings(K, name, bindings, &exprs, false); - int32_t dummy; - UNUSED(check_list(K, name, true, body, &dummy)); + krooted_tvs_push(K, bptree); + krooted_tvs_push(K, exprs); + + UNUSED(check_list(K, name, true, body, NULL)); body = copy_es_immutable_h(K, name, body, false); + krooted_tvs_push(K, body); TValue new_env = kmake_environment(K, denv); + krooted_tvs_push(K, new_env); TValue new_cont = kmake_continuation(K, kget_cc(K), KNIL, KNIL, do_let, 7, sname, bptree, KNIL, KNIL, new_env, b2tv(false), body); kset_cc(K, new_cont); - ktail_eval(K, kcons(K, K->list_app, exprs), denv); + + TValue expr = kcons(K, K->list_app, exprs); + + krooted_tvs_pop(K); + krooted_tvs_pop(K); + krooted_tvs_pop(K); + krooted_tvs_pop(K); + + ktail_eval(K, expr, denv); } /* Helper for $binds? */ @@ -262,13 +285,14 @@ void Sbindsp(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) bind_al1p(K, "binds?", ptree, env_expr, symbols); /* REFACTOR replace with single function check_copy_typed_list */ - int32_t dummy; int32_t count = check_typed_list(K, "$binds?", "symbol", ksymbolp, - true, symbols, &dummy); + true, symbols, NULL); symbols = check_copy_list(K, "$binds?", symbols, false); + krooted_tvs_push(K, symbols); TValue new_cont = kmake_continuation(K, kget_cc(K), KNIL, KNIL, do_bindsp, 2, symbols, i2tv(count)); + krooted_tvs_pop(K); kset_cc(K, new_cont); ktail_eval(K, env_expr, denv); } @@ -306,24 +330,39 @@ void SletS(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) TValue exprs; TValue bptree = split_check_let_bindings(K, name, bindings, &exprs, true); - int32_t dummy; - UNUSED(check_list(K, name, true, body, &dummy)); + krooted_tvs_push(K, exprs); + krooted_tvs_push(K, bptree); + UNUSED(check_list(K, name, true, body, NULL)); body = copy_es_immutable_h(K, name, body, false); + krooted_tvs_push(K, body); TValue new_env = kmake_environment(K, denv); + krooted_tvs_push(K, new_env); + if (ttisnil(bptree)) { /* same as $let */ TValue new_cont = kmake_continuation(K, kget_cc(K), KNIL, KNIL, do_let, 7, sname, bptree, KNIL, KNIL, new_env, b2tv(false), body); kset_cc(K, new_cont); - ktail_eval(K, kcons(K, K->list_app, exprs), denv); + + TValue expr = kcons(K, K->list_app, exprs); + krooted_tvs_pop(K); + krooted_tvs_pop(K); + krooted_tvs_pop(K); + krooted_tvs_pop(K); + ktail_eval(K, expr, denv); } else { TValue new_cont = kmake_continuation(K, kget_cc(K), KNIL, KNIL, do_let, 7, sname, kcar(bptree), kcdr(bptree), kcdr(exprs), new_env, b2tv(false), body); kset_cc(K, new_cont); + + krooted_tvs_pop(K); + krooted_tvs_pop(K); + krooted_tvs_pop(K); + krooted_tvs_pop(K); ktail_eval(K, kcar(exprs), denv); } } @@ -340,16 +379,29 @@ void Sletrec(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) TValue exprs; TValue bptree = split_check_let_bindings(K, name, bindings, &exprs, false); - int32_t dummy; - UNUSED(check_list(K, name, true, body, &dummy)); + krooted_tvs_push(K, exprs); + krooted_tvs_push(K, bptree); + + UNUSED(check_list(K, name, true, body, NULL)); body = copy_es_immutable_h(K, name, body, false); + krooted_tvs_push(K, body); TValue new_env = kmake_environment(K, denv); + krooted_tvs_push(K, new_env); + TValue new_cont = kmake_continuation(K, kget_cc(K), KNIL, KNIL, do_let, 7, sname, bptree, KNIL, KNIL, new_env, b2tv(true), body); kset_cc(K, new_cont); - ktail_eval(K, kcons(K, K->list_app, exprs), new_env); + + TValue expr = kcons(K, K->list_app, exprs); + + krooted_tvs_pop(K); + krooted_tvs_pop(K); + krooted_tvs_pop(K); + krooted_tvs_pop(K); + + ktail_eval(K, expr, new_env); } /* 6.7.6 $letrec* */ @@ -364,24 +416,40 @@ void SletrecS(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) TValue exprs; TValue bptree = split_check_let_bindings(K, name, bindings, &exprs, true); - int32_t dummy; - UNUSED(check_list(K, name, true, body, &dummy)); + krooted_tvs_push(K, exprs); + krooted_tvs_push(K, bptree); + UNUSED(check_list(K, name, true, body, NULL)); body = copy_es_immutable_h(K, name, body, false); + krooted_tvs_push(K, body); TValue new_env = kmake_environment(K, denv); + krooted_tvs_push(K, new_env); + if (ttisnil(bptree)) { /* same as $letrec */ TValue new_cont = kmake_continuation(K, kget_cc(K), KNIL, KNIL, do_let, 7, sname, bptree, KNIL, KNIL, new_env, b2tv(true), body); kset_cc(K, new_cont); - ktail_eval(K, kcons(K, K->list_app, exprs), new_env); + + TValue expr = kcons(K, K->list_app, exprs); + + krooted_tvs_pop(K); + krooted_tvs_pop(K); + krooted_tvs_pop(K); + krooted_tvs_pop(K); + ktail_eval(K, expr, new_env); } else { TValue new_cont = kmake_continuation(K, kget_cc(K), KNIL, KNIL, do_let, 7, sname, kcar(bptree), kcdr(bptree), kcdr(exprs), new_env, b2tv(true), body); kset_cc(K, new_cont); + + krooted_tvs_pop(K); + krooted_tvs_pop(K); + krooted_tvs_pop(K); + krooted_tvs_pop(K); ktail_eval(K, kcar(exprs), new_env); } } @@ -408,10 +476,13 @@ void do_let_redirect(klisp_State *K, TValue *xparams, TValue obj) return; } TValue new_env = kmake_environment(K, obj); + krooted_tvs_push(K, new_env); TValue new_cont = kmake_continuation(K, kget_cc(K), KNIL, KNIL, do_let, 7, sname, bptree, KNIL, KNIL, new_env, b2tv(false), body); kset_cc(K, new_cont); + + krooted_tvs_pop(K); ktail_eval(K, lexpr, denv); } @@ -427,15 +498,26 @@ void Slet_redirect(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) TValue exprs; TValue bptree = split_check_let_bindings(K, name, bindings, &exprs, false); - int32_t dummy; - UNUSED(check_list(K, name, true, body, &dummy)); + krooted_tvs_push(K, exprs); + krooted_tvs_push(K, bptree); + + UNUSED(check_list(K, name, true, body, NULL)); body = copy_es_immutable_h(K, name, body, false); + krooted_tvs_push(K, body); TValue eexpr = kcons(K, K->list_app, exprs); + krooted_tvs_push(K, eexpr); + TValue new_cont = kmake_continuation(K, kget_cc(K), KNIL, KNIL, do_let_redirect, 5, sname, bptree, eexpr, denv, body); kset_cc(K, new_cont); + + krooted_tvs_pop(K); + krooted_tvs_pop(K); + krooted_tvs_pop(K); + krooted_tvs_pop(K); + ktail_eval(K, env_exp, denv); } @@ -451,18 +533,31 @@ void Slet_safe(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) TValue exprs; TValue bptree = split_check_let_bindings(K, name, bindings, &exprs, false); - int32_t dummy; - UNUSED(check_list(K, name, true, body, &dummy)); + krooted_tvs_push(K, exprs); + krooted_tvs_push(K, bptree); + + UNUSED(check_list(K, name, true, body, NULL)); + body = copy_es_immutable_h(K, name, body, false); + krooted_tvs_push(K, body); + /* according to the definition of the report it should be a child of a child of the ground environment, but since this is a fresh environment, the semantics are the same */ TValue new_env = kmake_environment(K, K->ground_env); + krooted_tvs_push(K, new_env); TValue new_cont = kmake_continuation(K, kget_cc(K), KNIL, KNIL, do_let, 7, sname, bptree, KNIL, KNIL, new_env, b2tv(false), body); kset_cc(K, new_cont); - ktail_eval(K, kcons(K, K->list_app, exprs), denv); + + TValue expr = kcons(K, K->list_app, exprs); + krooted_tvs_pop(K); + krooted_tvs_pop(K); + krooted_tvs_pop(K); + krooted_tvs_pop(K); + + ktail_eval(K, expr, denv); } /* 6.7.9 $remote-eval */ @@ -515,9 +610,20 @@ void Sbindings_to_environment(klisp_State *K, TValue *xparams, TValue ptree, TValue exprs; TValue bptree = split_check_let_bindings(K, "$bindings->environment", ptree, &exprs, false); + krooted_tvs_push(K, exprs); + krooted_tvs_push(K, bptree); + TValue new_env = kmake_environment(K, KNIL); + krooted_tvs_push(K, new_env); + TValue new_cont = kmake_continuation(K, kget_cc(K), KNIL, KNIL, do_b_to_env, 2, bptree, new_env); kset_cc(K, new_cont); - ktail_eval(K, kcons(K, K->list_app, exprs), denv); + TValue expr = kcons(K, K->list_app, exprs); + + krooted_tvs_pop(K); + krooted_tvs_pop(K); + krooted_tvs_pop(K); + + ktail_eval(K, expr, denv); }