aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPhilipp Stephani2015-11-28 14:08:21 +0200
committerEli Zaretskii2015-11-28 14:08:21 +0200
commitc217802b0f1b5b2b3858b1036a71b9570d0b5cbe (patch)
treecf740ee26df168876a26f4bb2e3398e7e4cdcd89 /src
parenta63d1eca8de317b85e59732f8628eae52250901a (diff)
downloademacs-c217802b0f1b5b2b3858b1036a71b9570d0b5cbe.tar.gz
emacs-c217802b0f1b5b2b3858b1036a71b9570d0b5cbe.zip
Simplify the prologue of emacs-module.c functions
* emacs-module.c (MODULE_FUNCTION_BEGIN): New macro. (module_make_global_ref) (module_free_global_ref, module_make_function, module_funcall) (module_intern, module_type_of, module_extract_integer) (module_make_integer, module_extract_float, module_make_float) (module_copy_string_contents, module_make_string) (module_make_user_ptr, module_get_user_ptr, module_set_user_ptr) (module_get_user_finalizer, module_set_user_finalizer) (module_vec_set, module_vec_get, module_vec_size): Use new helper macro MODULE_FUNCTION_BEGIN.
Diffstat (limited to 'src')
-rw-r--r--src/emacs-module.c132
1 files changed, 46 insertions, 86 deletions
diff --git a/src/emacs-module.c b/src/emacs-module.c
index 403e7d24d3e..7d68caddd56 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -156,24 +156,14 @@ static void module_wrong_type (emacs_env *, Lisp_Object, Lisp_Object);
156 passing information to the handler functions. */ 156 passing information to the handler functions. */
157 157
158/* Place this macro at the beginning of a function returning a number 158/* Place this macro at the beginning of a function returning a number
159 or a pointer to handle signals. The function must have an ENV 159 or a pointer to handle non-local exits. The function must have an
160 parameter. The function will return 0 (or NULL) if a signal is 160 ENV parameter. The function will return the specified value if a
161 caught. */ 161 signal or throw is caught. */
162#define MODULE_HANDLE_SIGNALS MODULE_HANDLE_SIGNALS_RETURN (0) 162// TODO: Have Fsignal check for CATCHER_ALL so we only have to install
163 163// one handler.
164/* Place this macro at the beginning of a function returning void to 164#define MODULE_HANDLE_NONLOCAL_EXIT(retval) \
165 handle signals. The function must have an ENV parameter. */ 165 MODULE_SETJMP (CONDITION_CASE, module_handle_signal, retval); \
166#define MODULE_HANDLE_SIGNALS_VOID MODULE_HANDLE_SIGNALS_RETURN () 166 MODULE_SETJMP (CATCHER_ALL, module_handle_throw, retval)
167
168#define MODULE_HANDLE_SIGNALS_RETURN(retval) \
169 MODULE_SETJMP (CONDITION_CASE, module_handle_signal, retval)
170
171/* Place this macro at the beginning of a function returning a pointer
172 to handle non-local exits via `throw'. The function must have an
173 ENV parameter. The function will return NULL if a `throw' is
174 caught. */
175#define MODULE_HANDLE_THROW \
176 MODULE_SETJMP (CATCHER_ALL, module_handle_throw, NULL)
177 167
178#define MODULE_SETJMP(handlertype, handlerfunc, retval) \ 168#define MODULE_SETJMP(handlertype, handlerfunc, retval) \
179 MODULE_SETJMP_1 (handlertype, handlerfunc, retval, \ 169 MODULE_SETJMP_1 (handlertype, handlerfunc, retval, \
@@ -190,6 +180,8 @@ static void module_wrong_type (emacs_env *, Lisp_Object, Lisp_Object);
190 code after the macro may longjmp back into the macro, which means 180 code after the macro may longjmp back into the macro, which means
191 its local variable C must stay live in later code. */ 181 its local variable C must stay live in later code. */
192 182
183// TODO: Make backtraces work if this macros is used.
184
193#define MODULE_SETJMP_1(handlertype, handlerfunc, retval, c, dummy) \ 185#define MODULE_SETJMP_1(handlertype, handlerfunc, retval, c, dummy) \
194 if (module_non_local_exit_check (env) != emacs_funcall_exit_return) \ 186 if (module_non_local_exit_check (env) != emacs_funcall_exit_return) \
195 return retval; \ 187 return retval; \
@@ -247,8 +239,8 @@ struct module_fun_env
247 4. Any function that needs to call Emacs facilities, such as 239 4. Any function that needs to call Emacs facilities, such as
248 encoding or decoding functions, or 'intern', or 'make_string', 240 encoding or decoding functions, or 'intern', or 'make_string',
249 should protect itself from signals and 'throw' in the called 241 should protect itself from signals and 'throw' in the called
250 Emacs functions, by placing the macros MODULE_HANDLE_SIGNALS 242 Emacs functions, by placing the macro
251 and/or MODULE_HANDLE_THROW right after the above 2 tests. 243 MODULE_HANDLE_NONLOCAL_EXIT right after the above 2 tests.
252 244
253 5. Do NOT use 'eassert' for checking validity of user code in the 245 5. Do NOT use 'eassert' for checking validity of user code in the
254 module. Instead, make those checks part of the code, and if the 246 module. Instead, make those checks part of the code, and if the
@@ -258,6 +250,16 @@ struct module_fun_env
258 instead of reporting the error back to Lisp, and also because 250 instead of reporting the error back to Lisp, and also because
259 'eassert' is compiled to nothing in the release version. */ 251 'eassert' is compiled to nothing in the release version. */
260 252
253/* Use MODULE_FUNCTION_BEGIN to implement steps 2 through 4 for most
254 environment functions. On error it will return its argument, which
255 should be a sentinel value. */
256
257#define MODULE_FUNCTION_BEGIN(error_retval) \
258 check_main_thread (); \
259 if (module_non_local_exit_check (env) != emacs_funcall_exit_return) \
260 return error_retval; \
261 MODULE_HANDLE_NONLOCAL_EXIT (error_retval)
262
261/* Catch signals and throws only if the code can actually signal or 263/* Catch signals and throws only if the code can actually signal or
262 throw. If checking is enabled, abort if the current thread is not 264 throw. If checking is enabled, abort if the current thread is not
263 the Emacs main thread. */ 265 the Emacs main thread. */
@@ -275,10 +277,7 @@ module_get_environment (struct emacs_runtime *ert)
275static emacs_value 277static emacs_value
276module_make_global_ref (emacs_env *env, emacs_value ref) 278module_make_global_ref (emacs_env *env, emacs_value ref)
277{ 279{
278 check_main_thread (); 280 MODULE_FUNCTION_BEGIN (NULL);
279 if (module_non_local_exit_check (env) != emacs_funcall_exit_return)
280 return NULL;
281 MODULE_HANDLE_SIGNALS;
282 struct Lisp_Hash_Table *h = XHASH_TABLE (Vmodule_refs_hash); 281 struct Lisp_Hash_Table *h = XHASH_TABLE (Vmodule_refs_hash);
283 Lisp_Object new_obj = value_to_lisp (ref); 282 Lisp_Object new_obj = value_to_lisp (ref);
284 EMACS_UINT hashcode; 283 EMACS_UINT hashcode;
@@ -307,13 +306,10 @@ module_make_global_ref (emacs_env *env, emacs_value ref)
307static void 306static void
308module_free_global_ref (emacs_env *env, emacs_value ref) 307module_free_global_ref (emacs_env *env, emacs_value ref)
309{ 308{
310 check_main_thread ();
311 if (module_non_local_exit_check (env) != emacs_funcall_exit_return)
312 return;
313 /* TODO: This probably never signals. */ 309 /* TODO: This probably never signals. */
314 /* FIXME: Wait a minute. Shouldn't this function report an error if 310 /* FIXME: Wait a minute. Shouldn't this function report an error if
315 the hash lookup fails? */ 311 the hash lookup fails? */
316 MODULE_HANDLE_SIGNALS_VOID; 312 MODULE_FUNCTION_BEGIN ();
317 struct Lisp_Hash_Table *h = XHASH_TABLE (Vmodule_refs_hash); 313 struct Lisp_Hash_Table *h = XHASH_TABLE (Vmodule_refs_hash);
318 Lisp_Object obj = value_to_lisp (ref); 314 Lisp_Object obj = value_to_lisp (ref);
319 EMACS_UINT hashcode; 315 EMACS_UINT hashcode;
@@ -391,10 +387,7 @@ module_make_function (emacs_env *env, ptrdiff_t min_arity, ptrdiff_t max_arity,
391 emacs_subr subr, const char *documentation, 387 emacs_subr subr, const char *documentation,
392 void *data) 388 void *data)
393{ 389{
394 check_main_thread (); 390 MODULE_FUNCTION_BEGIN (NULL);
395 if (module_non_local_exit_check (env) != emacs_funcall_exit_return)
396 return NULL;
397 MODULE_HANDLE_SIGNALS;
398 391
399 if (! (0 <= min_arity 392 if (! (0 <= min_arity
400 && (max_arity < 0 393 && (max_arity < 0
@@ -429,11 +422,7 @@ static emacs_value
429module_funcall (emacs_env *env, emacs_value fun, ptrdiff_t nargs, 422module_funcall (emacs_env *env, emacs_value fun, ptrdiff_t nargs,
430 emacs_value args[]) 423 emacs_value args[])
431{ 424{
432 check_main_thread (); 425 MODULE_FUNCTION_BEGIN (NULL);
433 if (module_non_local_exit_check (env) != emacs_funcall_exit_return)
434 return NULL;
435 MODULE_HANDLE_SIGNALS;
436 MODULE_HANDLE_THROW;
437 426
438 /* Make a new Lisp_Object array starting with the function as the 427 /* Make a new Lisp_Object array starting with the function as the
439 first arg, because that's what Ffuncall takes. */ 428 first arg, because that's what Ffuncall takes. */
@@ -451,19 +440,14 @@ module_funcall (emacs_env *env, emacs_value fun, ptrdiff_t nargs,
451static emacs_value 440static emacs_value
452module_intern (emacs_env *env, const char *name) 441module_intern (emacs_env *env, const char *name)
453{ 442{
454 check_main_thread (); 443 MODULE_FUNCTION_BEGIN (NULL);
455 if (module_non_local_exit_check (env) != emacs_funcall_exit_return)
456 return NULL;
457 MODULE_HANDLE_SIGNALS;
458 return lisp_to_value (env, intern (name)); 444 return lisp_to_value (env, intern (name));
459} 445}
460 446
461static emacs_value 447static emacs_value
462module_type_of (emacs_env *env, emacs_value value) 448module_type_of (emacs_env *env, emacs_value value)
463{ 449{
464 check_main_thread (); 450 MODULE_FUNCTION_BEGIN (NULL);
465 if (module_non_local_exit_check (env) != emacs_funcall_exit_return)
466 return NULL;
467 return lisp_to_value (env, Ftype_of (value_to_lisp (value))); 451 return lisp_to_value (env, Ftype_of (value_to_lisp (value)));
468} 452}
469 453
@@ -488,9 +472,7 @@ module_eq (emacs_env *env, emacs_value a, emacs_value b)
488static intmax_t 472static intmax_t
489module_extract_integer (emacs_env *env, emacs_value n) 473module_extract_integer (emacs_env *env, emacs_value n)
490{ 474{
491 check_main_thread (); 475 MODULE_FUNCTION_BEGIN (0);
492 if (module_non_local_exit_check (env) != emacs_funcall_exit_return)
493 return 0;
494 Lisp_Object l = value_to_lisp (n); 476 Lisp_Object l = value_to_lisp (n);
495 if (! INTEGERP (l)) 477 if (! INTEGERP (l))
496 { 478 {
@@ -503,9 +485,7 @@ module_extract_integer (emacs_env *env, emacs_value n)
503static emacs_value 485static emacs_value
504module_make_integer (emacs_env *env, intmax_t n) 486module_make_integer (emacs_env *env, intmax_t n)
505{ 487{
506 check_main_thread (); 488 MODULE_FUNCTION_BEGIN (NULL);
507 if (module_non_local_exit_check (env) != emacs_funcall_exit_return)
508 return NULL;
509 if (! (MOST_NEGATIVE_FIXNUM <= n && n <= MOST_POSITIVE_FIXNUM)) 489 if (! (MOST_NEGATIVE_FIXNUM <= n && n <= MOST_POSITIVE_FIXNUM))
510 { 490 {
511 module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil); 491 module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil);
@@ -517,9 +497,7 @@ module_make_integer (emacs_env *env, intmax_t n)
517static double 497static double
518module_extract_float (emacs_env *env, emacs_value f) 498module_extract_float (emacs_env *env, emacs_value f)
519{ 499{
520 check_main_thread (); 500 MODULE_FUNCTION_BEGIN (0);
521 if (module_non_local_exit_check (env) != emacs_funcall_exit_return)
522 return 0;
523 Lisp_Object lisp = value_to_lisp (f); 501 Lisp_Object lisp = value_to_lisp (f);
524 if (! FLOATP (lisp)) 502 if (! FLOATP (lisp))
525 { 503 {
@@ -532,10 +510,7 @@ module_extract_float (emacs_env *env, emacs_value f)
532static emacs_value 510static emacs_value
533module_make_float (emacs_env *env, double d) 511module_make_float (emacs_env *env, double d)
534{ 512{
535 check_main_thread (); 513 MODULE_FUNCTION_BEGIN (NULL);
536 if (module_non_local_exit_check (env) != emacs_funcall_exit_return)
537 return NULL;
538 MODULE_HANDLE_SIGNALS;
539 return lisp_to_value (env, make_float (d)); 514 return lisp_to_value (env, make_float (d));
540} 515}
541 516
@@ -543,10 +518,7 @@ static bool
543module_copy_string_contents (emacs_env *env, emacs_value value, char *buffer, 518module_copy_string_contents (emacs_env *env, emacs_value value, char *buffer,
544 ptrdiff_t *length) 519 ptrdiff_t *length)
545{ 520{
546 check_main_thread (); 521 MODULE_FUNCTION_BEGIN (false);
547 if (module_non_local_exit_check (env) != emacs_funcall_exit_return)
548 return false;
549 MODULE_HANDLE_SIGNALS;
550 Lisp_Object lisp_str = value_to_lisp (value); 522 Lisp_Object lisp_str = value_to_lisp (value);
551 if (! STRINGP (lisp_str)) 523 if (! STRINGP (lisp_str))
552 { 524 {
@@ -589,10 +561,7 @@ module_copy_string_contents (emacs_env *env, emacs_value value, char *buffer,
589static emacs_value 561static emacs_value
590module_make_string (emacs_env *env, const char *str, ptrdiff_t length) 562module_make_string (emacs_env *env, const char *str, ptrdiff_t length)
591{ 563{
592 check_main_thread (); 564 MODULE_FUNCTION_BEGIN (NULL);
593 if (module_non_local_exit_check (env) != emacs_funcall_exit_return)
594 return NULL;
595 MODULE_HANDLE_SIGNALS;
596 if (length > STRING_BYTES_BOUND) 565 if (length > STRING_BYTES_BOUND)
597 { 566 {
598 module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil); 567 module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil);
@@ -606,18 +575,14 @@ module_make_string (emacs_env *env, const char *str, ptrdiff_t length)
606static emacs_value 575static emacs_value
607module_make_user_ptr (emacs_env *env, emacs_finalizer_function fin, void *ptr) 576module_make_user_ptr (emacs_env *env, emacs_finalizer_function fin, void *ptr)
608{ 577{
609 check_main_thread (); 578 MODULE_FUNCTION_BEGIN (NULL);
610 if (module_non_local_exit_check (env) != emacs_funcall_exit_return)
611 return NULL;
612 return lisp_to_value (env, make_user_ptr (fin, ptr)); 579 return lisp_to_value (env, make_user_ptr (fin, ptr));
613} 580}
614 581
615static void * 582static void *
616module_get_user_ptr (emacs_env *env, emacs_value uptr) 583module_get_user_ptr (emacs_env *env, emacs_value uptr)
617{ 584{
618 check_main_thread (); 585 MODULE_FUNCTION_BEGIN (NULL);
619 if (module_non_local_exit_check (env) != emacs_funcall_exit_return)
620 return NULL;
621 Lisp_Object lisp = value_to_lisp (uptr); 586 Lisp_Object lisp = value_to_lisp (uptr);
622 if (! USER_PTRP (lisp)) 587 if (! USER_PTRP (lisp))
623 { 588 {
@@ -630,6 +595,8 @@ module_get_user_ptr (emacs_env *env, emacs_value uptr)
630static void 595static void
631module_set_user_ptr (emacs_env *env, emacs_value uptr, void *ptr) 596module_set_user_ptr (emacs_env *env, emacs_value uptr, void *ptr)
632{ 597{
598 // FIXME: This function should return bool because it can fail.
599 MODULE_FUNCTION_BEGIN ();
633 check_main_thread (); 600 check_main_thread ();
634 if (module_non_local_exit_check (env) != emacs_funcall_exit_return) 601 if (module_non_local_exit_check (env) != emacs_funcall_exit_return)
635 return; 602 return;
@@ -642,9 +609,7 @@ module_set_user_ptr (emacs_env *env, emacs_value uptr, void *ptr)
642static emacs_finalizer_function 609static emacs_finalizer_function
643module_get_user_finalizer (emacs_env *env, emacs_value uptr) 610module_get_user_finalizer (emacs_env *env, emacs_value uptr)
644{ 611{
645 check_main_thread (); 612 MODULE_FUNCTION_BEGIN (NULL);
646 if (module_non_local_exit_check (env) != emacs_funcall_exit_return)
647 return NULL;
648 Lisp_Object lisp = value_to_lisp (uptr); 613 Lisp_Object lisp = value_to_lisp (uptr);
649 if (! USER_PTRP (lisp)) 614 if (! USER_PTRP (lisp))
650 { 615 {
@@ -658,9 +623,8 @@ static void
658module_set_user_finalizer (emacs_env *env, emacs_value uptr, 623module_set_user_finalizer (emacs_env *env, emacs_value uptr,
659 emacs_finalizer_function fin) 624 emacs_finalizer_function fin)
660{ 625{
661 check_main_thread (); 626 // FIXME: This function should return bool because it can fail.
662 if (module_non_local_exit_check (env) != emacs_funcall_exit_return) 627 MODULE_FUNCTION_BEGIN ();
663 return;
664 Lisp_Object lisp = value_to_lisp (uptr); 628 Lisp_Object lisp = value_to_lisp (uptr);
665 if (! USER_PTRP (lisp)) 629 if (! USER_PTRP (lisp))
666 module_wrong_type (env, Quser_ptr, lisp); 630 module_wrong_type (env, Quser_ptr, lisp);
@@ -670,9 +634,8 @@ module_set_user_finalizer (emacs_env *env, emacs_value uptr,
670static void 634static void
671module_vec_set (emacs_env *env, emacs_value vec, ptrdiff_t i, emacs_value val) 635module_vec_set (emacs_env *env, emacs_value vec, ptrdiff_t i, emacs_value val)
672{ 636{
673 check_main_thread (); 637 // FIXME: This function should return bool because it can fail.
674 if (module_non_local_exit_check (env) != emacs_funcall_exit_return) 638 MODULE_FUNCTION_BEGIN ();
675 return;
676 Lisp_Object lvec = value_to_lisp (vec); 639 Lisp_Object lvec = value_to_lisp (vec);
677 if (! VECTORP (lvec)) 640 if (! VECTORP (lvec))
678 { 641 {
@@ -693,9 +656,7 @@ module_vec_set (emacs_env *env, emacs_value vec, ptrdiff_t i, emacs_value val)
693static emacs_value 656static emacs_value
694module_vec_get (emacs_env *env, emacs_value vec, ptrdiff_t i) 657module_vec_get (emacs_env *env, emacs_value vec, ptrdiff_t i)
695{ 658{
696 check_main_thread (); 659 MODULE_FUNCTION_BEGIN (NULL);
697 if (module_non_local_exit_check (env) != emacs_funcall_exit_return)
698 return NULL;
699 Lisp_Object lvec = value_to_lisp (vec); 660 Lisp_Object lvec = value_to_lisp (vec);
700 if (! VECTORP (lvec)) 661 if (! VECTORP (lvec))
701 { 662 {
@@ -716,9 +677,8 @@ module_vec_get (emacs_env *env, emacs_value vec, ptrdiff_t i)
716static ptrdiff_t 677static ptrdiff_t
717module_vec_size (emacs_env *env, emacs_value vec) 678module_vec_size (emacs_env *env, emacs_value vec)
718{ 679{
719 check_main_thread (); 680 // FIXME: Return a sentinel value (e.g., -1) on error.
720 if (module_non_local_exit_check (env) != emacs_funcall_exit_return) 681 MODULE_FUNCTION_BEGIN (0);
721 return 0;
722 Lisp_Object lvec = value_to_lisp (vec); 682 Lisp_Object lvec = value_to_lisp (vec);
723 if (! VECTORP (lvec)) 683 if (! VECTORP (lvec))
724 { 684 {