aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Stephani2020-01-05 16:05:14 +0100
committerPhilipp Stephani2020-01-05 16:07:28 +0100
commitfc92c2d8942cf466aa6dbc422f2e798801b18408 (patch)
treeddf5bc386ba474733db39de3d23f76c8563ebd4b
parent9d38564cdde8cbe9d4c08a7ffef7f25e9692814a (diff)
downloademacs-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.c6
-rw-r--r--src/lisp.h1
-rw-r--r--src/print.c18
-rw-r--r--test/data/emacs-module/mod-test.c5
-rw-r--r--test/src/emacs-module-tests.el6
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
1101void *
1102module_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 *);
4246extern module_funcptr module_function_address 4246extern module_funcptr module_function_address
4247 (struct Lisp_Module_Function const *); 4247 (struct Lisp_Module_Function const *);
4248extern void *module_function_data (const struct Lisp_Module_Function *);
4248extern void module_finalize_function (const struct Lisp_Module_Function *); 4249extern void module_finalize_function (const struct Lisp_Module_Function *);
4249extern void mark_modules (void); 4250extern void mark_modules (void);
4250extern void init_module_assertions (bool); 4251extern 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
86Fmod_test_sum (emacs_env *env, ptrdiff_t nargs, emacs_value args[], void *data) 87Fmod_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)))))