commit 1aa0401c3e53c8e3ddaec8133f4d9b505b95812d
parent 6eaca8feb345e6f926c631a90c693e2c2917ccdd
Author: Andres Navarro <canavarro82@gmail.com>
Date: Wed, 22 Aug 2012 16:38:20 -0300
Some more refactoring in kstate and kcontinuation to move the interception code out of kstate and normalize the initialization of the ground environment.
Diffstat:
9 files changed, 284 insertions(+), 281 deletions(-)
diff --git a/src/Makefile b/src/Makefile
@@ -148,7 +148,8 @@ kbytevector.o: kbytevector.c kbytevector.h kobject.h klimits.h klisp.h \
klispconf.h kstate.h ktoken.h kmem.h kgc.h kstring.h
kchar.o: kchar.c kobject.h klimits.h klisp.h klispconf.h
kcontinuation.o: kcontinuation.c kcontinuation.h kobject.h klimits.h \
- klisp.h klispconf.h kstate.h ktoken.h kmem.h kgc.h
+ klisp.h klispconf.h kstate.h ktoken.h kmem.h kpair.h kgc.h \
+ kapplicative.h koperative.h
kencapsulation.o: kencapsulation.c kobject.h klimits.h klisp.h \
klispconf.h kmem.h kstate.h ktoken.h kencapsulation.h kpair.h kgc.h
kenvironment.o: kenvironment.c kenvironment.h kobject.h klimits.h klisp.h \
diff --git a/src/kcontinuation.c b/src/kcontinuation.c
@@ -7,6 +7,8 @@
#include <stdarg.h>
#include "kcontinuation.h"
+#include "kpair.h"
+#include "kapplicative.h"
#include "kobject.h"
#include "kstate.h"
#include "kmem.h"
@@ -50,3 +52,194 @@ TValue kmake_continuation(klisp_State *K, TValue parent, klisp_CFunction fn,
kset_source_info(K, res, kget_csi(K));
return res;
}
+
+/*
+**
+** Interception Handling
+**
+*/
+
+/* Helper for continuation->applicative */
+/* this passes the operand tree to the continuation */
+void cont_app(klisp_State *K)
+{
+ TValue *xparams = K->next_xparams;
+ TValue ptree = K->next_value;
+ TValue denv = K->next_env;
+ klisp_assert(ttisenvironment(K->next_env));
+ UNUSED(denv);
+ TValue cont = xparams[0];
+ /* guards and dynamic variables are handled in kcall_cont() */
+ kcall_cont(K, cont, ptree);
+}
+
+/*
+** This is used to determine if cont is in the dynamic extent of
+** some other continuation. That's the case iff that continuation
+** was marked by the call to mark_iancestors(cont)
+*/
+
+/* TODO: maybe add some inlines here, profile first and check size difference */
+static void mark_iancestors(TValue cont)
+{
+ while(!ttisnil(cont)) {
+ kmark(cont);
+ cont = tv2cont(cont)->parent;
+ }
+}
+
+static void unmark_iancestors(TValue cont)
+{
+ while(!ttisnil(cont)) {
+ kunmark(cont);
+ cont = tv2cont(cont)->parent;
+ }
+}
+
+/*
+** Returns the first interceptor whose dynamic extent includes cont
+** or nil if there isn't any. The cont is implicitly passed because
+** all of its improper ancestors are marked.
+*/
+static TValue select_interceptor(TValue guard_ls)
+{
+ /* the guard list can't be cyclic, that case is
+ replaced by a simple list while copyng guards */
+ while(!ttisnil(guard_ls)) {
+ /* entry is (selector . interceptor-op) */
+ TValue entry = kcar(guard_ls);
+ TValue selector = kcar(entry);
+ if (kis_marked(selector))
+ return kcdr(entry); /* only interceptor is important */
+ guard_ls = kcdr(guard_ls);
+ }
+ return KNIL;
+}
+
+/*
+** Returns a list of entries like the following:
+** (interceptor-op outer_cont . denv)
+*/
+
+/* GC: assume src_cont & dst_cont are rooted */
+TValue create_interception_list(klisp_State *K, TValue src_cont,
+ TValue dst_cont)
+{
+ mark_iancestors(dst_cont);
+ TValue ilist = kcons(K, KNIL, KNIL);
+ krooted_vars_push(K, &ilist);
+ TValue tail = ilist;
+ TValue cont = src_cont;
+
+ /* exit guards are from the inside to the outside, and
+ selected by destination */
+
+ /* the loop is until we find the common ancestor, that has to be marked */
+ while(!kis_marked(cont)) {
+ /* only inner conts have exit guards */
+ if (kis_inner_cont(cont)) {
+ klisp_assert(tv2cont(cont)->extra_size > 1);
+ TValue entries = tv2cont(cont)->extra[0]; /* TODO make a macro */
+
+ TValue interceptor = select_interceptor(entries);
+ if (!ttisnil(interceptor)) {
+ /* TODO make macros */
+ TValue denv = tv2cont(cont)->extra[1];
+ TValue outer = tv2cont(cont)->parent;
+ TValue outer_denv = kcons(K, outer, denv);
+ krooted_tvs_push(K, outer_denv);
+ TValue new_entry = kcons(K, interceptor, outer_denv);
+ krooted_tvs_pop(K); /* already in entry */
+ krooted_tvs_push(K, new_entry);
+ TValue new_pair = kcons(K, new_entry, KNIL);
+ krooted_tvs_pop(K);
+ kset_cdr(tail, new_pair);
+ tail = new_pair;
+ }
+ }
+ cont = tv2cont(cont)->parent;
+ }
+ unmark_iancestors(dst_cont);
+
+ /* entry guards are from the outside to the inside, and
+ selected by source, we create the list from the outside
+ by cons and then append it to the exit list to avoid
+ reversing */
+ mark_iancestors(src_cont);
+
+ cont = dst_cont;
+ TValue entry_int = KNIL;
+ krooted_vars_push(K, &entry_int);
+
+ while(!kis_marked(cont)) {
+ /* only outer conts have entry guards */
+ if (kis_outer_cont(cont)) {
+ klisp_assert(tv2cont(cont)->extra_size > 1);
+ TValue entries = tv2cont(cont)->extra[0]; /* TODO make a macro */
+ /* this is rooted because it's a substructure of entries */
+ TValue interceptor = select_interceptor(entries);
+ if (!ttisnil(interceptor)) {
+ /* TODO make macros */
+ TValue denv = tv2cont(cont)->extra[1];
+ TValue outer = cont;
+ TValue outer_denv = kcons(K, outer, denv);
+ krooted_tvs_push(K, outer_denv);
+ TValue new_entry = kcons(K, interceptor, outer_denv);
+ krooted_tvs_pop(K); /* already in entry */
+ krooted_tvs_push(K, new_entry);
+ entry_int = kcons(K, new_entry, entry_int);
+ krooted_tvs_pop(K);
+ }
+ }
+ cont = tv2cont(cont)->parent;
+ }
+
+ unmark_iancestors(src_cont);
+
+ /* all interceptions collected, append the two lists and return */
+ kset_cdr(tail, entry_int);
+ krooted_vars_pop(K);
+ krooted_vars_pop(K);
+ return kcdr(ilist);
+}
+
+void do_interception(klisp_State *K)
+{
+ TValue *xparams = K->next_xparams;
+ TValue obj = K->next_value;
+ klisp_assert(ttisnil(K->next_env));
+ /*
+ ** xparams[0]:
+ ** xparams[1]: dst cont
+ */
+ TValue ls = xparams[0];
+ TValue dst_cont = xparams[1];
+ if (ttisnil(ls)) {
+ /* all interceptors returned normally */
+ /* this is a normal pass/not subject to interception */
+ kset_cc(K, dst_cont);
+ kapply_cc(K, obj);
+ } else {
+ /* call the operative with the passed obj and applicative
+ for outer cont as ptree in the dynamic environment of
+ the corresponding call to guard-continuation in the
+ dynamic extent of the associated outer continuation.
+ If the operative normally returns a value, others
+ interceptions should be scheduled */
+ TValue first = kcar(ls);
+ TValue op = kcar(first);
+ TValue outer = kcadr(first);
+ TValue denv = kcddr(first);
+ TValue app = kmake_applicative(K, cont_app, 1, outer);
+ krooted_tvs_push(K, app);
+ TValue ptree = klist(K, 2, obj, app);
+ krooted_tvs_pop(K); /* already in ptree */
+ krooted_tvs_push(K, ptree);
+ TValue new_cont = kmake_continuation(K, outer, do_interception,
+ 2, kcdr(ls), dst_cont);
+ kset_cc(K, new_cont);
+ krooted_tvs_pop(K);
+ /* XXX: what to pass as si? */
+ ktail_call(K, op, ptree, denv);
+ }
+}
diff --git a/src/kcontinuation.h b/src/kcontinuation.h
@@ -14,4 +14,10 @@
TValue kmake_continuation(klisp_State *K, TValue parent, klisp_CFunction fn,
int xcount, ...);
+/* Interceptions */
+void cont_app(klisp_State *K);
+TValue create_interception_list(klisp_State *K, TValue src_cont,
+ TValue dst_cont);
+void do_interception(klisp_State *K);
+
#endif
diff --git a/src/kgcontinuations.c b/src/kgcontinuations.c
@@ -124,7 +124,6 @@ void guard_continuation(klisp_State *K)
kapply_cc(K, inner_cont);
}
-
/* 7.2.5 continuation->applicative */
void continuation_applicative(klisp_State *K)
{
@@ -138,17 +137,42 @@ void continuation_applicative(klisp_State *K)
bind_1tp(K, ptree, "continuation",
ttiscontinuation, cont);
- /* cont_app is from kstate, it handles dynamic vars &
- interceptions */
TValue app = kmake_applicative(K, cont_app, 1, cont);
kapply_cc(K, app);
}
/* 7.2.6 root-continuation */
-/* done in kground.c/krepl.c */
+static void do_root_exit(klisp_State *K)
+{
+ TValue *xparams = K->next_xparams;
+ TValue obj = K->next_value;
+ klisp_assert(ttisnil(K->next_env));
+ UNUSED(xparams);
+
+ /* TODO/REFACTOR move this to a end_loop function in kstate.c */
+ /* Just save the value and end the loop */
+ K->next_value = obj;
+ K->next_func = NULL; /* force the loop to terminate */
+ return;
+}
+
+
+static void kinit_root_cont(klisp_State *K)
+{
+ klisp_assert(ttisinert(G(K)->root_cont));
+ G(K)->root_cont = kmake_continuation(K, KNIL, do_root_exit, 0);
+ TValue str, tail, si;
+#if KTRACK_SI
+ /* Add source info to the cont */
+ str = kstring_new_b_imm(K, __FILE__);
+ tail = kcons(K, i2tv(__LINE__), i2tv(0));
+ si = kcons(K, str, tail);
+ kset_source_info(K, G(K)->root_cont, si);
+#endif
+}
/* 7.2.7 error-continuation */
-/* done in kground.c/krepl.c */
+/* done in kgerrors.c */
/*
** 7.3 Library features
@@ -234,8 +258,7 @@ void kgexit(klisp_State *K)
if (!get_opt_tpar(K, obj, "any", anytype))
obj = KINERT;
- /* TODO: look out for guards and dynamic variables */
- /* should be probably handled in kcall_cont() */
+ /* guards and dynamic variables are handled in kcall_cont() */
kcall_cont(K, G(K)->root_cont, obj);
}
@@ -260,13 +283,12 @@ void kinit_continuations_ground_env(klisp_State *K)
add_applicative(K, ground_env, "continuation->applicative",
continuation_applicative, 0);
/* 7.2.6 root-continuation */
- klisp_assert(ttiscontinuation(G(K)->root_cont));
- add_value(K, ground_env, "root-continuation",
- G(K)->root_cont);
+ kinit_root_cont(K);
+ add_value(K, ground_env, "root-continuation", G(K)->root_cont);
+
/* 7.2.7 error-continuation */
- klisp_assert(ttiscontinuation(G(K)->error_cont));
- add_value(K, ground_env, "error-continuation",
- G(K)->error_cont);
+ /* done in kgerrors.c */
+
/* 7.3.1 apply-continuation */
add_applicative(K, ground_env, "apply-continuation", apply_continuation,
0);
@@ -288,4 +310,7 @@ void kinit_continuations_cont_names(klisp_State *K)
Table *t = tv2table(G(K)->cont_name_table);
add_cont_name(K, t, do_extended_cont, "extended-cont");
+ add_cont_name(K, t, do_root_exit, "exit");
+ /* this is defined in kcontinuation.c */
+ add_cont_name(K, t, do_interception, "do-interception");
}
diff --git a/src/kgerrors.c b/src/kgerrors.c
@@ -75,8 +75,19 @@ void error_object_irritants(klisp_State *K)
kapply_cc(K, err_obj->irritants);
}
+void do_error_exit(klisp_State *K)
+{
+ TValue *xparams = K->next_xparams;
+ TValue obj = K->next_value;
+ klisp_assert(ttisnil(K->next_env));
+ UNUSED(xparams);
+
+ /* TEMP Just pass the error to the root continuation */
+ kapply_cc(K, obj);
+}
+
/* REFACTOR this is the same as do_pass_value */
-void do_exception_cont(klisp_State *K)
+static void do_exception_cont(klisp_State *K)
{
TValue *xparams = K->next_xparams;
TValue obj = K->next_value;
@@ -88,13 +99,30 @@ void do_exception_cont(klisp_State *K)
/* REFACTOR maybe this should be in kerror.c */
/* Create system-error-continuation. */
-void kinit_error_hierarchy(klisp_State *K)
+static void kinit_error_hierarchy(klisp_State *K)
{
- klisp_assert(ttiscontinuation(G(K)->error_cont));
- klisp_assert(ttisinert(G(K)->system_error_cont));
+ klisp_assert(ttisinert(G(K)->error_cont));
+ G(K)->error_cont = kmake_continuation(K, G(K)->root_cont,
+ do_error_exit, 0);
+ TValue str, tail, si;
+
+#if KTRACK_SI
+ str = kstring_new_b_imm(K, __FILE__);
+ tail = kcons(K, i2tv(__LINE__), i2tv(0));
+ si = kcons(K, str, tail);
+ kset_source_info(K, G(K)->error_cont, si);
+#endif
+
+ klisp_assert(ttisinert(G(K)->system_error_cont));
G(K)->system_error_cont = kmake_continuation(K, G(K)->error_cont,
do_exception_cont, 0);
+#if KTRACK_SI
+ str = kstring_new_b_imm(K, __FILE__);
+ tail = kcons(K, i2tv(__LINE__), i2tv(0));
+ si = kcons(K, str, tail);
+ kset_source_info(K, G(K)->system_error_cont, si);
+#endif
}
/* init ground */
@@ -122,6 +150,16 @@ void kinit_error_ground_env(klisp_State *K)
See Common Lisp and mit scheme for examples
*/
- klisp_assert(ttiscontinuation(G(K)->system_error_cont));
+ /* 7.2.7 error-continuation */
+ kinit_error_hierarchy(K);
+ add_value(K, ground_env, "error-continuation", G(K)->error_cont);
add_value(K, ground_env, "system-error-continuation", G(K)->system_error_cont);
}
+
+void kinit_error_cont_names(klisp_State *K)
+{
+ Table *t = tv2table(G(K)->cont_name_table);
+
+ add_cont_name(K, t, do_error_exit, "error");
+ add_cont_name(K, t, do_exception_cont, "system-error");
+}
diff --git a/src/kgerrors.h b/src/kgerrors.h
@@ -12,9 +12,4 @@
/* init ground */
void kinit_error_ground_env(klisp_State *K);
-/* Second stage of itialization of ground environment. Must be
- * called after initializing general error continuation
- * K->error_cont. */
-void kinit_error_hierarchy(klisp_State *K);
-
#endif
diff --git a/src/kground.c b/src/kground.c
@@ -62,13 +62,6 @@
*/
void kinit_cont_names(klisp_State *K)
{
- /* TEMP root and error continuations are set here (they are in kstate) */
- Table *t = tv2table(G(K)->cont_name_table);
- add_cont_name(K, t, do_root_exit, "exit");
- add_cont_name(K, t, do_error_exit, "error");
- /* TEMP this is also in kstate */
- add_cont_name(K, t, do_interception, "do-interception");
-
/* TEMP repl ones should be done in the interpreter, and not in
the init state */
kinit_repl_cont_names(K);
@@ -88,6 +81,7 @@ void kinit_cont_names(klisp_State *K)
#if KUSE_LIBFFI
kinit_ffi_cont_names(K);
#endif
+ kinit_error_cont_names(K);
kinit_libraries_cont_names(K);
}
diff --git a/src/kstate.c b/src/kstate.c
@@ -379,29 +379,6 @@ klisp_State *klisp_newstate(klisp_Alloc f, void *ud)
/* TODO si */
g->module_params_sym = ksymbol_new_b(K, "module-parameters", KNIL);
- /* Create the root and error continuation (will be added to the
- environment in kinit_ground_env) */
- g->root_cont = kmake_continuation(K, KNIL, do_root_exit, 0);
-
-#if KTRACK_SI
- /* Add source info to the cont */
- TValue str = kstring_new_b_imm(K, __FILE__);
- TValue tail = kcons(K, i2tv(__LINE__), i2tv(0));
- si = kcons(K, str, tail);
- kset_source_info(K, g->root_cont, si);
-#endif
-
- g->error_cont = kmake_continuation(K, g->root_cont, do_error_exit, 0);
-
-#if KTRACK_SI
- str = kstring_new_b_imm(K, __FILE__);
- tail = kcons(K, i2tv(__LINE__), i2tv(0));
- si = kcons(K, str, tail);
- kset_source_info(K, g->error_cont, si);
-#endif
-
- /* this must be done before calling kinit_ground_env */
- kinit_error_hierarchy(K);
kinit_ground_env(K);
kinit_cont_names(K);
@@ -476,33 +453,6 @@ void klisp_close (klisp_State *K)
}
/*
-** Root and Error continuations
-*/
-void do_root_exit(klisp_State *K)
-{
- TValue *xparams = K->next_xparams;
- TValue obj = K->next_value;
- klisp_assert(ttisnil(K->next_env));
- UNUSED(xparams);
-
- /* Just save the value and end the loop */
- K->next_value = obj;
- K->next_func = NULL; /* force the loop to terminate */
- return;
-}
-
-void do_error_exit(klisp_State *K)
-{
- TValue *xparams = K->next_xparams;
- TValue obj = K->next_value;
- klisp_assert(ttisnil(K->next_env));
- UNUSED(xparams);
-
- /* TEMP Just pass the error to the root continuation */
- kapply_cc(K, obj);
-}
-
-/*
** Stacks memory management
*/
@@ -569,198 +519,6 @@ void ks_tbshrink(klisp_State *K, int32_t new_top)
ks_tbsize(K) = new_size;
}
-
-/*
-**
-** This is for handling interceptions
-** TODO: move to a different file
-**
-*/
-
-/*
-** This is used to determine if cont is in the dynamic extent of
-** some other continuation. That's the case iff that continuation
-** was marked by the call to mark_iancestors(cont)
-*/
-
-/* TODO: maybe add some inlines here, profile first and check size difference */
-void mark_iancestors(TValue cont)
-{
- while(!ttisnil(cont)) {
- kmark(cont);
- cont = tv2cont(cont)->parent;
- }
-}
-
-void unmark_iancestors(TValue cont)
-{
- while(!ttisnil(cont)) {
- kunmark(cont);
- cont = tv2cont(cont)->parent;
- }
-}
-
-/*
-** Returns the first interceptor whose dynamic extent includes cont
-** or nil if there isn't any. The cont is implicitly passed because
-** all of its improper ancestors are marked.
-*/
-TValue select_interceptor(TValue guard_ls)
-{
- /* the guard list can't be cyclic, that case is
- replaced by a simple list while copyng guards */
- while(!ttisnil(guard_ls)) {
- /* entry is (selector . interceptor-op) */
- TValue entry = kcar(guard_ls);
- TValue selector = kcar(entry);
- if (kis_marked(selector))
- return kcdr(entry); /* only interceptor is important */
- guard_ls = kcdr(guard_ls);
- }
- return KNIL;
-}
-
-/*
-** Returns a list of entries like the following:
-** (interceptor-op outer_cont . denv)
-*/
-
-/* GC: assume src_cont & dst_cont are rooted */
-static inline TValue create_interception_list(klisp_State *K, TValue src_cont,
- TValue dst_cont)
-{
- mark_iancestors(dst_cont);
- TValue ilist = kcons(K, KNIL, KNIL);
- krooted_vars_push(K, &ilist);
- TValue tail = ilist;
- TValue cont = src_cont;
-
- /* exit guards are from the inside to the outside, and
- selected by destination */
-
- /* the loop is until we find the common ancestor, that has to be marked */
- while(!kis_marked(cont)) {
- /* only inner conts have exit guards */
- if (kis_inner_cont(cont)) {
- klisp_assert(tv2cont(cont)->extra_size > 1);
- TValue entries = tv2cont(cont)->extra[0]; /* TODO make a macro */
-
- TValue interceptor = select_interceptor(entries);
- if (!ttisnil(interceptor)) {
- /* TODO make macros */
- TValue denv = tv2cont(cont)->extra[1];
- TValue outer = tv2cont(cont)->parent;
- TValue outer_denv = kcons(K, outer, denv);
- krooted_tvs_push(K, outer_denv);
- TValue new_entry = kcons(K, interceptor, outer_denv);
- krooted_tvs_pop(K); /* already in entry */
- krooted_tvs_push(K, new_entry);
- TValue new_pair = kcons(K, new_entry, KNIL);
- krooted_tvs_pop(K);
- kset_cdr(tail, new_pair);
- tail = new_pair;
- }
- }
- cont = tv2cont(cont)->parent;
- }
- unmark_iancestors(dst_cont);
-
- /* entry guards are from the outside to the inside, and
- selected by source, we create the list from the outside
- by cons and then append it to the exit list to avoid
- reversing */
- mark_iancestors(src_cont);
-
- cont = dst_cont;
- TValue entry_int = KNIL;
- krooted_vars_push(K, &entry_int);
-
- while(!kis_marked(cont)) {
- /* only outer conts have entry guards */
- if (kis_outer_cont(cont)) {
- klisp_assert(tv2cont(cont)->extra_size > 1);
- TValue entries = tv2cont(cont)->extra[0]; /* TODO make a macro */
- /* this is rooted because it's a substructure of entries */
- TValue interceptor = select_interceptor(entries);
- if (!ttisnil(interceptor)) {
- /* TODO make macros */
- TValue denv = tv2cont(cont)->extra[1];
- TValue outer = cont;
- TValue outer_denv = kcons(K, outer, denv);
- krooted_tvs_push(K, outer_denv);
- TValue new_entry = kcons(K, interceptor, outer_denv);
- krooted_tvs_pop(K); /* already in entry */
- krooted_tvs_push(K, new_entry);
- entry_int = kcons(K, new_entry, entry_int);
- krooted_tvs_pop(K);
- }
- }
- cont = tv2cont(cont)->parent;
- }
-
- unmark_iancestors(src_cont);
-
- /* all interceptions collected, append the two lists and return */
- kset_cdr(tail, entry_int);
- krooted_vars_pop(K);
- krooted_vars_pop(K);
- return kcdr(ilist);
-}
-
-/* this passes the operand tree to the continuation */
-void cont_app(klisp_State *K)
-{
- TValue *xparams = K->next_xparams;
- TValue ptree = K->next_value;
- TValue denv = K->next_env;
- klisp_assert(ttisenvironment(K->next_env));
- UNUSED(denv);
- TValue cont = xparams[0];
- /* guards and dynamic variables are handled in kcall_cont() */
- kcall_cont(K, cont, ptree);
-}
-
-void do_interception(klisp_State *K)
-{
- TValue *xparams = K->next_xparams;
- TValue obj = K->next_value;
- klisp_assert(ttisnil(K->next_env));
- /*
- ** xparams[0]:
- ** xparams[1]: dst cont
- */
- TValue ls = xparams[0];
- TValue dst_cont = xparams[1];
- if (ttisnil(ls)) {
- /* all interceptors returned normally */
- /* this is a normal pass/not subject to interception */
- kset_cc(K, dst_cont);
- kapply_cc(K, obj);
- } else {
- /* call the operative with the passed obj and applicative
- for outer cont as ptree in the dynamic environment of
- the corresponding call to guard-continuation in the
- dynamic extent of the associated outer continuation.
- If the operative normally returns a value, others
- interceptions should be scheduled */
- TValue first = kcar(ls);
- TValue op = kcar(first);
- TValue outer = kcadr(first);
- TValue denv = kcddr(first);
- TValue app = kmake_applicative(K, cont_app, 1, outer);
- krooted_tvs_push(K, app);
- TValue ptree = klist(K, 2, obj, app);
- krooted_tvs_pop(K); /* already in ptree */
- krooted_tvs_push(K, ptree);
- TValue new_cont = kmake_continuation(K, outer, do_interception,
- 2, kcdr(ls), dst_cont);
- kset_cc(K, new_cont);
- krooted_tvs_pop(K);
- /* XXX: what to pass as si? */
- ktail_call(K, op, ptree, denv);
- }
-}
-
/* GC: Don't assume anything about obj & dst_cont, they may not be rooted.
In the most common case of apply-continuation & continuation->applicative
they are rooted, but in general there's no way to protect them, because
diff --git a/src/kstate.h b/src/kstate.h
@@ -526,19 +526,12 @@ static inline void klispT_tail_call_si(klisp_State *K, TValue top, TValue ptree,
ktry_get_si(K__, p__)); \
return; }
-/* helper for continuation->applicative & kcall_cont */
-void cont_app(klisp_State *K);
+void do_interception(klisp_State *K);
void kcall_cont(klisp_State *K, TValue dst_cont, TValue obj);
void klispT_init_repl(klisp_State *K);
void klispT_run(klisp_State *K);
void klisp_close (klisp_State *K);
-void do_interception(klisp_State *K);
-
-/* for root and error continuations */
-void do_root_exit(klisp_State *K);
-void do_error_exit(klisp_State *K);
-
/* simple accessors for dynamic keys */
/* XXX: this is ugly but we can't include kpair.h here so... */