aboutsummaryrefslogtreecommitdiffstats
path: root/src/emacs.c
diff options
context:
space:
mode:
authorPhilipp Stephani2017-06-05 13:29:14 +0200
committerPhilipp Stephani2017-06-12 15:22:27 +0200
commitcf97132764572928adc77fd555d04a9f41cd3cfc (patch)
tree65f707de87b811caec7b08f96938059859cf001c /src/emacs.c
parentb49dd3b047bf07994d9577e08daba55f143a8bb1 (diff)
downloademacs-cf97132764572928adc77fd555d04a9f41cd3cfc.tar.gz
emacs-cf97132764572928adc77fd555d04a9f41cd3cfc.zip
Implement module assertions for users
Add a new command-line option '-module-assertions' that users can enable developing or debugging a module. If this option is present, Emacs performs additional checks to verify that modules fulfill their requirements. These checks are expensive and crash Emacs if modules are invalid, so disable them by default. This is a command-line option instead of an ordinary variable because changing it while Emacs is running would cause data structure imbalances. * src/emacs.c (main): New command line option '-module-assertions'. * src/emacs-module.c (module_assert_main_thread) (module_assert_runtime, module_assert_env, module_assert_value): New functions to assert module requirements. (syms_of_module): New uninterned variable 'module-runtimes'. (init_module_assertions, in_main_thread, module_abort): New helper functions. (initialize_environment): Initialize value list. If assertions are enabled, use a heap-allocated environment object. (finalize_environment): Add assertion that environment list is never empty. (finalize_runtime_unwind): Pop module runtime object stack. (value_to_lisp): Assert that the value is valid. (lisp_to_value): Record new value if assertions are enabled. (mark_modules): Mark allocated object list. (MODULE_FUNCTION_BEGIN_NO_CATCH) (module_non_local_exit_check, module_non_local_exit_clear) (module_non_local_exit_get, module_non_local_exit_signal) (module_non_local_exit_throw): Assert thread and environment. (module_get_environment): Assert thread and runtime. (module_make_function, module_funcall, module_intern) (module_funcall, module_make_integer, module_make_float) (module_make_string, module_make_user_ptr, module_vec_get) (funcall_module, Fmodule_load): Adapt callers. (module_make_global_ref): If assertions are enabled, use the global environment to store global values. (module_free_global_ref): Remove value from global value list. * test/Makefile.in (EMACSOPT): Enable module assertions when testing modules. * test/data/emacs-module/mod-test.c (Fmod_test_invalid_store) (Fmod_test_invalid_load): New functions to test module assertions. (emacs_module_init): Bind the new functions. * test/src/emacs-module-tests.el (mod-test-emacs): New constant for the Emacs binary file. (mod-test-file): New constant for the test module file name. (module--test-assertions): New unit test.
Diffstat (limited to 'src/emacs.c')
-rw-r--r--src/emacs.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/src/emacs.c b/src/emacs.c
index 49ebb817678..b0892c7ebb8 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -223,6 +223,7 @@ Initialization options:\n\
223--fg-daemon[=NAME] start a (named) server in the foreground\n\ 223--fg-daemon[=NAME] start a (named) server in the foreground\n\
224--debug-init enable Emacs Lisp debugger for init file\n\ 224--debug-init enable Emacs Lisp debugger for init file\n\
225--display, -d DISPLAY use X server DISPLAY\n\ 225--display, -d DISPLAY use X server DISPLAY\n\
226--module-assertions assert behavior of dynamic modules\n\
226", 227",
227 "\ 228 "\
228--no-build-details do not add build details such as time stamps\n\ 229--no-build-details do not add build details such as time stamps\n\
@@ -1263,6 +1264,18 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1263 build_details = ! argmatch (argv, argc, "-no-build-details", 1264 build_details = ! argmatch (argv, argc, "-no-build-details",
1264 "--no-build-details", 7, NULL, &skip_args); 1265 "--no-build-details", 7, NULL, &skip_args);
1265 1266
1267#ifdef HAVE_MODULES
1268 bool module_assertions
1269 = argmatch (argv, argc, "-module-assertions", "--module-assertions", 15,
1270 NULL, &skip_args);
1271 if (dumping && module_assertions)
1272 {
1273 fputs ("Module assertions are not supported during dumping\n", stderr);
1274 exit (1);
1275 }
1276 init_module_assertions (module_assertions);
1277#endif
1278
1266#ifdef HAVE_NS 1279#ifdef HAVE_NS
1267 ns_pool = ns_alloc_autorelease_pool (); 1280 ns_pool = ns_alloc_autorelease_pool ();
1268#ifdef NS_IMPL_GNUSTEP 1281#ifdef NS_IMPL_GNUSTEP
@@ -1720,6 +1733,7 @@ static const struct standard_args standard_args[] =
1720 { "-nl", "--no-loadup", 70, 0 }, 1733 { "-nl", "--no-loadup", 70, 0 },
1721 { "-nsl", "--no-site-lisp", 65, 0 }, 1734 { "-nsl", "--no-site-lisp", 65, 0 },
1722 { "-no-build-details", "--no-build-details", 63, 0 }, 1735 { "-no-build-details", "--no-build-details", 63, 0 },
1736 { "-module-assertions", "--module-assertions", 62, 0 },
1723 /* -d must come last before the options handled in startup.el. */ 1737 /* -d must come last before the options handled in startup.el. */
1724 { "-d", "--display", 60, 1 }, 1738 { "-d", "--display", 60, 1 },
1725 { "-display", 0, 60, 1 }, 1739 { "-display", 0, 60, 1 },