emacs-diffs
[Top][All Lists]
Advanced

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

master 861f9cb7837: Don't use pointer arithmetic for untagging Lisp valu


From: Mattias Engdegård
Subject: master 861f9cb7837: Don't use pointer arithmetic for untagging Lisp values (bug#65491)
Date: Mon, 18 Sep 2023 14:06:16 -0400 (EDT)

branch: master
commit 861f9cb78370e2b78f852e5ccde9b63c94486ca8
Author: Mattias Engdegård <mattiase@acm.org>
Commit: Mattias Engdegård <mattiase@acm.org>

    Don't use pointer arithmetic for untagging Lisp values (bug#65491)
    
    * src/lisp.h (XUNTAG):
    Instead of casting a Lisp value to char * and subtracting the tag,
    cast it to a suitable integral type and work on that.
    
    This should result in identical or at least equivalent code, except
    that it avoids potential problems arising from the restrictions on
    pointer arithmetic in C.  In particular, a null pointer can be neither
    an operand in nor the result of pointer arithmetic.
    
    C compilers know this and would, prior to this change, optimise
    
      XUNTAG(obj, Lisp_Int0, mytype) != NULL
    
    to 1.  This means, for example, that make_pointer_integer and
    XFIXNUMPTR could not be entrusted with null pointers, and
    next_vector in alloc.c was unsafe to use.
---
 src/lisp.h | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/lisp.h b/src/lisp.h
index 50b68f2e767..de6746f1c07 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -808,10 +808,12 @@ INLINE void
 }
 
 /* Extract A's pointer value, assuming A's Lisp type is TYPE and the
-   extracted pointer's type is CTYPE *.  */
-
-#define XUNTAG(a, type, ctype) ((ctype *) \
-                               ((char *) XLP (a) - LISP_WORD_TAG (type)))
+   extracted pointer's type is CTYPE *.
+   Note that the second term vanishes if EMACS_INT is wider than pointers
+   and the tag is in the upper bits (ie, USE_LSB_TAG=0); this makes
+   untagging slightly cheaper in that case.  */
+#define XUNTAG(a, type, ctype) \
+  ((ctype *) ((uintptr_t) XLP (a) - (uintptr_t) LISP_WORD_TAG (type)))
 
 /* A forwarding pointer to a value.  It uses a generic pointer to
    avoid alignment bugs that could occur if it used a pointer to a



reply via email to

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