diff options
| author | Paul Eggert | 2019-05-05 17:35:05 -0700 |
|---|---|---|
| committer | Paul Eggert | 2019-05-05 17:40:55 -0700 |
| commit | 926a394997eaae55b797a90cb2cd037bbe3c3db4 (patch) | |
| tree | a075ef40927dc732c254f2d63a98af8ca3d99c82 /src/print.c | |
| parent | 31c60dfbd8541c9f1b1bc8127dde85e5d5af51b5 (diff) | |
| download | emacs-926a394997eaae55b797a90cb2cd037bbe3c3db4.tar.gz emacs-926a394997eaae55b797a90cb2cd037bbe3c3db4.zip | |
Use simpler way to print function pointers
The module code can’t possibly work on weird platforms where
function pointers are wider than data pointers, so there’s no need
to bother with the stackoverflow-like approach that is intended
only for portability to such platforms. Besides, the
stackoverflow-like approach does not work well on weird platforms
where CHAR_BIT is not a multiple of 4.
* src/lisp.h (pMx): New macro.
* src/print.c (data_from_funcptr) [HAVE_MODULES]: New function.
(print_vectorlike) [HAVE_MODULES]: Use it.
(print_object): Make sure buf is big enough for this.
Diffstat (limited to 'src/print.c')
| -rw-r--r-- | src/print.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/src/print.c b/src/print.c index 08c39d34664..406abbf4a3f 100644 --- a/src/print.c +++ b/src/print.c | |||
| @@ -1361,6 +1361,19 @@ print_prune_string_charset (Lisp_Object string) | |||
| 1361 | return string; | 1361 | return string; |
| 1362 | } | 1362 | } |
| 1363 | 1363 | ||
| 1364 | #ifdef HAVE_MODULES | ||
| 1365 | /* Return a data pointer equal to FUNCPTR. */ | ||
| 1366 | |||
| 1367 | static void const * | ||
| 1368 | data_from_funcptr (void (*funcptr) (void)) | ||
| 1369 | { | ||
| 1370 | /* The module code, and the POSIX API for dynamic linking, already | ||
| 1371 | assume that function and data pointers are represented | ||
| 1372 | interchangeably, so it's OK to assume that here too. */ | ||
| 1373 | return (void const *) funcptr; | ||
| 1374 | } | ||
| 1375 | #endif | ||
| 1376 | |||
| 1364 | static bool | 1377 | static bool |
| 1365 | print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag, | 1378 | print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag, |
| 1366 | char *buf) | 1379 | char *buf) |
| @@ -1788,30 +1801,20 @@ print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag, | |||
| 1788 | { | 1801 | { |
| 1789 | print_c_string ("#<module function ", printcharfun); | 1802 | print_c_string ("#<module function ", printcharfun); |
| 1790 | module_funcptr ptr = module_function_address (XMODULE_FUNCTION (obj)); | 1803 | module_funcptr ptr = module_function_address (XMODULE_FUNCTION (obj)); |
| 1791 | const char *file = NULL; | 1804 | char const *file; |
| 1792 | const char *symbol = NULL; | 1805 | char const *symbol; |
| 1793 | dynlib_addr (ptr, &file, &symbol); | 1806 | dynlib_addr (ptr, &file, &symbol); |
| 1794 | 1807 | ||
| 1795 | if (symbol == NULL) | 1808 | if (symbol == NULL) |
| 1796 | { | 1809 | { |
| 1797 | print_c_string ("at 0x", printcharfun); | 1810 | uintptr_t ui = (uintptr_t) data_from_funcptr (ptr); |
| 1798 | /* See https://stackoverflow.com/a/2741896 for how to | 1811 | |
| 1799 | portably print a function pointer. */ | 1812 | /* In theory this assignment could lose info on pre-C99 |
| 1800 | const unsigned char *p = (const unsigned char *) &ptr; | 1813 | hosts, but in practice it doesn't. */ |
| 1801 | for (size_t i = 0; i < sizeof ptr; ++i) | 1814 | uprintmax_t up = ui; |
| 1802 | { | 1815 | |
| 1803 | #ifdef WORDS_BIGENDIAN | 1816 | int len = sprintf (buf, "at 0x%"pMx, up); |
| 1804 | unsigned char b = p[i]; | 1817 | strout (buf, len, len, printcharfun); |
| 1805 | #else | ||
| 1806 | unsigned char b = p[sizeof ptr - i - 1]; | ||
| 1807 | #endif | ||
| 1808 | enum { digits = (CHAR_BIT + 4 - 1) / 4 }; | ||
| 1809 | char buffer[digits + 1]; | ||
| 1810 | int needed | ||
| 1811 | = snprintf (buffer, sizeof buffer, "%0*x", digits, b); | ||
| 1812 | eassert (needed == digits); | ||
| 1813 | print_c_string (buffer, printcharfun); | ||
| 1814 | } | ||
| 1815 | } | 1818 | } |
| 1816 | else | 1819 | else |
| 1817 | print_c_string (symbol, printcharfun); | 1820 | print_c_string (symbol, printcharfun); |
| @@ -1839,7 +1842,9 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) | |||
| 1839 | { | 1842 | { |
| 1840 | char buf[max (sizeof "from..to..in " + 2 * INT_STRLEN_BOUND (EMACS_INT), | 1843 | char buf[max (sizeof "from..to..in " + 2 * INT_STRLEN_BOUND (EMACS_INT), |
| 1841 | max (sizeof " . #" + INT_STRLEN_BOUND (printmax_t), | 1844 | max (sizeof " . #" + INT_STRLEN_BOUND (printmax_t), |
| 1842 | 40))]; | 1845 | max ((sizeof "at 0x" |
| 1846 | + (sizeof (uprintmax_t) * CHAR_BIT + 4 - 1) / 4), | ||
| 1847 | 40)))]; | ||
| 1843 | current_thread->stack_top = buf; | 1848 | current_thread->stack_top = buf; |
| 1844 | maybe_quit (); | 1849 | maybe_quit (); |
| 1845 | 1850 | ||