diff options
| author | Philipp Stephani | 2020-01-05 16:05:14 +0100 |
|---|---|---|
| committer | Philipp Stephani | 2020-01-05 16:07:28 +0100 |
| commit | fc92c2d8942cf466aa6dbc422f2e798801b18408 (patch) | |
| tree | ddf5bc386ba474733db39de3d23f76c8563ebd4b | |
| parent | 9d38564cdde8cbe9d4c08a7ffef7f25e9692814a (diff) | |
| download | emacs-fc92c2d8942cf466aa6dbc422f2e798801b18408.tar.gz emacs-fc92c2d8942cf466aa6dbc422f2e798801b18408.zip | |
Also print function data when printing module functions.
This is especially useful in cases where modules only use a single
entry point and use the data to dispatch to the actual function. Such
a design is common for languages such as Go and C++.
* src/emacs-module.c (module_function_data): New function.
* src/print.c (print_vectorlike): Use it to print module function data
if not NULL.
(print_object): Adapt size of buffer.
* test/data/emacs-module/mod-test.c (emacs_module_init): Pass some
non-NULL data to ‘mod-test-sum’.
(Fmod_test_sum): Check that correct data is passed through.
* test/src/emacs-module-tests.el (mod-test-sum-test)
(module-function-object): Adapt unit tests.
| -rw-r--r-- | src/emacs-module.c | 6 | ||||
| -rw-r--r-- | src/lisp.h | 1 | ||||
| -rw-r--r-- | src/print.c | 18 | ||||
| -rw-r--r-- | test/data/emacs-module/mod-test.c | 5 | ||||
| -rw-r--r-- | test/src/emacs-module-tests.el | 6 |
5 files changed, 31 insertions, 5 deletions
diff --git a/src/emacs-module.c b/src/emacs-module.c index 3855a33f254..f40ca931fa9 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c | |||
| @@ -1098,6 +1098,12 @@ module_function_address (const struct Lisp_Module_Function *function) | |||
| 1098 | return (module_funcptr) function->subr; | 1098 | return (module_funcptr) function->subr; |
| 1099 | } | 1099 | } |
| 1100 | 1100 | ||
| 1101 | void * | ||
| 1102 | module_function_data (const struct Lisp_Module_Function *function) | ||
| 1103 | { | ||
| 1104 | return function->data; | ||
| 1105 | } | ||
| 1106 | |||
| 1101 | 1107 | ||
| 1102 | /* Helper functions. */ | 1108 | /* Helper functions. */ |
| 1103 | 1109 | ||
diff --git a/src/lisp.h b/src/lisp.h index 9be7bfec5c0..e1bbb53ad49 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -4245,6 +4245,7 @@ extern Lisp_Object module_function_documentation | |||
| 4245 | (struct Lisp_Module_Function const *); | 4245 | (struct Lisp_Module_Function const *); |
| 4246 | extern module_funcptr module_function_address | 4246 | extern module_funcptr module_function_address |
| 4247 | (struct Lisp_Module_Function const *); | 4247 | (struct Lisp_Module_Function const *); |
| 4248 | extern void *module_function_data (const struct Lisp_Module_Function *); | ||
| 4248 | extern void module_finalize_function (const struct Lisp_Module_Function *); | 4249 | extern void module_finalize_function (const struct Lisp_Module_Function *); |
| 4249 | extern void mark_modules (void); | 4250 | extern void mark_modules (void); |
| 4250 | extern void init_module_assertions (bool); | 4251 | extern void init_module_assertions (bool); |
diff --git a/src/print.c b/src/print.c index 425b0dc4ee3..b373aaf6551 100644 --- a/src/print.c +++ b/src/print.c | |||
| @@ -1796,7 +1796,8 @@ print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag, | |||
| 1796 | case PVEC_MODULE_FUNCTION: | 1796 | case PVEC_MODULE_FUNCTION: |
| 1797 | { | 1797 | { |
| 1798 | print_c_string ("#<module function ", printcharfun); | 1798 | print_c_string ("#<module function ", printcharfun); |
| 1799 | module_funcptr ptr = module_function_address (XMODULE_FUNCTION (obj)); | 1799 | const struct Lisp_Module_Function *function = XMODULE_FUNCTION (obj); |
| 1800 | module_funcptr ptr = module_function_address (function); | ||
| 1800 | char const *file; | 1801 | char const *file; |
| 1801 | char const *symbol; | 1802 | char const *symbol; |
| 1802 | dynlib_addr (ptr, &file, &symbol); | 1803 | dynlib_addr (ptr, &file, &symbol); |
| @@ -1815,6 +1816,19 @@ print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag, | |||
| 1815 | else | 1816 | else |
| 1816 | print_c_string (symbol, printcharfun); | 1817 | print_c_string (symbol, printcharfun); |
| 1817 | 1818 | ||
| 1819 | void *data = module_function_data (function); | ||
| 1820 | if (data != NULL) | ||
| 1821 | { | ||
| 1822 | uintptr_t ui = (uintptr_t) data; | ||
| 1823 | |||
| 1824 | /* In theory this assignment could lose info on pre-C99 | ||
| 1825 | hosts, but in practice it doesn't. */ | ||
| 1826 | uintmax_t up = ui; | ||
| 1827 | |||
| 1828 | int len = sprintf (buf, " with data 0x%"PRIxMAX, up); | ||
| 1829 | strout (buf, len, len, printcharfun); | ||
| 1830 | } | ||
| 1831 | |||
| 1818 | if (file != NULL) | 1832 | if (file != NULL) |
| 1819 | { | 1833 | { |
| 1820 | print_c_string (" from ", printcharfun); | 1834 | print_c_string (" from ", printcharfun); |
| @@ -1838,7 +1852,7 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) | |||
| 1838 | { | 1852 | { |
| 1839 | char buf[max (sizeof "from..to..in " + 2 * INT_STRLEN_BOUND (EMACS_INT), | 1853 | char buf[max (sizeof "from..to..in " + 2 * INT_STRLEN_BOUND (EMACS_INT), |
| 1840 | max (sizeof " . #" + INT_STRLEN_BOUND (intmax_t), | 1854 | max (sizeof " . #" + INT_STRLEN_BOUND (intmax_t), |
| 1841 | max ((sizeof "at 0x" | 1855 | max ((sizeof " with data 0x" |
| 1842 | + (sizeof (uintmax_t) * CHAR_BIT + 4 - 1) / 4), | 1856 | + (sizeof (uintmax_t) * CHAR_BIT + 4 - 1) / 4), |
| 1843 | 40)))]; | 1857 | 40)))]; |
| 1844 | current_thread->stack_top = buf; | 1858 | current_thread->stack_top = buf; |
diff --git a/test/data/emacs-module/mod-test.c b/test/data/emacs-module/mod-test.c index 1a0a879a1bc..ec6948921f2 100644 --- a/test/data/emacs-module/mod-test.c +++ b/test/data/emacs-module/mod-test.c | |||
| @@ -24,6 +24,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 24 | 24 | ||
| 25 | #include <errno.h> | 25 | #include <errno.h> |
| 26 | #include <limits.h> | 26 | #include <limits.h> |
| 27 | #include <stdint.h> | ||
| 27 | #include <stdio.h> | 28 | #include <stdio.h> |
| 28 | #include <stdlib.h> | 29 | #include <stdlib.h> |
| 29 | #include <string.h> | 30 | #include <string.h> |
| @@ -86,6 +87,7 @@ static emacs_value | |||
| 86 | Fmod_test_sum (emacs_env *env, ptrdiff_t nargs, emacs_value args[], void *data) | 87 | Fmod_test_sum (emacs_env *env, ptrdiff_t nargs, emacs_value args[], void *data) |
| 87 | { | 88 | { |
| 88 | assert (nargs == 2); | 89 | assert (nargs == 2); |
| 90 | assert ((uintptr_t) data == 0x1234); | ||
| 89 | 91 | ||
| 90 | intmax_t a = env->extract_integer (env, args[0]); | 92 | intmax_t a = env->extract_integer (env, args[0]); |
| 91 | intmax_t b = env->extract_integer (env, args[1]); | 93 | intmax_t b = env->extract_integer (env, args[1]); |
| @@ -587,7 +589,8 @@ emacs_module_init (struct emacs_runtime *ert) | |||
| 587 | env->make_function (env, amin, amax, csym, doc, data)) | 589 | env->make_function (env, amin, amax, csym, doc, data)) |
| 588 | 590 | ||
| 589 | DEFUN ("mod-test-return-t", Fmod_test_return_t, 1, 1, NULL, NULL); | 591 | DEFUN ("mod-test-return-t", Fmod_test_return_t, 1, 1, NULL, NULL); |
| 590 | DEFUN ("mod-test-sum", Fmod_test_sum, 2, 2, "Return A + B\n\n(fn a b)", NULL); | 592 | DEFUN ("mod-test-sum", Fmod_test_sum, 2, 2, "Return A + B\n\n(fn a b)", |
| 593 | (void *) (uintptr_t) 0x1234); | ||
| 591 | DEFUN ("mod-test-signal", Fmod_test_signal, 0, 0, NULL, NULL); | 594 | DEFUN ("mod-test-signal", Fmod_test_signal, 0, 0, NULL, NULL); |
| 592 | DEFUN ("mod-test-throw", Fmod_test_throw, 0, 0, NULL, NULL); | 595 | DEFUN ("mod-test-throw", Fmod_test_throw, 0, 0, NULL, NULL); |
| 593 | DEFUN ("mod-test-non-local-exit-funcall", Fmod_test_non_local_exit_funcall, | 596 | DEFUN ("mod-test-non-local-exit-funcall", Fmod_test_non_local_exit_funcall, |
diff --git a/test/src/emacs-module-tests.el b/test/src/emacs-module-tests.el index c61abfdf683..48d2e86a605 100644 --- a/test/src/emacs-module-tests.el +++ b/test/src/emacs-module-tests.el | |||
| @@ -60,8 +60,9 @@ | |||
| 60 | (should (eq 0 | 60 | (should (eq 0 |
| 61 | (string-match | 61 | (string-match |
| 62 | (concat "#<module function " | 62 | (concat "#<module function " |
| 63 | "\\(at \\(0x\\)?[[:xdigit:]]+\\( from .*\\)?" | 63 | "\\(at \\(0x\\)?[[:xdigit:]]+ " |
| 64 | "\\|Fmod_test_sum from .*\\)>") | 64 | "with data 0x1234\\( from .*\\)?" |
| 65 | "\\|Fmod_test_sum with data 0x1234 from .*\\)>") | ||
| 65 | (prin1-to-string (nth 1 descr))))) | 66 | (prin1-to-string (nth 1 descr))))) |
| 66 | (should (= (nth 2 descr) 3))) | 67 | (should (= (nth 2 descr) 3))) |
| 67 | (should-error (mod-test-sum "1" 2) :type 'wrong-type-argument) | 68 | (should-error (mod-test-sum "1" 2) :type 'wrong-type-argument) |
| @@ -97,6 +98,7 @@ changes." | |||
| 97 | (rx bos "#<module function " | 98 | (rx bos "#<module function " |
| 98 | (or "Fmod_test_sum" | 99 | (or "Fmod_test_sum" |
| 99 | (and "at 0x" (+ hex-digit))) | 100 | (and "at 0x" (+ hex-digit))) |
| 101 | " with data 0x1234" | ||
| 100 | (? " from " (* nonl) "mod-test" (* nonl) ) | 102 | (? " from " (* nonl) "mod-test" (* nonl) ) |
| 101 | ">" eos) | 103 | ">" eos) |
| 102 | (prin1-to-string func))))) | 104 | (prin1-to-string func))))) |