aboutsummaryrefslogtreecommitdiffstats
path: root/test/src
diff options
context:
space:
mode:
authorPhilipp Stephani2017-06-05 13:29:14 +0200
committerPhilipp Stephani2017-06-12 15:22:27 +0200
commitcf97132764572928adc77fd555d04a9f41cd3cfc (patch)
tree65f707de87b811caec7b08f96938059859cf001c /test/src
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 'test/src')
-rw-r--r--test/src/emacs-module-tests.el40
1 files changed, 37 insertions, 3 deletions
diff --git a/test/src/emacs-module-tests.el b/test/src/emacs-module-tests.el
index 622bbadb3ef..99a853b17e0 100644
--- a/test/src/emacs-module-tests.el
+++ b/test/src/emacs-module-tests.el
@@ -19,9 +19,17 @@
19 19
20(require 'ert) 20(require 'ert)
21 21
22(require 'mod-test 22(defconst mod-test-emacs
23 (expand-file-name "data/emacs-module/mod-test" 23 (expand-file-name invocation-name invocation-directory)
24 (getenv "EMACS_TEST_DIRECTORY"))) 24 "File name of the Emacs binary currently running.")
25
26(eval-and-compile
27 (defconst mod-test-file
28 (substitute-in-file-name
29 "$EMACS_TEST_DIRECTORY/data/emacs-module/mod-test")
30 "File name of the module test file."))
31
32(require 'mod-test mod-test-file)
25 33
26;; 34;;
27;; Basic tests. 35;; Basic tests.
@@ -174,4 +182,30 @@ changes."
174 (should (equal (help-function-arglist #'mod-test-sum) 182 (should (equal (help-function-arglist #'mod-test-sum)
175 '(arg1 arg2)))) 183 '(arg1 arg2))))
176 184
185(ert-deftest module--test-assertions ()
186 "Check that -module-assertions work."
187 (skip-unless (file-executable-p mod-test-emacs))
188 ;; This doesn’t yet cause undefined behavior.
189 (should (eq (mod-test-invalid-store) 123))
190 (with-temp-buffer
191 (should (equal (call-process mod-test-emacs nil t nil
192 "-batch" "-Q" "-module-assertions" "-eval"
193 (prin1-to-string
194 `(progn
195 (require 'mod-test ,mod-test-file)
196 ;; Storing and reloading a local
197 ;; value causes undefined
198 ;; behavior, which should be
199 ;; detected by the module
200 ;; assertions.
201 (mod-test-invalid-store)
202 (mod-test-invalid-load))))
203 ;; FIXME: This string is probably different on
204 ;; Windows and Linux.
205 "Abort trap: 6"))
206 (re-search-backward (rx bos "Emacs module assertion: "
207 "Emacs value not found in "
208 (+ digit) " values of "
209 (+ digit) " environments" ?\n eos))))
210
177;;; emacs-module-tests.el ends here 211;;; emacs-module-tests.el ends here