summaryrefslogtreecommitdiffstats
path: root/unwind.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-11-02 18:30:50 -0800
committerKaz Kylheku <kaz@kylheku.com>2015-11-02 18:30:50 -0800
commit3ac0654ecebb31ebaaf553446244408fcf0f79fc (patch)
tree186eab038084aa05c1598b86ba2b684cb7572440 /unwind.c
parent18dd42f65e620326bb21ffcde92004cc9705cbf8 (diff)
downloadtxr-3ac0654ecebb31ebaaf553446244408fcf0f79fc.tar.gz
txr-3ac0654ecebb31ebaaf553446244408fcf0f79fc.tar.bz2
txr-3ac0654ecebb31ebaaf553446244408fcf0f79fc.zip
Moving sys:capture-cont to call/cc style API.
* unwind.c (revive_cont): Don't wrap cons cell around passed arg; just pass it directly. We don't need that convention any more. * capture_cont: Take functional argument. Pass the captured continuation to the function. If the function returns, return whatever it returned. When resuming, return the continuation argument. (uw_capture_cont): Take functional second argument and pass to capture_cont. Context form becomes third argument. (uw_late_init): Update registration of sys:capture-cont to three arguments, two required. * unwind.h (uw_capture_cont): Declaration updated. * share/txr/stdlib/yield.tl (sys:yield-impl): Not needed any more; all this was doing was implementing a call/cc style interface around sys:capture-cont which can now be used directly. (yield-from): Use sys:capture-cont directly. (suspend): Simplified to the point of triviality with new sys:capture-cont. * txr.1: Documented.
Diffstat (limited to 'unwind.c')
-rw-r--r--unwind.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/unwind.c b/unwind.c
index f72839f0..a3f63038 100644
--- a/unwind.c
+++ b/unwind.c
@@ -754,7 +754,7 @@ static val revive_cont(val dc, val arg)
bug_unless (uw_stack->uw.type == UW_BLOCK);
- uw_stack->bl.result = cons(nil, arg);
+ uw_stack->bl.result = arg;
uw_exit_point = if3(arg == sys_cont_poison_s, &uw_blk, uw_stack);
uw_unwind_to_exit_point();
abort();
@@ -767,8 +767,9 @@ static val revive_cont(val dc, val arg)
}
}
-static val capture_cont(val tag, uw_frame_t *block)
+static val capture_cont(val tag, val fun, uw_frame_t *block)
{
+ volatile val cont_obj = nil;
uw_block_begin (nil, result);
bug_unless (uw_stack < block);
@@ -792,19 +793,22 @@ static val capture_cont(val tag, uw_frame_t *block)
blcopy->uw.up = 0;
blcopy->uw.type = UW_CAPTURED_BLOCK;
- result = cobj(coerce(mem_t *, cont), sys_cont_s, &cont_ops);
+ cont_obj = cobj(coerce(mem_t *, cont), sys_cont_s, &cont_ops);
cont->tag = tag;
- result = cons(t, func_f1(result, revive_cont));
+ result = nil;
}
uw_block_end;
+ if (cont_obj)
+ result = funcall1(fun, func_f1(cont_obj, revive_cont));
+
return result;
}
-val uw_capture_cont(val tag, val ctx_form)
+val uw_capture_cont(val tag, val fun, val ctx_form)
{
uw_frame_t *fr;
@@ -825,7 +829,7 @@ val uw_capture_cont(val tag, val ctx_form)
abort();
}
- return capture_cont(tag, fr);
+ return capture_cont(tag, fun, fr);
}
void uw_init(void)
@@ -874,5 +878,5 @@ void uw_late_init(void)
reg_fun(intern(lit("invoke-catch"), user_package),
func_n2v(uw_invoke_catch));
reg_fun(sys_capture_cont_s = intern(lit("capture-cont"), system_package),
- func_n2o(uw_capture_cont, 1));
+ func_n3o(uw_capture_cont, 2));
}