aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJim Blandy1992-09-22 06:23:30 +0000
committerJim Blandy1992-09-22 06:23:30 +0000
commitba410f40e997e8653a51ab8904a4a5509190f40a (patch)
treed4b371aecdbcfc15f5e850ddc11f31357a0f4b88 /src
parent5d6533f1865725d8171b3014f74f5ab17b777622 (diff)
downloademacs-ba410f40e997e8653a51ab8904a4a5509190f40a.tar.gz
emacs-ba410f40e997e8653a51ab8904a4a5509190f40a.zip
* 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.
Diffstat (limited to 'src')
-rw-r--r--src/eval.c46
1 files changed, 26 insertions, 20 deletions
diff --git a/src/eval.c b/src/eval.c
index ca78a065045..f3cb1135d2b 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -879,23 +879,32 @@ internal_catch (tag, func, arg)
879 return c.val; 879 return c.val;
880} 880}
881 881
882/* Discard from the catchlist all catch tags back through CATCH. 882/* Unwind the specbind, catch, and handler stacks back to CATCH, and
883 Before each catch is discarded, unbind all special bindings 883 jump to that CATCH, returning VALUE as the value of that catch.
884 made within that catch. Also, when discarding a catch that
885 corresponds to a condition handler, discard that handler.
886 884
887 At the end, restore some static info saved in CATCH. 885 This is the guts Fthrow and Fsignal; they differ only in the way
886 they choose the catch tag to throw to. A catch tag for a
887 condition-case form has a TAG of Qnil.
888 888
889 This is used for correct unwinding in Fthrow and Fsignal, 889 Before each catch is discarded, unbind all special bindings and
890 before doing the longjmp that actually destroys the stack frames 890 execute all unwind-protect clauses made above that catch. Unwind
891 in which these handlers and catches reside. */ 891 the handler stack as we go, so that the proper handlers are in
892 effect for each unwind-protect clause we run. At the end, restore
893 some static info saved in CATCH, and longjmp to the location
894 specified in the
895
896 This is used for correct unwinding in Fthrow and Fsignal. */
892 897
893static void 898static void
894unbind_catch (catch) 899unwind_to_catch (catch, value)
895 struct catchtag *catch; 900 struct catchtag *catch;
901 Lisp_Object value;
896{ 902{
897 register int last_time; 903 register int last_time;
898 904
905 /* Save the value in the tag. */
906 catch->val = value;
907
899 /* Restore the polling-suppression count. */ 908 /* Restore the polling-suppression count. */
900 if (catch->poll_suppress_count > poll_suppress_count) 909 if (catch->poll_suppress_count > poll_suppress_count)
901 abort (); 910 abort ();
@@ -917,6 +926,8 @@ unbind_catch (catch)
917 gcprolist = catch->gcpro; 926 gcprolist = catch->gcpro;
918 backtrace_list = catch->backlist; 927 backtrace_list = catch->backlist;
919 lisp_eval_depth = catch->lisp_eval_depth; 928 lisp_eval_depth = catch->lisp_eval_depth;
929
930 _longjmp (catch->jmp, 1);
920} 931}
921 932
922DEFUN ("throw", Fthrow, Sthrow, 2, 2, 0, 933DEFUN ("throw", Fthrow, Sthrow, 2, 2, 0,
@@ -933,11 +944,7 @@ Both TAG and VALUE are evalled.")
933 for (c = catchlist; c; c = c->next) 944 for (c = catchlist; c; c = c->next)
934 { 945 {
935 if (EQ (c->tag, tag)) 946 if (EQ (c->tag, tag))
936 { 947 unwind_to_catch (c, val);
937 c->val = val;
938 unbind_catch (c);
939 _longjmp (c->jmp, 1);
940 }
941 } 948 }
942 tag = Fsignal (Qno_catch, Fcons (tag, Fcons (val, Qnil))); 949 tag = Fsignal (Qno_catch, Fcons (tag, Fcons (val, Qnil)));
943 } 950 }
@@ -1140,9 +1147,7 @@ See also the function `condition-case'.")
1140 { 1147 {
1141 struct handler *h = handlerlist; 1148 struct handler *h = handlerlist;
1142 handlerlist = allhandlers; 1149 handlerlist = allhandlers;
1143 unbind_catch (h->tag); 1150 unwind_to_catch (h->tag, Fcons (clause, Fcons (sig, data)));
1144 h->tag->val = Fcons (clause, Fcons (sig, data));
1145 _longjmp (h->tag->jmp, 1);
1146 } 1151 }
1147 } 1152 }
1148 1153
@@ -1195,9 +1200,10 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr)
1195 { 1200 {
1196 if (wants_debugger (Vstack_trace_on_error, conditions)) 1201 if (wants_debugger (Vstack_trace_on_error, conditions))
1197 internal_with_output_to_temp_buffer ("*Backtrace*", Fbacktrace, Qnil); 1202 internal_with_output_to_temp_buffer ("*Backtrace*", Fbacktrace, Qnil);
1198 if (when_entered_debugger < num_nonmacro_input_chars 1203 if ((EQ (sig, Qquit)
1199 && (EQ (sig, Qquit) ? debug_on_quit 1204 ? debug_on_quit
1200 : wants_debugger (Vdebug_on_error, conditions))) 1205 : wants_debugger (Vdebug_on_error, conditions))
1206 && when_entered_debugger < num_nonmacro_input_chars)
1201 { 1207 {
1202 int count = specpdl_ptr - specpdl; 1208 int count = specpdl_ptr - specpdl;
1203 specbind (Qdebug_on_error, Qnil); 1209 specbind (Qdebug_on_error, Qnil);