aboutsummaryrefslogtreecommitdiffstats
path: root/test/data
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/data
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/data')
-rw-r--r--test/data/emacs-module/mod-test.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/test/data/emacs-module/mod-test.c b/test/data/emacs-module/mod-test.c
index 309179d1501..fc29a0d6b9a 100644
--- a/test/data/emacs-module/mod-test.c
+++ b/test/data/emacs-module/mod-test.c
@@ -213,6 +213,28 @@ Fmod_test_vector_eq (emacs_env *env, ptrdiff_t nargs, emacs_value args[],
213 return env->intern (env, "t"); 213 return env->intern (env, "t");
214} 214}
215 215
216static emacs_value invalid_stored_value;
217
218/* The next two functions perform a possibly-invalid operation: they
219 store a value in a static variable and load it. This causes
220 undefined behavior if the environment that the value was created
221 from is no longer live. The module assertions check for this
222 error. */
223
224static emacs_value
225Fmod_test_invalid_store (emacs_env *env, ptrdiff_t nargs, emacs_value *args,
226 void *data)
227{
228 return invalid_stored_value = env->make_integer (env, 123);
229}
230
231static emacs_value
232Fmod_test_invalid_load (emacs_env *env, ptrdiff_t nargs, emacs_value *args,
233 void *data)
234{
235 return invalid_stored_value;
236}
237
216 238
217/* Lisp utilities for easier readability (simple wrappers). */ 239/* Lisp utilities for easier readability (simple wrappers). */
218 240
@@ -260,6 +282,8 @@ emacs_module_init (struct emacs_runtime *ert)
260 DEFUN ("mod-test-userptr-get", Fmod_test_userptr_get, 1, 1, NULL, NULL); 282 DEFUN ("mod-test-userptr-get", Fmod_test_userptr_get, 1, 1, NULL, NULL);
261 DEFUN ("mod-test-vector-fill", Fmod_test_vector_fill, 2, 2, NULL, NULL); 283 DEFUN ("mod-test-vector-fill", Fmod_test_vector_fill, 2, 2, NULL, NULL);
262 DEFUN ("mod-test-vector-eq", Fmod_test_vector_eq, 2, 2, NULL, NULL); 284 DEFUN ("mod-test-vector-eq", Fmod_test_vector_eq, 2, 2, NULL, NULL);
285 DEFUN ("mod-test-invalid-store", Fmod_test_invalid_store, 0, 0, NULL, NULL);
286 DEFUN ("mod-test-invalid-load", Fmod_test_invalid_load, 0, 0, NULL, NULL);
263 287
264#undef DEFUN 288#undef DEFUN
265 289