aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2019-05-05 17:35:05 -0700
committerPaul Eggert2019-05-05 17:40:55 -0700
commit926a394997eaae55b797a90cb2cd037bbe3c3db4 (patch)
treea075ef40927dc732c254f2d63a98af8ca3d99c82 /src
parent31c60dfbd8541c9f1b1bc8127dde85e5d5af51b5 (diff)
downloademacs-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')
-rw-r--r--src/lisp.h2
-rw-r--r--src/print.c47
2 files changed, 28 insertions, 21 deletions
diff --git a/src/lisp.h b/src/lisp.h
index ca833476c03..61cc20e9d42 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -144,11 +144,13 @@ typedef intmax_t printmax_t;
144typedef uintmax_t uprintmax_t; 144typedef uintmax_t uprintmax_t;
145# define pMd PRIdMAX 145# define pMd PRIdMAX
146# define pMu PRIuMAX 146# define pMu PRIuMAX
147# define pMx PRIxMAX
147#else 148#else
148typedef EMACS_INT printmax_t; 149typedef EMACS_INT printmax_t;
149typedef EMACS_UINT uprintmax_t; 150typedef EMACS_UINT uprintmax_t;
150# define pMd pI"d" 151# define pMd pI"d"
151# define pMu pI"u" 152# define pMu pI"u"
153# define pMx pI"x"
152#endif 154#endif
153 155
154/* Use pD to format ptrdiff_t values, which suffice for indexes into 156/* Use pD to format ptrdiff_t values, which suffice for indexes into
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
1367static void const *
1368data_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
1364static bool 1377static bool
1365print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag, 1378print_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