aboutsummaryrefslogtreecommitdiffstats
path: root/src/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c336
1 files changed, 131 insertions, 205 deletions
diff --git a/src/eval.c b/src/eval.c
index 6e964f6604b..5526b28b2e0 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -32,20 +32,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
32#include "xterm.h" 32#include "xterm.h"
33#endif 33#endif
34 34
35#if !BYTE_MARK_STACK 35/* Chain of condition and catch handlers currently in effect. */
36static
37#endif
38struct catchtag *catchlist;
39
40/* Chain of condition handlers currently in effect.
41 The elements of this chain are contained in the stack frames
42 of Fcondition_case and internal_condition_case.
43 When an error is signaled (by calling Fsignal, below),
44 this chain is searched for an element that applies. */
45 36
46#if !BYTE_MARK_STACK
47static
48#endif
49struct handler *handlerlist; 37struct handler *handlerlist;
50 38
51#ifdef DEBUG_GCPRO 39#ifdef DEBUG_GCPRO
@@ -92,7 +80,7 @@ union specbinding *specpdl_ptr;
92 80
93/* Depth in Lisp evaluations and function calls. */ 81/* Depth in Lisp evaluations and function calls. */
94 82
95static EMACS_INT lisp_eval_depth; 83EMACS_INT lisp_eval_depth;
96 84
97/* The value of num_nonmacro_input_events as of the last time we 85/* The value of num_nonmacro_input_events as of the last time we
98 started to enter the debugger. If we decide to enter the debugger 86 started to enter the debugger. If we decide to enter the debugger
@@ -253,8 +241,7 @@ void
253init_eval (void) 241init_eval (void)
254{ 242{
255 specpdl_ptr = specpdl; 243 specpdl_ptr = specpdl;
256 catchlist = 0; 244 handlerlist = NULL;
257 handlerlist = 0;
258 Vquit_flag = Qnil; 245 Vquit_flag = Qnil;
259 debug_on_next_call = 0; 246 debug_on_next_call = 0;
260 lisp_eval_depth = 0; 247 lisp_eval_depth = 0;
@@ -1093,28 +1080,26 @@ Lisp_Object
1093internal_catch (Lisp_Object tag, Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) 1080internal_catch (Lisp_Object tag, Lisp_Object (*func) (Lisp_Object), Lisp_Object arg)
1094{ 1081{
1095 /* This structure is made part of the chain `catchlist'. */ 1082 /* This structure is made part of the chain `catchlist'. */
1096 struct catchtag c; 1083 struct handler *c;
1097 1084
1098 /* Fill in the components of c, and put it on the list. */ 1085 /* Fill in the components of c, and put it on the list. */
1099 c.next = catchlist; 1086 PUSH_HANDLER (c, tag, CATCHER);
1100 c.tag = tag;
1101 c.val = Qnil;
1102 c.handlerlist = handlerlist;
1103 c.lisp_eval_depth = lisp_eval_depth;
1104 c.pdlcount = SPECPDL_INDEX ();
1105 c.poll_suppress_count = poll_suppress_count;
1106 c.interrupt_input_blocked = interrupt_input_blocked;
1107 c.gcpro = gcprolist;
1108 c.byte_stack = byte_stack_list;
1109 catchlist = &c;
1110 1087
1111 /* Call FUNC. */ 1088 /* Call FUNC. */
1112 if (! sys_setjmp (c.jmp)) 1089 if (! sys_setjmp (c->jmp))
1113 c.val = (*func) (arg); 1090 {
1114 1091 Lisp_Object val = (*func) (arg);
1115 /* Throw works by a longjmp that comes right here. */ 1092 eassert (handlerlist == c);
1116 catchlist = c.next; 1093 handlerlist = c->next;
1117 return c.val; 1094 return val;
1095 }
1096 else
1097 { /* Throw works by a longjmp that comes right here. */
1098 Lisp_Object val = handlerlist->val;
1099 eassert (handlerlist == c);
1100 handlerlist = handlerlist->next;
1101 return val;
1102 }
1118} 1103}
1119 1104
1120/* Unwind the specbind, catch, and handler stacks back to CATCH, and 1105/* Unwind the specbind, catch, and handler stacks back to CATCH, and
@@ -1134,7 +1119,7 @@ internal_catch (Lisp_Object tag, Lisp_Object (*func) (Lisp_Object), Lisp_Object
1134 This is used for correct unwinding in Fthrow and Fsignal. */ 1119 This is used for correct unwinding in Fthrow and Fsignal. */
1135 1120
1136static _Noreturn void 1121static _Noreturn void
1137unwind_to_catch (struct catchtag *catch, Lisp_Object value) 1122unwind_to_catch (struct handler *catch, Lisp_Object value)
1138{ 1123{
1139 bool last_time; 1124 bool last_time;
1140 1125
@@ -1148,16 +1133,17 @@ unwind_to_catch (struct catchtag *catch, Lisp_Object value)
1148 1133
1149 do 1134 do
1150 { 1135 {
1151 last_time = catchlist == catch;
1152
1153 /* Unwind the specpdl stack, and then restore the proper set of 1136 /* Unwind the specpdl stack, and then restore the proper set of
1154 handlers. */ 1137 handlers. */
1155 unbind_to (catchlist->pdlcount, Qnil); 1138 unbind_to (handlerlist->pdlcount, Qnil);
1156 handlerlist = catchlist->handlerlist; 1139 last_time = handlerlist == catch;
1157 catchlist = catchlist->next; 1140 if (! last_time)
1141 handlerlist = handlerlist->next;
1158 } 1142 }
1159 while (! last_time); 1143 while (! last_time);
1160 1144
1145 eassert (handlerlist == catch);
1146
1161 byte_stack_list = catch->byte_stack; 1147 byte_stack_list = catch->byte_stack;
1162 gcprolist = catch->gcpro; 1148 gcprolist = catch->gcpro;
1163#ifdef DEBUG_GCPRO 1149#ifdef DEBUG_GCPRO
@@ -1173,12 +1159,12 @@ DEFUN ("throw", Fthrow, Sthrow, 2, 2, 0,
1173Both TAG and VALUE are evalled. */) 1159Both TAG and VALUE are evalled. */)
1174 (register Lisp_Object tag, Lisp_Object value) 1160 (register Lisp_Object tag, Lisp_Object value)
1175{ 1161{
1176 register struct catchtag *c; 1162 struct handler *c;
1177 1163
1178 if (!NILP (tag)) 1164 if (!NILP (tag))
1179 for (c = catchlist; c; c = c->next) 1165 for (c = handlerlist; c; c = c->next)
1180 { 1166 {
1181 if (EQ (c->tag, tag)) 1167 if (c->type == CATCHER && EQ (c->tag_or_ch, tag))
1182 unwind_to_catch (c, value); 1168 unwind_to_catch (c, value);
1183 } 1169 }
1184 xsignal2 (Qno_catch, tag, value); 1170 xsignal2 (Qno_catch, tag, value);
@@ -1244,15 +1230,16 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform,
1244 Lisp_Object handlers) 1230 Lisp_Object handlers)
1245{ 1231{
1246 Lisp_Object val; 1232 Lisp_Object val;
1247 struct catchtag c; 1233 struct handler *c;
1248 struct handler h; 1234 struct handler *oldhandlerlist = handlerlist;
1235 int clausenb = 0;
1249 1236
1250 CHECK_SYMBOL (var); 1237 CHECK_SYMBOL (var);
1251 1238
1252 for (val = handlers; CONSP (val); val = XCDR (val)) 1239 for (val = handlers; CONSP (val); val = XCDR (val))
1253 { 1240 {
1254 Lisp_Object tem; 1241 Lisp_Object tem = XCAR (val);
1255 tem = XCAR (val); 1242 clausenb++;
1256 if (! (NILP (tem) 1243 if (! (NILP (tem)
1257 || (CONSP (tem) 1244 || (CONSP (tem)
1258 && (SYMBOLP (XCAR (tem)) 1245 && (SYMBOLP (XCAR (tem))
@@ -1261,39 +1248,50 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform,
1261 SDATA (Fprin1_to_string (tem, Qt))); 1248 SDATA (Fprin1_to_string (tem, Qt)));
1262 } 1249 }
1263 1250
1264 c.tag = Qnil; 1251 { /* The first clause is the one that should be checked first, so it should
1265 c.val = Qnil; 1252 be added to handlerlist last. So we build in `clauses' a table that
1266 c.handlerlist = handlerlist; 1253 contains `handlers' but in reverse order. */
1267 c.lisp_eval_depth = lisp_eval_depth; 1254 Lisp_Object *clauses = alloca (clausenb * sizeof (Lisp_Object *));
1268 c.pdlcount = SPECPDL_INDEX (); 1255 int i = clausenb;
1269 c.poll_suppress_count = poll_suppress_count; 1256 for (val = handlers; CONSP (val); val = XCDR (val))
1270 c.interrupt_input_blocked = interrupt_input_blocked; 1257 clauses[--i] = XCAR (val);
1271 c.gcpro = gcprolist; 1258 for (i = 0; i < clausenb; i++)
1272 c.byte_stack = byte_stack_list; 1259 {
1273 if (sys_setjmp (c.jmp)) 1260 Lisp_Object clause = clauses[i];
1274 { 1261 Lisp_Object condition = XCAR (clause);
1275 if (!NILP (h.var)) 1262 if (!CONSP (condition))
1276 specbind (h.var, c.val); 1263 condition = Fcons (condition, Qnil);
1277 val = Fprogn (Fcdr (h.chosen_clause)); 1264 PUSH_HANDLER (c, condition, CONDITION_CASE);
1278 1265 if (sys_setjmp (c->jmp))
1279 /* Note that this just undoes the binding of h.var; whoever 1266 {
1280 longjumped to us unwound the stack to c.pdlcount before 1267 ptrdiff_t count = SPECPDL_INDEX ();
1281 throwing. */ 1268 Lisp_Object val = handlerlist->val;
1282 unbind_to (c.pdlcount, Qnil); 1269 Lisp_Object *chosen_clause = clauses;
1283 return val; 1270 for (c = handlerlist->next; c != oldhandlerlist; c = c->next)
1271 chosen_clause++;
1272 handlerlist = oldhandlerlist;
1273 if (!NILP (var))
1274 {
1275 if (!NILP (Vinternal_interpreter_environment))
1276 specbind (Qinternal_interpreter_environment,
1277 Fcons (Fcons (var, val),
1278 Vinternal_interpreter_environment));
1279 else
1280 specbind (var, val);
1281 }
1282 val = Fprogn (XCDR (*chosen_clause));
1283 /* Note that this just undoes the binding of var; whoever
1284 longjumped to us unwound the stack to c.pdlcount before
1285 throwing. */
1286 if (!NILP (var))
1287 unbind_to (count, Qnil);
1288 return val;
1289 }
1290 }
1284 } 1291 }
1285 c.next = catchlist;
1286 catchlist = &c;
1287
1288 h.var = var;
1289 h.handler = handlers;
1290 h.next = handlerlist;
1291 h.tag = &c;
1292 handlerlist = &h;
1293 1292
1294 val = eval_sub (bodyform); 1293 val = eval_sub (bodyform);
1295 catchlist = c.next; 1294 handlerlist = oldhandlerlist;
1296 handlerlist = h.next;
1297 return val; 1295 return val;
1298} 1296}
1299 1297
@@ -1312,33 +1310,20 @@ internal_condition_case (Lisp_Object (*bfun) (void), Lisp_Object handlers,
1312 Lisp_Object (*hfun) (Lisp_Object)) 1310 Lisp_Object (*hfun) (Lisp_Object))
1313{ 1311{
1314 Lisp_Object val; 1312 Lisp_Object val;
1315 struct catchtag c; 1313 struct handler *c;
1316 struct handler h; 1314
1317 1315 PUSH_HANDLER (c, handlers, CONDITION_CASE);
1318 c.tag = Qnil; 1316 if (sys_setjmp (c->jmp))
1319 c.val = Qnil; 1317 {
1320 c.handlerlist = handlerlist; 1318 Lisp_Object val = handlerlist->val;
1321 c.lisp_eval_depth = lisp_eval_depth; 1319 eassert (handlerlist == c);
1322 c.pdlcount = SPECPDL_INDEX (); 1320 handlerlist = handlerlist->next;
1323 c.poll_suppress_count = poll_suppress_count; 1321 return (*hfun) (val);
1324 c.interrupt_input_blocked = interrupt_input_blocked; 1322 }
1325 c.gcpro = gcprolist;
1326 c.byte_stack = byte_stack_list;
1327 if (sys_setjmp (c.jmp))
1328 {
1329 return (*hfun) (c.val);
1330 }
1331 c.next = catchlist;
1332 catchlist = &c;
1333 h.handler = handlers;
1334 h.var = Qnil;
1335 h.next = handlerlist;
1336 h.tag = &c;
1337 handlerlist = &h;
1338 1323
1339 val = (*bfun) (); 1324 val = (*bfun) ();
1340 catchlist = c.next; 1325 eassert (handlerlist == c);
1341 handlerlist = h.next; 1326 handlerlist = c->next;
1342 return val; 1327 return val;
1343} 1328}
1344 1329
@@ -1349,33 +1334,20 @@ internal_condition_case_1 (Lisp_Object (*bfun) (Lisp_Object), Lisp_Object arg,
1349 Lisp_Object handlers, Lisp_Object (*hfun) (Lisp_Object)) 1334 Lisp_Object handlers, Lisp_Object (*hfun) (Lisp_Object))
1350{ 1335{
1351 Lisp_Object val; 1336 Lisp_Object val;
1352 struct catchtag c; 1337 struct handler *c;
1353 struct handler h; 1338
1354 1339 PUSH_HANDLER (c, handlers, CONDITION_CASE);
1355 c.tag = Qnil; 1340 if (sys_setjmp (c->jmp))
1356 c.val = Qnil; 1341 {
1357 c.handlerlist = handlerlist; 1342 Lisp_Object val = handlerlist->val;
1358 c.lisp_eval_depth = lisp_eval_depth; 1343 eassert (handlerlist == c);
1359 c.pdlcount = SPECPDL_INDEX (); 1344 handlerlist = handlerlist->next;
1360 c.poll_suppress_count = poll_suppress_count; 1345 return (*hfun) (val);
1361 c.interrupt_input_blocked = interrupt_input_blocked; 1346 }
1362 c.gcpro = gcprolist;
1363 c.byte_stack = byte_stack_list;
1364 if (sys_setjmp (c.jmp))
1365 {
1366 return (*hfun) (c.val);
1367 }
1368 c.next = catchlist;
1369 catchlist = &c;
1370 h.handler = handlers;
1371 h.var = Qnil;
1372 h.next = handlerlist;
1373 h.tag = &c;
1374 handlerlist = &h;
1375 1347
1376 val = (*bfun) (arg); 1348 val = (*bfun) (arg);
1377 catchlist = c.next; 1349 eassert (handlerlist == c);
1378 handlerlist = h.next; 1350 handlerlist = c->next;
1379 return val; 1351 return val;
1380} 1352}
1381 1353
@@ -1390,33 +1362,20 @@ internal_condition_case_2 (Lisp_Object (*bfun) (Lisp_Object, Lisp_Object),
1390 Lisp_Object (*hfun) (Lisp_Object)) 1362 Lisp_Object (*hfun) (Lisp_Object))
1391{ 1363{
1392 Lisp_Object val; 1364 Lisp_Object val;
1393 struct catchtag c; 1365 struct handler *c;
1394 struct handler h; 1366
1395 1367 PUSH_HANDLER (c, handlers, CONDITION_CASE);
1396 c.tag = Qnil; 1368 if (sys_setjmp (c->jmp))
1397 c.val = Qnil; 1369 {
1398 c.handlerlist = handlerlist; 1370 Lisp_Object val = handlerlist->val;
1399 c.lisp_eval_depth = lisp_eval_depth; 1371 eassert (handlerlist == c);
1400 c.pdlcount = SPECPDL_INDEX (); 1372 handlerlist = handlerlist->next;
1401 c.poll_suppress_count = poll_suppress_count; 1373 return (*hfun) (val);
1402 c.interrupt_input_blocked = interrupt_input_blocked; 1374 }
1403 c.gcpro = gcprolist;
1404 c.byte_stack = byte_stack_list;
1405 if (sys_setjmp (c.jmp))
1406 {
1407 return (*hfun) (c.val);
1408 }
1409 c.next = catchlist;
1410 catchlist = &c;
1411 h.handler = handlers;
1412 h.var = Qnil;
1413 h.next = handlerlist;
1414 h.tag = &c;
1415 handlerlist = &h;
1416 1375
1417 val = (*bfun) (arg1, arg2); 1376 val = (*bfun) (arg1, arg2);
1418 catchlist = c.next; 1377 eassert (handlerlist == c);
1419 handlerlist = h.next; 1378 handlerlist = c->next;
1420 return val; 1379 return val;
1421} 1380}
1422 1381
@@ -1433,33 +1392,20 @@ internal_condition_case_n (Lisp_Object (*bfun) (ptrdiff_t, Lisp_Object *),
1433 Lisp_Object *args)) 1392 Lisp_Object *args))
1434{ 1393{
1435 Lisp_Object val; 1394 Lisp_Object val;
1436 struct catchtag c; 1395 struct handler *c;
1437 struct handler h; 1396
1438 1397 PUSH_HANDLER (c, handlers, CONDITION_CASE);
1439 c.tag = Qnil; 1398 if (sys_setjmp (c->jmp))
1440 c.val = Qnil; 1399 {
1441 c.handlerlist = handlerlist; 1400 Lisp_Object val = handlerlist->val;
1442 c.lisp_eval_depth = lisp_eval_depth; 1401 eassert (handlerlist == c);
1443 c.pdlcount = SPECPDL_INDEX (); 1402 handlerlist = handlerlist->next;
1444 c.poll_suppress_count = poll_suppress_count; 1403 return (*hfun) (val, nargs, args);
1445 c.interrupt_input_blocked = interrupt_input_blocked; 1404 }
1446 c.gcpro = gcprolist;
1447 c.byte_stack = byte_stack_list;
1448 if (sys_setjmp (c.jmp))
1449 {
1450 return (*hfun) (c.val, nargs, args);
1451 }
1452 c.next = catchlist;
1453 catchlist = &c;
1454 h.handler = handlers;
1455 h.var = Qnil;
1456 h.next = handlerlist;
1457 h.tag = &c;
1458 handlerlist = &h;
1459 1405
1460 val = (*bfun) (nargs, args); 1406 val = (*bfun) (nargs, args);
1461 catchlist = c.next; 1407 eassert (handlerlist == c);
1462 handlerlist = h.next; 1408 handlerlist = c->next;
1463 return val; 1409 return val;
1464} 1410}
1465 1411
@@ -1551,7 +1497,9 @@ See also the function `condition-case'. */)
1551 1497
1552 for (h = handlerlist; h; h = h->next) 1498 for (h = handlerlist; h; h = h->next)
1553 { 1499 {
1554 clause = find_handler_clause (h->handler, conditions); 1500 if (h->type != CONDITION_CASE)
1501 continue;
1502 clause = find_handler_clause (h->tag_or_ch, conditions);
1555 if (!NILP (clause)) 1503 if (!NILP (clause))
1556 break; 1504 break;
1557 } 1505 }
@@ -1568,7 +1516,7 @@ See also the function `condition-case'. */)
1568 && !NILP (Fmemq (Qdebug, XCAR (clause)))) 1516 && !NILP (Fmemq (Qdebug, XCAR (clause))))
1569 /* Special handler that means "print a message and run debugger 1517 /* Special handler that means "print a message and run debugger
1570 if requested". */ 1518 if requested". */
1571 || EQ (h->handler, Qerror))) 1519 || EQ (h->tag_or_ch, Qerror)))
1572 { 1520 {
1573 bool debugger_called 1521 bool debugger_called
1574 = maybe_call_debugger (conditions, error_symbol, data); 1522 = maybe_call_debugger (conditions, error_symbol, data);
@@ -1583,12 +1531,11 @@ See also the function `condition-case'. */)
1583 Lisp_Object unwind_data 1531 Lisp_Object unwind_data
1584 = (NILP (error_symbol) ? data : Fcons (error_symbol, data)); 1532 = (NILP (error_symbol) ? data : Fcons (error_symbol, data));
1585 1533
1586 h->chosen_clause = clause; 1534 unwind_to_catch (h, unwind_data);
1587 unwind_to_catch (h->tag, unwind_data);
1588 } 1535 }
1589 else 1536 else
1590 { 1537 {
1591 if (catchlist != 0) 1538 if (handlerlist != 0)
1592 Fthrow (Qtop_level, Qt); 1539 Fthrow (Qtop_level, Qt);
1593 } 1540 }
1594 1541
@@ -1774,29 +1721,8 @@ find_handler_clause (Lisp_Object handlers, Lisp_Object conditions)
1774 for (h = handlers; CONSP (h); h = XCDR (h)) 1721 for (h = handlers; CONSP (h); h = XCDR (h))
1775 { 1722 {
1776 Lisp_Object handler = XCAR (h); 1723 Lisp_Object handler = XCAR (h);
1777 Lisp_Object condit, tem; 1724 if (!NILP (Fmemq (handler, conditions)))
1778 1725 return handlers;
1779 if (!CONSP (handler))
1780 continue;
1781 condit = XCAR (handler);
1782 /* Handle a single condition name in handler HANDLER. */
1783 if (SYMBOLP (condit))
1784 {
1785 tem = Fmemq (Fcar (handler), conditions);
1786 if (!NILP (tem))
1787 return handler;
1788 }
1789 /* Handle a list of condition names in handler HANDLER. */
1790 else if (CONSP (condit))
1791 {
1792 Lisp_Object tail;
1793 for (tail = condit; CONSP (tail); tail = XCDR (tail))
1794 {
1795 tem = Fmemq (XCAR (tail), conditions);
1796 if (!NILP (tem))
1797 return handler;
1798 }
1799 }
1800 } 1726 }
1801 1727
1802 return Qnil; 1728 return Qnil;