diff options
| author | Jim Blandy | 1992-09-22 06:23:30 +0000 |
|---|---|---|
| committer | Jim Blandy | 1992-09-22 06:23:30 +0000 |
| commit | ba410f40e997e8653a51ab8904a4a5509190f40a (patch) | |
| tree | d4b371aecdbcfc15f5e850ddc11f31357a0f4b88 /src | |
| parent | 5d6533f1865725d8171b3014f74f5ab17b777622 (diff) | |
| download | emacs-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.c | 46 |
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 | ||
| 893 | static void | 898 | static void |
| 894 | unbind_catch (catch) | 899 | unwind_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 | ||
| 922 | DEFUN ("throw", Fthrow, Sthrow, 2, 2, 0, | 933 | DEFUN ("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); |