diff options
| author | Philipp Stephani | 2017-06-11 14:50:20 +0200 |
|---|---|---|
| committer | Philipp Stephani | 2017-06-11 14:54:05 +0200 |
| commit | 9a86966edb5ce760976bd7ce36c92e3b4eb0705d (patch) | |
| tree | 8c29344501f197643f28127143adec165d8805b7 /src | |
| parent | cf557fa9c53bb8795ddc744319e067515a9dba67 (diff) | |
| download | emacs-9a86966edb5ce760976bd7ce36c92e3b4eb0705d.tar.gz emacs-9a86966edb5ce760976bd7ce36c92e3b4eb0705d.zip | |
Allow non-local exits in module initializers
Previously signals, throws, and quits from module initialization
functions were ignored. These function aren't special, and better
errors can be reported using signals than with the initialization
return code, so allow non-local exits.
* src/emacs-module.c (module_signal_or_throw): New helper function.
(Fmodule_load, funcall_module): Use it.
(Fmodule_load): Also allow quitting.
Diffstat (limited to 'src')
| -rw-r--r-- | src/emacs-module.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/src/emacs-module.c b/src/emacs-module.c index 1a8c1768230..c0f2c3fcd0f 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c | |||
| @@ -606,6 +606,22 @@ module_should_quit (emacs_env *env) | |||
| 606 | 606 | ||
| 607 | /* Subroutines. */ | 607 | /* Subroutines. */ |
| 608 | 608 | ||
| 609 | static void | ||
| 610 | module_signal_or_throw (struct emacs_env_private *env) | ||
| 611 | { | ||
| 612 | switch (env->pending_non_local_exit) | ||
| 613 | { | ||
| 614 | case emacs_funcall_exit_return: | ||
| 615 | return; | ||
| 616 | case emacs_funcall_exit_signal: | ||
| 617 | xsignal (env->non_local_exit_symbol, env->non_local_exit_data); | ||
| 618 | case emacs_funcall_exit_throw: | ||
| 619 | Fthrow (env->non_local_exit_symbol, env->non_local_exit_data); | ||
| 620 | default: | ||
| 621 | eassume (false); | ||
| 622 | } | ||
| 623 | } | ||
| 624 | |||
| 609 | DEFUN ("module-load", Fmodule_load, Smodule_load, 1, 1, 0, | 625 | DEFUN ("module-load", Fmodule_load, Smodule_load, 1, 1, 0, |
| 610 | doc: /* Load module FILE. */) | 626 | doc: /* Load module FILE. */) |
| 611 | (Lisp_Object file) | 627 | (Lisp_Object file) |
| @@ -641,6 +657,10 @@ DEFUN ("module-load", Fmodule_load, Smodule_load, 1, 1, 0, | |||
| 641 | 657 | ||
| 642 | int r = module_init (&pub); | 658 | int r = module_init (&pub); |
| 643 | 659 | ||
| 660 | /* Process the quit flag first, so that quitting doesn't get | ||
| 661 | overridden by other non-local exits. */ | ||
| 662 | maybe_quit (); | ||
| 663 | |||
| 644 | if (r != 0) | 664 | if (r != 0) |
| 645 | { | 665 | { |
| 646 | if (FIXNUM_OVERFLOW_P (r)) | 666 | if (FIXNUM_OVERFLOW_P (r)) |
| @@ -648,6 +668,7 @@ DEFUN ("module-load", Fmodule_load, Smodule_load, 1, 1, 0, | |||
| 648 | xsignal2 (Qmodule_init_failed, file, make_number (r)); | 668 | xsignal2 (Qmodule_init_failed, file, make_number (r)); |
| 649 | } | 669 | } |
| 650 | 670 | ||
| 671 | module_signal_or_throw (&priv); | ||
| 651 | return unbind_to (count, Qt); | 672 | return unbind_to (count, Qt); |
| 652 | } | 673 | } |
| 653 | 674 | ||
| @@ -686,17 +707,8 @@ funcall_module (Lisp_Object function, ptrdiff_t nargs, Lisp_Object *arglist) | |||
| 686 | overridden by other non-local exits. */ | 707 | overridden by other non-local exits. */ |
| 687 | maybe_quit (); | 708 | maybe_quit (); |
| 688 | 709 | ||
| 689 | switch (priv.pending_non_local_exit) | 710 | module_signal_or_throw (&priv); |
| 690 | { | 711 | return unbind_to (count, value_to_lisp (ret)); |
| 691 | case emacs_funcall_exit_return: | ||
| 692 | return unbind_to (count, value_to_lisp (ret)); | ||
| 693 | case emacs_funcall_exit_signal: | ||
| 694 | xsignal (priv.non_local_exit_symbol, priv.non_local_exit_data); | ||
| 695 | case emacs_funcall_exit_throw: | ||
| 696 | Fthrow (priv.non_local_exit_symbol, priv.non_local_exit_data); | ||
| 697 | default: | ||
| 698 | eassume (false); | ||
| 699 | } | ||
| 700 | } | 712 | } |
| 701 | 713 | ||
| 702 | Lisp_Object | 714 | Lisp_Object |