emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 926a394: Use simpler way to print function pointers


From: Paul Eggert
Subject: [Emacs-diffs] master 926a394: Use simpler way to print function pointers
Date: Sun, 5 May 2019 20:41:51 -0400 (EDT)

branch: master
commit 926a394997eaae55b797a90cb2cd037bbe3c3db4
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    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.
---
 src/lisp.h  |  2 ++
 src/print.c | 47 ++++++++++++++++++++++++++---------------------
 2 files changed, 28 insertions(+), 21 deletions(-)

diff --git a/src/lisp.h b/src/lisp.h
index ca83347..61cc20e 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -144,11 +144,13 @@ typedef intmax_t printmax_t;
 typedef uintmax_t uprintmax_t;
 # define pMd PRIdMAX
 # define pMu PRIuMAX
+# define pMx PRIxMAX
 #else
 typedef EMACS_INT printmax_t;
 typedef EMACS_UINT uprintmax_t;
 # define pMd pI"d"
 # define pMu pI"u"
+# define pMx pI"x"
 #endif
 
 /* Use pD to format ptrdiff_t values, which suffice for indexes into
diff --git a/src/print.c b/src/print.c
index 08c39d3..406abbf 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1361,6 +1361,19 @@ print_prune_string_charset (Lisp_Object string)
   return string;
 }
 
+#ifdef HAVE_MODULES
+/* Return a data pointer equal to FUNCPTR.  */
+
+static void const *
+data_from_funcptr (void (*funcptr) (void))
+{
+  /* The module code, and the POSIX API for dynamic linking, already
+     assume that function and data pointers are represented
+     interchangeably, so it's OK to assume that here too.  */
+  return (void const *) funcptr;
+}
+#endif
+
 static bool
 print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag,
                  char *buf)
@@ -1788,30 +1801,20 @@ print_vectorlike (Lisp_Object obj, Lisp_Object 
printcharfun, bool escapeflag,
       {
        print_c_string ("#<module function ", printcharfun);
         module_funcptr ptr = module_function_address (XMODULE_FUNCTION (obj));
-        const char *file = NULL;
-       const char *symbol = NULL;
+       char const *file;
+       char const *symbol;
        dynlib_addr (ptr, &file, &symbol);
 
        if (symbol == NULL)
          {
-           print_c_string ("at 0x", printcharfun);
-            /* See https://stackoverflow.com/a/2741896 for how to
-               portably print a function pointer.  */
-            const unsigned char *p = (const unsigned char *) &ptr;
-            for (size_t i = 0; i < sizeof ptr; ++i)
-              {
-#ifdef WORDS_BIGENDIAN
-                unsigned char b = p[i];
-#else
-                unsigned char b = p[sizeof ptr - i - 1];
-#endif
-                enum { digits = (CHAR_BIT + 4 - 1) / 4 };
-                char buffer[digits + 1];
-                int needed
-                  = snprintf (buffer, sizeof buffer, "%0*x", digits, b);
-                eassert (needed == digits);
-                print_c_string (buffer, printcharfun);
-              }
+           uintptr_t ui = (uintptr_t) data_from_funcptr (ptr);
+
+           /* In theory this assignment could lose info on pre-C99
+              hosts, but in practice it doesn't.  */
+           uprintmax_t up = ui;
+
+           int len = sprintf (buf, "at 0x%"pMx, up);
+           strout (buf, len, len, printcharfun);
          }
        else
          print_c_string (symbol, printcharfun);
@@ -1839,7 +1842,9 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, 
bool escapeflag)
 {
   char buf[max (sizeof "from..to..in " + 2 * INT_STRLEN_BOUND (EMACS_INT),
                max (sizeof " . #" + INT_STRLEN_BOUND (printmax_t),
-                    40))];
+                    max ((sizeof "at 0x"
+                          + (sizeof (uprintmax_t) * CHAR_BIT + 4 - 1) / 4),
+                         40)))];
   current_thread->stack_top = buf;
   maybe_quit ();
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]