aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lisp.h23
1 files changed, 19 insertions, 4 deletions
diff --git a/src/lisp.h b/src/lisp.h
index 65b783f7b46..625027769cf 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -606,6 +606,8 @@ extern Lisp_Object make_number (EMACS_INT);
606 ((v)->size_member |= PSEUDOVECTOR_FLAG | (code)) 606 ((v)->size_member |= PSEUDOVECTOR_FLAG | (code))
607#define XSETPVECTYPESIZE(v, code, sizeval) \ 607#define XSETPVECTYPESIZE(v, code, sizeval) \
608 ((v)->header.size = PSEUDOVECTOR_FLAG | (code) | (sizeval)) 608 ((v)->header.size = PSEUDOVECTOR_FLAG | (code) | (sizeval))
609
610/* The cast to struct vectorlike_header * avoids aliasing issues. */
609#define XSETPSEUDOVECTOR(a, b, code) \ 611#define XSETPSEUDOVECTOR(a, b, code) \
610 XSETTYPED_PSEUDOVECTOR(a, b, \ 612 XSETTYPED_PSEUDOVECTOR(a, b, \
611 ((struct vectorlike_header *) XPNTR (a))->size, \ 613 ((struct vectorlike_header *) XPNTR (a))->size, \
@@ -614,11 +616,13 @@ extern Lisp_Object make_number (EMACS_INT);
614 (XSETVECTOR (a, b), \ 616 (XSETVECTOR (a, b), \
615 eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \ 617 eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \
616 == (PSEUDOVECTOR_FLAG | (code)))) 618 == (PSEUDOVECTOR_FLAG | (code))))
619
617#define XSETWINDOW_CONFIGURATION(a, b) \ 620#define XSETWINDOW_CONFIGURATION(a, b) \
618 (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION)) 621 (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION))
619#define XSETPROCESS(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_PROCESS)) 622#define XSETPROCESS(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_PROCESS))
620#define XSETWINDOW(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW)) 623#define XSETWINDOW(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW))
621#define XSETTERMINAL(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL)) 624#define XSETTERMINAL(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL))
625/* XSETSUBR is special since Lisp_Subr lacks struct vectorlike_header. */
622#define XSETSUBR(a, b) \ 626#define XSETSUBR(a, b) \
623 XSETTYPED_PSEUDOVECTOR (a, b, XSUBR (a)->size, PVEC_SUBR) 627 XSETTYPED_PSEUDOVECTOR (a, b, XSUBR (a)->size, PVEC_SUBR)
624#define XSETCOMPILED(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_COMPILED)) 628#define XSETCOMPILED(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_COMPILED))
@@ -787,12 +791,21 @@ struct Lisp_String
787 unsigned char *data; 791 unsigned char *data;
788 }; 792 };
789 793
790/* Header of vector-like objects. This type documents the constraints on 794/* Header of vector-like objects. This documents the layout constraints on
791 layout of vectors and pseudovectors, and helps optimizing compilers not get 795 vectors and pseudovectors other than struct Lisp_Subr. It also prevents
792 fooled by Emacs's type punning. */ 796 compilers from being fooled by Emacs's type punning: the XSETPSEUDOVECTOR
797 and PSEUDOVECTORP macros cast their pointers to struct vectorlike_header *,
798 because when two such pointers potentially alias, a compiler won't
799 incorrectly reorder loads and stores to their size fields. See
800 <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8546>. */
793struct vectorlike_header 801struct vectorlike_header
794 { 802 {
795 EMACS_UINT size; 803 EMACS_UINT size;
804
805 /* Pointer to the next vector-like object. It is generally a buffer or a
806 Lisp_Vector alias, so for convenience it is a union instead of a
807 pointer: this way, one can write P->next.vector instead of ((struct
808 Lisp_Vector *) P->next). */
796 union { 809 union {
797 struct buffer *buffer; 810 struct buffer *buffer;
798 struct Lisp_Vector *vector; 811 struct Lisp_Vector *vector;
@@ -1647,7 +1660,8 @@ typedef struct {
1647#define BUFFER_OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Buffer_Obj) 1660#define BUFFER_OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Buffer_Obj)
1648#define KBOARD_OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Kboard_Obj) 1661#define KBOARD_OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Kboard_Obj)
1649 1662
1650/* True if object X is a pseudovector whose code is CODE. */ 1663/* True if object X is a pseudovector whose code is CODE. The cast to struct
1664 vectorlike_header * avoids aliasing issues. */
1651#define PSEUDOVECTORP(x, code) \ 1665#define PSEUDOVECTORP(x, code) \
1652 TYPED_PSEUDOVECTORP(x, vectorlike_header, code) 1666 TYPED_PSEUDOVECTORP(x, vectorlike_header, code)
1653 1667
@@ -1664,6 +1678,7 @@ typedef struct {
1664#define PROCESSP(x) PSEUDOVECTORP (x, PVEC_PROCESS) 1678#define PROCESSP(x) PSEUDOVECTORP (x, PVEC_PROCESS)
1665#define WINDOWP(x) PSEUDOVECTORP (x, PVEC_WINDOW) 1679#define WINDOWP(x) PSEUDOVECTORP (x, PVEC_WINDOW)
1666#define TERMINALP(x) PSEUDOVECTORP (x, PVEC_TERMINAL) 1680#define TERMINALP(x) PSEUDOVECTORP (x, PVEC_TERMINAL)
1681/* SUBRP is special since Lisp_Subr lacks struct vectorlike_header. */
1667#define SUBRP(x) TYPED_PSEUDOVECTORP (x, Lisp_Subr, PVEC_SUBR) 1682#define SUBRP(x) TYPED_PSEUDOVECTORP (x, Lisp_Subr, PVEC_SUBR)
1668#define COMPILEDP(x) PSEUDOVECTORP (x, PVEC_COMPILED) 1683#define COMPILEDP(x) PSEUDOVECTORP (x, PVEC_COMPILED)
1669#define BUFFERP(x) PSEUDOVECTORP (x, PVEC_BUFFER) 1684#define BUFFERP(x) PSEUDOVECTORP (x, PVEC_BUFFER)