aboutsummaryrefslogtreecommitdiffstats
path: root/src/eval.c
diff options
context:
space:
mode:
authorPhilipp Stephani2019-04-19 01:04:55 +0200
committerPhilipp Stephani2019-04-19 01:04:55 +0200
commit23a82cba12380b0905670c34395dc460a4bc9984 (patch)
treedf001ea84a8173dab9381a3ec75d36d25f6a3650 /src/eval.c
parente712a8fe0929a18eaf3f4ec83b023f475afdc4d4 (diff)
downloademacs-23a82cba12380b0905670c34395dc460a4bc9984.tar.gz
emacs-23a82cba12380b0905670c34395dc460a4bc9984.zip
Refactoring: have CATCHER_ALL also catch signals.
In all cases where we use a CATCHER_ALL handler we also want to catch signals. Therefore have 'signal' respect CATCHER_ALL. Adapt internal interfaces so that handlers can distinguish among the two types of nonlocal exits in CATCHER_ALL handlers. * src/lisp.h (enum nonlocal_exit): New enum. (struct handler): Add member 'nonlocal_exit' to hold the type of nonlocal exit during stack unwinding. * src/eval.c (signal_or_quit): Also respect CATCHER_ALL handlers. (unwind_to_catch): Store nonlocal exit type in catch structure. (Fthrow, signal_or_quit): Adapt callers. (internal_catch_all): Install only one handler. Give handler a nonlocal exit type argument. (internal_catch_all_1): Remove, no longer needed. * src/emacs-module.c (MODULE_SETJMP): Install only one handler. (module_handle_nonlocal_exit): New function to handle all nonlocal exits. (MODULE_SETJMP_1): Pass nonlocal exit type to handler function. (module_handle_signal, module_handle_throw): Remove, no longer needed. * src/json.c (json_handle_nonlocal_exit): New helper function. (json_insert_callback): Adapt to change in 'internal_catch_all'.
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c49
1 files changed, 17 insertions, 32 deletions
diff --git a/src/eval.c b/src/eval.c
index c2e996a9474..23fd0efd54a 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1134,13 +1134,15 @@ internal_catch (Lisp_Object tag,
1134 This is used for correct unwinding in Fthrow and Fsignal. */ 1134 This is used for correct unwinding in Fthrow and Fsignal. */
1135 1135
1136static AVOID 1136static AVOID
1137unwind_to_catch (struct handler *catch, Lisp_Object value) 1137unwind_to_catch (struct handler *catch, enum nonlocal_exit type,
1138 Lisp_Object value)
1138{ 1139{
1139 bool last_time; 1140 bool last_time;
1140 1141
1141 eassert (catch->next); 1142 eassert (catch->next);
1142 1143
1143 /* Save the value in the tag. */ 1144 /* Save the value in the tag. */
1145 catch->nonlocal_exit = type;
1144 catch->val = value; 1146 catch->val = value;
1145 1147
1146 /* Restore certain special C variables. */ 1148 /* Restore certain special C variables. */
@@ -1177,9 +1179,9 @@ Both TAG and VALUE are evalled. */
1177 for (c = handlerlist; c; c = c->next) 1179 for (c = handlerlist; c; c = c->next)
1178 { 1180 {
1179 if (c->type == CATCHER_ALL) 1181 if (c->type == CATCHER_ALL)
1180 unwind_to_catch (c, Fcons (tag, value)); 1182 unwind_to_catch (c, NONLOCAL_EXIT_THROW, Fcons (tag, value));
1181 if (c->type == CATCHER && EQ (c->tag_or_ch, tag)) 1183 if (c->type == CATCHER && EQ (c->tag_or_ch, tag))
1182 unwind_to_catch (c, value); 1184 unwind_to_catch (c, NONLOCAL_EXIT_THROW, value);
1183 } 1185 }
1184 xsignal2 (Qno_catch, tag, value); 1186 xsignal2 (Qno_catch, tag, value);
1185} 1187}
@@ -1427,44 +1429,21 @@ internal_condition_case_n (Lisp_Object (*bfun) (ptrdiff_t, Lisp_Object *),
1427 } 1429 }
1428} 1430}
1429 1431
1430static Lisp_Object
1431internal_catch_all_1 (Lisp_Object (*function) (void *), void *argument)
1432{
1433 struct handler *c = push_handler_nosignal (Qt, CATCHER_ALL);
1434 if (c == NULL)
1435 return Qcatch_all_memory_full;
1436
1437 if (sys_setjmp (c->jmp) == 0)
1438 {
1439 Lisp_Object val = function (argument);
1440 eassert (handlerlist == c);
1441 handlerlist = c->next;
1442 return val;
1443 }
1444 else
1445 {
1446 eassert (handlerlist == c);
1447 Lisp_Object val = c->val;
1448 handlerlist = c->next;
1449 Fsignal (Qno_catch, val);
1450 }
1451}
1452
1453/* Like a combination of internal_condition_case_1 and internal_catch. 1432/* Like a combination of internal_condition_case_1 and internal_catch.
1454 Catches all signals and throws. Never exits nonlocally; returns 1433 Catches all signals and throws. Never exits nonlocally; returns
1455 Qcatch_all_memory_full if no handler could be allocated. */ 1434 Qcatch_all_memory_full if no handler could be allocated. */
1456 1435
1457Lisp_Object 1436Lisp_Object
1458internal_catch_all (Lisp_Object (*function) (void *), void *argument, 1437internal_catch_all (Lisp_Object (*function) (void *), void *argument,
1459 Lisp_Object (*handler) (Lisp_Object)) 1438 Lisp_Object (*handler) (enum nonlocal_exit, Lisp_Object))
1460{ 1439{
1461 struct handler *c = push_handler_nosignal (Qt, CONDITION_CASE); 1440 struct handler *c = push_handler_nosignal (Qt, CATCHER_ALL);
1462 if (c == NULL) 1441 if (c == NULL)
1463 return Qcatch_all_memory_full; 1442 return Qcatch_all_memory_full;
1464 1443
1465 if (sys_setjmp (c->jmp) == 0) 1444 if (sys_setjmp (c->jmp) == 0)
1466 { 1445 {
1467 Lisp_Object val = internal_catch_all_1 (function, argument); 1446 Lisp_Object val = function (argument);
1468 eassert (handlerlist == c); 1447 eassert (handlerlist == c);
1469 handlerlist = c->next; 1448 handlerlist = c->next;
1470 return val; 1449 return val;
@@ -1472,9 +1451,10 @@ internal_catch_all (Lisp_Object (*function) (void *), void *argument,
1472 else 1451 else
1473 { 1452 {
1474 eassert (handlerlist == c); 1453 eassert (handlerlist == c);
1454 enum nonlocal_exit type = c->nonlocal_exit;
1475 Lisp_Object val = c->val; 1455 Lisp_Object val = c->val;
1476 handlerlist = c->next; 1456 handlerlist = c->next;
1477 return handler (val); 1457 return handler (type, val);
1478 } 1458 }
1479} 1459}
1480 1460
@@ -1645,6 +1625,11 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
1645 1625
1646 for (h = handlerlist; h; h = h->next) 1626 for (h = handlerlist; h; h = h->next)
1647 { 1627 {
1628 if (h->type == CATCHER_ALL)
1629 {
1630 clause = Qt;
1631 break;
1632 }
1648 if (h->type != CONDITION_CASE) 1633 if (h->type != CONDITION_CASE)
1649 continue; 1634 continue;
1650 clause = find_handler_clause (h->tag_or_ch, conditions); 1635 clause = find_handler_clause (h->tag_or_ch, conditions);
@@ -1678,7 +1663,7 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
1678 Lisp_Object unwind_data 1663 Lisp_Object unwind_data
1679 = (NILP (error_symbol) ? data : Fcons (error_symbol, data)); 1664 = (NILP (error_symbol) ? data : Fcons (error_symbol, data));
1680 1665
1681 unwind_to_catch (h, unwind_data); 1666 unwind_to_catch (h, NONLOCAL_EXIT_SIGNAL, unwind_data);
1682 } 1667 }
1683 else 1668 else
1684 { 1669 {