From ba410f40e997e8653a51ab8904a4a5509190f40a Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Tue, 22 Sep 1992 06:23:30 +0000 Subject: [PATCH] * eval.c (unbind_catch): Do the long-jump here. Take a VALUE argument, which specifies the value to return to the catch, or the data to give to the condition handler. Renamed to unwind_to_catch, to reflect new role. (Fsignal, Fthrow): Removed code to set catch tag value and do the long-jump; this is taken care of by unwind_to_catch. --- src/eval.c | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/src/eval.c b/src/eval.c index ca78a06504..f3cb1135d2 100644 --- a/src/eval.c +++ b/src/eval.c @@ -879,23 +879,32 @@ internal_catch (tag, func, arg) return c.val; } -/* Discard from the catchlist all catch tags back through CATCH. - Before each catch is discarded, unbind all special bindings - made within that catch. Also, when discarding a catch that - corresponds to a condition handler, discard that handler. +/* Unwind the specbind, catch, and handler stacks back to CATCH, and + jump to that CATCH, returning VALUE as the value of that catch. - At the end, restore some static info saved in CATCH. + This is the guts Fthrow and Fsignal; they differ only in the way + they choose the catch tag to throw to. A catch tag for a + condition-case form has a TAG of Qnil. - This is used for correct unwinding in Fthrow and Fsignal, - before doing the longjmp that actually destroys the stack frames - in which these handlers and catches reside. */ + Before each catch is discarded, unbind all special bindings and + execute all unwind-protect clauses made above that catch. Unwind + the handler stack as we go, so that the proper handlers are in + effect for each unwind-protect clause we run. At the end, restore + some static info saved in CATCH, and longjmp to the location + specified in the + + This is used for correct unwinding in Fthrow and Fsignal. */ static void -unbind_catch (catch) +unwind_to_catch (catch, value) struct catchtag *catch; + Lisp_Object value; { register int last_time; + /* Save the value in the tag. */ + catch->val = value; + /* Restore the polling-suppression count. */ if (catch->poll_suppress_count > poll_suppress_count) abort (); @@ -917,6 +926,8 @@ unbind_catch (catch) gcprolist = catch->gcpro; backtrace_list = catch->backlist; lisp_eval_depth = catch->lisp_eval_depth; + + _longjmp (catch->jmp, 1); } DEFUN ("throw", Fthrow, Sthrow, 2, 2, 0, @@ -933,11 +944,7 @@ Both TAG and VALUE are evalled.") for (c = catchlist; c; c = c->next) { if (EQ (c->tag, tag)) - { - c->val = val; - unbind_catch (c); - _longjmp (c->jmp, 1); - } + unwind_to_catch (c, val); } tag = Fsignal (Qno_catch, Fcons (tag, Fcons (val, Qnil))); } @@ -1140,9 +1147,7 @@ See also the function `condition-case'.") { struct handler *h = handlerlist; handlerlist = allhandlers; - unbind_catch (h->tag); - h->tag->val = Fcons (clause, Fcons (sig, data)); - _longjmp (h->tag->jmp, 1); + unwind_to_catch (h->tag, Fcons (clause, Fcons (sig, data))); } } @@ -1195,9 +1200,10 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr) { if (wants_debugger (Vstack_trace_on_error, conditions)) internal_with_output_to_temp_buffer ("*Backtrace*", Fbacktrace, Qnil); - if (when_entered_debugger < num_nonmacro_input_chars - && (EQ (sig, Qquit) ? debug_on_quit - : wants_debugger (Vdebug_on_error, conditions))) + if ((EQ (sig, Qquit) + ? debug_on_quit + : wants_debugger (Vdebug_on_error, conditions)) + && when_entered_debugger < num_nonmacro_input_chars) { int count = specpdl_ptr - specpdl; specbind (Qdebug_on_error, Qnil); -- 2.20.1