aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJim Blandy1992-09-22 05:17:48 +0000
committerJim Blandy1992-09-22 05:17:48 +0000
commit82da7701c884bda5329ca7115d151a5e8c69439c (patch)
tree434e9737d593b5e1658629702cf1ab7e5085c023 /src
parentb44895bc92df5e32f03693b7c881bce9fc80b50d (diff)
downloademacs-82da7701c884bda5329ca7115d151a5e8c69439c.tar.gz
emacs-82da7701c884bda5329ca7115d151a5e8c69439c.zip
* eval.c (Fcondition_case): Rearranged for clarity. Don't worry
about setting h.poll_suppress_count; it's guaranteed to be the same as c.poll_suppress_count. (internal_condition_case): Don't worry about h.poll_suppress_count. (Fsignal): Use h->tag->poll_suppress_count instead of h->poll_suppress_count. * eval.c (Fsignal): It's okay for the debugger to return to the caller if the caller was signalling a quit. * eval.c (unbind_catch): Restore the polling suppression count here, instead of in Fsignal and Fthrow. (Fthrow, Fsignal): Don't restore the polling suppression count here. * eval.c (struct catchtag): More documentation. * eval.c (entering_debugger): Variable renamed when_entered_debugger, and is now a timestamp based on num_nonmacro_input_chars. (init_eval): Initialize when_entered_debugger, not entering_debugger. (call_debugger): Set when_entered_debugger to the current value of num_nonmacro_input_chars. (find_handler_clause): Don't call debugger unless num_nonmacro_input_chars is greater than when_entered_debugger; that way, we won't call the debugger unless the user has had a chance to take control. (Fbacktrace): Don't clear entering_debugger here.
Diffstat (limited to 'src')
-rw-r--r--src/eval.c99
1 files changed, 65 insertions, 34 deletions
diff --git a/src/eval.c b/src/eval.c
index 2f3d684f469..ca78a065045 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -51,6 +51,24 @@ struct backtrace
51 51
52struct backtrace *backtrace_list; 52struct backtrace *backtrace_list;
53 53
54/* This structure helps implement the `catch' and `throw' control
55 structure. A struct catchtag contains all the information needed
56 to restore the state of the interpreter after a non-local jump.
57
58 Handlers for error conditions (represented by `struct handler'
59 structures) just point to a catch tag to do the cleanup required
60 for their jumps.
61
62 catchtag structures are chained together in the C calling stack;
63 the `next' member points to the next outer catchtag.
64
65 A call like (throw TAG VAL) searches for a catchtag whose `tag'
66 member is TAG, and then unbinds to it. The `val' member is used to
67 hold VAL while the stack is unwound; `val' is returned as the value
68 of the catch form.
69
70 All the other members are concerned with restoring the interpreter
71 state. */
54struct catchtag 72struct catchtag
55 { 73 {
56 Lisp_Object tag; 74 Lisp_Object tag;
@@ -115,9 +133,13 @@ Lisp_Object Vdebug_on_error;
115 is handled by the command loop's error handler. */ 133 is handled by the command loop's error handler. */
116int debug_on_quit; 134int debug_on_quit;
117 135
118/* Nonzero means we are trying to enter the debugger. 136/* The value of num_nonmacro_input_chars as of the last time we
119 This is to prevent recursive attempts. */ 137 started to enter the debugger. If we decide to enter the debugger
120int entering_debugger; 138 again when this is still equal to num_nonmacro_input_chars, then we
139 know that the debugger itself has an error, and we should just
140 signal the error instead of entering an infinite loop of debugger
141 invocations. */
142int when_entered_debugger;
121 143
122Lisp_Object Vdebugger; 144Lisp_Object Vdebugger;
123 145
@@ -143,7 +165,7 @@ init_eval ()
143 Vquit_flag = Qnil; 165 Vquit_flag = Qnil;
144 debug_on_next_call = 0; 166 debug_on_next_call = 0;
145 lisp_eval_depth = 0; 167 lisp_eval_depth = 0;
146 entering_debugger = 0; 168 when_entered_debugger = 0;
147} 169}
148 170
149Lisp_Object 171Lisp_Object
@@ -155,7 +177,7 @@ call_debugger (arg)
155 if (specpdl_size + 40 > max_specpdl_size) 177 if (specpdl_size + 40 > max_specpdl_size)
156 max_specpdl_size = specpdl_size + 40; 178 max_specpdl_size = specpdl_size + 40;
157 debug_on_next_call = 0; 179 debug_on_next_call = 0;
158 entering_debugger = 1; 180 when_entered_debugger = num_nonmacro_input_chars;
159 return apply1 (Vdebugger, arg); 181 return apply1 (Vdebugger, arg);
160} 182}
161 183
@@ -874,9 +896,18 @@ unbind_catch (catch)
874{ 896{
875 register int last_time; 897 register int last_time;
876 898
899 /* Restore the polling-suppression count. */
900 if (catch->poll_suppress_count > poll_suppress_count)
901 abort ();
902 while (catch->poll_suppress_count < poll_suppress_count)
903 start_polling ();
904
877 do 905 do
878 { 906 {
879 last_time = catchlist == catch; 907 last_time = catchlist == catch;
908
909 /* Unwind the specpdl stack, and then restore the proper set of
910 handlers. */
880 unbind_to (catchlist->pdlcount, Qnil); 911 unbind_to (catchlist->pdlcount, Qnil);
881 handlerlist = catchlist->handlerlist; 912 handlerlist = catchlist->handlerlist;
882 catchlist = catchlist->next; 913 catchlist = catchlist->next;
@@ -903,11 +934,6 @@ Both TAG and VALUE are evalled.")
903 { 934 {
904 if (EQ (c->tag, tag)) 935 if (EQ (c->tag, tag))
905 { 936 {
906 /* Restore the polling-suppression count. */
907 if (c->poll_suppress_count > poll_suppress_count)
908 abort ();
909 while (c->poll_suppress_count < poll_suppress_count)
910 start_polling ();
911 c->val = val; 937 c->val = val;
912 unbind_catch (c); 938 unbind_catch (c);
913 _longjmp (c->jmp, 1); 939 _longjmp (c->jmp, 1);
@@ -966,10 +992,21 @@ See also the function `signal' for more info.")
966 Lisp_Object val; 992 Lisp_Object val;
967 struct catchtag c; 993 struct catchtag c;
968 struct handler h; 994 struct handler h;
969 register Lisp_Object tem; 995 register Lisp_Object var, bodyform, handlers;
996
997 var = Fcar (args);
998 bodyform = Fcar (Fcdr (args));
999 handlers = Fcdr (Fcdr (args));
1000 CHECK_SYMBOL (var, 0);
970 1001
971 tem = Fcar (args); 1002 for (val = handlers; ! NILP (val); val = Fcdr (val))
972 CHECK_SYMBOL (tem, 0); 1003 {
1004 Lisp_Object tem;
1005 tem = Fcar (val);
1006 if ((!NILP (tem)) &&
1007 (!CONSP (tem) || (XTYPE (XCONS (tem)->car) != Lisp_Symbol)))
1008 error ("Invalid condition handler", tem);
1009 }
973 1010
974 c.tag = Qnil; 1011 c.tag = Qnil;
975 c.val = Qnil; 1012 c.val = Qnil;
@@ -984,28 +1021,23 @@ See also the function `signal' for more info.")
984 if (!NILP (h.var)) 1021 if (!NILP (h.var))
985 specbind (h.var, Fcdr (c.val)); 1022 specbind (h.var, Fcdr (c.val));
986 val = Fprogn (Fcdr (Fcar (c.val))); 1023 val = Fprogn (Fcdr (Fcar (c.val)));
1024
1025 /* Note that this just undoes the binding of h.var; whoever
1026 longjumped to us unwound the stack to c.pdlcount before
1027 throwing. */
987 unbind_to (c.pdlcount, Qnil); 1028 unbind_to (c.pdlcount, Qnil);
988 return val; 1029 return val;
989 } 1030 }
990 c.next = catchlist; 1031 c.next = catchlist;
991 catchlist = &c; 1032 catchlist = &c;
992 h.var = Fcar (args);
993 h.handler = Fcdr (Fcdr (args));
994
995 for (val = h.handler; ! NILP (val); val = Fcdr (val))
996 {
997 tem = Fcar (val);
998 if ((!NILP (tem)) &&
999 (!CONSP (tem) || (XTYPE (XCONS (tem)->car) != Lisp_Symbol)))
1000 error ("Invalid condition handler", tem);
1001 }
1002 1033
1034 h.var = var;
1035 h.handler = handlers;
1003 h.next = handlerlist; 1036 h.next = handlerlist;
1004 h.poll_suppress_count = poll_suppress_count;
1005 h.tag = &c; 1037 h.tag = &c;
1006 handlerlist = &h; 1038 handlerlist = &h;
1007 1039
1008 val = Feval (Fcar (Fcdr (args))); 1040 val = Feval (bodyform);
1009 catchlist = c.next; 1041 catchlist = c.next;
1010 handlerlist = h.next; 1042 handlerlist = h.next;
1011 return val; 1043 return val;
@@ -1037,7 +1069,6 @@ internal_condition_case (bfun, handlers, hfun)
1037 catchlist = &c; 1069 catchlist = &c;
1038 h.handler = handlers; 1070 h.handler = handlers;
1039 h.var = Qnil; 1071 h.var = Qnil;
1040 h.poll_suppress_count = poll_suppress_count;
1041 h.next = handlerlist; 1072 h.next = handlerlist;
1042 h.tag = &c; 1073 h.tag = &c;
1043 handlerlist = &h; 1074 handlerlist = &h;
@@ -1095,17 +1126,19 @@ See also the function `condition-case'.")
1095 return debugger_value; 1126 return debugger_value;
1096#else 1127#else
1097 if (EQ (clause, Qlambda)) 1128 if (EQ (clause, Qlambda))
1129 {
1130 /* We can't return values to code which signalled an error, but we
1131 can continue code which has signalled a quit. */
1132 if (EQ (sig, Qquit))
1133 return Qnil;
1134 else
1098 error ("Returning a value from an error is no longer supported"); 1135 error ("Returning a value from an error is no longer supported");
1136 }
1099#endif 1137#endif
1100 1138
1101 if (!NILP (clause)) 1139 if (!NILP (clause))
1102 { 1140 {
1103 struct handler *h = handlerlist; 1141 struct handler *h = handlerlist;
1104 /* Restore the polling-suppression count. */
1105 if (h->poll_suppress_count > poll_suppress_count)
1106 abort ();
1107 while (h->poll_suppress_count < poll_suppress_count)
1108 start_polling ();
1109 handlerlist = allhandlers; 1142 handlerlist = allhandlers;
1110 unbind_catch (h->tag); 1143 unbind_catch (h->tag);
1111 h->tag->val = Fcons (clause, Fcons (sig, data)); 1144 h->tag->val = Fcons (clause, Fcons (sig, data));
@@ -1162,7 +1195,7 @@ find_handler_clause (handlers, conditions, sig, data, debugger_value_ptr)
1162 { 1195 {
1163 if (wants_debugger (Vstack_trace_on_error, conditions)) 1196 if (wants_debugger (Vstack_trace_on_error, conditions))
1164 internal_with_output_to_temp_buffer ("*Backtrace*", Fbacktrace, Qnil); 1197 internal_with_output_to_temp_buffer ("*Backtrace*", Fbacktrace, Qnil);
1165 if (!entering_debugger 1198 if (when_entered_debugger < num_nonmacro_input_chars
1166 && (EQ (sig, Qquit) ? debug_on_quit 1199 && (EQ (sig, Qquit) ? debug_on_quit
1167 : wants_debugger (Vdebug_on_error, conditions))) 1200 : wants_debugger (Vdebug_on_error, conditions)))
1168 { 1201 {
@@ -2158,8 +2191,6 @@ Output stream used is value of `standard-output'.")
2158 extern Lisp_Object Vprint_level; 2191 extern Lisp_Object Vprint_level;
2159 struct gcpro gcpro1; 2192 struct gcpro gcpro1;
2160 2193
2161 entering_debugger = 0;
2162
2163 XFASTINT (Vprint_level) = 3; 2194 XFASTINT (Vprint_level) = 3;
2164 2195
2165 tail = Qnil; 2196 tail = Qnil;