diff --git a/core/bootstrap/primitives.factor b/core/bootstrap/primitives.factor index a1e7a84cae..838fe3251c 100644 --- a/core/bootstrap/primitives.factor +++ b/core/bootstrap/primitives.factor @@ -270,6 +270,7 @@ H{ } clone update-map set { "innermost-frame-quot" "kernel.private" } { "innermost-frame-scan" "kernel.private" } { "set-innermost-frame-quot" "kernel.private" } + { "call-clear" "kernel" } } dup length [ >r first2 r> make-primitive ] 2each diff --git a/core/kernel/kernel-docs.factor b/core/kernel/kernel-docs.factor index bbfd15ce53..5251f2b231 100644 --- a/core/kernel/kernel-docs.factor +++ b/core/kernel/kernel-docs.factor @@ -338,6 +338,11 @@ $nl { $code "2 [ 2 + 3 * ] call" "2 2 + 3 *" } } ; +HELP: call-clear ( quot -- ) +{ $values { "quot" callable } } +{ $description "Calls a quotation with an empty call stack. If the quotation returns, Factor will exit.." } +{ $notes "Used to implement " { $link "threads" } "." } ; + HELP: slip { $values { "quot" quotation } { "x" object } } { $description "Calls a quotation while hiding the top of the stack." } ; diff --git a/core/threads/threads.factor b/core/threads/threads.factor index c76118d14c..ee249c70a7 100644 --- a/core/threads/threads.factor +++ b/core/threads/threads.factor @@ -51,7 +51,7 @@ PRIVATE> >r schedule-thread r> [ V{ } set-catchstack { } set-retainstack - [ print-error ] recover stop + [ [ print-error ] recover stop ] call-clear ] (throw) ] curry callcc0 ; diff --git a/vm/errors.c b/vm/errors.c index 88659e4654..b8f7a2c52a 100644 --- a/vm/errors.c +++ b/vm/errors.c @@ -137,3 +137,9 @@ DEFINE_PRIMITIVE(throw) uncurry(dpop()); throw_impl(dpop(),stack_chain->callstack_top); } + +DEFINE_PRIMITIVE(call_clear) +{ + uncurry(dpop()); + throw_impl(dpop(),stack_chain->callstack_bottom); +} diff --git a/vm/errors.h b/vm/errors.h index cef4505a82..5295197f40 100644 --- a/vm/errors.h +++ b/vm/errors.h @@ -35,6 +35,7 @@ void not_implemented_error(void); F_FASTCALL void undefined_error(CELL word, F_STACK_FRAME *callstack_top); DECLARE_PRIMITIVE(throw); +DECLARE_PRIMITIVE(call_clear); INLINE void type_check(CELL type, CELL tagged) { diff --git a/vm/primitives.c b/vm/primitives.c index 6e7b67ba61..649b7294f9 100644 --- a/vm/primitives.c +++ b/vm/primitives.c @@ -193,4 +193,5 @@ void *primitives[] = { primitive_innermost_stack_frame_quot, primitive_innermost_stack_frame_scan, primitive_set_innermost_stack_frame_quot, + primitive_call_clear, };