aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPhilipp Stephani2015-11-16 00:31:56 +0100
committerTed Zlatanov2015-11-18 14:23:41 -0500
commit7cdc5d628a737e2153c38d0d285c9879071beaa7 (patch)
tree58d21223b8d1b7de7230449dfb24d85efcab86f5 /src
parent133ad3e2006d136a6153a75140a880f8ff16ea65 (diff)
downloademacs-7cdc5d628a737e2153c38d0d285c9879071beaa7.tar.gz
emacs-7cdc5d628a737e2153c38d0d285c9879071beaa7.zip
Add catch-all & no-signal version of PUSH_HANDLER
Ground work for modules. Add a non-signaling version of PUSH_HANDLER and a new "catch-all" handler type. * src/eval.c (init_handler, push_handler, push_handler_nosignal): New functions. * src/fns.c (hash_remove_from_table): Expose function public. * src/lisp.h: New handler type, define macro to push_handler call.
Diffstat (limited to 'src')
-rw-r--r--src/eval.c53
-rw-r--r--src/fns.c5
-rw-r--r--src/lisp.h35
3 files changed, 68 insertions, 25 deletions
diff --git a/src/eval.c b/src/eval.c
index 3ee07a71c69..396ca84a71d 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1145,7 +1145,9 @@ Both TAG and VALUE are evalled. */
1145 if (!NILP (tag)) 1145 if (!NILP (tag))
1146 for (c = handlerlist; c; c = c->next) 1146 for (c = handlerlist; c; c = c->next)
1147 { 1147 {
1148 if (c->type == CATCHER && EQ (c->tag_or_ch, tag)) 1148 if (c->type == CATCHER_ALL)
1149 unwind_to_catch (c, Fcons (tag, value));
1150 if (c->type == CATCHER && EQ (c->tag_or_ch, tag))
1149 unwind_to_catch (c, value); 1151 unwind_to_catch (c, value);
1150 } 1152 }
1151 xsignal2 (Qno_catch, tag, value); 1153 xsignal2 (Qno_catch, tag, value);
@@ -1394,6 +1396,55 @@ internal_condition_case_n (Lisp_Object (*bfun) (ptrdiff_t, Lisp_Object *),
1394 return val; 1396 return val;
1395} 1397}
1396 1398
1399static void init_handler (struct handler *c, Lisp_Object tag_ch_val,
1400 enum handlertype handlertype);
1401
1402void push_handler (struct handler **const c, const Lisp_Object tag_ch_val,
1403 const enum handlertype handlertype)
1404{
1405 if (handlerlist->nextfree)
1406 *c = handlerlist->nextfree;
1407 else
1408 {
1409 *c = xmalloc (sizeof (struct handler));
1410 (*c)->nextfree = NULL;
1411 handlerlist->nextfree = *c;
1412 }
1413 init_handler (*c, tag_ch_val, handlertype);
1414}
1415
1416bool push_handler_nosignal (struct handler **const c, const Lisp_Object tag_ch_val,
1417 const enum handlertype handlertype)
1418{
1419 if (handlerlist->nextfree)
1420 *c = handlerlist->nextfree;
1421 else
1422 {
1423 struct handler *const h = malloc (sizeof (struct handler));
1424 if (! h) return false;
1425 *c = h;
1426 h->nextfree = NULL;
1427 handlerlist->nextfree = h;
1428 }
1429 init_handler (*c, tag_ch_val, handlertype);
1430 return true;
1431}
1432
1433static void init_handler (struct handler *const c, const Lisp_Object tag_ch_val,
1434 const enum handlertype handlertype)
1435{
1436 c->type = handlertype;
1437 c->tag_or_ch = tag_ch_val;
1438 c->val = Qnil;
1439 c->next = handlerlist;
1440 c->lisp_eval_depth = lisp_eval_depth;
1441 c->pdlcount = SPECPDL_INDEX ();
1442 c->poll_suppress_count = poll_suppress_count;
1443 c->interrupt_input_blocked = interrupt_input_blocked;
1444 c->byte_stack = byte_stack_list;
1445 handlerlist = c;
1446}
1447
1397 1448
1398static Lisp_Object find_handler_clause (Lisp_Object, Lisp_Object); 1449static Lisp_Object find_handler_clause (Lisp_Object, Lisp_Object);
1399static bool maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig, 1450static bool maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig,
diff --git a/src/fns.c b/src/fns.c
index 9931e80c970..029ac6a83bb 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -3620,8 +3620,7 @@ larger_vector (Lisp_Object vec, ptrdiff_t incr_min, ptrdiff_t nitems_max)
3620 Low-level Functions 3620 Low-level Functions
3621 ***********************************************************************/ 3621 ***********************************************************************/
3622 3622
3623static struct hash_table_test hashtest_eq; 3623struct hash_table_test hashtest_eq, hashtest_eql, hashtest_equal;
3624struct hash_table_test hashtest_eql, hashtest_equal;
3625 3624
3626/* Compare KEY1 which has hash code HASH1 and KEY2 with hash code 3625/* Compare KEY1 which has hash code HASH1 and KEY2 with hash code
3627 HASH2 in hash table H using `eql'. Value is true if KEY1 and 3626 HASH2 in hash table H using `eql'. Value is true if KEY1 and
@@ -3992,7 +3991,7 @@ hash_put (struct Lisp_Hash_Table *h, Lisp_Object key, Lisp_Object value,
3992 3991
3993/* Remove the entry matching KEY from hash table H, if there is one. */ 3992/* Remove the entry matching KEY from hash table H, if there is one. */
3994 3993
3995static void 3994void
3996hash_remove_from_table (struct Lisp_Hash_Table *h, Lisp_Object key) 3995hash_remove_from_table (struct Lisp_Hash_Table *h, Lisp_Object key)
3997{ 3996{
3998 EMACS_UINT hash_code; 3997 EMACS_UINT hash_code;
diff --git a/src/lisp.h b/src/lisp.h
index 3efa492e0e8..cab912e7401 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3104,7 +3104,9 @@ SPECPDL_INDEX (void)
3104 A call like (throw TAG VAL) searches for a catchtag whose `tag_or_ch' 3104 A call like (throw TAG VAL) searches for a catchtag whose `tag_or_ch'
3105 member is TAG, and then unbinds to it. The `val' member is used to 3105 member is TAG, and then unbinds to it. The `val' member is used to
3106 hold VAL while the stack is unwound; `val' is returned as the value 3106 hold VAL while the stack is unwound; `val' is returned as the value
3107 of the catch form. 3107 of the catch form. If there is a handler of type CATCHER_ALL, it will
3108 be treated as a handler for all invocations of `throw'; in this case
3109 `val' will be set to (TAG . VAL).
3108 3110
3109 All the other members are concerned with restoring the interpreter 3111 All the other members are concerned with restoring the interpreter
3110 state. 3112 state.
@@ -3112,7 +3114,7 @@ SPECPDL_INDEX (void)
3112 Members are volatile if their values need to survive _longjmp when 3114 Members are volatile if their values need to survive _longjmp when
3113 a 'struct handler' is a local variable. */ 3115 a 'struct handler' is a local variable. */
3114 3116
3115enum handlertype { CATCHER, CONDITION_CASE }; 3117enum handlertype { CATCHER, CONDITION_CASE, CATCHER_ALL };
3116 3118
3117struct handler 3119struct handler
3118{ 3120{
@@ -3142,25 +3144,15 @@ struct handler
3142 3144
3143/* Fill in the components of c, and put it on the list. */ 3145/* Fill in the components of c, and put it on the list. */
3144#define PUSH_HANDLER(c, tag_ch_val, handlertype) \ 3146#define PUSH_HANDLER(c, tag_ch_val, handlertype) \
3145 if (handlerlist->nextfree) \ 3147 push_handler(&(c), (tag_ch_val), (handlertype))
3146 (c) = handlerlist->nextfree; \
3147 else \
3148 { \
3149 (c) = xmalloc (sizeof (struct handler)); \
3150 (c)->nextfree = NULL; \
3151 handlerlist->nextfree = (c); \
3152 } \
3153 (c)->type = (handlertype); \
3154 (c)->tag_or_ch = (tag_ch_val); \
3155 (c)->val = Qnil; \
3156 (c)->next = handlerlist; \
3157 (c)->lisp_eval_depth = lisp_eval_depth; \
3158 (c)->pdlcount = SPECPDL_INDEX (); \
3159 (c)->poll_suppress_count = poll_suppress_count; \
3160 (c)->interrupt_input_blocked = interrupt_input_blocked;\
3161 (c)->byte_stack = byte_stack_list; \
3162 handlerlist = (c);
3163 3148
3149extern void push_handler (struct handler **c, Lisp_Object tag_ch_val,
3150 enum handlertype handlertype);
3151
3152/* Like push_handler, but don't signal if the handler could not be
3153 allocated. Instead return false in that case. */
3154extern bool push_handler_nosignal (struct handler **c, Lisp_Object tag_ch_val,
3155 enum handlertype handlertype);
3164 3156
3165extern Lisp_Object memory_signal_data; 3157extern Lisp_Object memory_signal_data;
3166 3158
@@ -3407,7 +3399,8 @@ Lisp_Object make_hash_table (struct hash_table_test, Lisp_Object, Lisp_Object,
3407ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *); 3399ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *);
3408ptrdiff_t hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object, 3400ptrdiff_t hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object,
3409 EMACS_UINT); 3401 EMACS_UINT);
3410extern struct hash_table_test hashtest_eql, hashtest_equal; 3402void hash_remove_from_table (struct Lisp_Hash_Table *, Lisp_Object);
3403extern struct hash_table_test hashtest_eq, hashtest_eql, hashtest_equal;
3411extern void validate_subarray (Lisp_Object, Lisp_Object, Lisp_Object, 3404extern void validate_subarray (Lisp_Object, Lisp_Object, Lisp_Object,
3412 ptrdiff_t, ptrdiff_t *, ptrdiff_t *); 3405 ptrdiff_t, ptrdiff_t *, ptrdiff_t *);
3413extern Lisp_Object substring_both (Lisp_Object, ptrdiff_t, ptrdiff_t, 3406extern Lisp_Object substring_both (Lisp_Object, ptrdiff_t, ptrdiff_t,