From d651ee10089e684686d9255e6f479fa16c7576db Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Thu, 29 Oct 2015 06:26:18 -0700 Subject: Unwinding continuations via "poison" value. * unwind.c (sys_cont_poison_s): New symbol variable. (revive_cont): If the argument is the poison symbol, then unwind through the continuation all the way back to revive_cont's own block, instead of to the continuation's very top block. Thus the continuation is not restarted but completely unwound. (uw_late_init): Initialize sys_cont_poison_s. * txr.1: Documented sys:cont-poison. --- txr.1 | 8 ++++++++ unwind.c | 5 +++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/txr.1 b/txr.1 index 23958b86..71c8f5e8 100644 --- a/txr.1 +++ b/txr.1 @@ -27512,6 +27512,14 @@ delimiting block named by then the result value of that block will appear as the return value of the continuation function. +If the symbol +.code sys:cont-poison +is passed to the continuation function, the continuation will be +resumed in a different manner: its context will be restored as in the +ordinary resume case, whereupon it will be immediately abandoned by +a nonlocal exit, causing unwinding to take place across all of the +evaluation's continuation frames. + .TP* Note: The continuation function may be used any time after it is produced, and may be diff --git a/unwind.c b/unwind.c index c679c54e..3f04c800 100644 --- a/unwind.c +++ b/unwind.c @@ -50,7 +50,7 @@ static uw_frame_t *uw_env_stack; static uw_frame_t *uw_exit_point; static uw_frame_t toplevel_env; -static val unhandled_hook_s, types_s, jump_s, sys_cont_s; +static val unhandled_hook_s, types_s, jump_s, sys_cont_s, sys_cont_poison_s; static val sys_capture_cont_s; static val frame_type, catch_frame_type, handle_frame_type; @@ -748,7 +748,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_exit_point = uw_stack; + uw_exit_point = if3(arg == sys_cont_poison_s, &uw_blk, uw_stack); uw_unwind_to_exit_point(); abort(); @@ -843,6 +843,7 @@ void uw_late_init(void) types_s = intern(lit("types"), user_package); jump_s = intern(lit("jump"), user_package); sys_cont_s = intern(lit("cont"), system_package); + sys_cont_poison_s = intern(lit("cont-poison"), system_package); frame_type = make_struct_type(intern(lit("frame"), user_package), nil, nil, nil, nil, nil, nil); catch_frame_type = make_struct_type(intern(lit("catch-frame"), -- cgit v1.2.3