klisp

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

commit e1f93041d47235fcb4a605ed60eaf47f746e4a3c
parent 7df728e54ae373499e63b7d45d9846c19b02ae56
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Sat, 16 Apr 2011 14:21:43 -0300

Added gc rooting to ports. Bugfix to kwrite (bigint writing was pushing str twice )

Diffstat:
Msrc/kghelpers.h | 1+
Msrc/kgports.c | 84++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
Msrc/kwrite.c | 3+--
3 files changed, 64 insertions(+), 24 deletions(-)

diff --git a/src/kghelpers.h b/src/kghelpers.h @@ -392,6 +392,7 @@ void ftyped_bpredp(klisp_State *K, TValue *xparams, TValue ptree, TValue denv); */ void do_return_value(klisp_State *K, TValue *xparams, TValue obj); +/* GC: assumes parent & obj are rooted */ inline TValue make_return_value_cont(klisp_State *K, TValue parent, TValue obj) { return kmake_continuation(K, parent, KNIL, KNIL, do_return_value, 1, obj); diff --git a/src/kgports.c b/src/kgports.c @@ -65,15 +65,21 @@ void with_file(klisp_State *K, TValue *xparams, TValue ptree, bind_2tp(K, name, ptree, "string", ttisstring, filename, "combiner", ttiscombiner, comb); - /* gc: root intermediate values */ TValue new_port = kmake_port(K, filename, writep, KNIL, KNIL); + krooted_tvs_push(K, new_port); /* make the continuation to close the file before returning */ TValue new_cont = kmake_continuation(K, kget_cc(K), KNIL, KNIL, do_close_file_ret, 1, new_port); - kset_cc(K, new_cont); + kset_cc(K, new_cont); /* cont implicitly rooted */ + krooted_tvs_pop(K); /* new_port is in cont */ TValue op = kmake_operative(K, do_bind, 1, key); - TValue args = kcons(K, new_port, kcons(K, comb, KNIL)); + krooted_tvs_push(K, op); + + TValue args = klist(K, 2, new_port, comb); + + krooted_tvs_pop(K); + /* even if we call with denv, do_bind calls comb in an empty env */ ktail_call(K, op, args, denv); } @@ -350,21 +356,25 @@ void call_with_file(klisp_State *K, TValue *xparams, TValue ptree, bind_2tp(K, name, ptree, "string", ttisstring, filename, "combiner", ttiscombiner, comb); - /* gc: root intermediate values */ - TValue empty_env = kmake_empty_environment(K); TValue new_port = kmake_port(K, filename, writep, KNIL, KNIL); - TValue expr = kcons(K, comb, kcons(K, new_port, KNIL)); - + krooted_tvs_push(K, new_port); /* make the continuation to close the file before returning */ TValue new_cont = kmake_continuation(K, kget_cc(K), KNIL, KNIL, do_close_file_ret, 1, new_port); - kset_cc(K, new_cont); + kset_cc(K, new_cont); /* implicit rooting */ + krooted_tvs_pop(K); /* new_port is in new_cont */ + TValue empty_env = kmake_empty_environment(K); + krooted_tvs_push(K, empty_env); + TValue expr = klist(K, 2, comb, new_port); + + krooted_tvs_pop(K); ktail_eval(K, expr, empty_env); } /* helpers for load */ /* read all expressions in a file, as immutable pairs */ +/* GC: assume port is rooted */ TValue read_all_expr(klisp_State *K, TValue port) { /* TEMP: for now set this by hand */ @@ -373,14 +383,15 @@ TValue read_all_expr(klisp_State *K, TValue port) K->read_mconsp = false; /* read immutable pairs */ /* GC: root dummy and obj */ - TValue dummy = kimm_cons(K, KNIL, KNIL); - TValue tail = dummy; + TValue tail = kget_dummy1(K); TValue obj = KINERT; + krooted_vars_push(K, &obj); while(true) { obj = kread(K); if (ttiseof(obj)) { - return kcdr(dummy); + krooted_vars_pop(K); + return kcutoff_dummy1(K); } else { TValue new_pair = kimm_cons(K, obj, KNIL); kset_cdr(tail, new_pair); @@ -410,22 +421,34 @@ void do_int_close_file(klisp_State *K, TValue *xparams, TValue ptree, /* ** guarded continuation making for read seq */ + +/* GC: assumes parent & port are rooted */ TValue make_guarded_read_cont(klisp_State *K, TValue parent, TValue port) { /* create the guard to close file after read errors */ TValue exit_int = kmake_operative(K, do_int_close_file, 1, port); + krooted_tvs_push(K, exit_int); TValue exit_guard = kcons(K, K->error_cont, exit_int); + krooted_tvs_pop(K); /* alread in guard */ + krooted_tvs_push(K, exit_guard); TValue exit_guards = kcons(K, exit_guard, KNIL); + krooted_tvs_pop(K); /* alread in guards */ + krooted_tvs_push(K, exit_guards); + TValue entry_guards = KNIL; + /* this is needed for interception code */ TValue env = kmake_empty_environment(K); + krooted_tvs_push(K, env); TValue outer_cont = kmake_continuation(K, parent, KNIL, KNIL, do_pass_value, 2, entry_guards, env); kset_outer_cont(outer_cont); + krooted_tvs_push(K, outer_cont); TValue inner_cont = kmake_continuation(K, outer_cont, KNIL, KNIL, do_pass_value, 2, exit_guards, env); kset_inner_cont(inner_cont); + krooted_tvs_pop(K); krooted_tvs_pop(K); krooted_tvs_pop(K); return inner_cont; } @@ -449,28 +472,37 @@ void load(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) this continuation also will return inert after the evaluation of the last expression is done */ TValue port = kmake_port(K, filename, false, KNIL, KNIL); + krooted_tvs_push(K, port); + + TValue inert_cont = make_return_value_cont(K, kget_cc(K), KINERT); + krooted_tvs_push(K, inert_cont); + TValue guarded_cont = make_guarded_read_cont(K, kget_cc(K), port); /* this will be used later, but contruct it now to use the current continuation as parent GC: root this obj */ - TValue inert_cont = make_return_value_cont(K, kget_cc(K), KINERT); - - kset_cc(K, guarded_cont); + kset_cc(K, guarded_cont); /* implicit rooting */ TValue ls = read_all_expr(K, port); /* any error will close the port */ /* now the sequence of expresions should be evaluated in denv and #inert returned after all are done */ - kset_cc(K, inert_cont); + kset_cc(K, inert_cont); /* implicit rooting */ + krooted_tvs_pop(K); /* already rooted */ + if (ttisnil(ls)) { + krooted_tvs_pop(K); /* port */ kapply_cc(K, KINERT); } else { TValue tail = kcdr(ls); if (ttispair(tail)) { + krooted_tvs_push(K, ls); TValue new_cont = kmake_continuation(K, kget_cc(K), KNIL, KNIL, do_seq, 2, tail, denv); kset_cc(K, new_cont); + krooted_tvs_pop(K); /* ls */ } + krooted_tvs_pop(K); /* port */ ktail_eval(K, kcar(ls), denv); } } @@ -483,38 +515,46 @@ void get_module(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) bind_al1tp(K, "get-module", ptree, "string", ttisstring, filename, maybe_env); + TValue port = kmake_port(K, filename, false, KNIL, KNIL); + krooted_tvs_push(K, port); + TValue env = kmake_environment(K, K->ground_env); + krooted_tvs_push(K, env); if (get_opt_tpar(K, "", K_TENVIRONMENT, &maybe_env)) { kadd_binding(K, env, K->module_params_sym, maybe_env); } + TValue ret_env_cont = make_return_value_cont(K, kget_cc(K), env); + krooted_tvs_pop(K); /* env alread in cont */ + krooted_tvs_push(K, ret_env_cont); + /* the reads must be guarded to close the file if there is some error this continuation also will return inert after the evaluation of the last expression is done */ - TValue port = kmake_port(K, filename, false, KNIL, KNIL); TValue guarded_cont = make_guarded_read_cont(K, kget_cc(K), port); - /* this will be used later, but contruct it now to use the - current continuation as parent - GC: root this obj */ - TValue ret_env_cont = make_return_value_cont(K, kget_cc(K), env); + kset_cc(K, guarded_cont); /* implicit roooting */ - kset_cc(K, guarded_cont); TValue ls = read_all_expr(K, port); /* any error will close the port */ /* now the sequence of expresions should be evaluated in the created env and the environment returned after all are done */ - kset_cc(K, ret_env_cont); + kset_cc(K, ret_env_cont); /* implicit rooting */ + krooted_tvs_pop(K); /* implicitly rooted */ if (ttisnil(ls)) { + krooted_tvs_pop(K); /* port */ kapply_cc(K, KINERT); } else { TValue tail = kcdr(ls); if (ttispair(tail)) { + krooted_tvs_push(K, ls); TValue new_cont = kmake_continuation(K, kget_cc(K), KNIL, KNIL, do_seq, 2, tail, env); kset_cc(K, new_cont); + krooted_tvs_pop(K); } + krooted_tvs_pop(K); /* port */ ktail_eval(K, kcar(ls), env); } } diff --git a/src/kwrite.c b/src/kwrite.c @@ -49,7 +49,6 @@ void kw_print_bigint(klisp_State *K, TValue bigint) /* write backwards so we can use printf later */ char *buf = kstring_buf(buf_str) + size - 1; - krooted_tvs_push(K, buf_str); TValue copy = kbigint_copy(K, bigint); krooted_vars_push(K, &copy); @@ -69,9 +68,9 @@ void kw_print_bigint(klisp_State *K, TValue bigint) kw_printf(K, "%s", buf+1); - krooted_vars_pop(K); krooted_tvs_pop(K); krooted_tvs_pop(K); + krooted_vars_pop(K); } /*