diff options
| author | Paul Eggert | 2017-11-13 08:51:41 -0800 |
|---|---|---|
| committer | Paul Eggert | 2017-11-13 10:16:51 -0800 |
| commit | b1573a97e17b518723ab3f906eb6d521caed196d (patch) | |
| tree | 2bcfe8f47a99d7ba9b46e75ed5bffd2ba37970e0 /src | |
| parent | 5d68dc9a2fd1b9b883db6bc1c226541b50de8bb1 (diff) | |
| download | emacs-b1573a97e17b518723ab3f906eb6d521caed196d.tar.gz emacs-b1573a97e17b518723ab3f906eb6d521caed196d.zip | |
Use alignas to fix GCALIGN-related bugs
Use alignas and unions to specify alignments of objects needing
addresses that are at least a multiple of GCALIGNMENT. Using
these standard C facilities should be safer than relying on ad hoc
and poorly-understood features like GCC’s __attribute__
((aligned (N))), the root cause for recent porting bugs like
Bug#29040. The alignas macro was standardized by C11 and Gnulib
supports alignas for pre-C11 platforms. I have tested this on Sun
Studio 12 sparc (2007) and GCC 4.4.7 x86-64 (2012) as well as on
more recent platforms like GCC 7.2.1 (2017) on Fedora 26 (both
x86-64 and x86).
* lib-src/make-docfile.c (close_emacs_globals): lispsym is now
just an array of struct Lisp_Symbol, since struct Lisp_Symbol is
now properly aligned. All uses changed.
* src/alloc.c (NEXT_FREE_LISP_STRING): Just use the new u.next
member; this is simpler and safer than casting a pointer that
might not be aligned properly.
(aligned_Lisp_Symbol): Remove. No longer needed, now that struct
Lisp_Symbol is aligned properly. All uses replaced with struct
Lisp_Symbol.
* src/lisp.h (GCALIGNED): Remove, as it does not work as expected:
it can cause the natural alignment to be ignored. All uses
replaced by unions with a ‘char alignas (GCALIGNMENT)’ member as
described below.
(struct Lisp_Symbol, struct Lisp_Cons, struct Lisp_String):
Change definition from ‘struct TAG { MEMBERS };’ to
‘struct TAG { union { struct { MEMBERS } s; char alignas
(GCALIGNMENT) gcaligned; } u; };’. This guarantees ‘struct TAG’
to have an alignment that at least max (GCALIGNMENT, N) where N is
its old alignment. All uses like ‘PTR->MEMBER’ changed to
‘PTR->u.s.MEMBER’; these uses were supposed to be mostly private
anyway. Verify that the resulting ‘struct TAG’ is properly
aligned for Emacs.
(union vectorlike_header): New member ‘gcaligned’ to guarantee
that this type, and its containing types like ‘struct Lisp_Subr’,
‘struct buffer’ and ‘struct thread_state’, are all properly
aligned for Emacs.
(struct Lisp_String): New union member ‘next’, for the benefit
of NEXT_FREE_LISP_STRING.
(union Aligned_Cons, union Aligned_String): Remove. All uses
replaced by struct Lisp_Cons and struct Lisp_String, since they
are now properly aligned.
(USE_STACK_CONS, USE_STACK_STRING): Simplify now that we can
assume struct Lisp_Cons and struct Lisp_String are properly
aligned.
Diffstat (limited to 'src')
| -rw-r--r-- | src/alloc.c | 211 | ||||
| -rw-r--r-- | src/buffer.c | 19 | ||||
| -rw-r--r-- | src/bytecode.c | 4 | ||||
| -rw-r--r-- | src/casefiddle.c | 4 | ||||
| -rw-r--r-- | src/cmds.c | 6 | ||||
| -rw-r--r-- | src/data.c | 76 | ||||
| -rw-r--r-- | src/doc.c | 2 | ||||
| -rw-r--r-- | src/eval.c | 59 | ||||
| -rw-r--r-- | src/fns.c | 4 | ||||
| -rw-r--r-- | src/keyboard.c | 10 | ||||
| -rw-r--r-- | src/lisp.h | 277 | ||||
| -rw-r--r-- | src/lread.c | 52 | ||||
| -rw-r--r-- | src/minibuf.c | 12 | ||||
| -rw-r--r-- | src/thread.c | 2 | ||||
| -rw-r--r-- | src/xterm.c | 2 |
15 files changed, 366 insertions, 374 deletions
diff --git a/src/alloc.c b/src/alloc.c index 5a44d7a9fc2..3b87195b707 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -211,9 +211,9 @@ alloc_unexec_post (void) | |||
| 211 | /* Mark, unmark, query mark bit of a Lisp string. S must be a pointer | 211 | /* Mark, unmark, query mark bit of a Lisp string. S must be a pointer |
| 212 | to a struct Lisp_String. */ | 212 | to a struct Lisp_String. */ |
| 213 | 213 | ||
| 214 | #define MARK_STRING(S) ((S)->size |= ARRAY_MARK_FLAG) | 214 | #define MARK_STRING(S) ((S)->u.s.size |= ARRAY_MARK_FLAG) |
| 215 | #define UNMARK_STRING(S) ((S)->size &= ~ARRAY_MARK_FLAG) | 215 | #define UNMARK_STRING(S) ((S)->u.s.size &= ~ARRAY_MARK_FLAG) |
| 216 | #define STRING_MARKED_P(S) (((S)->size & ARRAY_MARK_FLAG) != 0) | 216 | #define STRING_MARKED_P(S) (((S)->u.s.size & ARRAY_MARK_FLAG) != 0) |
| 217 | 217 | ||
| 218 | #define VECTOR_MARK(V) ((V)->header.size |= ARRAY_MARK_FLAG) | 218 | #define VECTOR_MARK(V) ((V)->header.size |= ARRAY_MARK_FLAG) |
| 219 | #define VECTOR_UNMARK(V) ((V)->header.size &= ~ARRAY_MARK_FLAG) | 219 | #define VECTOR_UNMARK(V) ((V)->header.size &= ~ARRAY_MARK_FLAG) |
| @@ -1730,14 +1730,14 @@ static EMACS_INT total_string_bytes; | |||
| 1730 | string_free_list, return a pointer to its successor in the | 1730 | string_free_list, return a pointer to its successor in the |
| 1731 | free-list. */ | 1731 | free-list. */ |
| 1732 | 1732 | ||
| 1733 | #define NEXT_FREE_LISP_STRING(S) (*(struct Lisp_String **) (S)) | 1733 | #define NEXT_FREE_LISP_STRING(S) ((S)->u.next) |
| 1734 | 1734 | ||
| 1735 | /* Return a pointer to the sdata structure belonging to Lisp string S. | 1735 | /* Return a pointer to the sdata structure belonging to Lisp string S. |
| 1736 | S must be live, i.e. S->data must not be null. S->data is actually | 1736 | S must be live, i.e. S->data must not be null. S->data is actually |
| 1737 | a pointer to the `u.data' member of its sdata structure; the | 1737 | a pointer to the `u.data' member of its sdata structure; the |
| 1738 | structure starts at a constant offset in front of that. */ | 1738 | structure starts at a constant offset in front of that. */ |
| 1739 | 1739 | ||
| 1740 | #define SDATA_OF_STRING(S) ((sdata *) ((S)->data - SDATA_DATA_OFFSET)) | 1740 | #define SDATA_OF_STRING(S) ((sdata *) ((S)->u.s.data - SDATA_DATA_OFFSET)) |
| 1741 | 1741 | ||
| 1742 | 1742 | ||
| 1743 | #ifdef GC_CHECK_STRING_OVERRUN | 1743 | #ifdef GC_CHECK_STRING_OVERRUN |
| @@ -1818,9 +1818,10 @@ ptrdiff_t | |||
| 1818 | string_bytes (struct Lisp_String *s) | 1818 | string_bytes (struct Lisp_String *s) |
| 1819 | { | 1819 | { |
| 1820 | ptrdiff_t nbytes = | 1820 | ptrdiff_t nbytes = |
| 1821 | (s->size_byte < 0 ? s->size & ~ARRAY_MARK_FLAG : s->size_byte); | 1821 | (s->u.s.size_byte < 0 ? s->u.s.size & ~ARRAY_MARK_FLAG : s->u.s.size_byte); |
| 1822 | 1822 | ||
| 1823 | if (!PURE_P (s) && s->data && nbytes != SDATA_NBYTES (SDATA_OF_STRING (s))) | 1823 | if (!PURE_P (s) && s->u.s.data |
| 1824 | && nbytes != SDATA_NBYTES (SDATA_OF_STRING (s))) | ||
| 1824 | emacs_abort (); | 1825 | emacs_abort (); |
| 1825 | return nbytes; | 1826 | return nbytes; |
| 1826 | } | 1827 | } |
| @@ -1926,7 +1927,7 @@ allocate_string (void) | |||
| 1926 | { | 1927 | { |
| 1927 | s = b->strings + i; | 1928 | s = b->strings + i; |
| 1928 | /* Every string on a free list should have NULL data pointer. */ | 1929 | /* Every string on a free list should have NULL data pointer. */ |
| 1929 | s->data = NULL; | 1930 | s->u.s.data = NULL; |
| 1930 | NEXT_FREE_LISP_STRING (s) = string_free_list; | 1931 | NEXT_FREE_LISP_STRING (s) = string_free_list; |
| 1931 | string_free_list = s; | 1932 | string_free_list = s; |
| 1932 | } | 1933 | } |
| @@ -1965,10 +1966,10 @@ allocate_string (void) | |||
| 1965 | 1966 | ||
| 1966 | 1967 | ||
| 1967 | /* Set up Lisp_String S for holding NCHARS characters, NBYTES bytes, | 1968 | /* Set up Lisp_String S for holding NCHARS characters, NBYTES bytes, |
| 1968 | plus a NUL byte at the end. Allocate an sdata structure for S, and | 1969 | plus a NUL byte at the end. Allocate an sdata structure DATA for |
| 1969 | set S->data to its `u.data' member. Store a NUL byte at the end of | 1970 | S, and set S->u.s.data to SDATA->u.data. Store a NUL byte at the |
| 1970 | S->data. Set S->size to NCHARS and S->size_byte to NBYTES. Free | 1971 | end of S->u.s.data. Set S->u.s.size to NCHARS and S->u.s.size_byte |
| 1971 | S->data if it was initially non-null. */ | 1972 | to NBYTES. Free S->u.s.data if it was initially non-null. */ |
| 1972 | 1973 | ||
| 1973 | void | 1974 | void |
| 1974 | allocate_string_data (struct Lisp_String *s, | 1975 | allocate_string_data (struct Lisp_String *s, |
| @@ -1984,7 +1985,7 @@ allocate_string_data (struct Lisp_String *s, | |||
| 1984 | /* Determine the number of bytes needed to store NBYTES bytes | 1985 | /* Determine the number of bytes needed to store NBYTES bytes |
| 1985 | of string data. */ | 1986 | of string data. */ |
| 1986 | needed = SDATA_SIZE (nbytes); | 1987 | needed = SDATA_SIZE (nbytes); |
| 1987 | if (s->data) | 1988 | if (s->u.s.data) |
| 1988 | { | 1989 | { |
| 1989 | old_data = SDATA_OF_STRING (s); | 1990 | old_data = SDATA_OF_STRING (s); |
| 1990 | old_nbytes = STRING_BYTES (s); | 1991 | old_nbytes = STRING_BYTES (s); |
| @@ -2043,13 +2044,13 @@ allocate_string_data (struct Lisp_String *s, | |||
| 2043 | 2044 | ||
| 2044 | MALLOC_UNBLOCK_INPUT; | 2045 | MALLOC_UNBLOCK_INPUT; |
| 2045 | 2046 | ||
| 2046 | s->data = SDATA_DATA (data); | 2047 | s->u.s.data = SDATA_DATA (data); |
| 2047 | #ifdef GC_CHECK_STRING_BYTES | 2048 | #ifdef GC_CHECK_STRING_BYTES |
| 2048 | SDATA_NBYTES (data) = nbytes; | 2049 | SDATA_NBYTES (data) = nbytes; |
| 2049 | #endif | 2050 | #endif |
| 2050 | s->size = nchars; | 2051 | s->u.s.size = nchars; |
| 2051 | s->size_byte = nbytes; | 2052 | s->u.s.size_byte = nbytes; |
| 2052 | s->data[nbytes] = '\0'; | 2053 | s->u.s.data[nbytes] = '\0'; |
| 2053 | #ifdef GC_CHECK_STRING_OVERRUN | 2054 | #ifdef GC_CHECK_STRING_OVERRUN |
| 2054 | memcpy ((char *) data + needed, string_overrun_cookie, | 2055 | memcpy ((char *) data + needed, string_overrun_cookie, |
| 2055 | GC_STRING_OVERRUN_COOKIE_SIZE); | 2056 | GC_STRING_OVERRUN_COOKIE_SIZE); |
| @@ -2093,7 +2094,7 @@ sweep_strings (void) | |||
| 2093 | { | 2094 | { |
| 2094 | struct Lisp_String *s = b->strings + i; | 2095 | struct Lisp_String *s = b->strings + i; |
| 2095 | 2096 | ||
| 2096 | if (s->data) | 2097 | if (s->u.s.data) |
| 2097 | { | 2098 | { |
| 2098 | /* String was not on free-list before. */ | 2099 | /* String was not on free-list before. */ |
| 2099 | if (STRING_MARKED_P (s)) | 2100 | if (STRING_MARKED_P (s)) |
| @@ -2102,7 +2103,7 @@ sweep_strings (void) | |||
| 2102 | UNMARK_STRING (s); | 2103 | UNMARK_STRING (s); |
| 2103 | 2104 | ||
| 2104 | /* Do not use string_(set|get)_intervals here. */ | 2105 | /* Do not use string_(set|get)_intervals here. */ |
| 2105 | s->intervals = balance_intervals (s->intervals); | 2106 | s->u.s.intervals = balance_intervals (s->u.s.intervals); |
| 2106 | 2107 | ||
| 2107 | ++total_strings; | 2108 | ++total_strings; |
| 2108 | total_string_bytes += STRING_BYTES (s); | 2109 | total_string_bytes += STRING_BYTES (s); |
| @@ -2125,7 +2126,7 @@ sweep_strings (void) | |||
| 2125 | 2126 | ||
| 2126 | /* Reset the strings's `data' member so that we | 2127 | /* Reset the strings's `data' member so that we |
| 2127 | know it's free. */ | 2128 | know it's free. */ |
| 2128 | s->data = NULL; | 2129 | s->u.s.data = NULL; |
| 2129 | 2130 | ||
| 2130 | /* Put the string on the free-list. */ | 2131 | /* Put the string on the free-list. */ |
| 2131 | NEXT_FREE_LISP_STRING (s) = string_free_list; | 2132 | NEXT_FREE_LISP_STRING (s) = string_free_list; |
| @@ -2264,7 +2265,7 @@ compact_small_strings (void) | |||
| 2264 | { | 2265 | { |
| 2265 | eassert (tb != b || to < from); | 2266 | eassert (tb != b || to < from); |
| 2266 | memmove (to, from, nbytes + GC_STRING_EXTRA); | 2267 | memmove (to, from, nbytes + GC_STRING_EXTRA); |
| 2267 | to->string->data = SDATA_DATA (to); | 2268 | to->string->u.s.data = SDATA_DATA (to); |
| 2268 | } | 2269 | } |
| 2269 | 2270 | ||
| 2270 | /* Advance past the sdata we copied to. */ | 2271 | /* Advance past the sdata we copied to. */ |
| @@ -2544,7 +2545,7 @@ make_uninit_multibyte_string (EMACS_INT nchars, EMACS_INT nbytes) | |||
| 2544 | return empty_multibyte_string; | 2545 | return empty_multibyte_string; |
| 2545 | 2546 | ||
| 2546 | s = allocate_string (); | 2547 | s = allocate_string (); |
| 2547 | s->intervals = NULL; | 2548 | s->u.s.intervals = NULL; |
| 2548 | allocate_string_data (s, nchars, nbytes); | 2549 | allocate_string_data (s, nchars, nbytes); |
| 2549 | XSETSTRING (string, s); | 2550 | XSETSTRING (string, s); |
| 2550 | string_chars_consed += nbytes; | 2551 | string_chars_consed += nbytes; |
| @@ -2729,8 +2730,8 @@ static struct Lisp_Cons *cons_free_list; | |||
| 2729 | void | 2730 | void |
| 2730 | free_cons (struct Lisp_Cons *ptr) | 2731 | free_cons (struct Lisp_Cons *ptr) |
| 2731 | { | 2732 | { |
| 2732 | ptr->u.chain = cons_free_list; | 2733 | ptr->u.s.u.chain = cons_free_list; |
| 2733 | ptr->car = Vdead; | 2734 | ptr->u.s.car = Vdead; |
| 2734 | cons_free_list = ptr; | 2735 | cons_free_list = ptr; |
| 2735 | consing_since_gc -= sizeof *ptr; | 2736 | consing_since_gc -= sizeof *ptr; |
| 2736 | total_free_conses++; | 2737 | total_free_conses++; |
| @@ -2749,7 +2750,7 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0, | |||
| 2749 | /* We use the cdr for chaining the free list | 2750 | /* We use the cdr for chaining the free list |
| 2750 | so that we won't use the same field that has the mark bit. */ | 2751 | so that we won't use the same field that has the mark bit. */ |
| 2751 | XSETCONS (val, cons_free_list); | 2752 | XSETCONS (val, cons_free_list); |
| 2752 | cons_free_list = cons_free_list->u.chain; | 2753 | cons_free_list = cons_free_list->u.s.u.chain; |
| 2753 | } | 2754 | } |
| 2754 | else | 2755 | else |
| 2755 | { | 2756 | { |
| @@ -2786,7 +2787,7 @@ check_cons_list (void) | |||
| 2786 | struct Lisp_Cons *tail = cons_free_list; | 2787 | struct Lisp_Cons *tail = cons_free_list; |
| 2787 | 2788 | ||
| 2788 | while (tail) | 2789 | while (tail) |
| 2789 | tail = tail->u.chain; | 2790 | tail = tail->u.s.u.chain; |
| 2790 | } | 2791 | } |
| 2791 | #endif | 2792 | #endif |
| 2792 | 2793 | ||
| @@ -3543,27 +3544,17 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT | |||
| 3543 | Symbol Allocation | 3544 | Symbol Allocation |
| 3544 | ***********************************************************************/ | 3545 | ***********************************************************************/ |
| 3545 | 3546 | ||
| 3546 | /* Like struct Lisp_Symbol, but padded so that the size is a multiple | ||
| 3547 | of the required alignment. */ | ||
| 3548 | |||
| 3549 | union aligned_Lisp_Symbol | ||
| 3550 | { | ||
| 3551 | struct Lisp_Symbol s; | ||
| 3552 | unsigned char c[(sizeof (struct Lisp_Symbol) + GCALIGNMENT - 1) | ||
| 3553 | & -GCALIGNMENT]; | ||
| 3554 | }; | ||
| 3555 | |||
| 3556 | /* Each symbol_block is just under 1020 bytes long, since malloc | 3547 | /* Each symbol_block is just under 1020 bytes long, since malloc |
| 3557 | really allocates in units of powers of two and uses 4 bytes for its | 3548 | really allocates in units of powers of two and uses 4 bytes for its |
| 3558 | own overhead. */ | 3549 | own overhead. */ |
| 3559 | 3550 | ||
| 3560 | #define SYMBOL_BLOCK_SIZE \ | 3551 | #define SYMBOL_BLOCK_SIZE \ |
| 3561 | ((1020 - sizeof (struct symbol_block *)) / sizeof (union aligned_Lisp_Symbol)) | 3552 | ((1020 - sizeof (struct symbol_block *)) / sizeof (struct Lisp_Symbol)) |
| 3562 | 3553 | ||
| 3563 | struct symbol_block | 3554 | struct symbol_block |
| 3564 | { | 3555 | { |
| 3565 | /* Place `symbols' first, to preserve alignment. */ | 3556 | /* Place `symbols' first, to preserve alignment. */ |
| 3566 | union aligned_Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE]; | 3557 | struct Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE]; |
| 3567 | struct symbol_block *next; | 3558 | struct symbol_block *next; |
| 3568 | }; | 3559 | }; |
| 3569 | 3560 | ||
| @@ -3587,7 +3578,7 @@ static struct Lisp_Symbol *symbol_free_list; | |||
| 3587 | static void | 3578 | static void |
| 3588 | set_symbol_name (Lisp_Object sym, Lisp_Object name) | 3579 | set_symbol_name (Lisp_Object sym, Lisp_Object name) |
| 3589 | { | 3580 | { |
| 3590 | XSYMBOL (sym)->name = name; | 3581 | XSYMBOL (sym)->u.s.name = name; |
| 3591 | } | 3582 | } |
| 3592 | 3583 | ||
| 3593 | void | 3584 | void |
| @@ -3596,15 +3587,15 @@ init_symbol (Lisp_Object val, Lisp_Object name) | |||
| 3596 | struct Lisp_Symbol *p = XSYMBOL (val); | 3587 | struct Lisp_Symbol *p = XSYMBOL (val); |
| 3597 | set_symbol_name (val, name); | 3588 | set_symbol_name (val, name); |
| 3598 | set_symbol_plist (val, Qnil); | 3589 | set_symbol_plist (val, Qnil); |
| 3599 | p->redirect = SYMBOL_PLAINVAL; | 3590 | p->u.s.redirect = SYMBOL_PLAINVAL; |
| 3600 | SET_SYMBOL_VAL (p, Qunbound); | 3591 | SET_SYMBOL_VAL (p, Qunbound); |
| 3601 | set_symbol_function (val, Qnil); | 3592 | set_symbol_function (val, Qnil); |
| 3602 | set_symbol_next (val, NULL); | 3593 | set_symbol_next (val, NULL); |
| 3603 | p->gcmarkbit = false; | 3594 | p->u.s.gcmarkbit = false; |
| 3604 | p->interned = SYMBOL_UNINTERNED; | 3595 | p->u.s.interned = SYMBOL_UNINTERNED; |
| 3605 | p->trapped_write = SYMBOL_UNTRAPPED_WRITE; | 3596 | p->u.s.trapped_write = SYMBOL_UNTRAPPED_WRITE; |
| 3606 | p->declared_special = false; | 3597 | p->u.s.declared_special = false; |
| 3607 | p->pinned = false; | 3598 | p->u.s.pinned = false; |
| 3608 | } | 3599 | } |
| 3609 | 3600 | ||
| 3610 | DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0, | 3601 | DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0, |
| @@ -3621,7 +3612,7 @@ Its value is void, and its function definition and property list are nil. */) | |||
| 3621 | if (symbol_free_list) | 3612 | if (symbol_free_list) |
| 3622 | { | 3613 | { |
| 3623 | XSETSYMBOL (val, symbol_free_list); | 3614 | XSETSYMBOL (val, symbol_free_list); |
| 3624 | symbol_free_list = symbol_free_list->next; | 3615 | symbol_free_list = symbol_free_list->u.s.next; |
| 3625 | } | 3616 | } |
| 3626 | else | 3617 | else |
| 3627 | { | 3618 | { |
| @@ -3634,7 +3625,7 @@ Its value is void, and its function definition and property list are nil. */) | |||
| 3634 | symbol_block_index = 0; | 3625 | symbol_block_index = 0; |
| 3635 | total_free_symbols += SYMBOL_BLOCK_SIZE; | 3626 | total_free_symbols += SYMBOL_BLOCK_SIZE; |
| 3636 | } | 3627 | } |
| 3637 | XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index].s); | 3628 | XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index]); |
| 3638 | symbol_block_index++; | 3629 | symbol_block_index++; |
| 3639 | } | 3630 | } |
| 3640 | 3631 | ||
| @@ -4587,7 +4578,7 @@ live_string_holding (struct mem_node *m, void *p) | |||
| 4587 | if (0 <= offset && offset < STRING_BLOCK_SIZE * sizeof b->strings[0]) | 4578 | if (0 <= offset && offset < STRING_BLOCK_SIZE * sizeof b->strings[0]) |
| 4588 | { | 4579 | { |
| 4589 | struct Lisp_String *s = p = cp -= offset % sizeof b->strings[0]; | 4580 | struct Lisp_String *s = p = cp -= offset % sizeof b->strings[0]; |
| 4590 | if (s->data) | 4581 | if (s->u.s.data) |
| 4591 | return make_lisp_ptr (s, Lisp_String); | 4582 | return make_lisp_ptr (s, Lisp_String); |
| 4592 | } | 4583 | } |
| 4593 | } | 4584 | } |
| @@ -4621,7 +4612,7 @@ live_cons_holding (struct mem_node *m, void *p) | |||
| 4621 | || offset / sizeof b->conses[0] < cons_block_index)) | 4612 | || offset / sizeof b->conses[0] < cons_block_index)) |
| 4622 | { | 4613 | { |
| 4623 | struct Lisp_Cons *s = p = cp -= offset % sizeof b->conses[0]; | 4614 | struct Lisp_Cons *s = p = cp -= offset % sizeof b->conses[0]; |
| 4624 | if (!EQ (s->car, Vdead)) | 4615 | if (!EQ (s->u.s.car, Vdead)) |
| 4625 | return make_lisp_ptr (s, Lisp_Cons); | 4616 | return make_lisp_ptr (s, Lisp_Cons); |
| 4626 | } | 4617 | } |
| 4627 | } | 4618 | } |
| @@ -4656,7 +4647,7 @@ live_symbol_holding (struct mem_node *m, void *p) | |||
| 4656 | || offset / sizeof b->symbols[0] < symbol_block_index)) | 4647 | || offset / sizeof b->symbols[0] < symbol_block_index)) |
| 4657 | { | 4648 | { |
| 4658 | struct Lisp_Symbol *s = p = cp -= offset % sizeof b->symbols[0]; | 4649 | struct Lisp_Symbol *s = p = cp -= offset % sizeof b->symbols[0]; |
| 4659 | if (!EQ (s->function, Vdead)) | 4650 | if (!EQ (s->u.s.function, Vdead)) |
| 4660 | return make_lisp_symbol (s); | 4651 | return make_lisp_symbol (s); |
| 4661 | } | 4652 | } |
| 4662 | } | 4653 | } |
| @@ -4984,7 +4975,7 @@ mark_memory (void *start, void *end) | |||
| 4984 | Lisp_Object obj = build_string ("test"); | 4975 | Lisp_Object obj = build_string ("test"); |
| 4985 | struct Lisp_String *s = XSTRING (obj); | 4976 | struct Lisp_String *s = XSTRING (obj); |
| 4986 | Fgarbage_collect (); | 4977 | Fgarbage_collect (); |
| 4987 | fprintf (stderr, "test '%s'\n", s->data); | 4978 | fprintf (stderr, "test '%s'\n", s->u.s.data); |
| 4988 | return Qnil; | 4979 | return Qnil; |
| 4989 | } | 4980 | } |
| 4990 | 4981 | ||
| @@ -5484,16 +5475,16 @@ make_pure_string (const char *data, | |||
| 5484 | { | 5475 | { |
| 5485 | Lisp_Object string; | 5476 | Lisp_Object string; |
| 5486 | struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String); | 5477 | struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String); |
| 5487 | s->data = (unsigned char *) find_string_data_in_pure (data, nbytes); | 5478 | s->u.s.data = (unsigned char *) find_string_data_in_pure (data, nbytes); |
| 5488 | if (s->data == NULL) | 5479 | if (s->u.s.data == NULL) |
| 5489 | { | 5480 | { |
| 5490 | s->data = pure_alloc (nbytes + 1, -1); | 5481 | s->u.s.data = pure_alloc (nbytes + 1, -1); |
| 5491 | memcpy (s->data, data, nbytes); | 5482 | memcpy (s->u.s.data, data, nbytes); |
| 5492 | s->data[nbytes] = '\0'; | 5483 | s->u.s.data[nbytes] = '\0'; |
| 5493 | } | 5484 | } |
| 5494 | s->size = nchars; | 5485 | s->u.s.size = nchars; |
| 5495 | s->size_byte = multibyte ? nbytes : -1; | 5486 | s->u.s.size_byte = multibyte ? nbytes : -1; |
| 5496 | s->intervals = NULL; | 5487 | s->u.s.intervals = NULL; |
| 5497 | XSETSTRING (string, s); | 5488 | XSETSTRING (string, s); |
| 5498 | return string; | 5489 | return string; |
| 5499 | } | 5490 | } |
| @@ -5506,10 +5497,10 @@ make_pure_c_string (const char *data, ptrdiff_t nchars) | |||
| 5506 | { | 5497 | { |
| 5507 | Lisp_Object string; | 5498 | Lisp_Object string; |
| 5508 | struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String); | 5499 | struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String); |
| 5509 | s->size = nchars; | 5500 | s->u.s.size = nchars; |
| 5510 | s->size_byte = -1; | 5501 | s->u.s.size_byte = -1; |
| 5511 | s->data = (unsigned char *) data; | 5502 | s->u.s.data = (unsigned char *) data; |
| 5512 | s->intervals = NULL; | 5503 | s->u.s.intervals = NULL; |
| 5513 | XSETSTRING (string, s); | 5504 | XSETSTRING (string, s); |
| 5514 | return string; | 5505 | return string; |
| 5515 | } | 5506 | } |
| @@ -5620,7 +5611,7 @@ purecopy (Lisp_Object obj) | |||
| 5620 | || SUBRP (obj)) | 5611 | || SUBRP (obj)) |
| 5621 | return obj; /* Already pure. */ | 5612 | return obj; /* Already pure. */ |
| 5622 | 5613 | ||
| 5623 | if (STRINGP (obj) && XSTRING (obj)->intervals) | 5614 | if (STRINGP (obj) && XSTRING (obj)->u.s.intervals) |
| 5624 | message_with_string ("Dropping text-properties while making string `%s' pure", | 5615 | message_with_string ("Dropping text-properties while making string `%s' pure", |
| 5625 | obj, true); | 5616 | obj, true); |
| 5626 | 5617 | ||
| @@ -5675,10 +5666,10 @@ purecopy (Lisp_Object obj) | |||
| 5675 | } | 5666 | } |
| 5676 | else if (SYMBOLP (obj)) | 5667 | else if (SYMBOLP (obj)) |
| 5677 | { | 5668 | { |
| 5678 | if (!XSYMBOL (obj)->pinned && !c_symbol_p (XSYMBOL (obj))) | 5669 | if (!XSYMBOL (obj)->u.s.pinned && !c_symbol_p (XSYMBOL (obj))) |
| 5679 | { /* We can't purify them, but they appear in many pure objects. | 5670 | { /* We can't purify them, but they appear in many pure objects. |
| 5680 | Mark them as `pinned' so we know to mark them at every GC cycle. */ | 5671 | Mark them as `pinned' so we know to mark them at every GC cycle. */ |
| 5681 | XSYMBOL (obj)->pinned = true; | 5672 | XSYMBOL (obj)->u.s.pinned = true; |
| 5682 | symbol_block_pinned = symbol_block; | 5673 | symbol_block_pinned = symbol_block; |
| 5683 | } | 5674 | } |
| 5684 | /* Don't hash-cons it. */ | 5675 | /* Don't hash-cons it. */ |
| @@ -5891,10 +5882,10 @@ mark_pinned_symbols (void) | |||
| 5891 | 5882 | ||
| 5892 | for (sblk = symbol_block_pinned; sblk; sblk = sblk->next) | 5883 | for (sblk = symbol_block_pinned; sblk; sblk = sblk->next) |
| 5893 | { | 5884 | { |
| 5894 | union aligned_Lisp_Symbol *sym = sblk->symbols, *end = sym + lim; | 5885 | struct Lisp_Symbol *sym = sblk->symbols, *end = sym + lim; |
| 5895 | for (; sym < end; ++sym) | 5886 | for (; sym < end; ++sym) |
| 5896 | if (sym->s.pinned) | 5887 | if (sym->u.s.pinned) |
| 5897 | mark_object (make_lisp_symbol (&sym->s)); | 5888 | mark_object (make_lisp_symbol (sym)); |
| 5898 | 5889 | ||
| 5899 | lim = SYMBOL_BLOCK_SIZE; | 5890 | lim = SYMBOL_BLOCK_SIZE; |
| 5900 | } | 5891 | } |
| @@ -6256,7 +6247,7 @@ mark_char_table (struct Lisp_Vector *ptr, enum pvec_type pvectype) | |||
| 6256 | { | 6247 | { |
| 6257 | Lisp_Object val = ptr->contents[i]; | 6248 | Lisp_Object val = ptr->contents[i]; |
| 6258 | 6249 | ||
| 6259 | if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->gcmarkbit)) | 6250 | if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->u.s.gcmarkbit)) |
| 6260 | continue; | 6251 | continue; |
| 6261 | if (SUB_CHAR_TABLE_P (val)) | 6252 | if (SUB_CHAR_TABLE_P (val)) |
| 6262 | { | 6253 | { |
| @@ -6499,7 +6490,7 @@ mark_object (Lisp_Object arg) | |||
| 6499 | break; | 6490 | break; |
| 6500 | CHECK_ALLOCATED_AND_LIVE (live_string_p); | 6491 | CHECK_ALLOCATED_AND_LIVE (live_string_p); |
| 6501 | MARK_STRING (ptr); | 6492 | MARK_STRING (ptr); |
| 6502 | MARK_INTERVAL_TREE (ptr->intervals); | 6493 | MARK_INTERVAL_TREE (ptr->u.s.intervals); |
| 6503 | #ifdef GC_CHECK_STRING_BYTES | 6494 | #ifdef GC_CHECK_STRING_BYTES |
| 6504 | /* Check that the string size recorded in the string is the | 6495 | /* Check that the string size recorded in the string is the |
| 6505 | same as the one recorded in the sdata structure. */ | 6496 | same as the one recorded in the sdata structure. */ |
| @@ -6640,17 +6631,17 @@ mark_object (Lisp_Object arg) | |||
| 6640 | 6631 | ||
| 6641 | case Lisp_Symbol: | 6632 | case Lisp_Symbol: |
| 6642 | { | 6633 | { |
| 6643 | register struct Lisp_Symbol *ptr = XSYMBOL (obj); | 6634 | struct Lisp_Symbol *ptr = XSYMBOL (obj); |
| 6644 | nextsym: | 6635 | nextsym: |
| 6645 | if (ptr->gcmarkbit) | 6636 | if (ptr->u.s.gcmarkbit) |
| 6646 | break; | 6637 | break; |
| 6647 | CHECK_ALLOCATED_AND_LIVE_SYMBOL (); | 6638 | CHECK_ALLOCATED_AND_LIVE_SYMBOL (); |
| 6648 | ptr->gcmarkbit = 1; | 6639 | ptr->u.s.gcmarkbit = 1; |
| 6649 | /* Attempt to catch bogus objects. */ | 6640 | /* Attempt to catch bogus objects. */ |
| 6650 | eassert (valid_lisp_object_p (ptr->function)); | 6641 | eassert (valid_lisp_object_p (ptr->u.s.function)); |
| 6651 | mark_object (ptr->function); | 6642 | mark_object (ptr->u.s.function); |
| 6652 | mark_object (ptr->plist); | 6643 | mark_object (ptr->u.s.plist); |
| 6653 | switch (ptr->redirect) | 6644 | switch (ptr->u.s.redirect) |
| 6654 | { | 6645 | { |
| 6655 | case SYMBOL_PLAINVAL: mark_object (SYMBOL_VAL (ptr)); break; | 6646 | case SYMBOL_PLAINVAL: mark_object (SYMBOL_VAL (ptr)); break; |
| 6656 | case SYMBOL_VARALIAS: | 6647 | case SYMBOL_VARALIAS: |
| @@ -6671,11 +6662,11 @@ mark_object (Lisp_Object arg) | |||
| 6671 | break; | 6662 | break; |
| 6672 | default: emacs_abort (); | 6663 | default: emacs_abort (); |
| 6673 | } | 6664 | } |
| 6674 | if (!PURE_P (XSTRING (ptr->name))) | 6665 | if (!PURE_P (XSTRING (ptr->u.s.name))) |
| 6675 | MARK_STRING (XSTRING (ptr->name)); | 6666 | MARK_STRING (XSTRING (ptr->u.s.name)); |
| 6676 | MARK_INTERVAL_TREE (string_intervals (ptr->name)); | 6667 | MARK_INTERVAL_TREE (string_intervals (ptr->u.s.name)); |
| 6677 | /* Inner loop to mark next symbol in this bucket, if any. */ | 6668 | /* Inner loop to mark next symbol in this bucket, if any. */ |
| 6678 | po = ptr = ptr->next; | 6669 | po = ptr = ptr->u.s.next; |
| 6679 | if (ptr) | 6670 | if (ptr) |
| 6680 | goto nextsym; | 6671 | goto nextsym; |
| 6681 | } | 6672 | } |
| @@ -6729,14 +6720,14 @@ mark_object (Lisp_Object arg) | |||
| 6729 | CHECK_ALLOCATED_AND_LIVE (live_cons_p); | 6720 | CHECK_ALLOCATED_AND_LIVE (live_cons_p); |
| 6730 | CONS_MARK (ptr); | 6721 | CONS_MARK (ptr); |
| 6731 | /* If the cdr is nil, avoid recursion for the car. */ | 6722 | /* If the cdr is nil, avoid recursion for the car. */ |
| 6732 | if (EQ (ptr->u.cdr, Qnil)) | 6723 | if (EQ (ptr->u.s.u.cdr, Qnil)) |
| 6733 | { | 6724 | { |
| 6734 | obj = ptr->car; | 6725 | obj = ptr->u.s.car; |
| 6735 | cdr_count = 0; | 6726 | cdr_count = 0; |
| 6736 | goto loop; | 6727 | goto loop; |
| 6737 | } | 6728 | } |
| 6738 | mark_object (ptr->car); | 6729 | mark_object (ptr->u.s.car); |
| 6739 | obj = ptr->u.cdr; | 6730 | obj = ptr->u.s.u.cdr; |
| 6740 | cdr_count++; | 6731 | cdr_count++; |
| 6741 | if (cdr_count == mark_object_loop_halt) | 6732 | if (cdr_count == mark_object_loop_halt) |
| 6742 | emacs_abort (); | 6733 | emacs_abort (); |
| @@ -6797,7 +6788,7 @@ survives_gc_p (Lisp_Object obj) | |||
| 6797 | break; | 6788 | break; |
| 6798 | 6789 | ||
| 6799 | case Lisp_Symbol: | 6790 | case Lisp_Symbol: |
| 6800 | survives_p = XSYMBOL (obj)->gcmarkbit; | 6791 | survives_p = XSYMBOL (obj)->u.s.gcmarkbit; |
| 6801 | break; | 6792 | break; |
| 6802 | 6793 | ||
| 6803 | case Lisp_Misc: | 6794 | case Lisp_Misc: |
| @@ -6873,9 +6864,9 @@ sweep_conses (void) | |||
| 6873 | if (!CONS_MARKED_P (&cblk->conses[pos])) | 6864 | if (!CONS_MARKED_P (&cblk->conses[pos])) |
| 6874 | { | 6865 | { |
| 6875 | this_free++; | 6866 | this_free++; |
| 6876 | cblk->conses[pos].u.chain = cons_free_list; | 6867 | cblk->conses[pos].u.s.u.chain = cons_free_list; |
| 6877 | cons_free_list = &cblk->conses[pos]; | 6868 | cons_free_list = &cblk->conses[pos]; |
| 6878 | cons_free_list->car = Vdead; | 6869 | cons_free_list->u.s.car = Vdead; |
| 6879 | } | 6870 | } |
| 6880 | else | 6871 | else |
| 6881 | { | 6872 | { |
| @@ -6894,7 +6885,7 @@ sweep_conses (void) | |||
| 6894 | { | 6885 | { |
| 6895 | *cprev = cblk->next; | 6886 | *cprev = cblk->next; |
| 6896 | /* Unhook from the free list. */ | 6887 | /* Unhook from the free list. */ |
| 6897 | cons_free_list = cblk->conses[0].u.chain; | 6888 | cons_free_list = cblk->conses[0].u.s.u.chain; |
| 6898 | lisp_align_free (cblk); | 6889 | lisp_align_free (cblk); |
| 6899 | } | 6890 | } |
| 6900 | else | 6891 | else |
| @@ -7018,39 +7009,39 @@ sweep_symbols (void) | |||
| 7018 | symbol_free_list = NULL; | 7009 | symbol_free_list = NULL; |
| 7019 | 7010 | ||
| 7020 | for (int i = 0; i < ARRAYELTS (lispsym); i++) | 7011 | for (int i = 0; i < ARRAYELTS (lispsym); i++) |
| 7021 | lispsym[i].s.gcmarkbit = 0; | 7012 | lispsym[i].u.s.gcmarkbit = 0; |
| 7022 | 7013 | ||
| 7023 | for (sblk = symbol_block; sblk; sblk = *sprev) | 7014 | for (sblk = symbol_block; sblk; sblk = *sprev) |
| 7024 | { | 7015 | { |
| 7025 | int this_free = 0; | 7016 | int this_free = 0; |
| 7026 | union aligned_Lisp_Symbol *sym = sblk->symbols; | 7017 | struct Lisp_Symbol *sym = sblk->symbols; |
| 7027 | union aligned_Lisp_Symbol *end = sym + lim; | 7018 | struct Lisp_Symbol *end = sym + lim; |
| 7028 | 7019 | ||
| 7029 | for (; sym < end; ++sym) | 7020 | for (; sym < end; ++sym) |
| 7030 | { | 7021 | { |
| 7031 | if (!sym->s.gcmarkbit) | 7022 | if (!sym->u.s.gcmarkbit) |
| 7032 | { | 7023 | { |
| 7033 | if (sym->s.redirect == SYMBOL_LOCALIZED) | 7024 | if (sym->u.s.redirect == SYMBOL_LOCALIZED) |
| 7034 | { | 7025 | { |
| 7035 | xfree (SYMBOL_BLV (&sym->s)); | 7026 | xfree (SYMBOL_BLV (sym)); |
| 7036 | /* At every GC we sweep all symbol_blocks and rebuild the | 7027 | /* At every GC we sweep all symbol_blocks and rebuild the |
| 7037 | symbol_free_list, so those symbols which stayed unused | 7028 | symbol_free_list, so those symbols which stayed unused |
| 7038 | between the two will be re-swept. | 7029 | between the two will be re-swept. |
| 7039 | So we have to make sure we don't re-free this blv next | 7030 | So we have to make sure we don't re-free this blv next |
| 7040 | time we sweep this symbol_block (bug#29066). */ | 7031 | time we sweep this symbol_block (bug#29066). */ |
| 7041 | sym->s.redirect = SYMBOL_PLAINVAL; | 7032 | sym->u.s.redirect = SYMBOL_PLAINVAL; |
| 7042 | } | 7033 | } |
| 7043 | sym->s.next = symbol_free_list; | 7034 | sym->u.s.next = symbol_free_list; |
| 7044 | symbol_free_list = &sym->s; | 7035 | symbol_free_list = sym; |
| 7045 | symbol_free_list->function = Vdead; | 7036 | symbol_free_list->u.s.function = Vdead; |
| 7046 | ++this_free; | 7037 | ++this_free; |
| 7047 | } | 7038 | } |
| 7048 | else | 7039 | else |
| 7049 | { | 7040 | { |
| 7050 | ++num_used; | 7041 | ++num_used; |
| 7051 | sym->s.gcmarkbit = 0; | 7042 | sym->u.s.gcmarkbit = 0; |
| 7052 | /* Attempt to catch bogus objects. */ | 7043 | /* Attempt to catch bogus objects. */ |
| 7053 | eassert (valid_lisp_object_p (sym->s.function)); | 7044 | eassert (valid_lisp_object_p (sym->u.s.function)); |
| 7054 | } | 7045 | } |
| 7055 | } | 7046 | } |
| 7056 | 7047 | ||
| @@ -7062,7 +7053,7 @@ sweep_symbols (void) | |||
| 7062 | { | 7053 | { |
| 7063 | *sprev = sblk->next; | 7054 | *sprev = sblk->next; |
| 7064 | /* Unhook from the free list. */ | 7055 | /* Unhook from the free list. */ |
| 7065 | symbol_free_list = sblk->symbols[0].s.next; | 7056 | symbol_free_list = sblk->symbols[0].u.s.next; |
| 7066 | lisp_free (sblk); | 7057 | lisp_free (sblk); |
| 7067 | } | 7058 | } |
| 7068 | else | 7059 | else |
| @@ -7289,10 +7280,10 @@ symbol_uses_obj (Lisp_Object symbol, Lisp_Object obj) | |||
| 7289 | struct Lisp_Symbol *sym = XSYMBOL (symbol); | 7280 | struct Lisp_Symbol *sym = XSYMBOL (symbol); |
| 7290 | Lisp_Object val = find_symbol_value (symbol); | 7281 | Lisp_Object val = find_symbol_value (symbol); |
| 7291 | return (EQ (val, obj) | 7282 | return (EQ (val, obj) |
| 7292 | || EQ (sym->function, obj) | 7283 | || EQ (sym->u.s.function, obj) |
| 7293 | || (!NILP (sym->function) | 7284 | || (!NILP (sym->u.s.function) |
| 7294 | && COMPILEDP (sym->function) | 7285 | && COMPILEDP (sym->u.s.function) |
| 7295 | && EQ (AREF (sym->function, COMPILED_BYTECODE), obj)) | 7286 | && EQ (AREF (sym->u.s.function, COMPILED_BYTECODE), obj)) |
| 7296 | || (!NILP (val) | 7287 | || (!NILP (val) |
| 7297 | && COMPILEDP (val) | 7288 | && COMPILEDP (val) |
| 7298 | && EQ (AREF (val, COMPILED_BYTECODE), obj))); | 7289 | && EQ (AREF (val, COMPILED_BYTECODE), obj))); |
| @@ -7323,15 +7314,15 @@ which_symbols (Lisp_Object obj, EMACS_INT find_max) | |||
| 7323 | 7314 | ||
| 7324 | for (sblk = symbol_block; sblk; sblk = sblk->next) | 7315 | for (sblk = symbol_block; sblk; sblk = sblk->next) |
| 7325 | { | 7316 | { |
| 7326 | union aligned_Lisp_Symbol *aligned_sym = sblk->symbols; | 7317 | struct Lisp_Symbol *asym = sblk->symbols; |
| 7327 | int bn; | 7318 | int bn; |
| 7328 | 7319 | ||
| 7329 | for (bn = 0; bn < SYMBOL_BLOCK_SIZE; bn++, aligned_sym++) | 7320 | for (bn = 0; bn < SYMBOL_BLOCK_SIZE; bn++, asym++) |
| 7330 | { | 7321 | { |
| 7331 | if (sblk == symbol_block && bn >= symbol_block_index) | 7322 | if (sblk == symbol_block && bn >= symbol_block_index) |
| 7332 | break; | 7323 | break; |
| 7333 | 7324 | ||
| 7334 | Lisp_Object sym = make_lisp_symbol (&aligned_sym->s); | 7325 | Lisp_Object sym = make_lisp_symbol (asym); |
| 7335 | if (symbol_uses_obj (sym, obj)) | 7326 | if (symbol_uses_obj (sym, obj)) |
| 7336 | { | 7327 | { |
| 7337 | found = Fcons (sym, found); | 7328 | found = Fcons (sym, found); |
diff --git a/src/buffer.c b/src/buffer.c index edeed55e8be..4ae5e811b07 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -61,7 +61,7 @@ struct buffer *all_buffers; | |||
| 61 | Setting the default value also goes through the alist of buffers | 61 | Setting the default value also goes through the alist of buffers |
| 62 | and stores into each buffer that does not say it has a local value. */ | 62 | and stores into each buffer that does not say it has a local value. */ |
| 63 | 63 | ||
| 64 | struct GCALIGNED buffer buffer_defaults; | 64 | struct buffer buffer_defaults; |
| 65 | 65 | ||
| 66 | /* This structure marks which slots in a buffer have corresponding | 66 | /* This structure marks which slots in a buffer have corresponding |
| 67 | default values in buffer_defaults. | 67 | default values in buffer_defaults. |
| @@ -84,7 +84,7 @@ struct buffer buffer_local_flags; | |||
| 84 | /* This structure holds the names of symbols whose values may be | 84 | /* This structure holds the names of symbols whose values may be |
| 85 | buffer-local. It is indexed and accessed in the same way as the above. */ | 85 | buffer-local. It is indexed and accessed in the same way as the above. */ |
| 86 | 86 | ||
| 87 | struct GCALIGNED buffer buffer_local_symbols; | 87 | struct buffer buffer_local_symbols; |
| 88 | 88 | ||
| 89 | /* Return the symbol of the per-buffer variable at offset OFFSET in | 89 | /* Return the symbol of the per-buffer variable at offset OFFSET in |
| 90 | the buffer structure. */ | 90 | the buffer structure. */ |
| @@ -1021,7 +1021,8 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too) | |||
| 1021 | newlist = Fcons (elt, newlist); | 1021 | newlist = Fcons (elt, newlist); |
| 1022 | } | 1022 | } |
| 1023 | newlist = Fnreverse (newlist); | 1023 | newlist = Fnreverse (newlist); |
| 1024 | if (XSYMBOL (local_var)->trapped_write == SYMBOL_TRAPPED_WRITE) | 1024 | if (XSYMBOL (local_var)->u.s.trapped_write |
| 1025 | == SYMBOL_TRAPPED_WRITE) | ||
| 1025 | notify_variable_watchers (local_var, newlist, | 1026 | notify_variable_watchers (local_var, newlist, |
| 1026 | Qmakunbound, Fcurrent_buffer ()); | 1027 | Qmakunbound, Fcurrent_buffer ()); |
| 1027 | XSETCDR (XCAR (tmp), newlist); | 1028 | XSETCDR (XCAR (tmp), newlist); |
| @@ -1034,7 +1035,7 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too) | |||
| 1034 | else | 1035 | else |
| 1035 | XSETCDR (last, XCDR (tmp)); | 1036 | XSETCDR (last, XCDR (tmp)); |
| 1036 | 1037 | ||
| 1037 | if (XSYMBOL (local_var)->trapped_write == SYMBOL_TRAPPED_WRITE) | 1038 | if (XSYMBOL (local_var)->u.s.trapped_write == SYMBOL_TRAPPED_WRITE) |
| 1038 | notify_variable_watchers (local_var, Qnil, | 1039 | notify_variable_watchers (local_var, Qnil, |
| 1039 | Qmakunbound, Fcurrent_buffer ()); | 1040 | Qmakunbound, Fcurrent_buffer ()); |
| 1040 | } | 1041 | } |
| @@ -1166,7 +1167,7 @@ buffer_local_value (Lisp_Object variable, Lisp_Object buffer) | |||
| 1166 | sym = XSYMBOL (variable); | 1167 | sym = XSYMBOL (variable); |
| 1167 | 1168 | ||
| 1168 | start: | 1169 | start: |
| 1169 | switch (sym->redirect) | 1170 | switch (sym->u.s.redirect) |
| 1170 | { | 1171 | { |
| 1171 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; | 1172 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; |
| 1172 | case SYMBOL_PLAINVAL: result = SYMBOL_VAL (sym); break; | 1173 | case SYMBOL_PLAINVAL: result = SYMBOL_VAL (sym); break; |
| @@ -2096,7 +2097,7 @@ void set_buffer_internal_2 (register struct buffer *b) | |||
| 2096 | { | 2097 | { |
| 2097 | Lisp_Object var = XCAR (XCAR (tail)); | 2098 | Lisp_Object var = XCAR (XCAR (tail)); |
| 2098 | struct Lisp_Symbol *sym = XSYMBOL (var); | 2099 | struct Lisp_Symbol *sym = XSYMBOL (var); |
| 2099 | if (sym->redirect == SYMBOL_LOCALIZED /* Just to be sure. */ | 2100 | if (sym->u.s.redirect == SYMBOL_LOCALIZED /* Just to be sure. */ |
| 2100 | && SYMBOL_BLV (sym)->fwd) | 2101 | && SYMBOL_BLV (sym)->fwd) |
| 2101 | /* Just reference the variable | 2102 | /* Just reference the variable |
| 2102 | to cause it to become set for this buffer. */ | 2103 | to cause it to become set for this buffer. */ |
| @@ -2752,7 +2753,7 @@ swap_out_buffer_local_variables (struct buffer *b) | |||
| 2752 | for (alist = oalist; CONSP (alist); alist = XCDR (alist)) | 2753 | for (alist = oalist; CONSP (alist); alist = XCDR (alist)) |
| 2753 | { | 2754 | { |
| 2754 | Lisp_Object sym = XCAR (XCAR (alist)); | 2755 | Lisp_Object sym = XCAR (XCAR (alist)); |
| 2755 | eassert (XSYMBOL (sym)->redirect == SYMBOL_LOCALIZED); | 2756 | eassert (XSYMBOL (sym)->u.s.redirect == SYMBOL_LOCALIZED); |
| 2756 | /* Need not do anything if some other buffer's binding is | 2757 | /* Need not do anything if some other buffer's binding is |
| 2757 | now cached. */ | 2758 | now cached. */ |
| 2758 | if (EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer)) | 2759 | if (EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer)) |
| @@ -5423,8 +5424,8 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring, | |||
| 5423 | bo_fwd->type = Lisp_Fwd_Buffer_Obj; | 5424 | bo_fwd->type = Lisp_Fwd_Buffer_Obj; |
| 5424 | bo_fwd->offset = offset; | 5425 | bo_fwd->offset = offset; |
| 5425 | bo_fwd->predicate = predicate; | 5426 | bo_fwd->predicate = predicate; |
| 5426 | sym->declared_special = 1; | 5427 | sym->u.s.declared_special = true; |
| 5427 | sym->redirect = SYMBOL_FORWARDED; | 5428 | sym->u.s.redirect = SYMBOL_FORWARDED; |
| 5428 | SET_SYMBOL_FWD (sym, (union Lisp_Fwd *) bo_fwd); | 5429 | SET_SYMBOL_FWD (sym, (union Lisp_Fwd *) bo_fwd); |
| 5429 | XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym); | 5430 | XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym); |
| 5430 | 5431 | ||
diff --git a/src/bytecode.c b/src/bytecode.c index 50c7abe2891..ebaf3c3a7fc 100644 --- a/src/bytecode.c +++ b/src/bytecode.c | |||
| @@ -489,7 +489,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 489 | { | 489 | { |
| 490 | Lisp_Object v1 = vectorp[op], v2; | 490 | Lisp_Object v1 = vectorp[op], v2; |
| 491 | if (!SYMBOLP (v1) | 491 | if (!SYMBOLP (v1) |
| 492 | || XSYMBOL (v1)->redirect != SYMBOL_PLAINVAL | 492 | || XSYMBOL (v1)->u.s.redirect != SYMBOL_PLAINVAL |
| 493 | || (v2 = SYMBOL_VAL (XSYMBOL (v1)), EQ (v2, Qunbound))) | 493 | || (v2 = SYMBOL_VAL (XSYMBOL (v1)), EQ (v2, Qunbound))) |
| 494 | v2 = Fsymbol_value (v1); | 494 | v2 = Fsymbol_value (v1); |
| 495 | PUSH (v2); | 495 | PUSH (v2); |
| @@ -558,7 +558,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, | |||
| 558 | /* Inline the most common case. */ | 558 | /* Inline the most common case. */ |
| 559 | if (SYMBOLP (sym) | 559 | if (SYMBOLP (sym) |
| 560 | && !EQ (val, Qunbound) | 560 | && !EQ (val, Qunbound) |
| 561 | && !XSYMBOL (sym)->redirect | 561 | && !XSYMBOL (sym)->u.s.redirect |
| 562 | && !SYMBOL_TRAPPED_WRITE_P (sym)) | 562 | && !SYMBOL_TRAPPED_WRITE_P (sym)) |
| 563 | SET_SYMBOL_VAL (XSYMBOL (sym), val); | 563 | SET_SYMBOL_VAL (XSYMBOL (sym), val); |
| 564 | else | 564 | else |
diff --git a/src/casefiddle.c b/src/casefiddle.c index 8f564edeb95..7b34f78a5c9 100644 --- a/src/casefiddle.c +++ b/src/casefiddle.c | |||
| @@ -133,9 +133,9 @@ case_character_impl (struct casing_str_buf *buf, | |||
| 133 | struct Lisp_String *str = XSTRING (prop); | 133 | struct Lisp_String *str = XSTRING (prop); |
| 134 | if (STRING_BYTES (str) <= sizeof buf->data) | 134 | if (STRING_BYTES (str) <= sizeof buf->data) |
| 135 | { | 135 | { |
| 136 | buf->len_chars = str->size; | 136 | buf->len_chars = str->u.s.size; |
| 137 | buf->len_bytes = STRING_BYTES (str); | 137 | buf->len_bytes = STRING_BYTES (str); |
| 138 | memcpy (buf->data, str->data, buf->len_bytes); | 138 | memcpy (buf->data, str->u.s.data, buf->len_bytes); |
| 139 | return 1; | 139 | return 1; |
| 140 | } | 140 | } |
| 141 | } | 141 | } |
diff --git a/src/cmds.c b/src/cmds.c index e4c0c866916..1788f22fe57 100644 --- a/src/cmds.c +++ b/src/cmds.c | |||
| @@ -421,11 +421,11 @@ internal_self_insert (int c, EMACS_INT n) | |||
| 421 | and the hook has a non-nil `no-self-insert' property, | 421 | and the hook has a non-nil `no-self-insert' property, |
| 422 | return right away--don't really self-insert. */ | 422 | return right away--don't really self-insert. */ |
| 423 | if (SYMBOLP (sym) && ! NILP (sym) | 423 | if (SYMBOLP (sym) && ! NILP (sym) |
| 424 | && ! NILP (XSYMBOL (sym)->function) | 424 | && ! NILP (XSYMBOL (sym)->u.s.function) |
| 425 | && SYMBOLP (XSYMBOL (sym)->function)) | 425 | && SYMBOLP (XSYMBOL (sym)->u.s.function)) |
| 426 | { | 426 | { |
| 427 | Lisp_Object prop; | 427 | Lisp_Object prop; |
| 428 | prop = Fget (XSYMBOL (sym)->function, intern ("no-self-insert")); | 428 | prop = Fget (XSYMBOL (sym)->u.s.function, intern ("no-self-insert")); |
| 429 | if (! NILP (prop)) | 429 | if (! NILP (prop)) |
| 430 | return 1; | 430 | return 1; |
| 431 | } | 431 | } |
diff --git a/src/data.c b/src/data.c index ef7210fbfa0..b4f6fd5c652 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -670,7 +670,7 @@ global value outside of any lexical scope. */) | |||
| 670 | sym = XSYMBOL (symbol); | 670 | sym = XSYMBOL (symbol); |
| 671 | 671 | ||
| 672 | start: | 672 | start: |
| 673 | switch (sym->redirect) | 673 | switch (sym->u.s.redirect) |
| 674 | { | 674 | { |
| 675 | case SYMBOL_PLAINVAL: valcontents = SYMBOL_VAL (sym); break; | 675 | case SYMBOL_PLAINVAL: valcontents = SYMBOL_VAL (sym); break; |
| 676 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; | 676 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; |
| @@ -704,10 +704,10 @@ global value outside of any lexical scope. */) | |||
| 704 | expect `t' in particular, rather than any true value. */ | 704 | expect `t' in particular, rather than any true value. */ |
| 705 | DEFUN ("fboundp", Ffboundp, Sfboundp, 1, 1, 0, | 705 | DEFUN ("fboundp", Ffboundp, Sfboundp, 1, 1, 0, |
| 706 | doc: /* Return t if SYMBOL's function definition is not void. */) | 706 | doc: /* Return t if SYMBOL's function definition is not void. */) |
| 707 | (register Lisp_Object symbol) | 707 | (Lisp_Object symbol) |
| 708 | { | 708 | { |
| 709 | CHECK_SYMBOL (symbol); | 709 | CHECK_SYMBOL (symbol); |
| 710 | return NILP (XSYMBOL (symbol)->function) ? Qnil : Qt; | 710 | return NILP (XSYMBOL (symbol)->u.s.function) ? Qnil : Qt; |
| 711 | } | 711 | } |
| 712 | 712 | ||
| 713 | DEFUN ("makunbound", Fmakunbound, Smakunbound, 1, 1, 0, | 713 | DEFUN ("makunbound", Fmakunbound, Smakunbound, 1, 1, 0, |
| @@ -736,18 +736,18 @@ Return SYMBOL. */) | |||
| 736 | 736 | ||
| 737 | DEFUN ("symbol-function", Fsymbol_function, Ssymbol_function, 1, 1, 0, | 737 | DEFUN ("symbol-function", Fsymbol_function, Ssymbol_function, 1, 1, 0, |
| 738 | doc: /* Return SYMBOL's function definition, or nil if that is void. */) | 738 | doc: /* Return SYMBOL's function definition, or nil if that is void. */) |
| 739 | (register Lisp_Object symbol) | 739 | (Lisp_Object symbol) |
| 740 | { | 740 | { |
| 741 | CHECK_SYMBOL (symbol); | 741 | CHECK_SYMBOL (symbol); |
| 742 | return XSYMBOL (symbol)->function; | 742 | return XSYMBOL (symbol)->u.s.function; |
| 743 | } | 743 | } |
| 744 | 744 | ||
| 745 | DEFUN ("symbol-plist", Fsymbol_plist, Ssymbol_plist, 1, 1, 0, | 745 | DEFUN ("symbol-plist", Fsymbol_plist, Ssymbol_plist, 1, 1, 0, |
| 746 | doc: /* Return SYMBOL's property list. */) | 746 | doc: /* Return SYMBOL's property list. */) |
| 747 | (register Lisp_Object symbol) | 747 | (Lisp_Object symbol) |
| 748 | { | 748 | { |
| 749 | CHECK_SYMBOL (symbol); | 749 | CHECK_SYMBOL (symbol); |
| 750 | return XSYMBOL (symbol)->plist; | 750 | return XSYMBOL (symbol)->u.s.plist; |
| 751 | } | 751 | } |
| 752 | 752 | ||
| 753 | DEFUN ("symbol-name", Fsymbol_name, Ssymbol_name, 1, 1, 0, | 753 | DEFUN ("symbol-name", Fsymbol_name, Ssymbol_name, 1, 1, 0, |
| @@ -771,7 +771,7 @@ DEFUN ("fset", Ffset, Sfset, 2, 2, 0, | |||
| 771 | if (NILP (symbol)) | 771 | if (NILP (symbol)) |
| 772 | xsignal1 (Qsetting_constant, symbol); | 772 | xsignal1 (Qsetting_constant, symbol); |
| 773 | 773 | ||
| 774 | function = XSYMBOL (symbol)->function; | 774 | function = XSYMBOL (symbol)->u.s.function; |
| 775 | 775 | ||
| 776 | if (!NILP (Vautoload_queue) && !NILP (function)) | 776 | if (!NILP (Vautoload_queue) && !NILP (function)) |
| 777 | Vautoload_queue = Fcons (Fcons (symbol, function), Vautoload_queue); | 777 | Vautoload_queue = Fcons (Fcons (symbol, function), Vautoload_queue); |
| @@ -814,7 +814,7 @@ The return value is undefined. */) | |||
| 814 | { /* Only add autoload entries after dumping, because the ones before are | 814 | { /* Only add autoload entries after dumping, because the ones before are |
| 815 | not useful and else we get loads of them from the loaddefs.el. */ | 815 | not useful and else we get loads of them from the loaddefs.el. */ |
| 816 | 816 | ||
| 817 | if (AUTOLOADP (XSYMBOL (symbol)->function)) | 817 | if (AUTOLOADP (XSYMBOL (symbol)->u.s.function)) |
| 818 | /* Remember that the function was already an autoload. */ | 818 | /* Remember that the function was already an autoload. */ |
| 819 | LOADHIST_ATTACH (Fcons (Qt, symbol)); | 819 | LOADHIST_ATTACH (Fcons (Qt, symbol)); |
| 820 | LOADHIST_ATTACH (Fcons (autoload ? Qautoload : Qdefun, symbol)); | 820 | LOADHIST_ATTACH (Fcons (autoload ? Qautoload : Qdefun, symbol)); |
| @@ -940,10 +940,10 @@ indirect_variable (struct Lisp_Symbol *symbol) | |||
| 940 | 940 | ||
| 941 | hare = tortoise = symbol; | 941 | hare = tortoise = symbol; |
| 942 | 942 | ||
| 943 | while (hare->redirect == SYMBOL_VARALIAS) | 943 | while (hare->u.s.redirect == SYMBOL_VARALIAS) |
| 944 | { | 944 | { |
| 945 | hare = SYMBOL_ALIAS (hare); | 945 | hare = SYMBOL_ALIAS (hare); |
| 946 | if (hare->redirect != SYMBOL_VARALIAS) | 946 | if (hare->u.s.redirect != SYMBOL_VARALIAS) |
| 947 | break; | 947 | break; |
| 948 | 948 | ||
| 949 | hare = SYMBOL_ALIAS (hare); | 949 | hare = SYMBOL_ALIAS (hare); |
| @@ -1247,7 +1247,7 @@ find_symbol_value (Lisp_Object symbol) | |||
| 1247 | sym = XSYMBOL (symbol); | 1247 | sym = XSYMBOL (symbol); |
| 1248 | 1248 | ||
| 1249 | start: | 1249 | start: |
| 1250 | switch (sym->redirect) | 1250 | switch (sym->u.s.redirect) |
| 1251 | { | 1251 | { |
| 1252 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; | 1252 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; |
| 1253 | case SYMBOL_PLAINVAL: return SYMBOL_VAL (sym); | 1253 | case SYMBOL_PLAINVAL: return SYMBOL_VAL (sym); |
| @@ -1310,7 +1310,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where, | |||
| 1310 | 1310 | ||
| 1311 | CHECK_SYMBOL (symbol); | 1311 | CHECK_SYMBOL (symbol); |
| 1312 | sym = XSYMBOL (symbol); | 1312 | sym = XSYMBOL (symbol); |
| 1313 | switch (sym->trapped_write) | 1313 | switch (sym->u.s.trapped_write) |
| 1314 | { | 1314 | { |
| 1315 | case SYMBOL_NOWRITE: | 1315 | case SYMBOL_NOWRITE: |
| 1316 | if (NILP (Fkeywordp (symbol)) | 1316 | if (NILP (Fkeywordp (symbol)) |
| @@ -1336,7 +1336,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where, | |||
| 1336 | } | 1336 | } |
| 1337 | 1337 | ||
| 1338 | start: | 1338 | start: |
| 1339 | switch (sym->redirect) | 1339 | switch (sym->u.s.redirect) |
| 1340 | { | 1340 | { |
| 1341 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; | 1341 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; |
| 1342 | case SYMBOL_PLAINVAL: SET_SYMBOL_VAL (sym , newval); return; | 1342 | case SYMBOL_PLAINVAL: SET_SYMBOL_VAL (sym , newval); return; |
| @@ -1436,7 +1436,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where, | |||
| 1436 | if (voide) | 1436 | if (voide) |
| 1437 | { /* If storing void (making the symbol void), forward only through | 1437 | { /* If storing void (making the symbol void), forward only through |
| 1438 | buffer-local indicator, not through Lisp_Objfwd, etc. */ | 1438 | buffer-local indicator, not through Lisp_Objfwd, etc. */ |
| 1439 | sym->redirect = SYMBOL_PLAINVAL; | 1439 | sym->u.s.redirect = SYMBOL_PLAINVAL; |
| 1440 | SET_SYMBOL_VAL (sym, newval); | 1440 | SET_SYMBOL_VAL (sym, newval); |
| 1441 | } | 1441 | } |
| 1442 | else | 1442 | else |
| @@ -1452,9 +1452,9 @@ static void | |||
| 1452 | set_symbol_trapped_write (Lisp_Object symbol, enum symbol_trapped_write trap) | 1452 | set_symbol_trapped_write (Lisp_Object symbol, enum symbol_trapped_write trap) |
| 1453 | { | 1453 | { |
| 1454 | struct Lisp_Symbol *sym = XSYMBOL (symbol); | 1454 | struct Lisp_Symbol *sym = XSYMBOL (symbol); |
| 1455 | if (sym->trapped_write == SYMBOL_NOWRITE) | 1455 | if (sym->u.s.trapped_write == SYMBOL_NOWRITE) |
| 1456 | xsignal1 (Qtrapping_constant, symbol); | 1456 | xsignal1 (Qtrapping_constant, symbol); |
| 1457 | sym->trapped_write = trap; | 1457 | sym->u.s.trapped_write = trap; |
| 1458 | } | 1458 | } |
| 1459 | 1459 | ||
| 1460 | static void | 1460 | static void |
| @@ -1469,7 +1469,7 @@ harmonize_variable_watchers (Lisp_Object alias, Lisp_Object base_variable) | |||
| 1469 | if (!EQ (base_variable, alias) | 1469 | if (!EQ (base_variable, alias) |
| 1470 | && EQ (base_variable, Findirect_variable (alias))) | 1470 | && EQ (base_variable, Findirect_variable (alias))) |
| 1471 | set_symbol_trapped_write | 1471 | set_symbol_trapped_write |
| 1472 | (alias, XSYMBOL (base_variable)->trapped_write); | 1472 | (alias, XSYMBOL (base_variable)->u.s.trapped_write); |
| 1473 | } | 1473 | } |
| 1474 | 1474 | ||
| 1475 | DEFUN ("add-variable-watcher", Fadd_variable_watcher, Sadd_variable_watcher, | 1475 | DEFUN ("add-variable-watcher", Fadd_variable_watcher, Sadd_variable_watcher, |
| @@ -1583,7 +1583,7 @@ default_value (Lisp_Object symbol) | |||
| 1583 | sym = XSYMBOL (symbol); | 1583 | sym = XSYMBOL (symbol); |
| 1584 | 1584 | ||
| 1585 | start: | 1585 | start: |
| 1586 | switch (sym->redirect) | 1586 | switch (sym->u.s.redirect) |
| 1587 | { | 1587 | { |
| 1588 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; | 1588 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; |
| 1589 | case SYMBOL_PLAINVAL: return SYMBOL_VAL (sym); | 1589 | case SYMBOL_PLAINVAL: return SYMBOL_VAL (sym); |
| @@ -1653,7 +1653,7 @@ set_default_internal (Lisp_Object symbol, Lisp_Object value, | |||
| 1653 | 1653 | ||
| 1654 | CHECK_SYMBOL (symbol); | 1654 | CHECK_SYMBOL (symbol); |
| 1655 | sym = XSYMBOL (symbol); | 1655 | sym = XSYMBOL (symbol); |
| 1656 | switch (sym->trapped_write) | 1656 | switch (sym->u.s.trapped_write) |
| 1657 | { | 1657 | { |
| 1658 | case SYMBOL_NOWRITE: | 1658 | case SYMBOL_NOWRITE: |
| 1659 | if (NILP (Fkeywordp (symbol)) | 1659 | if (NILP (Fkeywordp (symbol)) |
| @@ -1665,7 +1665,7 @@ set_default_internal (Lisp_Object symbol, Lisp_Object value, | |||
| 1665 | 1665 | ||
| 1666 | case SYMBOL_TRAPPED_WRITE: | 1666 | case SYMBOL_TRAPPED_WRITE: |
| 1667 | /* Don't notify here if we're going to call Fset anyway. */ | 1667 | /* Don't notify here if we're going to call Fset anyway. */ |
| 1668 | if (sym->redirect != SYMBOL_PLAINVAL | 1668 | if (sym->u.s.redirect != SYMBOL_PLAINVAL |
| 1669 | /* Setting due to thread switching doesn't count. */ | 1669 | /* Setting due to thread switching doesn't count. */ |
| 1670 | && bindflag != SET_INTERNAL_THREAD_SWITCH) | 1670 | && bindflag != SET_INTERNAL_THREAD_SWITCH) |
| 1671 | notify_variable_watchers (symbol, value, Qset_default, Qnil); | 1671 | notify_variable_watchers (symbol, value, Qset_default, Qnil); |
| @@ -1677,7 +1677,7 @@ set_default_internal (Lisp_Object symbol, Lisp_Object value, | |||
| 1677 | } | 1677 | } |
| 1678 | 1678 | ||
| 1679 | start: | 1679 | start: |
| 1680 | switch (sym->redirect) | 1680 | switch (sym->u.s.redirect) |
| 1681 | { | 1681 | { |
| 1682 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; | 1682 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; |
| 1683 | case SYMBOL_PLAINVAL: set_internal (symbol, value, Qnil, bindflag); return; | 1683 | case SYMBOL_PLAINVAL: set_internal (symbol, value, Qnil, bindflag); return; |
| @@ -1829,7 +1829,7 @@ The function `default-value' gets the default value and `set-default' sets it. | |||
| 1829 | sym = XSYMBOL (variable); | 1829 | sym = XSYMBOL (variable); |
| 1830 | 1830 | ||
| 1831 | start: | 1831 | start: |
| 1832 | switch (sym->redirect) | 1832 | switch (sym->u.s.redirect) |
| 1833 | { | 1833 | { |
| 1834 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; | 1834 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; |
| 1835 | case SYMBOL_PLAINVAL: | 1835 | case SYMBOL_PLAINVAL: |
| @@ -1857,7 +1857,7 @@ The function `default-value' gets the default value and `set-default' sets it. | |||
| 1857 | if (!blv) | 1857 | if (!blv) |
| 1858 | { | 1858 | { |
| 1859 | blv = make_blv (sym, forwarded, valcontents); | 1859 | blv = make_blv (sym, forwarded, valcontents); |
| 1860 | sym->redirect = SYMBOL_LOCALIZED; | 1860 | sym->u.s.redirect = SYMBOL_LOCALIZED; |
| 1861 | SET_SYMBOL_BLV (sym, blv); | 1861 | SET_SYMBOL_BLV (sym, blv); |
| 1862 | } | 1862 | } |
| 1863 | 1863 | ||
| @@ -1897,7 +1897,7 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */) | |||
| 1897 | sym = XSYMBOL (variable); | 1897 | sym = XSYMBOL (variable); |
| 1898 | 1898 | ||
| 1899 | start: | 1899 | start: |
| 1900 | switch (sym->redirect) | 1900 | switch (sym->u.s.redirect) |
| 1901 | { | 1901 | { |
| 1902 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; | 1902 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; |
| 1903 | case SYMBOL_PLAINVAL: | 1903 | case SYMBOL_PLAINVAL: |
| @@ -1914,7 +1914,7 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */) | |||
| 1914 | default: emacs_abort (); | 1914 | default: emacs_abort (); |
| 1915 | } | 1915 | } |
| 1916 | 1916 | ||
| 1917 | if (sym->trapped_write == SYMBOL_NOWRITE) | 1917 | if (sym->u.s.trapped_write == SYMBOL_NOWRITE) |
| 1918 | error ("Symbol %s may not be buffer-local", | 1918 | error ("Symbol %s may not be buffer-local", |
| 1919 | SDATA (SYMBOL_NAME (variable))); | 1919 | SDATA (SYMBOL_NAME (variable))); |
| 1920 | 1920 | ||
| @@ -1930,7 +1930,7 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */) | |||
| 1930 | if (!blv) | 1930 | if (!blv) |
| 1931 | { | 1931 | { |
| 1932 | blv = make_blv (sym, forwarded, valcontents); | 1932 | blv = make_blv (sym, forwarded, valcontents); |
| 1933 | sym->redirect = SYMBOL_LOCALIZED; | 1933 | sym->u.s.redirect = SYMBOL_LOCALIZED; |
| 1934 | SET_SYMBOL_BLV (sym, blv); | 1934 | SET_SYMBOL_BLV (sym, blv); |
| 1935 | } | 1935 | } |
| 1936 | 1936 | ||
| @@ -1987,7 +1987,7 @@ From now on the default value will apply in this buffer. Return VARIABLE. */) | |||
| 1987 | sym = XSYMBOL (variable); | 1987 | sym = XSYMBOL (variable); |
| 1988 | 1988 | ||
| 1989 | start: | 1989 | start: |
| 1990 | switch (sym->redirect) | 1990 | switch (sym->u.s.redirect) |
| 1991 | { | 1991 | { |
| 1992 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; | 1992 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; |
| 1993 | case SYMBOL_PLAINVAL: return variable; | 1993 | case SYMBOL_PLAINVAL: return variable; |
| @@ -2014,7 +2014,7 @@ From now on the default value will apply in this buffer. Return VARIABLE. */) | |||
| 2014 | default: emacs_abort (); | 2014 | default: emacs_abort (); |
| 2015 | } | 2015 | } |
| 2016 | 2016 | ||
| 2017 | if (sym->trapped_write == SYMBOL_TRAPPED_WRITE) | 2017 | if (sym->u.s.trapped_write == SYMBOL_TRAPPED_WRITE) |
| 2018 | notify_variable_watchers (variable, Qnil, Qmakunbound, Fcurrent_buffer ()); | 2018 | notify_variable_watchers (variable, Qnil, Qmakunbound, Fcurrent_buffer ()); |
| 2019 | 2019 | ||
| 2020 | /* Get rid of this buffer's alist element, if any. */ | 2020 | /* Get rid of this buffer's alist element, if any. */ |
| @@ -2056,7 +2056,7 @@ BUFFER defaults to the current buffer. */) | |||
| 2056 | sym = XSYMBOL (variable); | 2056 | sym = XSYMBOL (variable); |
| 2057 | 2057 | ||
| 2058 | start: | 2058 | start: |
| 2059 | switch (sym->redirect) | 2059 | switch (sym->u.s.redirect) |
| 2060 | { | 2060 | { |
| 2061 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; | 2061 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; |
| 2062 | case SYMBOL_PLAINVAL: return Qnil; | 2062 | case SYMBOL_PLAINVAL: return Qnil; |
| @@ -2110,7 +2110,7 @@ value in BUFFER, or if VARIABLE is automatically buffer-local (see | |||
| 2110 | sym = XSYMBOL (variable); | 2110 | sym = XSYMBOL (variable); |
| 2111 | 2111 | ||
| 2112 | start: | 2112 | start: |
| 2113 | switch (sym->redirect) | 2113 | switch (sym->u.s.redirect) |
| 2114 | { | 2114 | { |
| 2115 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; | 2115 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; |
| 2116 | case SYMBOL_PLAINVAL: return Qnil; | 2116 | case SYMBOL_PLAINVAL: return Qnil; |
| @@ -2145,7 +2145,7 @@ If the current binding is global (the default), the value is nil. */) | |||
| 2145 | find_symbol_value (variable); | 2145 | find_symbol_value (variable); |
| 2146 | 2146 | ||
| 2147 | start: | 2147 | start: |
| 2148 | switch (sym->redirect) | 2148 | switch (sym->u.s.redirect) |
| 2149 | { | 2149 | { |
| 2150 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; | 2150 | case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; |
| 2151 | case SYMBOL_PLAINVAL: return Qnil; | 2151 | case SYMBOL_PLAINVAL: return Qnil; |
| @@ -2163,7 +2163,7 @@ If the current binding is global (the default), the value is nil. */) | |||
| 2163 | buffer's or frame's value we are saving. */ | 2163 | buffer's or frame's value we are saving. */ |
| 2164 | if (!NILP (Flocal_variable_p (variable, Qnil))) | 2164 | if (!NILP (Flocal_variable_p (variable, Qnil))) |
| 2165 | return Fcurrent_buffer (); | 2165 | return Fcurrent_buffer (); |
| 2166 | else if (sym->redirect == SYMBOL_LOCALIZED | 2166 | else if (sym->u.s.redirect == SYMBOL_LOCALIZED |
| 2167 | && blv_found (SYMBOL_BLV (sym))) | 2167 | && blv_found (SYMBOL_BLV (sym))) |
| 2168 | return SYMBOL_BLV (sym)->where; | 2168 | return SYMBOL_BLV (sym)->where; |
| 2169 | else | 2169 | else |
| @@ -2234,12 +2234,12 @@ indirect_function (register Lisp_Object object) | |||
| 2234 | { | 2234 | { |
| 2235 | if (!SYMBOLP (hare) || NILP (hare)) | 2235 | if (!SYMBOLP (hare) || NILP (hare)) |
| 2236 | break; | 2236 | break; |
| 2237 | hare = XSYMBOL (hare)->function; | 2237 | hare = XSYMBOL (hare)->u.s.function; |
| 2238 | if (!SYMBOLP (hare) || NILP (hare)) | 2238 | if (!SYMBOLP (hare) || NILP (hare)) |
| 2239 | break; | 2239 | break; |
| 2240 | hare = XSYMBOL (hare)->function; | 2240 | hare = XSYMBOL (hare)->u.s.function; |
| 2241 | 2241 | ||
| 2242 | tortoise = XSYMBOL (tortoise)->function; | 2242 | tortoise = XSYMBOL (tortoise)->u.s.function; |
| 2243 | 2243 | ||
| 2244 | if (EQ (hare, tortoise)) | 2244 | if (EQ (hare, tortoise)) |
| 2245 | xsignal1 (Qcyclic_function_indirection, object); | 2245 | xsignal1 (Qcyclic_function_indirection, object); |
| @@ -2261,7 +2261,7 @@ function chain of symbols. */) | |||
| 2261 | /* Optimize for no indirection. */ | 2261 | /* Optimize for no indirection. */ |
| 2262 | result = object; | 2262 | result = object; |
| 2263 | if (SYMBOLP (result) && !NILP (result) | 2263 | if (SYMBOLP (result) && !NILP (result) |
| 2264 | && (result = XSYMBOL (result)->function, SYMBOLP (result))) | 2264 | && (result = XSYMBOL (result)->u.s.function, SYMBOLP (result))) |
| 2265 | result = indirect_function (result); | 2265 | result = indirect_function (result); |
| 2266 | if (!NILP (result)) | 2266 | if (!NILP (result)) |
| 2267 | return result; | 2267 | return result; |
| @@ -3877,7 +3877,7 @@ syms_of_data (void) | |||
| 3877 | defsubr (&Sbool_vector_count_consecutive); | 3877 | defsubr (&Sbool_vector_count_consecutive); |
| 3878 | defsubr (&Sbool_vector_count_population); | 3878 | defsubr (&Sbool_vector_count_population); |
| 3879 | 3879 | ||
| 3880 | set_symbol_function (Qwholenump, XSYMBOL (Qnatnump)->function); | 3880 | set_symbol_function (Qwholenump, XSYMBOL (Qnatnump)->u.s.function); |
| 3881 | 3881 | ||
| 3882 | DEFVAR_LISP ("most-positive-fixnum", Vmost_positive_fixnum, | 3882 | DEFVAR_LISP ("most-positive-fixnum", Vmost_positive_fixnum, |
| 3883 | doc: /* The largest value that is representable in a Lisp integer. */); | 3883 | doc: /* The largest value that is representable in a Lisp integer. */); |
| @@ -472,7 +472,7 @@ store_function_docstring (Lisp_Object obj, EMACS_INT offset) | |||
| 472 | { | 472 | { |
| 473 | /* Don't use indirect_function here, or defaliases will apply their | 473 | /* Don't use indirect_function here, or defaliases will apply their |
| 474 | docstrings to the base functions (Bug#2603). */ | 474 | docstrings to the base functions (Bug#2603). */ |
| 475 | Lisp_Object fun = SYMBOLP (obj) ? XSYMBOL (obj)->function : obj; | 475 | Lisp_Object fun = SYMBOLP (obj) ? XSYMBOL (obj)->u.s.function : obj; |
| 476 | 476 | ||
| 477 | /* The type determines where the docstring is stored. */ | 477 | /* The type determines where the docstring is stored. */ |
| 478 | 478 | ||
diff --git a/src/eval.c b/src/eval.c index 52e4c96d4b2..40b47968be2 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -603,7 +603,7 @@ The return value is BASE-VARIABLE. */) | |||
| 603 | 603 | ||
| 604 | sym = XSYMBOL (new_alias); | 604 | sym = XSYMBOL (new_alias); |
| 605 | 605 | ||
| 606 | switch (sym->redirect) | 606 | switch (sym->u.s.redirect) |
| 607 | { | 607 | { |
| 608 | case SYMBOL_FORWARDED: | 608 | case SYMBOL_FORWARDED: |
| 609 | error ("Cannot make an internal variable an alias"); | 609 | error ("Cannot make an internal variable an alias"); |
| @@ -632,14 +632,14 @@ The return value is BASE-VARIABLE. */) | |||
| 632 | error ("Don't know how to make a let-bound variable an alias"); | 632 | error ("Don't know how to make a let-bound variable an alias"); |
| 633 | } | 633 | } |
| 634 | 634 | ||
| 635 | if (sym->trapped_write == SYMBOL_TRAPPED_WRITE) | 635 | if (sym->u.s.trapped_write == SYMBOL_TRAPPED_WRITE) |
| 636 | notify_variable_watchers (new_alias, base_variable, Qdefvaralias, Qnil); | 636 | notify_variable_watchers (new_alias, base_variable, Qdefvaralias, Qnil); |
| 637 | 637 | ||
| 638 | sym->declared_special = 1; | 638 | sym->u.s.declared_special = true; |
| 639 | XSYMBOL (base_variable)->declared_special = 1; | 639 | XSYMBOL (base_variable)->u.s.declared_special = true; |
| 640 | sym->redirect = SYMBOL_VARALIAS; | 640 | sym->u.s.redirect = SYMBOL_VARALIAS; |
| 641 | SET_SYMBOL_ALIAS (sym, XSYMBOL (base_variable)); | 641 | SET_SYMBOL_ALIAS (sym, XSYMBOL (base_variable)); |
| 642 | sym->trapped_write = XSYMBOL (base_variable)->trapped_write; | 642 | sym->u.s.trapped_write = XSYMBOL (base_variable)->u.s.trapped_write; |
| 643 | LOADHIST_ATTACH (new_alias); | 643 | LOADHIST_ATTACH (new_alias); |
| 644 | /* Even if docstring is nil: remove old docstring. */ | 644 | /* Even if docstring is nil: remove old docstring. */ |
| 645 | Fput (new_alias, Qvariable_documentation, docstring); | 645 | Fput (new_alias, Qvariable_documentation, docstring); |
| @@ -745,7 +745,7 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) | |||
| 745 | tem = Fdefault_boundp (sym); | 745 | tem = Fdefault_boundp (sym); |
| 746 | 746 | ||
| 747 | /* Do it before evaluating the initial value, for self-references. */ | 747 | /* Do it before evaluating the initial value, for self-references. */ |
| 748 | XSYMBOL (sym)->declared_special = 1; | 748 | XSYMBOL (sym)->u.s.declared_special = true; |
| 749 | 749 | ||
| 750 | if (NILP (tem)) | 750 | if (NILP (tem)) |
| 751 | Fset_default (sym, eval_sub (XCAR (tail))); | 751 | Fset_default (sym, eval_sub (XCAR (tail))); |
| @@ -769,7 +769,7 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) | |||
| 769 | LOADHIST_ATTACH (sym); | 769 | LOADHIST_ATTACH (sym); |
| 770 | } | 770 | } |
| 771 | else if (!NILP (Vinternal_interpreter_environment) | 771 | else if (!NILP (Vinternal_interpreter_environment) |
| 772 | && !XSYMBOL (sym)->declared_special) | 772 | && !XSYMBOL (sym)->u.s.declared_special) |
| 773 | /* A simple (defvar foo) with lexical scoping does "nothing" except | 773 | /* A simple (defvar foo) with lexical scoping does "nothing" except |
| 774 | declare that var to be dynamically scoped *locally* (i.e. within | 774 | declare that var to be dynamically scoped *locally* (i.e. within |
| 775 | the current file or let-block). */ | 775 | the current file or let-block). */ |
| @@ -818,7 +818,7 @@ usage: (defconst SYMBOL INITVALUE [DOCSTRING]) */) | |||
| 818 | if (!NILP (Vpurify_flag)) | 818 | if (!NILP (Vpurify_flag)) |
| 819 | tem = Fpurecopy (tem); | 819 | tem = Fpurecopy (tem); |
| 820 | Fset_default (sym, tem); | 820 | Fset_default (sym, tem); |
| 821 | XSYMBOL (sym)->declared_special = 1; | 821 | XSYMBOL (sym)->u.s.declared_special = true; |
| 822 | if (!NILP (docstring)) | 822 | if (!NILP (docstring)) |
| 823 | { | 823 | { |
| 824 | if (!NILP (Vpurify_flag)) | 824 | if (!NILP (Vpurify_flag)) |
| @@ -837,7 +837,7 @@ DEFUN ("internal-make-var-non-special", Fmake_var_non_special, | |||
| 837 | (Lisp_Object symbol) | 837 | (Lisp_Object symbol) |
| 838 | { | 838 | { |
| 839 | CHECK_SYMBOL (symbol); | 839 | CHECK_SYMBOL (symbol); |
| 840 | XSYMBOL (symbol)->declared_special = 0; | 840 | XSYMBOL (symbol)->u.s.declared_special = false; |
| 841 | return Qnil; | 841 | return Qnil; |
| 842 | } | 842 | } |
| 843 | 843 | ||
| @@ -877,7 +877,7 @@ usage: (let* VARLIST BODY...) */) | |||
| 877 | } | 877 | } |
| 878 | 878 | ||
| 879 | if (!NILP (lexenv) && SYMBOLP (var) | 879 | if (!NILP (lexenv) && SYMBOLP (var) |
| 880 | && !XSYMBOL (var)->declared_special | 880 | && !XSYMBOL (var)->u.s.declared_special |
| 881 | && NILP (Fmemq (var, Vinternal_interpreter_environment))) | 881 | && NILP (Fmemq (var, Vinternal_interpreter_environment))) |
| 882 | /* Lexically bind VAR by adding it to the interpreter's binding | 882 | /* Lexically bind VAR by adding it to the interpreter's binding |
| 883 | alist. */ | 883 | alist. */ |
| @@ -953,7 +953,7 @@ usage: (let VARLIST BODY...) */) | |||
| 953 | tem = temps[argnum]; | 953 | tem = temps[argnum]; |
| 954 | 954 | ||
| 955 | if (!NILP (lexenv) && SYMBOLP (var) | 955 | if (!NILP (lexenv) && SYMBOLP (var) |
| 956 | && !XSYMBOL (var)->declared_special | 956 | && !XSYMBOL (var)->u.s.declared_special |
| 957 | && NILP (Fmemq (var, Vinternal_interpreter_environment))) | 957 | && NILP (Fmemq (var, Vinternal_interpreter_environment))) |
| 958 | /* Lexically bind VAR by adding it to the lexenv alist. */ | 958 | /* Lexically bind VAR by adding it to the lexenv alist. */ |
| 959 | lexenv = Fcons (Fcons (var, tem), lexenv); | 959 | lexenv = Fcons (Fcons (var, tem), lexenv); |
| @@ -1022,7 +1022,7 @@ definitions to shadow the loaded ones for use in file byte-compilation. */) | |||
| 1022 | tem = Fassq (sym, environment); | 1022 | tem = Fassq (sym, environment); |
| 1023 | if (NILP (tem)) | 1023 | if (NILP (tem)) |
| 1024 | { | 1024 | { |
| 1025 | def = XSYMBOL (sym)->function; | 1025 | def = XSYMBOL (sym)->u.s.function; |
| 1026 | if (!NILP (def)) | 1026 | if (!NILP (def)) |
| 1027 | continue; | 1027 | continue; |
| 1028 | } | 1028 | } |
| @@ -1932,8 +1932,8 @@ this does nothing and returns nil. */) | |||
| 1932 | CHECK_STRING (file); | 1932 | CHECK_STRING (file); |
| 1933 | 1933 | ||
| 1934 | /* If function is defined and not as an autoload, don't override. */ | 1934 | /* If function is defined and not as an autoload, don't override. */ |
| 1935 | if (!NILP (XSYMBOL (function)->function) | 1935 | if (!NILP (XSYMBOL (function)->u.s.function) |
| 1936 | && !AUTOLOADP (XSYMBOL (function)->function)) | 1936 | && !AUTOLOADP (XSYMBOL (function)->u.s.function)) |
| 1937 | return Qnil; | 1937 | return Qnil; |
| 1938 | 1938 | ||
| 1939 | if (!NILP (Vpurify_flag) && EQ (docstring, make_number (0))) | 1939 | if (!NILP (Vpurify_flag) && EQ (docstring, make_number (0))) |
| @@ -2164,7 +2164,7 @@ eval_sub (Lisp_Object form) | |||
| 2164 | fun = original_fun; | 2164 | fun = original_fun; |
| 2165 | if (!SYMBOLP (fun)) | 2165 | if (!SYMBOLP (fun)) |
| 2166 | fun = Ffunction (Fcons (fun, Qnil)); | 2166 | fun = Ffunction (Fcons (fun, Qnil)); |
| 2167 | else if (!NILP (fun) && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) | 2167 | else if (!NILP (fun) && (fun = XSYMBOL (fun)->u.s.function, SYMBOLP (fun))) |
| 2168 | fun = indirect_function (fun); | 2168 | fun = indirect_function (fun); |
| 2169 | 2169 | ||
| 2170 | if (SUBRP (fun)) | 2170 | if (SUBRP (fun)) |
| @@ -2347,7 +2347,7 @@ usage: (apply FUNCTION &rest ARGUMENTS) */) | |||
| 2347 | 2347 | ||
| 2348 | /* Optimize for no indirection. */ | 2348 | /* Optimize for no indirection. */ |
| 2349 | if (SYMBOLP (fun) && !NILP (fun) | 2349 | if (SYMBOLP (fun) && !NILP (fun) |
| 2350 | && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) | 2350 | && (fun = XSYMBOL (fun)->u.s.function, SYMBOLP (fun))) |
| 2351 | { | 2351 | { |
| 2352 | fun = indirect_function (fun); | 2352 | fun = indirect_function (fun); |
| 2353 | if (NILP (fun)) | 2353 | if (NILP (fun)) |
| @@ -2759,7 +2759,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) | |||
| 2759 | /* Optimize for no indirection. */ | 2759 | /* Optimize for no indirection. */ |
| 2760 | fun = original_fun; | 2760 | fun = original_fun; |
| 2761 | if (SYMBOLP (fun) && !NILP (fun) | 2761 | if (SYMBOLP (fun) && !NILP (fun) |
| 2762 | && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) | 2762 | && (fun = XSYMBOL (fun)->u.s.function, SYMBOLP (fun))) |
| 2763 | fun = indirect_function (fun); | 2763 | fun = indirect_function (fun); |
| 2764 | 2764 | ||
| 2765 | if (SUBRP (fun)) | 2765 | if (SUBRP (fun)) |
| @@ -3075,7 +3075,7 @@ function with `&rest' args, or `unevalled' for a special form. */) | |||
| 3075 | function = original; | 3075 | function = original; |
| 3076 | if (SYMBOLP (function) && !NILP (function)) | 3076 | if (SYMBOLP (function) && !NILP (function)) |
| 3077 | { | 3077 | { |
| 3078 | function = XSYMBOL (function)->function; | 3078 | function = XSYMBOL (function)->u.s.function; |
| 3079 | if (SYMBOLP (function)) | 3079 | if (SYMBOLP (function)) |
| 3080 | function = indirect_function (function); | 3080 | function = indirect_function (function); |
| 3081 | } | 3081 | } |
| @@ -3214,7 +3214,7 @@ let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol) | |||
| 3214 | if ((--p)->kind > SPECPDL_LET) | 3214 | if ((--p)->kind > SPECPDL_LET) |
| 3215 | { | 3215 | { |
| 3216 | struct Lisp_Symbol *let_bound_symbol = XSYMBOL (specpdl_symbol (p)); | 3216 | struct Lisp_Symbol *let_bound_symbol = XSYMBOL (specpdl_symbol (p)); |
| 3217 | eassert (let_bound_symbol->redirect != SYMBOL_VARALIAS); | 3217 | eassert (let_bound_symbol->u.s.redirect != SYMBOL_VARALIAS); |
| 3218 | if (symbol == let_bound_symbol | 3218 | if (symbol == let_bound_symbol |
| 3219 | && EQ (specpdl_where (p), buf)) | 3219 | && EQ (specpdl_where (p), buf)) |
| 3220 | return 1; | 3220 | return 1; |
| @@ -3227,10 +3227,10 @@ static void | |||
| 3227 | do_specbind (struct Lisp_Symbol *sym, union specbinding *bind, | 3227 | do_specbind (struct Lisp_Symbol *sym, union specbinding *bind, |
| 3228 | Lisp_Object value, enum Set_Internal_Bind bindflag) | 3228 | Lisp_Object value, enum Set_Internal_Bind bindflag) |
| 3229 | { | 3229 | { |
| 3230 | switch (sym->redirect) | 3230 | switch (sym->u.s.redirect) |
| 3231 | { | 3231 | { |
| 3232 | case SYMBOL_PLAINVAL: | 3232 | case SYMBOL_PLAINVAL: |
| 3233 | if (!sym->trapped_write) | 3233 | if (!sym->u.s.trapped_write) |
| 3234 | SET_SYMBOL_VAL (sym, value); | 3234 | SET_SYMBOL_VAL (sym, value); |
| 3235 | else | 3235 | else |
| 3236 | set_internal (specpdl_symbol (bind), value, Qnil, bindflag); | 3236 | set_internal (specpdl_symbol (bind), value, Qnil, bindflag); |
| @@ -3274,7 +3274,7 @@ specbind (Lisp_Object symbol, Lisp_Object value) | |||
| 3274 | sym = XSYMBOL (symbol); | 3274 | sym = XSYMBOL (symbol); |
| 3275 | 3275 | ||
| 3276 | start: | 3276 | start: |
| 3277 | switch (sym->redirect) | 3277 | switch (sym->u.s.redirect) |
| 3278 | { | 3278 | { |
| 3279 | case SYMBOL_VARALIAS: | 3279 | case SYMBOL_VARALIAS: |
| 3280 | sym = indirect_variable (sym); XSETSYMBOL (symbol, sym); goto start; | 3280 | sym = indirect_variable (sym); XSETSYMBOL (symbol, sym); goto start; |
| @@ -3298,10 +3298,10 @@ specbind (Lisp_Object symbol, Lisp_Object value) | |||
| 3298 | specpdl_ptr->let.where = Fcurrent_buffer (); | 3298 | specpdl_ptr->let.where = Fcurrent_buffer (); |
| 3299 | specpdl_ptr->let.saved_value = Qnil; | 3299 | specpdl_ptr->let.saved_value = Qnil; |
| 3300 | 3300 | ||
| 3301 | eassert (sym->redirect != SYMBOL_LOCALIZED | 3301 | eassert (sym->u.s.redirect != SYMBOL_LOCALIZED |
| 3302 | || (EQ (SYMBOL_BLV (sym)->where, Fcurrent_buffer ()))); | 3302 | || (EQ (SYMBOL_BLV (sym)->where, Fcurrent_buffer ()))); |
| 3303 | 3303 | ||
| 3304 | if (sym->redirect == SYMBOL_LOCALIZED) | 3304 | if (sym->u.s.redirect == SYMBOL_LOCALIZED) |
| 3305 | { | 3305 | { |
| 3306 | if (!blv_found (SYMBOL_BLV (sym))) | 3306 | if (!blv_found (SYMBOL_BLV (sym))) |
| 3307 | specpdl_ptr->let.kind = SPECPDL_LET_DEFAULT; | 3307 | specpdl_ptr->let.kind = SPECPDL_LET_DEFAULT; |
| @@ -3412,9 +3412,9 @@ do_one_unbind (union specbinding *this_binding, bool unwinding, | |||
| 3412 | { /* If variable has a trivial value (no forwarding), and isn't | 3412 | { /* If variable has a trivial value (no forwarding), and isn't |
| 3413 | trapped, we can just set it. */ | 3413 | trapped, we can just set it. */ |
| 3414 | Lisp_Object sym = specpdl_symbol (this_binding); | 3414 | Lisp_Object sym = specpdl_symbol (this_binding); |
| 3415 | if (SYMBOLP (sym) && XSYMBOL (sym)->redirect == SYMBOL_PLAINVAL) | 3415 | if (SYMBOLP (sym) && XSYMBOL (sym)->u.s.redirect == SYMBOL_PLAINVAL) |
| 3416 | { | 3416 | { |
| 3417 | if (XSYMBOL (sym)->trapped_write == SYMBOL_UNTRAPPED_WRITE) | 3417 | if (XSYMBOL (sym)->u.s.trapped_write == SYMBOL_UNTRAPPED_WRITE) |
| 3418 | SET_SYMBOL_VAL (XSYMBOL (sym), specpdl_old_value (this_binding)); | 3418 | SET_SYMBOL_VAL (XSYMBOL (sym), specpdl_old_value (this_binding)); |
| 3419 | else | 3419 | else |
| 3420 | set_internal (sym, specpdl_old_value (this_binding), | 3420 | set_internal (sym, specpdl_old_value (this_binding), |
| @@ -3546,7 +3546,7 @@ context where binding is lexical by default. */) | |||
| 3546 | (Lisp_Object symbol) | 3546 | (Lisp_Object symbol) |
| 3547 | { | 3547 | { |
| 3548 | CHECK_SYMBOL (symbol); | 3548 | CHECK_SYMBOL (symbol); |
| 3549 | return XSYMBOL (symbol)->declared_special ? Qt : Qnil; | 3549 | return XSYMBOL (symbol)->u.s.declared_special ? Qt : Qnil; |
| 3550 | } | 3550 | } |
| 3551 | 3551 | ||
| 3552 | 3552 | ||
| @@ -3702,7 +3702,8 @@ backtrace_eval_unrewind (int distance) | |||
| 3702 | just set it. No need to check for constant symbols here, | 3702 | just set it. No need to check for constant symbols here, |
| 3703 | since that was already done by specbind. */ | 3703 | since that was already done by specbind. */ |
| 3704 | Lisp_Object sym = specpdl_symbol (tmp); | 3704 | Lisp_Object sym = specpdl_symbol (tmp); |
| 3705 | if (SYMBOLP (sym) && XSYMBOL (sym)->redirect == SYMBOL_PLAINVAL) | 3705 | if (SYMBOLP (sym) |
| 3706 | && XSYMBOL (sym)->u.s.redirect == SYMBOL_PLAINVAL) | ||
| 3706 | { | 3707 | { |
| 3707 | Lisp_Object old_value = specpdl_old_value (tmp); | 3708 | Lisp_Object old_value = specpdl_old_value (tmp); |
| 3708 | set_specpdl_old_value (tmp, SYMBOL_VAL (XSYMBOL (sym))); | 3709 | set_specpdl_old_value (tmp, SYMBOL_VAL (XSYMBOL (sym))); |
| @@ -1993,7 +1993,7 @@ This is the last value stored with `(put SYMBOL PROPNAME VALUE)'. */) | |||
| 1993 | propname); | 1993 | propname); |
| 1994 | if (!NILP (propval)) | 1994 | if (!NILP (propval)) |
| 1995 | return propval; | 1995 | return propval; |
| 1996 | return Fplist_get (XSYMBOL (symbol)->plist, propname); | 1996 | return Fplist_get (XSYMBOL (symbol)->u.s.plist, propname); |
| 1997 | } | 1997 | } |
| 1998 | 1998 | ||
| 1999 | DEFUN ("plist-put", Fplist_put, Splist_put, 3, 3, 0, | 1999 | DEFUN ("plist-put", Fplist_put, Splist_put, 3, 3, 0, |
| @@ -2039,7 +2039,7 @@ It can be retrieved with `(get SYMBOL PROPNAME)'. */) | |||
| 2039 | { | 2039 | { |
| 2040 | CHECK_SYMBOL (symbol); | 2040 | CHECK_SYMBOL (symbol); |
| 2041 | set_symbol_plist | 2041 | set_symbol_plist |
| 2042 | (symbol, Fplist_put (XSYMBOL (symbol)->plist, propname, value)); | 2042 | (symbol, Fplist_put (XSYMBOL (symbol)->u.s.plist, propname, value)); |
| 2043 | return value; | 2043 | return value; |
| 2044 | } | 2044 | } |
| 2045 | 2045 | ||
diff --git a/src/keyboard.c b/src/keyboard.c index 7ddd6b96747..57757cf2112 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -7901,7 +7901,7 @@ parse_menu_item (Lisp_Object item, int inmenubar) | |||
| 7901 | (such as lmenu.el set it up), check if the | 7901 | (such as lmenu.el set it up), check if the |
| 7902 | original command matches the cached command. */ | 7902 | original command matches the cached command. */ |
| 7903 | && !(SYMBOLP (def) | 7903 | && !(SYMBOLP (def) |
| 7904 | && EQ (tem, XSYMBOL (def)->function)))) | 7904 | && EQ (tem, XSYMBOL (def)->u.s.function)))) |
| 7905 | keys = Qnil; | 7905 | keys = Qnil; |
| 7906 | } | 7906 | } |
| 7907 | 7907 | ||
| @@ -8761,9 +8761,9 @@ access_keymap_keyremap (Lisp_Object map, Lisp_Object key, Lisp_Object prompt, | |||
| 8761 | /* Handle a symbol whose function definition is a keymap | 8761 | /* Handle a symbol whose function definition is a keymap |
| 8762 | or an array. */ | 8762 | or an array. */ |
| 8763 | if (SYMBOLP (next) && !NILP (Ffboundp (next)) | 8763 | if (SYMBOLP (next) && !NILP (Ffboundp (next)) |
| 8764 | && (ARRAYP (XSYMBOL (next)->function) | 8764 | && (ARRAYP (XSYMBOL (next)->u.s.function) |
| 8765 | || KEYMAPP (XSYMBOL (next)->function))) | 8765 | || KEYMAPP (XSYMBOL (next)->u.s.function))) |
| 8766 | next = Fautoload_do_load (XSYMBOL (next)->function, next, Qnil); | 8766 | next = Fautoload_do_load (XSYMBOL (next)->u.s.function, next, Qnil); |
| 8767 | 8767 | ||
| 8768 | /* If the keymap gives a function, not an | 8768 | /* If the keymap gives a function, not an |
| 8769 | array, then call the function with one arg and use | 8769 | array, then call the function with one arg and use |
| @@ -11510,7 +11510,7 @@ for that character after that prefix key. */); | |||
| 11510 | doc: /* Form to evaluate when Emacs starts up. | 11510 | doc: /* Form to evaluate when Emacs starts up. |
| 11511 | Useful to set before you dump a modified Emacs. */); | 11511 | Useful to set before you dump a modified Emacs. */); |
| 11512 | Vtop_level = Qnil; | 11512 | Vtop_level = Qnil; |
| 11513 | XSYMBOL (Qtop_level)->declared_special = false; | 11513 | XSYMBOL (Qtop_level)->u.s.declared_special = false; |
| 11514 | 11514 | ||
| 11515 | DEFVAR_KBOARD ("keyboard-translate-table", Vkeyboard_translate_table, | 11515 | DEFVAR_KBOARD ("keyboard-translate-table", Vkeyboard_translate_table, |
| 11516 | doc: /* Translate table for local keyboard input, or nil. | 11516 | doc: /* Translate table for local keyboard input, or nil. |
diff --git a/src/lisp.h b/src/lisp.h index 1d6fd5a4fe2..e9aec4c5979 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -229,7 +229,7 @@ extern bool suppress_checking EXTERNALLY_VISIBLE; | |||
| 229 | USE_LSB_TAG not only requires the least 3 bits of pointers returned by | 229 | USE_LSB_TAG not only requires the least 3 bits of pointers returned by |
| 230 | malloc to be 0 but also needs to be able to impose a mult-of-8 alignment | 230 | malloc to be 0 but also needs to be able to impose a mult-of-8 alignment |
| 231 | on the few static Lisp_Objects used, all of which are aligned via | 231 | on the few static Lisp_Objects used, all of which are aligned via |
| 232 | the GCALIGN macro defined below. */ | 232 | 'char alignas (GCALIGNMENT) gcaligned;' inside a union. */ |
| 233 | 233 | ||
| 234 | enum Lisp_Bits | 234 | enum Lisp_Bits |
| 235 | { | 235 | { |
| @@ -277,20 +277,6 @@ DEFINE_GDB_SYMBOL_END (VALMASK) | |||
| 277 | error !; | 277 | error !; |
| 278 | #endif | 278 | #endif |
| 279 | 279 | ||
| 280 | /* Use GCALIGNED immediately after the 'struct' keyword to require the | ||
| 281 | struct to have an address that is a multiple of GCALIGNMENT. This | ||
| 282 | is a no-op if the struct's natural alignment is already a multiple | ||
| 283 | of GCALIGNMENT. GCALIGNED's implementation uses the 'aligned' | ||
| 284 | attribute instead of 'alignas (GCALIGNMENT)', as the latter would | ||
| 285 | fail if an object's natural alignment exceeds GCALIGNMENT. The | ||
| 286 | implementation hopes that natural alignment suffices on platforms | ||
| 287 | lacking 'aligned'. */ | ||
| 288 | #ifdef HAVE_STRUCT_ATTRIBUTE_ALIGNED | ||
| 289 | # define GCALIGNED __attribute__ ((aligned (GCALIGNMENT))) | ||
| 290 | #else | ||
| 291 | # define GCALIGNED /* empty */ | ||
| 292 | #endif | ||
| 293 | |||
| 294 | /* Some operations are so commonly executed that they are implemented | 280 | /* Some operations are so commonly executed that they are implemented |
| 295 | as macros, not functions, because otherwise runtime performance would | 281 | as macros, not functions, because otherwise runtime performance would |
| 296 | suffer too much when compiling with GCC without optimization. | 282 | suffer too much when compiling with GCC without optimization. |
| @@ -338,15 +324,17 @@ error !; | |||
| 338 | #define lisp_h_MISCP(x) (XTYPE (x) == Lisp_Misc) | 324 | #define lisp_h_MISCP(x) (XTYPE (x) == Lisp_Misc) |
| 339 | #define lisp_h_NILP(x) EQ (x, Qnil) | 325 | #define lisp_h_NILP(x) EQ (x, Qnil) |
| 340 | #define lisp_h_SET_SYMBOL_VAL(sym, v) \ | 326 | #define lisp_h_SET_SYMBOL_VAL(sym, v) \ |
| 341 | (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value = (v)) | 327 | (eassert ((sym)->u.s.redirect == SYMBOL_PLAINVAL), \ |
| 342 | #define lisp_h_SYMBOL_CONSTANT_P(sym) (XSYMBOL (sym)->trapped_write == SYMBOL_NOWRITE) | 328 | (sym)->u.s.val.value = (v)) |
| 343 | #define lisp_h_SYMBOL_TRAPPED_WRITE_P(sym) (XSYMBOL (sym)->trapped_write) | 329 | #define lisp_h_SYMBOL_CONSTANT_P(sym) \ |
| 330 | (XSYMBOL (sym)->u.s.trapped_write == SYMBOL_NOWRITE) | ||
| 331 | #define lisp_h_SYMBOL_TRAPPED_WRITE_P(sym) (XSYMBOL (sym)->u.s.trapped_write) | ||
| 344 | #define lisp_h_SYMBOL_VAL(sym) \ | 332 | #define lisp_h_SYMBOL_VAL(sym) \ |
| 345 | (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value) | 333 | (eassert ((sym)->u.s.redirect == SYMBOL_PLAINVAL), (sym)->u.s.val.value) |
| 346 | #define lisp_h_SYMBOLP(x) (XTYPE (x) == Lisp_Symbol) | 334 | #define lisp_h_SYMBOLP(x) (XTYPE (x) == Lisp_Symbol) |
| 347 | #define lisp_h_VECTORLIKEP(x) (XTYPE (x) == Lisp_Vectorlike) | 335 | #define lisp_h_VECTORLIKEP(x) (XTYPE (x) == Lisp_Vectorlike) |
| 348 | #define lisp_h_XCAR(c) XCONS (c)->car | 336 | #define lisp_h_XCAR(c) XCONS (c)->u.s.car |
| 349 | #define lisp_h_XCDR(c) XCONS (c)->u.cdr | 337 | #define lisp_h_XCDR(c) XCONS (c)->u.s.u.cdr |
| 350 | #define lisp_h_XCONS(a) \ | 338 | #define lisp_h_XCONS(a) \ |
| 351 | (eassert (CONSP (a)), (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons)) | 339 | (eassert (CONSP (a)), (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons)) |
| 352 | #define lisp_h_XHASH(a) XUINT (a) | 340 | #define lisp_h_XHASH(a) XUINT (a) |
| @@ -677,52 +665,60 @@ enum symbol_trapped_write | |||
| 677 | 665 | ||
| 678 | struct Lisp_Symbol | 666 | struct Lisp_Symbol |
| 679 | { | 667 | { |
| 680 | bool_bf gcmarkbit : 1; | 668 | union |
| 681 | 669 | { | |
| 682 | /* Indicates where the value can be found: | 670 | struct |
| 683 | 0 : it's a plain var, the value is in the `value' field. | 671 | { |
| 684 | 1 : it's a varalias, the value is really in the `alias' symbol. | 672 | bool_bf gcmarkbit : 1; |
| 685 | 2 : it's a localized var, the value is in the `blv' object. | 673 | |
| 686 | 3 : it's a forwarding variable, the value is in `forward'. */ | 674 | /* Indicates where the value can be found: |
| 687 | ENUM_BF (symbol_redirect) redirect : 3; | 675 | 0 : it's a plain var, the value is in the `value' field. |
| 688 | 676 | 1 : it's a varalias, the value is really in the `alias' symbol. | |
| 689 | /* 0 : normal case, just set the value | 677 | 2 : it's a localized var, the value is in the `blv' object. |
| 690 | 1 : constant, cannot set, e.g. nil, t, :keywords. | 678 | 3 : it's a forwarding variable, the value is in `forward'. */ |
| 691 | 2 : trap the write, call watcher functions. */ | 679 | ENUM_BF (symbol_redirect) redirect : 3; |
| 692 | ENUM_BF (symbol_trapped_write) trapped_write : 2; | 680 | |
| 693 | 681 | /* 0 : normal case, just set the value | |
| 694 | /* Interned state of the symbol. This is an enumerator from | 682 | 1 : constant, cannot set, e.g. nil, t, :keywords. |
| 695 | enum symbol_interned. */ | 683 | 2 : trap the write, call watcher functions. */ |
| 696 | unsigned interned : 2; | 684 | ENUM_BF (symbol_trapped_write) trapped_write : 2; |
| 697 | 685 | ||
| 698 | /* True means that this variable has been explicitly declared | 686 | /* Interned state of the symbol. This is an enumerator from |
| 699 | special (with `defvar' etc), and shouldn't be lexically bound. */ | 687 | enum symbol_interned. */ |
| 700 | bool_bf declared_special : 1; | 688 | unsigned interned : 2; |
| 701 | 689 | ||
| 702 | /* True if pointed to from purespace and hence can't be GC'd. */ | 690 | /* True means that this variable has been explicitly declared |
| 703 | bool_bf pinned : 1; | 691 | special (with `defvar' etc), and shouldn't be lexically bound. */ |
| 704 | 692 | bool_bf declared_special : 1; | |
| 705 | /* The symbol's name, as a Lisp string. */ | 693 | |
| 706 | Lisp_Object name; | 694 | /* True if pointed to from purespace and hence can't be GC'd. */ |
| 707 | 695 | bool_bf pinned : 1; | |
| 708 | /* Value of the symbol or Qunbound if unbound. Which alternative of the | 696 | |
| 709 | union is used depends on the `redirect' field above. */ | 697 | /* The symbol's name, as a Lisp string. */ |
| 710 | union { | 698 | Lisp_Object name; |
| 711 | Lisp_Object value; | 699 | |
| 712 | struct Lisp_Symbol *alias; | 700 | /* Value of the symbol or Qunbound if unbound. Which alternative of the |
| 713 | struct Lisp_Buffer_Local_Value *blv; | 701 | union is used depends on the `redirect' field above. */ |
| 714 | union Lisp_Fwd *fwd; | 702 | union { |
| 715 | } val; | 703 | Lisp_Object value; |
| 716 | 704 | struct Lisp_Symbol *alias; | |
| 717 | /* Function value of the symbol or Qnil if not fboundp. */ | 705 | struct Lisp_Buffer_Local_Value *blv; |
| 718 | Lisp_Object function; | 706 | union Lisp_Fwd *fwd; |
| 707 | } val; | ||
| 708 | |||
| 709 | /* Function value of the symbol or Qnil if not fboundp. */ | ||
| 710 | Lisp_Object function; | ||
| 719 | 711 | ||
| 720 | /* The symbol's property list. */ | 712 | /* The symbol's property list. */ |
| 721 | Lisp_Object plist; | 713 | Lisp_Object plist; |
| 722 | 714 | ||
| 723 | /* Next symbol in obarray bucket, if the symbol is interned. */ | 715 | /* Next symbol in obarray bucket, if the symbol is interned. */ |
| 724 | struct Lisp_Symbol *next; | 716 | struct Lisp_Symbol *next; |
| 717 | } s; | ||
| 718 | char alignas (GCALIGNMENT) gcaligned; | ||
| 719 | } u; | ||
| 725 | }; | 720 | }; |
| 721 | verify (alignof (struct Lisp_Symbol) % GCALIGNMENT == 0); | ||
| 726 | 722 | ||
| 727 | /* Declare a Lisp-callable function. The MAXARGS parameter has the same | 723 | /* Declare a Lisp-callable function. The MAXARGS parameter has the same |
| 728 | meaning as in the DEFUN macro, and is used to construct a prototype. */ | 724 | meaning as in the DEFUN macro, and is used to construct a prototype. */ |
| @@ -802,7 +798,7 @@ struct Lisp_Symbol | |||
| 802 | Bug#8546. */ | 798 | Bug#8546. */ |
| 803 | union vectorlike_header | 799 | union vectorlike_header |
| 804 | { | 800 | { |
| 805 | /* The only field contains various pieces of information: | 801 | /* The main member contains various pieces of information: |
| 806 | - The MSB (ARRAY_MARK_FLAG) holds the gcmarkbit. | 802 | - The MSB (ARRAY_MARK_FLAG) holds the gcmarkbit. |
| 807 | - The next bit (PSEUDOVECTOR_FLAG) indicates whether this is a plain | 803 | - The next bit (PSEUDOVECTOR_FLAG) indicates whether this is a plain |
| 808 | vector (0) or a pseudovector (1). | 804 | vector (0) or a pseudovector (1). |
| @@ -822,7 +818,9 @@ union vectorlike_header | |||
| 822 | Current layout limits the pseudovectors to 63 PVEC_xxx subtypes, | 818 | Current layout limits the pseudovectors to 63 PVEC_xxx subtypes, |
| 823 | 4095 Lisp_Objects in GC-ed area and 4095 word-sized other slots. */ | 819 | 4095 Lisp_Objects in GC-ed area and 4095 word-sized other slots. */ |
| 824 | ptrdiff_t size; | 820 | ptrdiff_t size; |
| 821 | char alignas (GCALIGNMENT) gcaligned; | ||
| 825 | }; | 822 | }; |
| 823 | verify (alignof (union vectorlike_header) % GCALIGNMENT == 0); | ||
| 826 | 824 | ||
| 827 | INLINE bool | 825 | INLINE bool |
| 828 | (SYMBOLP) (Lisp_Object x) | 826 | (SYMBOLP) (Lisp_Object x) |
| @@ -854,7 +852,7 @@ make_lisp_symbol (struct Lisp_Symbol *sym) | |||
| 854 | INLINE Lisp_Object | 852 | INLINE Lisp_Object |
| 855 | builtin_lisp_symbol (int index) | 853 | builtin_lisp_symbol (int index) |
| 856 | { | 854 | { |
| 857 | return make_lisp_symbol (&lispsym[index].s); | 855 | return make_lisp_symbol (&lispsym[index]); |
| 858 | } | 856 | } |
| 859 | 857 | ||
| 860 | INLINE void | 858 | INLINE void |
| @@ -1144,20 +1142,28 @@ make_pointer_integer (void *p) | |||
| 1144 | 1142 | ||
| 1145 | typedef struct interval *INTERVAL; | 1143 | typedef struct interval *INTERVAL; |
| 1146 | 1144 | ||
| 1147 | struct GCALIGNED Lisp_Cons | 1145 | struct Lisp_Cons |
| 1146 | { | ||
| 1147 | union | ||
| 1148 | { | 1148 | { |
| 1149 | /* Car of this cons cell. */ | 1149 | struct |
| 1150 | Lisp_Object car; | ||
| 1151 | |||
| 1152 | union | ||
| 1153 | { | 1150 | { |
| 1154 | /* Cdr of this cons cell. */ | 1151 | /* Car of this cons cell. */ |
| 1155 | Lisp_Object cdr; | 1152 | Lisp_Object car; |
| 1156 | 1153 | ||
| 1157 | /* Used to chain conses on a free list. */ | 1154 | union |
| 1158 | struct Lisp_Cons *chain; | 1155 | { |
| 1159 | } u; | 1156 | /* Cdr of this cons cell. */ |
| 1160 | }; | 1157 | Lisp_Object cdr; |
| 1158 | |||
| 1159 | /* Used to chain conses on a free list. */ | ||
| 1160 | struct Lisp_Cons *chain; | ||
| 1161 | } u; | ||
| 1162 | } s; | ||
| 1163 | char alignas (GCALIGNMENT) gcaligned; | ||
| 1164 | } u; | ||
| 1165 | }; | ||
| 1166 | verify (alignof (struct Lisp_Cons) % GCALIGNMENT == 0); | ||
| 1161 | 1167 | ||
| 1162 | INLINE bool | 1168 | INLINE bool |
| 1163 | (NILP) (Lisp_Object x) | 1169 | (NILP) (Lisp_Object x) |
| @@ -1193,12 +1199,12 @@ INLINE struct Lisp_Cons * | |||
| 1193 | INLINE Lisp_Object * | 1199 | INLINE Lisp_Object * |
| 1194 | xcar_addr (Lisp_Object c) | 1200 | xcar_addr (Lisp_Object c) |
| 1195 | { | 1201 | { |
| 1196 | return &XCONS (c)->car; | 1202 | return &XCONS (c)->u.s.car; |
| 1197 | } | 1203 | } |
| 1198 | INLINE Lisp_Object * | 1204 | INLINE Lisp_Object * |
| 1199 | xcdr_addr (Lisp_Object c) | 1205 | xcdr_addr (Lisp_Object c) |
| 1200 | { | 1206 | { |
| 1201 | return &XCONS (c)->u.cdr; | 1207 | return &XCONS (c)->u.s.u.cdr; |
| 1202 | } | 1208 | } |
| 1203 | 1209 | ||
| 1204 | /* Use these from normal code. */ | 1210 | /* Use these from normal code. */ |
| @@ -1262,15 +1268,24 @@ CDR_SAFE (Lisp_Object c) | |||
| 1262 | return CONSP (c) ? XCDR (c) : Qnil; | 1268 | return CONSP (c) ? XCDR (c) : Qnil; |
| 1263 | } | 1269 | } |
| 1264 | 1270 | ||
| 1265 | /* In a string or vector, the sign bit of the `size' is the gc mark bit. */ | 1271 | /* In a string or vector, the sign bit of u.s.size is the gc mark bit. */ |
| 1266 | 1272 | ||
| 1267 | struct GCALIGNED Lisp_String | 1273 | struct Lisp_String |
| 1274 | { | ||
| 1275 | union | ||
| 1268 | { | 1276 | { |
| 1269 | ptrdiff_t size; | 1277 | struct |
| 1270 | ptrdiff_t size_byte; | 1278 | { |
| 1271 | INTERVAL intervals; /* Text properties in this string. */ | 1279 | ptrdiff_t size; |
| 1272 | unsigned char *data; | 1280 | ptrdiff_t size_byte; |
| 1273 | }; | 1281 | INTERVAL intervals; /* Text properties in this string. */ |
| 1282 | unsigned char *data; | ||
| 1283 | } s; | ||
| 1284 | struct Lisp_String *next; | ||
| 1285 | char alignas (GCALIGNMENT) gcaligned; | ||
| 1286 | } u; | ||
| 1287 | }; | ||
| 1288 | verify (alignof (struct Lisp_String) % GCALIGNMENT == 0); | ||
| 1274 | 1289 | ||
| 1275 | INLINE bool | 1290 | INLINE bool |
| 1276 | STRINGP (Lisp_Object x) | 1291 | STRINGP (Lisp_Object x) |
| @@ -1295,7 +1310,7 @@ XSTRING (Lisp_Object a) | |||
| 1295 | INLINE bool | 1310 | INLINE bool |
| 1296 | STRING_MULTIBYTE (Lisp_Object str) | 1311 | STRING_MULTIBYTE (Lisp_Object str) |
| 1297 | { | 1312 | { |
| 1298 | return 0 <= XSTRING (str)->size_byte; | 1313 | return 0 <= XSTRING (str)->u.s.size_byte; |
| 1299 | } | 1314 | } |
| 1300 | 1315 | ||
| 1301 | /* An upper bound on the number of bytes in a Lisp string, not | 1316 | /* An upper bound on the number of bytes in a Lisp string, not |
| @@ -1317,20 +1332,20 @@ STRING_MULTIBYTE (Lisp_Object str) | |||
| 1317 | /* Mark STR as a unibyte string. */ | 1332 | /* Mark STR as a unibyte string. */ |
| 1318 | #define STRING_SET_UNIBYTE(STR) \ | 1333 | #define STRING_SET_UNIBYTE(STR) \ |
| 1319 | do { \ | 1334 | do { \ |
| 1320 | if (XSTRING (STR)->size == 0) \ | 1335 | if (XSTRING (STR)->u.s.size == 0) \ |
| 1321 | (STR) = empty_unibyte_string; \ | 1336 | (STR) = empty_unibyte_string; \ |
| 1322 | else \ | 1337 | else \ |
| 1323 | XSTRING (STR)->size_byte = -1; \ | 1338 | XSTRING (STR)->u.s.size_byte = -1; \ |
| 1324 | } while (false) | 1339 | } while (false) |
| 1325 | 1340 | ||
| 1326 | /* Mark STR as a multibyte string. Assure that STR contains only | 1341 | /* Mark STR as a multibyte string. Assure that STR contains only |
| 1327 | ASCII characters in advance. */ | 1342 | ASCII characters in advance. */ |
| 1328 | #define STRING_SET_MULTIBYTE(STR) \ | 1343 | #define STRING_SET_MULTIBYTE(STR) \ |
| 1329 | do { \ | 1344 | do { \ |
| 1330 | if (XSTRING (STR)->size == 0) \ | 1345 | if (XSTRING (STR)->u.s.size == 0) \ |
| 1331 | (STR) = empty_multibyte_string; \ | 1346 | (STR) = empty_multibyte_string; \ |
| 1332 | else \ | 1347 | else \ |
| 1333 | XSTRING (STR)->size_byte = XSTRING (STR)->size; \ | 1348 | XSTRING (STR)->u.s.size_byte = XSTRING (STR)->u.s.size; \ |
| 1334 | } while (false) | 1349 | } while (false) |
| 1335 | 1350 | ||
| 1336 | /* Convenience functions for dealing with Lisp strings. */ | 1351 | /* Convenience functions for dealing with Lisp strings. */ |
| @@ -1338,7 +1353,7 @@ STRING_MULTIBYTE (Lisp_Object str) | |||
| 1338 | INLINE unsigned char * | 1353 | INLINE unsigned char * |
| 1339 | SDATA (Lisp_Object string) | 1354 | SDATA (Lisp_Object string) |
| 1340 | { | 1355 | { |
| 1341 | return XSTRING (string)->data; | 1356 | return XSTRING (string)->u.s.data; |
| 1342 | } | 1357 | } |
| 1343 | INLINE char * | 1358 | INLINE char * |
| 1344 | SSDATA (Lisp_Object string) | 1359 | SSDATA (Lisp_Object string) |
| @@ -1359,7 +1374,7 @@ SSET (Lisp_Object string, ptrdiff_t index, unsigned char new) | |||
| 1359 | INLINE ptrdiff_t | 1374 | INLINE ptrdiff_t |
| 1360 | SCHARS (Lisp_Object string) | 1375 | SCHARS (Lisp_Object string) |
| 1361 | { | 1376 | { |
| 1362 | ptrdiff_t nchars = XSTRING (string)->size; | 1377 | ptrdiff_t nchars = XSTRING (string)->u.s.size; |
| 1363 | eassume (0 <= nchars); | 1378 | eassume (0 <= nchars); |
| 1364 | return nchars; | 1379 | return nchars; |
| 1365 | } | 1380 | } |
| @@ -1373,7 +1388,7 @@ STRING_BYTES (struct Lisp_String *s) | |||
| 1373 | #ifdef GC_CHECK_STRING_BYTES | 1388 | #ifdef GC_CHECK_STRING_BYTES |
| 1374 | ptrdiff_t nbytes = string_bytes (s); | 1389 | ptrdiff_t nbytes = string_bytes (s); |
| 1375 | #else | 1390 | #else |
| 1376 | ptrdiff_t nbytes = s->size_byte < 0 ? s->size : s->size_byte; | 1391 | ptrdiff_t nbytes = s->u.s.size_byte < 0 ? s->u.s.size : s->u.s.size_byte; |
| 1377 | #endif | 1392 | #endif |
| 1378 | eassume (0 <= nbytes); | 1393 | eassume (0 <= nbytes); |
| 1379 | return nbytes; | 1394 | return nbytes; |
| @@ -1392,7 +1407,7 @@ STRING_SET_CHARS (Lisp_Object string, ptrdiff_t newsize) | |||
| 1392 | eassert (STRING_MULTIBYTE (string) | 1407 | eassert (STRING_MULTIBYTE (string) |
| 1393 | ? 0 <= newsize && newsize <= SBYTES (string) | 1408 | ? 0 <= newsize && newsize <= SBYTES (string) |
| 1394 | : newsize == SCHARS (string)); | 1409 | : newsize == SCHARS (string)); |
| 1395 | XSTRING (string)->size = newsize; | 1410 | XSTRING (string)->u.s.size = newsize; |
| 1396 | } | 1411 | } |
| 1397 | 1412 | ||
| 1398 | /* A regular vector is just a header plus an array of Lisp_Objects. */ | 1413 | /* A regular vector is just a header plus an array of Lisp_Objects. */ |
| @@ -1910,20 +1925,20 @@ INLINE Lisp_Object | |||
| 1910 | INLINE struct Lisp_Symbol * | 1925 | INLINE struct Lisp_Symbol * |
| 1911 | SYMBOL_ALIAS (struct Lisp_Symbol *sym) | 1926 | SYMBOL_ALIAS (struct Lisp_Symbol *sym) |
| 1912 | { | 1927 | { |
| 1913 | eassume (sym->redirect == SYMBOL_VARALIAS && sym->val.alias); | 1928 | eassume (sym->u.s.redirect == SYMBOL_VARALIAS && sym->u.s.val.alias); |
| 1914 | return sym->val.alias; | 1929 | return sym->u.s.val.alias; |
| 1915 | } | 1930 | } |
| 1916 | INLINE struct Lisp_Buffer_Local_Value * | 1931 | INLINE struct Lisp_Buffer_Local_Value * |
| 1917 | SYMBOL_BLV (struct Lisp_Symbol *sym) | 1932 | SYMBOL_BLV (struct Lisp_Symbol *sym) |
| 1918 | { | 1933 | { |
| 1919 | eassume (sym->redirect == SYMBOL_LOCALIZED && sym->val.blv); | 1934 | eassume (sym->u.s.redirect == SYMBOL_LOCALIZED && sym->u.s.val.blv); |
| 1920 | return sym->val.blv; | 1935 | return sym->u.s.val.blv; |
| 1921 | } | 1936 | } |
| 1922 | INLINE union Lisp_Fwd * | 1937 | INLINE union Lisp_Fwd * |
| 1923 | SYMBOL_FWD (struct Lisp_Symbol *sym) | 1938 | SYMBOL_FWD (struct Lisp_Symbol *sym) |
| 1924 | { | 1939 | { |
| 1925 | eassume (sym->redirect == SYMBOL_FORWARDED && sym->val.fwd); | 1940 | eassume (sym->u.s.redirect == SYMBOL_FORWARDED && sym->u.s.val.fwd); |
| 1926 | return sym->val.fwd; | 1941 | return sym->u.s.val.fwd; |
| 1927 | } | 1942 | } |
| 1928 | 1943 | ||
| 1929 | INLINE void | 1944 | INLINE void |
| @@ -1935,26 +1950,26 @@ INLINE void | |||
| 1935 | INLINE void | 1950 | INLINE void |
| 1936 | SET_SYMBOL_ALIAS (struct Lisp_Symbol *sym, struct Lisp_Symbol *v) | 1951 | SET_SYMBOL_ALIAS (struct Lisp_Symbol *sym, struct Lisp_Symbol *v) |
| 1937 | { | 1952 | { |
| 1938 | eassume (sym->redirect == SYMBOL_VARALIAS && v); | 1953 | eassume (sym->u.s.redirect == SYMBOL_VARALIAS && v); |
| 1939 | sym->val.alias = v; | 1954 | sym->u.s.val.alias = v; |
| 1940 | } | 1955 | } |
| 1941 | INLINE void | 1956 | INLINE void |
| 1942 | SET_SYMBOL_BLV (struct Lisp_Symbol *sym, struct Lisp_Buffer_Local_Value *v) | 1957 | SET_SYMBOL_BLV (struct Lisp_Symbol *sym, struct Lisp_Buffer_Local_Value *v) |
| 1943 | { | 1958 | { |
| 1944 | eassume (sym->redirect == SYMBOL_LOCALIZED && v); | 1959 | eassume (sym->u.s.redirect == SYMBOL_LOCALIZED && v); |
| 1945 | sym->val.blv = v; | 1960 | sym->u.s.val.blv = v; |
| 1946 | } | 1961 | } |
| 1947 | INLINE void | 1962 | INLINE void |
| 1948 | SET_SYMBOL_FWD (struct Lisp_Symbol *sym, union Lisp_Fwd *v) | 1963 | SET_SYMBOL_FWD (struct Lisp_Symbol *sym, union Lisp_Fwd *v) |
| 1949 | { | 1964 | { |
| 1950 | eassume (sym->redirect == SYMBOL_FORWARDED && v); | 1965 | eassume (sym->u.s.redirect == SYMBOL_FORWARDED && v); |
| 1951 | sym->val.fwd = v; | 1966 | sym->u.s.val.fwd = v; |
| 1952 | } | 1967 | } |
| 1953 | 1968 | ||
| 1954 | INLINE Lisp_Object | 1969 | INLINE Lisp_Object |
| 1955 | SYMBOL_NAME (Lisp_Object sym) | 1970 | SYMBOL_NAME (Lisp_Object sym) |
| 1956 | { | 1971 | { |
| 1957 | return XSYMBOL (sym)->name; | 1972 | return XSYMBOL (sym)->u.s.name; |
| 1958 | } | 1973 | } |
| 1959 | 1974 | ||
| 1960 | /* Value is true if SYM is an interned symbol. */ | 1975 | /* Value is true if SYM is an interned symbol. */ |
| @@ -1962,7 +1977,7 @@ SYMBOL_NAME (Lisp_Object sym) | |||
| 1962 | INLINE bool | 1977 | INLINE bool |
| 1963 | SYMBOL_INTERNED_P (Lisp_Object sym) | 1978 | SYMBOL_INTERNED_P (Lisp_Object sym) |
| 1964 | { | 1979 | { |
| 1965 | return XSYMBOL (sym)->interned != SYMBOL_UNINTERNED; | 1980 | return XSYMBOL (sym)->u.s.interned != SYMBOL_UNINTERNED; |
| 1966 | } | 1981 | } |
| 1967 | 1982 | ||
| 1968 | /* Value is true if SYM is interned in initial_obarray. */ | 1983 | /* Value is true if SYM is interned in initial_obarray. */ |
| @@ -1970,7 +1985,7 @@ SYMBOL_INTERNED_P (Lisp_Object sym) | |||
| 1970 | INLINE bool | 1985 | INLINE bool |
| 1971 | SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (Lisp_Object sym) | 1986 | SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (Lisp_Object sym) |
| 1972 | { | 1987 | { |
| 1973 | return XSYMBOL (sym)->interned == SYMBOL_INTERNED_IN_INITIAL_OBARRAY; | 1988 | return XSYMBOL (sym)->u.s.interned == SYMBOL_INTERNED_IN_INITIAL_OBARRAY; |
| 1974 | } | 1989 | } |
| 1975 | 1990 | ||
| 1976 | /* Value is non-zero if symbol cannot be changed through a simple set, | 1991 | /* Value is non-zero if symbol cannot be changed through a simple set, |
| @@ -2948,7 +2963,7 @@ CHECK_NUMBER_CDR (Lisp_Object x) | |||
| 2948 | #ifdef _MSC_VER | 2963 | #ifdef _MSC_VER |
| 2949 | #define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ | 2964 | #define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ |
| 2950 | Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \ | 2965 | Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \ |
| 2951 | static struct GCALIGNED Lisp_Subr sname = \ | 2966 | static struct Lisp_Subr sname = \ |
| 2952 | { { (PVEC_SUBR << PSEUDOVECTOR_AREA_BITS) \ | 2967 | { { (PVEC_SUBR << PSEUDOVECTOR_AREA_BITS) \ |
| 2953 | | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)) }, \ | 2968 | | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)) }, \ |
| 2954 | { (Lisp_Object (__cdecl *)(void))fnname }, \ | 2969 | { (Lisp_Object (__cdecl *)(void))fnname }, \ |
| @@ -2956,7 +2971,7 @@ CHECK_NUMBER_CDR (Lisp_Object x) | |||
| 2956 | Lisp_Object fnname | 2971 | Lisp_Object fnname |
| 2957 | #else /* not _MSC_VER */ | 2972 | #else /* not _MSC_VER */ |
| 2958 | #define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ | 2973 | #define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ |
| 2959 | static struct GCALIGNED Lisp_Subr sname = \ | 2974 | static struct Lisp_Subr sname = \ |
| 2960 | { { PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, \ | 2975 | { { PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, \ |
| 2961 | { .a ## maxargs = fnname }, \ | 2976 | { .a ## maxargs = fnname }, \ |
| 2962 | minargs, maxargs, lname, intspec, 0}; \ | 2977 | minargs, maxargs, lname, intspec, 0}; \ |
| @@ -3224,25 +3239,25 @@ set_hash_value_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val) | |||
| 3224 | INLINE void | 3239 | INLINE void |
| 3225 | set_symbol_function (Lisp_Object sym, Lisp_Object function) | 3240 | set_symbol_function (Lisp_Object sym, Lisp_Object function) |
| 3226 | { | 3241 | { |
| 3227 | XSYMBOL (sym)->function = function; | 3242 | XSYMBOL (sym)->u.s.function = function; |
| 3228 | } | 3243 | } |
| 3229 | 3244 | ||
| 3230 | INLINE void | 3245 | INLINE void |
| 3231 | set_symbol_plist (Lisp_Object sym, Lisp_Object plist) | 3246 | set_symbol_plist (Lisp_Object sym, Lisp_Object plist) |
| 3232 | { | 3247 | { |
| 3233 | XSYMBOL (sym)->plist = plist; | 3248 | XSYMBOL (sym)->u.s.plist = plist; |
| 3234 | } | 3249 | } |
| 3235 | 3250 | ||
| 3236 | INLINE void | 3251 | INLINE void |
| 3237 | set_symbol_next (Lisp_Object sym, struct Lisp_Symbol *next) | 3252 | set_symbol_next (Lisp_Object sym, struct Lisp_Symbol *next) |
| 3238 | { | 3253 | { |
| 3239 | XSYMBOL (sym)->next = next; | 3254 | XSYMBOL (sym)->u.s.next = next; |
| 3240 | } | 3255 | } |
| 3241 | 3256 | ||
| 3242 | INLINE void | 3257 | INLINE void |
| 3243 | make_symbol_constant (Lisp_Object sym) | 3258 | make_symbol_constant (Lisp_Object sym) |
| 3244 | { | 3259 | { |
| 3245 | XSYMBOL (sym)->trapped_write = SYMBOL_NOWRITE; | 3260 | XSYMBOL (sym)->u.s.trapped_write = SYMBOL_NOWRITE; |
| 3246 | } | 3261 | } |
| 3247 | 3262 | ||
| 3248 | /* Buffer-local variable access functions. */ | 3263 | /* Buffer-local variable access functions. */ |
| @@ -3267,7 +3282,7 @@ set_overlay_plist (Lisp_Object overlay, Lisp_Object plist) | |||
| 3267 | INLINE INTERVAL | 3282 | INLINE INTERVAL |
| 3268 | string_intervals (Lisp_Object s) | 3283 | string_intervals (Lisp_Object s) |
| 3269 | { | 3284 | { |
| 3270 | return XSTRING (s)->intervals; | 3285 | return XSTRING (s)->u.s.intervals; |
| 3271 | } | 3286 | } |
| 3272 | 3287 | ||
| 3273 | /* Set text properties of S to I. */ | 3288 | /* Set text properties of S to I. */ |
| @@ -3275,7 +3290,7 @@ string_intervals (Lisp_Object s) | |||
| 3275 | INLINE void | 3290 | INLINE void |
| 3276 | set_string_intervals (Lisp_Object s, INTERVAL i) | 3291 | set_string_intervals (Lisp_Object s, INTERVAL i) |
| 3277 | { | 3292 | { |
| 3278 | XSTRING (s)->intervals = i; | 3293 | XSTRING (s)->u.s.intervals = i; |
| 3279 | } | 3294 | } |
| 3280 | 3295 | ||
| 3281 | /* Set a Lisp slot in TABLE to VAL. Most code should use this instead | 3296 | /* Set a Lisp slot in TABLE to VAL. Most code should use this instead |
| @@ -4600,20 +4615,6 @@ enum { defined_GC_CHECK_STRING_BYTES = true }; | |||
| 4600 | enum { defined_GC_CHECK_STRING_BYTES = false }; | 4615 | enum { defined_GC_CHECK_STRING_BYTES = false }; |
| 4601 | #endif | 4616 | #endif |
| 4602 | 4617 | ||
| 4603 | /* Struct inside unions that are typically no larger and aligned enough. */ | ||
| 4604 | |||
| 4605 | union Aligned_Cons | ||
| 4606 | { | ||
| 4607 | struct Lisp_Cons s; | ||
| 4608 | double d; intmax_t i; void *p; | ||
| 4609 | }; | ||
| 4610 | |||
| 4611 | union Aligned_String | ||
| 4612 | { | ||
| 4613 | struct Lisp_String s; | ||
| 4614 | double d; intmax_t i; void *p; | ||
| 4615 | }; | ||
| 4616 | |||
| 4617 | /* True for stack-based cons and string implementations, respectively. | 4618 | /* True for stack-based cons and string implementations, respectively. |
| 4618 | Use stack-based strings only if stack-based cons also works. | 4619 | Use stack-based strings only if stack-based cons also works. |
| 4619 | Otherwise, STACK_CONS would create heap-based cons cells that | 4620 | Otherwise, STACK_CONS would create heap-based cons cells that |
| @@ -4621,18 +4622,16 @@ union Aligned_String | |||
| 4621 | 4622 | ||
| 4622 | enum | 4623 | enum |
| 4623 | { | 4624 | { |
| 4624 | USE_STACK_CONS = (USE_STACK_LISP_OBJECTS | 4625 | USE_STACK_CONS = USE_STACK_LISP_OBJECTS, |
| 4625 | && alignof (union Aligned_Cons) % GCALIGNMENT == 0), | ||
| 4626 | USE_STACK_STRING = (USE_STACK_CONS | 4626 | USE_STACK_STRING = (USE_STACK_CONS |
| 4627 | && !defined_GC_CHECK_STRING_BYTES | 4627 | && !defined_GC_CHECK_STRING_BYTES) |
| 4628 | && alignof (union Aligned_String) % GCALIGNMENT == 0) | ||
| 4629 | }; | 4628 | }; |
| 4630 | 4629 | ||
| 4631 | /* Auxiliary macros used for auto allocation of Lisp objects. Please | 4630 | /* Auxiliary macros used for auto allocation of Lisp objects. Please |
| 4632 | use these only in macros like AUTO_CONS that declare a local | 4631 | use these only in macros like AUTO_CONS that declare a local |
| 4633 | variable whose lifetime will be clear to the programmer. */ | 4632 | variable whose lifetime will be clear to the programmer. */ |
| 4634 | #define STACK_CONS(a, b) \ | 4633 | #define STACK_CONS(a, b) \ |
| 4635 | make_lisp_ptr (&((union Aligned_Cons) { { a, { b } } }).s, Lisp_Cons) | 4634 | make_lisp_ptr (&((struct Lisp_Cons) {{{a, {b}}}}), Lisp_Cons) |
| 4636 | #define AUTO_CONS_EXPR(a, b) \ | 4635 | #define AUTO_CONS_EXPR(a, b) \ |
| 4637 | (USE_STACK_CONS ? STACK_CONS (a, b) : Fcons (a, b)) | 4636 | (USE_STACK_CONS ? STACK_CONS (a, b) : Fcons (a, b)) |
| 4638 | 4637 | ||
| @@ -4678,7 +4677,7 @@ enum | |||
| 4678 | Lisp_Object name = \ | 4677 | Lisp_Object name = \ |
| 4679 | (USE_STACK_STRING \ | 4678 | (USE_STACK_STRING \ |
| 4680 | ? (make_lisp_ptr \ | 4679 | ? (make_lisp_ptr \ |
| 4681 | ((&((union Aligned_String) {{len, -1, 0, (unsigned char *) (str)}}).s), \ | 4680 | ((&(struct Lisp_String) {{{len, -1, 0, (unsigned char *) (str)}}}), \ |
| 4682 | Lisp_String)) \ | 4681 | Lisp_String)) \ |
| 4683 | : make_unibyte_string (str, len)) | 4682 | : make_unibyte_string (str, len)) |
| 4684 | 4683 | ||
diff --git a/src/lread.c b/src/lread.c index 33da8667228..b056f4aaf38 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -4043,14 +4043,14 @@ intern_sym (Lisp_Object sym, Lisp_Object obarray, Lisp_Object index) | |||
| 4043 | { | 4043 | { |
| 4044 | Lisp_Object *ptr; | 4044 | Lisp_Object *ptr; |
| 4045 | 4045 | ||
| 4046 | XSYMBOL (sym)->interned = (EQ (obarray, initial_obarray) | 4046 | XSYMBOL (sym)->u.s.interned = (EQ (obarray, initial_obarray) |
| 4047 | ? SYMBOL_INTERNED_IN_INITIAL_OBARRAY | 4047 | ? SYMBOL_INTERNED_IN_INITIAL_OBARRAY |
| 4048 | : SYMBOL_INTERNED); | 4048 | : SYMBOL_INTERNED); |
| 4049 | 4049 | ||
| 4050 | if (SREF (SYMBOL_NAME (sym), 0) == ':' && EQ (obarray, initial_obarray)) | 4050 | if (SREF (SYMBOL_NAME (sym), 0) == ':' && EQ (obarray, initial_obarray)) |
| 4051 | { | 4051 | { |
| 4052 | make_symbol_constant (sym); | 4052 | make_symbol_constant (sym); |
| 4053 | XSYMBOL (sym)->redirect = SYMBOL_PLAINVAL; | 4053 | XSYMBOL (sym)->u.s.redirect = SYMBOL_PLAINVAL; |
| 4054 | SET_SYMBOL_VAL (XSYMBOL (sym), sym); | 4054 | SET_SYMBOL_VAL (XSYMBOL (sym), sym); |
| 4055 | } | 4055 | } |
| 4056 | 4056 | ||
| @@ -4203,16 +4203,16 @@ usage: (unintern NAME OBARRAY) */) | |||
| 4203 | /* if (EQ (tem, Qnil) || EQ (tem, Qt)) | 4203 | /* if (EQ (tem, Qnil) || EQ (tem, Qt)) |
| 4204 | error ("Attempt to unintern t or nil"); */ | 4204 | error ("Attempt to unintern t or nil"); */ |
| 4205 | 4205 | ||
| 4206 | XSYMBOL (tem)->interned = SYMBOL_UNINTERNED; | 4206 | XSYMBOL (tem)->u.s.interned = SYMBOL_UNINTERNED; |
| 4207 | 4207 | ||
| 4208 | hash = oblookup_last_bucket_number; | 4208 | hash = oblookup_last_bucket_number; |
| 4209 | 4209 | ||
| 4210 | if (EQ (AREF (obarray, hash), tem)) | 4210 | if (EQ (AREF (obarray, hash), tem)) |
| 4211 | { | 4211 | { |
| 4212 | if (XSYMBOL (tem)->next) | 4212 | if (XSYMBOL (tem)->u.s.next) |
| 4213 | { | 4213 | { |
| 4214 | Lisp_Object sym; | 4214 | Lisp_Object sym; |
| 4215 | XSETSYMBOL (sym, XSYMBOL (tem)->next); | 4215 | XSETSYMBOL (sym, XSYMBOL (tem)->u.s.next); |
| 4216 | ASET (obarray, hash, sym); | 4216 | ASET (obarray, hash, sym); |
| 4217 | } | 4217 | } |
| 4218 | else | 4218 | else |
| @@ -4223,13 +4223,13 @@ usage: (unintern NAME OBARRAY) */) | |||
| 4223 | Lisp_Object tail, following; | 4223 | Lisp_Object tail, following; |
| 4224 | 4224 | ||
| 4225 | for (tail = AREF (obarray, hash); | 4225 | for (tail = AREF (obarray, hash); |
| 4226 | XSYMBOL (tail)->next; | 4226 | XSYMBOL (tail)->u.s.next; |
| 4227 | tail = following) | 4227 | tail = following) |
| 4228 | { | 4228 | { |
| 4229 | XSETSYMBOL (following, XSYMBOL (tail)->next); | 4229 | XSETSYMBOL (following, XSYMBOL (tail)->u.s.next); |
| 4230 | if (EQ (following, tem)) | 4230 | if (EQ (following, tem)) |
| 4231 | { | 4231 | { |
| 4232 | set_symbol_next (tail, XSYMBOL (following)->next); | 4232 | set_symbol_next (tail, XSYMBOL (following)->u.s.next); |
| 4233 | break; | 4233 | break; |
| 4234 | } | 4234 | } |
| 4235 | } | 4235 | } |
| @@ -4264,13 +4264,13 @@ oblookup (Lisp_Object obarray, register const char *ptr, ptrdiff_t size, ptrdiff | |||
| 4264 | else if (!SYMBOLP (bucket)) | 4264 | else if (!SYMBOLP (bucket)) |
| 4265 | error ("Bad data in guts of obarray"); /* Like CADR error message. */ | 4265 | error ("Bad data in guts of obarray"); /* Like CADR error message. */ |
| 4266 | else | 4266 | else |
| 4267 | for (tail = bucket; ; XSETSYMBOL (tail, XSYMBOL (tail)->next)) | 4267 | for (tail = bucket; ; XSETSYMBOL (tail, XSYMBOL (tail)->u.s.next)) |
| 4268 | { | 4268 | { |
| 4269 | if (SBYTES (SYMBOL_NAME (tail)) == size_byte | 4269 | if (SBYTES (SYMBOL_NAME (tail)) == size_byte |
| 4270 | && SCHARS (SYMBOL_NAME (tail)) == size | 4270 | && SCHARS (SYMBOL_NAME (tail)) == size |
| 4271 | && !memcmp (SDATA (SYMBOL_NAME (tail)), ptr, size_byte)) | 4271 | && !memcmp (SDATA (SYMBOL_NAME (tail)), ptr, size_byte)) |
| 4272 | return tail; | 4272 | return tail; |
| 4273 | else if (XSYMBOL (tail)->next == 0) | 4273 | else if (XSYMBOL (tail)->u.s.next == 0) |
| 4274 | break; | 4274 | break; |
| 4275 | } | 4275 | } |
| 4276 | XSETINT (tem, hash); | 4276 | XSETINT (tem, hash); |
| @@ -4290,9 +4290,9 @@ map_obarray (Lisp_Object obarray, void (*fn) (Lisp_Object, Lisp_Object), Lisp_Ob | |||
| 4290 | while (1) | 4290 | while (1) |
| 4291 | { | 4291 | { |
| 4292 | (*fn) (tail, arg); | 4292 | (*fn) (tail, arg); |
| 4293 | if (XSYMBOL (tail)->next == 0) | 4293 | if (XSYMBOL (tail)->u.s.next == 0) |
| 4294 | break; | 4294 | break; |
| 4295 | XSETSYMBOL (tail, XSYMBOL (tail)->next); | 4295 | XSETSYMBOL (tail, XSYMBOL (tail)->u.s.next); |
| 4296 | } | 4296 | } |
| 4297 | } | 4297 | } |
| 4298 | } | 4298 | } |
| @@ -4332,12 +4332,12 @@ init_obarray (void) | |||
| 4332 | DEFSYM (Qnil, "nil"); | 4332 | DEFSYM (Qnil, "nil"); |
| 4333 | SET_SYMBOL_VAL (XSYMBOL (Qnil), Qnil); | 4333 | SET_SYMBOL_VAL (XSYMBOL (Qnil), Qnil); |
| 4334 | make_symbol_constant (Qnil); | 4334 | make_symbol_constant (Qnil); |
| 4335 | XSYMBOL (Qnil)->declared_special = true; | 4335 | XSYMBOL (Qnil)->u.s.declared_special = true; |
| 4336 | 4336 | ||
| 4337 | DEFSYM (Qt, "t"); | 4337 | DEFSYM (Qt, "t"); |
| 4338 | SET_SYMBOL_VAL (XSYMBOL (Qt), Qt); | 4338 | SET_SYMBOL_VAL (XSYMBOL (Qt), Qt); |
| 4339 | make_symbol_constant (Qt); | 4339 | make_symbol_constant (Qt); |
| 4340 | XSYMBOL (Qt)->declared_special = true; | 4340 | XSYMBOL (Qt)->u.s.declared_special = true; |
| 4341 | 4341 | ||
| 4342 | /* Qt is correct even if CANNOT_DUMP. loadup.el will set to nil at end. */ | 4342 | /* Qt is correct even if CANNOT_DUMP. loadup.el will set to nil at end. */ |
| 4343 | Vpurify_flag = Qt; | 4343 | Vpurify_flag = Qt; |
| @@ -4361,7 +4361,7 @@ defalias (struct Lisp_Subr *sname, char *string) | |||
| 4361 | { | 4361 | { |
| 4362 | Lisp_Object sym; | 4362 | Lisp_Object sym; |
| 4363 | sym = intern (string); | 4363 | sym = intern (string); |
| 4364 | XSETSUBR (XSYMBOL (sym)->function, sname); | 4364 | XSETSUBR (XSYMBOL (sym)->u.s.function, sname); |
| 4365 | } | 4365 | } |
| 4366 | #endif /* NOTDEF */ | 4366 | #endif /* NOTDEF */ |
| 4367 | 4367 | ||
| @@ -4376,8 +4376,8 @@ defvar_int (struct Lisp_Intfwd *i_fwd, | |||
| 4376 | sym = intern_c_string (namestring); | 4376 | sym = intern_c_string (namestring); |
| 4377 | i_fwd->type = Lisp_Fwd_Int; | 4377 | i_fwd->type = Lisp_Fwd_Int; |
| 4378 | i_fwd->intvar = address; | 4378 | i_fwd->intvar = address; |
| 4379 | XSYMBOL (sym)->declared_special = 1; | 4379 | XSYMBOL (sym)->u.s.declared_special = true; |
| 4380 | XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; | 4380 | XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; |
| 4381 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)i_fwd); | 4381 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)i_fwd); |
| 4382 | } | 4382 | } |
| 4383 | 4383 | ||
| @@ -4391,8 +4391,8 @@ defvar_bool (struct Lisp_Boolfwd *b_fwd, | |||
| 4391 | sym = intern_c_string (namestring); | 4391 | sym = intern_c_string (namestring); |
| 4392 | b_fwd->type = Lisp_Fwd_Bool; | 4392 | b_fwd->type = Lisp_Fwd_Bool; |
| 4393 | b_fwd->boolvar = address; | 4393 | b_fwd->boolvar = address; |
| 4394 | XSYMBOL (sym)->declared_special = 1; | 4394 | XSYMBOL (sym)->u.s.declared_special = true; |
| 4395 | XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; | 4395 | XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; |
| 4396 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)b_fwd); | 4396 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)b_fwd); |
| 4397 | Vbyte_boolean_vars = Fcons (sym, Vbyte_boolean_vars); | 4397 | Vbyte_boolean_vars = Fcons (sym, Vbyte_boolean_vars); |
| 4398 | } | 4398 | } |
| @@ -4410,8 +4410,8 @@ defvar_lisp_nopro (struct Lisp_Objfwd *o_fwd, | |||
| 4410 | sym = intern_c_string (namestring); | 4410 | sym = intern_c_string (namestring); |
| 4411 | o_fwd->type = Lisp_Fwd_Obj; | 4411 | o_fwd->type = Lisp_Fwd_Obj; |
| 4412 | o_fwd->objvar = address; | 4412 | o_fwd->objvar = address; |
| 4413 | XSYMBOL (sym)->declared_special = 1; | 4413 | XSYMBOL (sym)->u.s.declared_special = true; |
| 4414 | XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; | 4414 | XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; |
| 4415 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)o_fwd); | 4415 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)o_fwd); |
| 4416 | } | 4416 | } |
| 4417 | 4417 | ||
| @@ -4434,8 +4434,8 @@ defvar_kboard (struct Lisp_Kboard_Objfwd *ko_fwd, | |||
| 4434 | sym = intern_c_string (namestring); | 4434 | sym = intern_c_string (namestring); |
| 4435 | ko_fwd->type = Lisp_Fwd_Kboard_Obj; | 4435 | ko_fwd->type = Lisp_Fwd_Kboard_Obj; |
| 4436 | ko_fwd->offset = offset; | 4436 | ko_fwd->offset = offset; |
| 4437 | XSYMBOL (sym)->declared_special = 1; | 4437 | XSYMBOL (sym)->u.s.declared_special = true; |
| 4438 | XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; | 4438 | XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; |
| 4439 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)ko_fwd); | 4439 | SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)ko_fwd); |
| 4440 | } | 4440 | } |
| 4441 | 4441 | ||
| @@ -4769,7 +4769,7 @@ to find all the symbols in an obarray, use `mapatoms'. */); | |||
| 4769 | DEFVAR_LISP ("values", Vvalues, | 4769 | DEFVAR_LISP ("values", Vvalues, |
| 4770 | doc: /* List of values of all expressions which were read, evaluated and printed. | 4770 | doc: /* List of values of all expressions which were read, evaluated and printed. |
| 4771 | Order is reverse chronological. */); | 4771 | Order is reverse chronological. */); |
| 4772 | XSYMBOL (intern ("values"))->declared_special = 0; | 4772 | XSYMBOL (intern ("values"))->u.s.declared_special = true; |
| 4773 | 4773 | ||
| 4774 | DEFVAR_LISP ("standard-input", Vstandard_input, | 4774 | DEFVAR_LISP ("standard-input", Vstandard_input, |
| 4775 | doc: /* Stream for read to get input from. | 4775 | doc: /* Stream for read to get input from. |
diff --git a/src/minibuf.c b/src/minibuf.c index a2f3324f99f..913c93001ef 100644 --- a/src/minibuf.c +++ b/src/minibuf.c | |||
| @@ -1280,8 +1280,8 @@ is used to further constrain the set of candidates. */) | |||
| 1280 | error ("Bad data in guts of obarray"); | 1280 | error ("Bad data in guts of obarray"); |
| 1281 | elt = bucket; | 1281 | elt = bucket; |
| 1282 | eltstring = elt; | 1282 | eltstring = elt; |
| 1283 | if (XSYMBOL (bucket)->next) | 1283 | if (XSYMBOL (bucket)->u.s.next) |
| 1284 | XSETSYMBOL (bucket, XSYMBOL (bucket)->next); | 1284 | XSETSYMBOL (bucket, XSYMBOL (bucket)->u.s.next); |
| 1285 | else | 1285 | else |
| 1286 | XSETFASTINT (bucket, 0); | 1286 | XSETFASTINT (bucket, 0); |
| 1287 | } | 1287 | } |
| @@ -1533,8 +1533,8 @@ with a space are ignored unless STRING itself starts with a space. */) | |||
| 1533 | error ("Bad data in guts of obarray"); | 1533 | error ("Bad data in guts of obarray"); |
| 1534 | elt = bucket; | 1534 | elt = bucket; |
| 1535 | eltstring = elt; | 1535 | eltstring = elt; |
| 1536 | if (XSYMBOL (bucket)->next) | 1536 | if (XSYMBOL (bucket)->u.s.next) |
| 1537 | XSETSYMBOL (bucket, XSYMBOL (bucket)->next); | 1537 | XSETSYMBOL (bucket, XSYMBOL (bucket)->u.s.next); |
| 1538 | else | 1538 | else |
| 1539 | XSETFASTINT (bucket, 0); | 1539 | XSETFASTINT (bucket, 0); |
| 1540 | } | 1540 | } |
| @@ -1754,9 +1754,9 @@ the values STRING, PREDICATE and `lambda'. */) | |||
| 1754 | tem = tail; | 1754 | tem = tail; |
| 1755 | break; | 1755 | break; |
| 1756 | } | 1756 | } |
| 1757 | if (XSYMBOL (tail)->next == 0) | 1757 | if (XSYMBOL (tail)->u.s.next == 0) |
| 1758 | break; | 1758 | break; |
| 1759 | XSETSYMBOL (tail, XSYMBOL (tail)->next); | 1759 | XSETSYMBOL (tail, XSYMBOL (tail)->u.s.next); |
| 1760 | } | 1760 | } |
| 1761 | } | 1761 | } |
| 1762 | } | 1762 | } |
diff --git a/src/thread.c b/src/thread.c index 7335833cf94..c03cdda0fae 100644 --- a/src/thread.c +++ b/src/thread.c | |||
| @@ -26,7 +26,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 26 | #include "coding.h" | 26 | #include "coding.h" |
| 27 | #include "syssignal.h" | 27 | #include "syssignal.h" |
| 28 | 28 | ||
| 29 | static struct GCALIGNED thread_state main_thread; | 29 | static struct thread_state main_thread; |
| 30 | 30 | ||
| 31 | struct thread_state *current_thread = &main_thread; | 31 | struct thread_state *current_thread = &main_thread; |
| 32 | 32 | ||
diff --git a/src/xterm.c b/src/xterm.c index 5e2fc6d20a8..28abfaecde9 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -12515,7 +12515,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 12515 | { | 12515 | { |
| 12516 | terminal->kboard = allocate_kboard (Qx); | 12516 | terminal->kboard = allocate_kboard (Qx); |
| 12517 | 12517 | ||
| 12518 | if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->function, Qunbound)) | 12518 | if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->u.s.function, Qunbound)) |
| 12519 | { | 12519 | { |
| 12520 | char *vendor = ServerVendor (dpy); | 12520 | char *vendor = ServerVendor (dpy); |
| 12521 | 12521 | ||