From 19634bef6a161a513ace9669341efac8e782b732 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Fri, 10 Nov 2017 19:10:44 -0800 Subject: [PATCH 2/2] Use alignas to fix GCALIGN-related bugs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- lib-src/make-docfile.c | 4 +- src/alloc.c | 211 ++++++++++++++++++------------------- src/buffer.c | 19 ++-- src/bytecode.c | 4 +- src/casefiddle.c | 4 +- src/cmds.c | 6 +- src/data.c | 76 +++++++------- src/doc.c | 2 +- src/eval.c | 59 +++++------ src/fns.c | 4 +- src/keyboard.c | 10 +- src/lisp.h | 277 ++++++++++++++++++++++++------------------------- src/lread.c | 52 +++++----- src/minibuf.c | 12 +-- src/thread.c | 2 +- src/xterm.c | 2 +- 16 files changed, 367 insertions(+), 377 deletions(-) diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c index ff84df94a6..9e4755b63a 100644 --- a/lib-src/make-docfile.c +++ b/lib-src/make-docfile.c @@ -667,9 +667,7 @@ close_emacs_globals (ptrdiff_t num_symbols) "#ifndef DEFINE_SYMBOLS\n" "extern\n" "#endif\n" - "struct {\n" - " struct GCALIGNED Lisp_Symbol s;\n" - "} lispsym[%td];\n"), + "struct Lisp_Symbol lispsym[%td];\n"), num_symbols); } diff --git a/src/alloc.c b/src/alloc.c index 5a44d7a9fc..3b87195b70 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -211,9 +211,9 @@ alloc_unexec_post (void) /* Mark, unmark, query mark bit of a Lisp string. S must be a pointer to a struct Lisp_String. */ -#define MARK_STRING(S) ((S)->size |= ARRAY_MARK_FLAG) -#define UNMARK_STRING(S) ((S)->size &= ~ARRAY_MARK_FLAG) -#define STRING_MARKED_P(S) (((S)->size & ARRAY_MARK_FLAG) != 0) +#define MARK_STRING(S) ((S)->u.s.size |= ARRAY_MARK_FLAG) +#define UNMARK_STRING(S) ((S)->u.s.size &= ~ARRAY_MARK_FLAG) +#define STRING_MARKED_P(S) (((S)->u.s.size & ARRAY_MARK_FLAG) != 0) #define VECTOR_MARK(V) ((V)->header.size |= ARRAY_MARK_FLAG) #define VECTOR_UNMARK(V) ((V)->header.size &= ~ARRAY_MARK_FLAG) @@ -1730,14 +1730,14 @@ static EMACS_INT total_string_bytes; string_free_list, return a pointer to its successor in the free-list. */ -#define NEXT_FREE_LISP_STRING(S) (*(struct Lisp_String **) (S)) +#define NEXT_FREE_LISP_STRING(S) ((S)->u.next) /* Return a pointer to the sdata structure belonging to Lisp string S. S must be live, i.e. S->data must not be null. S->data is actually a pointer to the `u.data' member of its sdata structure; the structure starts at a constant offset in front of that. */ -#define SDATA_OF_STRING(S) ((sdata *) ((S)->data - SDATA_DATA_OFFSET)) +#define SDATA_OF_STRING(S) ((sdata *) ((S)->u.s.data - SDATA_DATA_OFFSET)) #ifdef GC_CHECK_STRING_OVERRUN @@ -1818,9 +1818,10 @@ ptrdiff_t string_bytes (struct Lisp_String *s) { ptrdiff_t nbytes = - (s->size_byte < 0 ? s->size & ~ARRAY_MARK_FLAG : s->size_byte); + (s->u.s.size_byte < 0 ? s->u.s.size & ~ARRAY_MARK_FLAG : s->u.s.size_byte); - if (!PURE_P (s) && s->data && nbytes != SDATA_NBYTES (SDATA_OF_STRING (s))) + if (!PURE_P (s) && s->u.s.data + && nbytes != SDATA_NBYTES (SDATA_OF_STRING (s))) emacs_abort (); return nbytes; } @@ -1926,7 +1927,7 @@ allocate_string (void) { s = b->strings + i; /* Every string on a free list should have NULL data pointer. */ - s->data = NULL; + s->u.s.data = NULL; NEXT_FREE_LISP_STRING (s) = string_free_list; string_free_list = s; } @@ -1965,10 +1966,10 @@ allocate_string (void) /* Set up Lisp_String S for holding NCHARS characters, NBYTES bytes, - plus a NUL byte at the end. Allocate an sdata structure for S, and - set S->data to its `u.data' member. Store a NUL byte at the end of - S->data. Set S->size to NCHARS and S->size_byte to NBYTES. Free - S->data if it was initially non-null. */ + plus a NUL byte at the end. Allocate an sdata structure DATA for + S, and set S->u.s.data to SDATA->u.data. Store a NUL byte at the + end of S->u.s.data. Set S->u.s.size to NCHARS and S->u.s.size_byte + to NBYTES. Free S->u.s.data if it was initially non-null. */ void allocate_string_data (struct Lisp_String *s, @@ -1984,7 +1985,7 @@ allocate_string_data (struct Lisp_String *s, /* Determine the number of bytes needed to store NBYTES bytes of string data. */ needed = SDATA_SIZE (nbytes); - if (s->data) + if (s->u.s.data) { old_data = SDATA_OF_STRING (s); old_nbytes = STRING_BYTES (s); @@ -2043,13 +2044,13 @@ allocate_string_data (struct Lisp_String *s, MALLOC_UNBLOCK_INPUT; - s->data = SDATA_DATA (data); + s->u.s.data = SDATA_DATA (data); #ifdef GC_CHECK_STRING_BYTES SDATA_NBYTES (data) = nbytes; #endif - s->size = nchars; - s->size_byte = nbytes; - s->data[nbytes] = '\0'; + s->u.s.size = nchars; + s->u.s.size_byte = nbytes; + s->u.s.data[nbytes] = '\0'; #ifdef GC_CHECK_STRING_OVERRUN memcpy ((char *) data + needed, string_overrun_cookie, GC_STRING_OVERRUN_COOKIE_SIZE); @@ -2093,7 +2094,7 @@ sweep_strings (void) { struct Lisp_String *s = b->strings + i; - if (s->data) + if (s->u.s.data) { /* String was not on free-list before. */ if (STRING_MARKED_P (s)) @@ -2102,7 +2103,7 @@ sweep_strings (void) UNMARK_STRING (s); /* Do not use string_(set|get)_intervals here. */ - s->intervals = balance_intervals (s->intervals); + s->u.s.intervals = balance_intervals (s->u.s.intervals); ++total_strings; total_string_bytes += STRING_BYTES (s); @@ -2125,7 +2126,7 @@ sweep_strings (void) /* Reset the strings's `data' member so that we know it's free. */ - s->data = NULL; + s->u.s.data = NULL; /* Put the string on the free-list. */ NEXT_FREE_LISP_STRING (s) = string_free_list; @@ -2264,7 +2265,7 @@ compact_small_strings (void) { eassert (tb != b || to < from); memmove (to, from, nbytes + GC_STRING_EXTRA); - to->string->data = SDATA_DATA (to); + to->string->u.s.data = SDATA_DATA (to); } /* Advance past the sdata we copied to. */ @@ -2544,7 +2545,7 @@ make_uninit_multibyte_string (EMACS_INT nchars, EMACS_INT nbytes) return empty_multibyte_string; s = allocate_string (); - s->intervals = NULL; + s->u.s.intervals = NULL; allocate_string_data (s, nchars, nbytes); XSETSTRING (string, s); string_chars_consed += nbytes; @@ -2729,8 +2730,8 @@ static struct Lisp_Cons *cons_free_list; void free_cons (struct Lisp_Cons *ptr) { - ptr->u.chain = cons_free_list; - ptr->car = Vdead; + ptr->u.s.u.chain = cons_free_list; + ptr->u.s.car = Vdead; cons_free_list = ptr; consing_since_gc -= sizeof *ptr; total_free_conses++; @@ -2749,7 +2750,7 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0, /* We use the cdr for chaining the free list so that we won't use the same field that has the mark bit. */ XSETCONS (val, cons_free_list); - cons_free_list = cons_free_list->u.chain; + cons_free_list = cons_free_list->u.s.u.chain; } else { @@ -2786,7 +2787,7 @@ check_cons_list (void) struct Lisp_Cons *tail = cons_free_list; while (tail) - tail = tail->u.chain; + tail = tail->u.s.u.chain; } #endif @@ -3543,27 +3544,17 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT Symbol Allocation ***********************************************************************/ -/* Like struct Lisp_Symbol, but padded so that the size is a multiple - of the required alignment. */ - -union aligned_Lisp_Symbol -{ - struct Lisp_Symbol s; - unsigned char c[(sizeof (struct Lisp_Symbol) + GCALIGNMENT - 1) - & -GCALIGNMENT]; -}; - /* Each symbol_block is just under 1020 bytes long, since malloc really allocates in units of powers of two and uses 4 bytes for its own overhead. */ #define SYMBOL_BLOCK_SIZE \ - ((1020 - sizeof (struct symbol_block *)) / sizeof (union aligned_Lisp_Symbol)) + ((1020 - sizeof (struct symbol_block *)) / sizeof (struct Lisp_Symbol)) struct symbol_block { /* Place `symbols' first, to preserve alignment. */ - union aligned_Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE]; + struct Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE]; struct symbol_block *next; }; @@ -3587,7 +3578,7 @@ static struct Lisp_Symbol *symbol_free_list; static void set_symbol_name (Lisp_Object sym, Lisp_Object name) { - XSYMBOL (sym)->name = name; + XSYMBOL (sym)->u.s.name = name; } void @@ -3596,15 +3587,15 @@ init_symbol (Lisp_Object val, Lisp_Object name) struct Lisp_Symbol *p = XSYMBOL (val); set_symbol_name (val, name); set_symbol_plist (val, Qnil); - p->redirect = SYMBOL_PLAINVAL; + p->u.s.redirect = SYMBOL_PLAINVAL; SET_SYMBOL_VAL (p, Qunbound); set_symbol_function (val, Qnil); set_symbol_next (val, NULL); - p->gcmarkbit = false; - p->interned = SYMBOL_UNINTERNED; - p->trapped_write = SYMBOL_UNTRAPPED_WRITE; - p->declared_special = false; - p->pinned = false; + p->u.s.gcmarkbit = false; + p->u.s.interned = SYMBOL_UNINTERNED; + p->u.s.trapped_write = SYMBOL_UNTRAPPED_WRITE; + p->u.s.declared_special = false; + p->u.s.pinned = false; } 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. */) if (symbol_free_list) { XSETSYMBOL (val, symbol_free_list); - symbol_free_list = symbol_free_list->next; + symbol_free_list = symbol_free_list->u.s.next; } else { @@ -3634,7 +3625,7 @@ Its value is void, and its function definition and property list are nil. */) symbol_block_index = 0; total_free_symbols += SYMBOL_BLOCK_SIZE; } - XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index].s); + XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index]); symbol_block_index++; } @@ -4587,7 +4578,7 @@ live_string_holding (struct mem_node *m, void *p) if (0 <= offset && offset < STRING_BLOCK_SIZE * sizeof b->strings[0]) { struct Lisp_String *s = p = cp -= offset % sizeof b->strings[0]; - if (s->data) + if (s->u.s.data) return make_lisp_ptr (s, Lisp_String); } } @@ -4621,7 +4612,7 @@ live_cons_holding (struct mem_node *m, void *p) || offset / sizeof b->conses[0] < cons_block_index)) { struct Lisp_Cons *s = p = cp -= offset % sizeof b->conses[0]; - if (!EQ (s->car, Vdead)) + if (!EQ (s->u.s.car, Vdead)) return make_lisp_ptr (s, Lisp_Cons); } } @@ -4656,7 +4647,7 @@ live_symbol_holding (struct mem_node *m, void *p) || offset / sizeof b->symbols[0] < symbol_block_index)) { struct Lisp_Symbol *s = p = cp -= offset % sizeof b->symbols[0]; - if (!EQ (s->function, Vdead)) + if (!EQ (s->u.s.function, Vdead)) return make_lisp_symbol (s); } } @@ -4984,7 +4975,7 @@ mark_memory (void *start, void *end) Lisp_Object obj = build_string ("test"); struct Lisp_String *s = XSTRING (obj); Fgarbage_collect (); - fprintf (stderr, "test '%s'\n", s->data); + fprintf (stderr, "test '%s'\n", s->u.s.data); return Qnil; } @@ -5484,16 +5475,16 @@ make_pure_string (const char *data, { Lisp_Object string; struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String); - s->data = (unsigned char *) find_string_data_in_pure (data, nbytes); - if (s->data == NULL) + s->u.s.data = (unsigned char *) find_string_data_in_pure (data, nbytes); + if (s->u.s.data == NULL) { - s->data = pure_alloc (nbytes + 1, -1); - memcpy (s->data, data, nbytes); - s->data[nbytes] = '\0'; + s->u.s.data = pure_alloc (nbytes + 1, -1); + memcpy (s->u.s.data, data, nbytes); + s->u.s.data[nbytes] = '\0'; } - s->size = nchars; - s->size_byte = multibyte ? nbytes : -1; - s->intervals = NULL; + s->u.s.size = nchars; + s->u.s.size_byte = multibyte ? nbytes : -1; + s->u.s.intervals = NULL; XSETSTRING (string, s); return string; } @@ -5506,10 +5497,10 @@ make_pure_c_string (const char *data, ptrdiff_t nchars) { Lisp_Object string; struct Lisp_String *s = pure_alloc (sizeof *s, Lisp_String); - s->size = nchars; - s->size_byte = -1; - s->data = (unsigned char *) data; - s->intervals = NULL; + s->u.s.size = nchars; + s->u.s.size_byte = -1; + s->u.s.data = (unsigned char *) data; + s->u.s.intervals = NULL; XSETSTRING (string, s); return string; } @@ -5620,7 +5611,7 @@ purecopy (Lisp_Object obj) || SUBRP (obj)) return obj; /* Already pure. */ - if (STRINGP (obj) && XSTRING (obj)->intervals) + if (STRINGP (obj) && XSTRING (obj)->u.s.intervals) message_with_string ("Dropping text-properties while making string `%s' pure", obj, true); @@ -5675,10 +5666,10 @@ purecopy (Lisp_Object obj) } else if (SYMBOLP (obj)) { - if (!XSYMBOL (obj)->pinned && !c_symbol_p (XSYMBOL (obj))) + if (!XSYMBOL (obj)->u.s.pinned && !c_symbol_p (XSYMBOL (obj))) { /* We can't purify them, but they appear in many pure objects. Mark them as `pinned' so we know to mark them at every GC cycle. */ - XSYMBOL (obj)->pinned = true; + XSYMBOL (obj)->u.s.pinned = true; symbol_block_pinned = symbol_block; } /* Don't hash-cons it. */ @@ -5891,10 +5882,10 @@ mark_pinned_symbols (void) for (sblk = symbol_block_pinned; sblk; sblk = sblk->next) { - union aligned_Lisp_Symbol *sym = sblk->symbols, *end = sym + lim; + struct Lisp_Symbol *sym = sblk->symbols, *end = sym + lim; for (; sym < end; ++sym) - if (sym->s.pinned) - mark_object (make_lisp_symbol (&sym->s)); + if (sym->u.s.pinned) + mark_object (make_lisp_symbol (sym)); lim = SYMBOL_BLOCK_SIZE; } @@ -6256,7 +6247,7 @@ mark_char_table (struct Lisp_Vector *ptr, enum pvec_type pvectype) { Lisp_Object val = ptr->contents[i]; - if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->gcmarkbit)) + if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->u.s.gcmarkbit)) continue; if (SUB_CHAR_TABLE_P (val)) { @@ -6499,7 +6490,7 @@ mark_object (Lisp_Object arg) break; CHECK_ALLOCATED_AND_LIVE (live_string_p); MARK_STRING (ptr); - MARK_INTERVAL_TREE (ptr->intervals); + MARK_INTERVAL_TREE (ptr->u.s.intervals); #ifdef GC_CHECK_STRING_BYTES /* Check that the string size recorded in the string is the same as the one recorded in the sdata structure. */ @@ -6640,17 +6631,17 @@ mark_object (Lisp_Object arg) case Lisp_Symbol: { - register struct Lisp_Symbol *ptr = XSYMBOL (obj); + struct Lisp_Symbol *ptr = XSYMBOL (obj); nextsym: - if (ptr->gcmarkbit) + if (ptr->u.s.gcmarkbit) break; CHECK_ALLOCATED_AND_LIVE_SYMBOL (); - ptr->gcmarkbit = 1; + ptr->u.s.gcmarkbit = 1; /* Attempt to catch bogus objects. */ - eassert (valid_lisp_object_p (ptr->function)); - mark_object (ptr->function); - mark_object (ptr->plist); - switch (ptr->redirect) + eassert (valid_lisp_object_p (ptr->u.s.function)); + mark_object (ptr->u.s.function); + mark_object (ptr->u.s.plist); + switch (ptr->u.s.redirect) { case SYMBOL_PLAINVAL: mark_object (SYMBOL_VAL (ptr)); break; case SYMBOL_VARALIAS: @@ -6671,11 +6662,11 @@ mark_object (Lisp_Object arg) break; default: emacs_abort (); } - if (!PURE_P (XSTRING (ptr->name))) - MARK_STRING (XSTRING (ptr->name)); - MARK_INTERVAL_TREE (string_intervals (ptr->name)); + if (!PURE_P (XSTRING (ptr->u.s.name))) + MARK_STRING (XSTRING (ptr->u.s.name)); + MARK_INTERVAL_TREE (string_intervals (ptr->u.s.name)); /* Inner loop to mark next symbol in this bucket, if any. */ - po = ptr = ptr->next; + po = ptr = ptr->u.s.next; if (ptr) goto nextsym; } @@ -6729,14 +6720,14 @@ mark_object (Lisp_Object arg) CHECK_ALLOCATED_AND_LIVE (live_cons_p); CONS_MARK (ptr); /* If the cdr is nil, avoid recursion for the car. */ - if (EQ (ptr->u.cdr, Qnil)) + if (EQ (ptr->u.s.u.cdr, Qnil)) { - obj = ptr->car; + obj = ptr->u.s.car; cdr_count = 0; goto loop; } - mark_object (ptr->car); - obj = ptr->u.cdr; + mark_object (ptr->u.s.car); + obj = ptr->u.s.u.cdr; cdr_count++; if (cdr_count == mark_object_loop_halt) emacs_abort (); @@ -6797,7 +6788,7 @@ survives_gc_p (Lisp_Object obj) break; case Lisp_Symbol: - survives_p = XSYMBOL (obj)->gcmarkbit; + survives_p = XSYMBOL (obj)->u.s.gcmarkbit; break; case Lisp_Misc: @@ -6873,9 +6864,9 @@ sweep_conses (void) if (!CONS_MARKED_P (&cblk->conses[pos])) { this_free++; - cblk->conses[pos].u.chain = cons_free_list; + cblk->conses[pos].u.s.u.chain = cons_free_list; cons_free_list = &cblk->conses[pos]; - cons_free_list->car = Vdead; + cons_free_list->u.s.car = Vdead; } else { @@ -6894,7 +6885,7 @@ sweep_conses (void) { *cprev = cblk->next; /* Unhook from the free list. */ - cons_free_list = cblk->conses[0].u.chain; + cons_free_list = cblk->conses[0].u.s.u.chain; lisp_align_free (cblk); } else @@ -7018,39 +7009,39 @@ sweep_symbols (void) symbol_free_list = NULL; for (int i = 0; i < ARRAYELTS (lispsym); i++) - lispsym[i].s.gcmarkbit = 0; + lispsym[i].u.s.gcmarkbit = 0; for (sblk = symbol_block; sblk; sblk = *sprev) { int this_free = 0; - union aligned_Lisp_Symbol *sym = sblk->symbols; - union aligned_Lisp_Symbol *end = sym + lim; + struct Lisp_Symbol *sym = sblk->symbols; + struct Lisp_Symbol *end = sym + lim; for (; sym < end; ++sym) { - if (!sym->s.gcmarkbit) + if (!sym->u.s.gcmarkbit) { - if (sym->s.redirect == SYMBOL_LOCALIZED) + if (sym->u.s.redirect == SYMBOL_LOCALIZED) { - xfree (SYMBOL_BLV (&sym->s)); + xfree (SYMBOL_BLV (sym)); /* At every GC we sweep all symbol_blocks and rebuild the symbol_free_list, so those symbols which stayed unused between the two will be re-swept. So we have to make sure we don't re-free this blv next time we sweep this symbol_block (bug#29066). */ - sym->s.redirect = SYMBOL_PLAINVAL; + sym->u.s.redirect = SYMBOL_PLAINVAL; } - sym->s.next = symbol_free_list; - symbol_free_list = &sym->s; - symbol_free_list->function = Vdead; + sym->u.s.next = symbol_free_list; + symbol_free_list = sym; + symbol_free_list->u.s.function = Vdead; ++this_free; } else { ++num_used; - sym->s.gcmarkbit = 0; + sym->u.s.gcmarkbit = 0; /* Attempt to catch bogus objects. */ - eassert (valid_lisp_object_p (sym->s.function)); + eassert (valid_lisp_object_p (sym->u.s.function)); } } @@ -7062,7 +7053,7 @@ sweep_symbols (void) { *sprev = sblk->next; /* Unhook from the free list. */ - symbol_free_list = sblk->symbols[0].s.next; + symbol_free_list = sblk->symbols[0].u.s.next; lisp_free (sblk); } else @@ -7289,10 +7280,10 @@ symbol_uses_obj (Lisp_Object symbol, Lisp_Object obj) struct Lisp_Symbol *sym = XSYMBOL (symbol); Lisp_Object val = find_symbol_value (symbol); return (EQ (val, obj) - || EQ (sym->function, obj) - || (!NILP (sym->function) - && COMPILEDP (sym->function) - && EQ (AREF (sym->function, COMPILED_BYTECODE), obj)) + || EQ (sym->u.s.function, obj) + || (!NILP (sym->u.s.function) + && COMPILEDP (sym->u.s.function) + && EQ (AREF (sym->u.s.function, COMPILED_BYTECODE), obj)) || (!NILP (val) && COMPILEDP (val) && EQ (AREF (val, COMPILED_BYTECODE), obj))); @@ -7323,15 +7314,15 @@ which_symbols (Lisp_Object obj, EMACS_INT find_max) for (sblk = symbol_block; sblk; sblk = sblk->next) { - union aligned_Lisp_Symbol *aligned_sym = sblk->symbols; + struct Lisp_Symbol *asym = sblk->symbols; int bn; - for (bn = 0; bn < SYMBOL_BLOCK_SIZE; bn++, aligned_sym++) + for (bn = 0; bn < SYMBOL_BLOCK_SIZE; bn++, asym++) { if (sblk == symbol_block && bn >= symbol_block_index) break; - Lisp_Object sym = make_lisp_symbol (&aligned_sym->s); + Lisp_Object sym = make_lisp_symbol (asym); if (symbol_uses_obj (sym, obj)) { found = Fcons (sym, found); diff --git a/src/buffer.c b/src/buffer.c index edeed55e8b..4ae5e811b0 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -61,7 +61,7 @@ struct buffer *all_buffers; Setting the default value also goes through the alist of buffers and stores into each buffer that does not say it has a local value. */ -struct GCALIGNED buffer buffer_defaults; +struct buffer buffer_defaults; /* This structure marks which slots in a buffer have corresponding default values in buffer_defaults. @@ -84,7 +84,7 @@ struct buffer buffer_local_flags; /* This structure holds the names of symbols whose values may be buffer-local. It is indexed and accessed in the same way as the above. */ -struct GCALIGNED buffer buffer_local_symbols; +struct buffer buffer_local_symbols; /* Return the symbol of the per-buffer variable at offset OFFSET in the buffer structure. */ @@ -1021,7 +1021,8 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too) newlist = Fcons (elt, newlist); } newlist = Fnreverse (newlist); - if (XSYMBOL (local_var)->trapped_write == SYMBOL_TRAPPED_WRITE) + if (XSYMBOL (local_var)->u.s.trapped_write + == SYMBOL_TRAPPED_WRITE) notify_variable_watchers (local_var, newlist, Qmakunbound, Fcurrent_buffer ()); XSETCDR (XCAR (tmp), newlist); @@ -1034,7 +1035,7 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too) else XSETCDR (last, XCDR (tmp)); - if (XSYMBOL (local_var)->trapped_write == SYMBOL_TRAPPED_WRITE) + if (XSYMBOL (local_var)->u.s.trapped_write == SYMBOL_TRAPPED_WRITE) notify_variable_watchers (local_var, Qnil, Qmakunbound, Fcurrent_buffer ()); } @@ -1166,7 +1167,7 @@ buffer_local_value (Lisp_Object variable, Lisp_Object buffer) sym = XSYMBOL (variable); start: - switch (sym->redirect) + switch (sym->u.s.redirect) { case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; case SYMBOL_PLAINVAL: result = SYMBOL_VAL (sym); break; @@ -2096,7 +2097,7 @@ void set_buffer_internal_2 (register struct buffer *b) { Lisp_Object var = XCAR (XCAR (tail)); struct Lisp_Symbol *sym = XSYMBOL (var); - if (sym->redirect == SYMBOL_LOCALIZED /* Just to be sure. */ + if (sym->u.s.redirect == SYMBOL_LOCALIZED /* Just to be sure. */ && SYMBOL_BLV (sym)->fwd) /* Just reference the variable to cause it to become set for this buffer. */ @@ -2752,7 +2753,7 @@ swap_out_buffer_local_variables (struct buffer *b) for (alist = oalist; CONSP (alist); alist = XCDR (alist)) { Lisp_Object sym = XCAR (XCAR (alist)); - eassert (XSYMBOL (sym)->redirect == SYMBOL_LOCALIZED); + eassert (XSYMBOL (sym)->u.s.redirect == SYMBOL_LOCALIZED); /* Need not do anything if some other buffer's binding is now cached. */ if (EQ (SYMBOL_BLV (XSYMBOL (sym))->where, buffer)) @@ -5423,8 +5424,8 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring, bo_fwd->type = Lisp_Fwd_Buffer_Obj; bo_fwd->offset = offset; bo_fwd->predicate = predicate; - sym->declared_special = 1; - sym->redirect = SYMBOL_FORWARDED; + sym->u.s.declared_special = true; + sym->u.s.redirect = SYMBOL_FORWARDED; SET_SYMBOL_FWD (sym, (union Lisp_Fwd *) bo_fwd); XSETSYMBOL (PER_BUFFER_SYMBOL (offset), sym); diff --git a/src/bytecode.c b/src/bytecode.c index 50c7abe289..ebaf3c3a7f 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, { Lisp_Object v1 = vectorp[op], v2; if (!SYMBOLP (v1) - || XSYMBOL (v1)->redirect != SYMBOL_PLAINVAL + || XSYMBOL (v1)->u.s.redirect != SYMBOL_PLAINVAL || (v2 = SYMBOL_VAL (XSYMBOL (v1)), EQ (v2, Qunbound))) v2 = Fsymbol_value (v1); PUSH (v2); @@ -558,7 +558,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, /* Inline the most common case. */ if (SYMBOLP (sym) && !EQ (val, Qunbound) - && !XSYMBOL (sym)->redirect + && !XSYMBOL (sym)->u.s.redirect && !SYMBOL_TRAPPED_WRITE_P (sym)) SET_SYMBOL_VAL (XSYMBOL (sym), val); else diff --git a/src/casefiddle.c b/src/casefiddle.c index 8f564edeb9..7b34f78a5c 100644 --- a/src/casefiddle.c +++ b/src/casefiddle.c @@ -133,9 +133,9 @@ case_character_impl (struct casing_str_buf *buf, struct Lisp_String *str = XSTRING (prop); if (STRING_BYTES (str) <= sizeof buf->data) { - buf->len_chars = str->size; + buf->len_chars = str->u.s.size; buf->len_bytes = STRING_BYTES (str); - memcpy (buf->data, str->data, buf->len_bytes); + memcpy (buf->data, str->u.s.data, buf->len_bytes); return 1; } } diff --git a/src/cmds.c b/src/cmds.c index e4c0c86691..1788f22fe5 100644 --- a/src/cmds.c +++ b/src/cmds.c @@ -421,11 +421,11 @@ internal_self_insert (int c, EMACS_INT n) and the hook has a non-nil `no-self-insert' property, return right away--don't really self-insert. */ if (SYMBOLP (sym) && ! NILP (sym) - && ! NILP (XSYMBOL (sym)->function) - && SYMBOLP (XSYMBOL (sym)->function)) + && ! NILP (XSYMBOL (sym)->u.s.function) + && SYMBOLP (XSYMBOL (sym)->u.s.function)) { Lisp_Object prop; - prop = Fget (XSYMBOL (sym)->function, intern ("no-self-insert")); + prop = Fget (XSYMBOL (sym)->u.s.function, intern ("no-self-insert")); if (! NILP (prop)) return 1; } diff --git a/src/data.c b/src/data.c index ef7210fbfa..b4f6fd5c65 100644 --- a/src/data.c +++ b/src/data.c @@ -670,7 +670,7 @@ global value outside of any lexical scope. */) sym = XSYMBOL (symbol); start: - switch (sym->redirect) + switch (sym->u.s.redirect) { case SYMBOL_PLAINVAL: valcontents = SYMBOL_VAL (sym); break; case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; @@ -704,10 +704,10 @@ global value outside of any lexical scope. */) expect `t' in particular, rather than any true value. */ DEFUN ("fboundp", Ffboundp, Sfboundp, 1, 1, 0, doc: /* Return t if SYMBOL's function definition is not void. */) - (register Lisp_Object symbol) + (Lisp_Object symbol) { CHECK_SYMBOL (symbol); - return NILP (XSYMBOL (symbol)->function) ? Qnil : Qt; + return NILP (XSYMBOL (symbol)->u.s.function) ? Qnil : Qt; } DEFUN ("makunbound", Fmakunbound, Smakunbound, 1, 1, 0, @@ -736,18 +736,18 @@ Return SYMBOL. */) DEFUN ("symbol-function", Fsymbol_function, Ssymbol_function, 1, 1, 0, doc: /* Return SYMBOL's function definition, or nil if that is void. */) - (register Lisp_Object symbol) + (Lisp_Object symbol) { CHECK_SYMBOL (symbol); - return XSYMBOL (symbol)->function; + return XSYMBOL (symbol)->u.s.function; } DEFUN ("symbol-plist", Fsymbol_plist, Ssymbol_plist, 1, 1, 0, doc: /* Return SYMBOL's property list. */) - (register Lisp_Object symbol) + (Lisp_Object symbol) { CHECK_SYMBOL (symbol); - return XSYMBOL (symbol)->plist; + return XSYMBOL (symbol)->u.s.plist; } DEFUN ("symbol-name", Fsymbol_name, Ssymbol_name, 1, 1, 0, @@ -771,7 +771,7 @@ DEFUN ("fset", Ffset, Sfset, 2, 2, 0, if (NILP (symbol)) xsignal1 (Qsetting_constant, symbol); - function = XSYMBOL (symbol)->function; + function = XSYMBOL (symbol)->u.s.function; if (!NILP (Vautoload_queue) && !NILP (function)) Vautoload_queue = Fcons (Fcons (symbol, function), Vautoload_queue); @@ -814,7 +814,7 @@ The return value is undefined. */) { /* Only add autoload entries after dumping, because the ones before are not useful and else we get loads of them from the loaddefs.el. */ - if (AUTOLOADP (XSYMBOL (symbol)->function)) + if (AUTOLOADP (XSYMBOL (symbol)->u.s.function)) /* Remember that the function was already an autoload. */ LOADHIST_ATTACH (Fcons (Qt, symbol)); LOADHIST_ATTACH (Fcons (autoload ? Qautoload : Qdefun, symbol)); @@ -940,10 +940,10 @@ indirect_variable (struct Lisp_Symbol *symbol) hare = tortoise = symbol; - while (hare->redirect == SYMBOL_VARALIAS) + while (hare->u.s.redirect == SYMBOL_VARALIAS) { hare = SYMBOL_ALIAS (hare); - if (hare->redirect != SYMBOL_VARALIAS) + if (hare->u.s.redirect != SYMBOL_VARALIAS) break; hare = SYMBOL_ALIAS (hare); @@ -1247,7 +1247,7 @@ find_symbol_value (Lisp_Object symbol) sym = XSYMBOL (symbol); start: - switch (sym->redirect) + switch (sym->u.s.redirect) { case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; case SYMBOL_PLAINVAL: return SYMBOL_VAL (sym); @@ -1310,7 +1310,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where, CHECK_SYMBOL (symbol); sym = XSYMBOL (symbol); - switch (sym->trapped_write) + switch (sym->u.s.trapped_write) { case SYMBOL_NOWRITE: if (NILP (Fkeywordp (symbol)) @@ -1336,7 +1336,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where, } start: - switch (sym->redirect) + switch (sym->u.s.redirect) { case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; case SYMBOL_PLAINVAL: SET_SYMBOL_VAL (sym , newval); return; @@ -1436,7 +1436,7 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where, if (voide) { /* If storing void (making the symbol void), forward only through buffer-local indicator, not through Lisp_Objfwd, etc. */ - sym->redirect = SYMBOL_PLAINVAL; + sym->u.s.redirect = SYMBOL_PLAINVAL; SET_SYMBOL_VAL (sym, newval); } else @@ -1452,9 +1452,9 @@ static void set_symbol_trapped_write (Lisp_Object symbol, enum symbol_trapped_write trap) { struct Lisp_Symbol *sym = XSYMBOL (symbol); - if (sym->trapped_write == SYMBOL_NOWRITE) + if (sym->u.s.trapped_write == SYMBOL_NOWRITE) xsignal1 (Qtrapping_constant, symbol); - sym->trapped_write = trap; + sym->u.s.trapped_write = trap; } static void @@ -1469,7 +1469,7 @@ harmonize_variable_watchers (Lisp_Object alias, Lisp_Object base_variable) if (!EQ (base_variable, alias) && EQ (base_variable, Findirect_variable (alias))) set_symbol_trapped_write - (alias, XSYMBOL (base_variable)->trapped_write); + (alias, XSYMBOL (base_variable)->u.s.trapped_write); } DEFUN ("add-variable-watcher", Fadd_variable_watcher, Sadd_variable_watcher, @@ -1583,7 +1583,7 @@ default_value (Lisp_Object symbol) sym = XSYMBOL (symbol); start: - switch (sym->redirect) + switch (sym->u.s.redirect) { case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; case SYMBOL_PLAINVAL: return SYMBOL_VAL (sym); @@ -1653,7 +1653,7 @@ set_default_internal (Lisp_Object symbol, Lisp_Object value, CHECK_SYMBOL (symbol); sym = XSYMBOL (symbol); - switch (sym->trapped_write) + switch (sym->u.s.trapped_write) { case SYMBOL_NOWRITE: if (NILP (Fkeywordp (symbol)) @@ -1665,7 +1665,7 @@ set_default_internal (Lisp_Object symbol, Lisp_Object value, case SYMBOL_TRAPPED_WRITE: /* Don't notify here if we're going to call Fset anyway. */ - if (sym->redirect != SYMBOL_PLAINVAL + if (sym->u.s.redirect != SYMBOL_PLAINVAL /* Setting due to thread switching doesn't count. */ && bindflag != SET_INTERNAL_THREAD_SWITCH) notify_variable_watchers (symbol, value, Qset_default, Qnil); @@ -1677,7 +1677,7 @@ set_default_internal (Lisp_Object symbol, Lisp_Object value, } start: - switch (sym->redirect) + switch (sym->u.s.redirect) { case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; 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. sym = XSYMBOL (variable); start: - switch (sym->redirect) + switch (sym->u.s.redirect) { case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; case SYMBOL_PLAINVAL: @@ -1857,7 +1857,7 @@ The function `default-value' gets the default value and `set-default' sets it. if (!blv) { blv = make_blv (sym, forwarded, valcontents); - sym->redirect = SYMBOL_LOCALIZED; + sym->u.s.redirect = SYMBOL_LOCALIZED; SET_SYMBOL_BLV (sym, blv); } @@ -1897,7 +1897,7 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */) sym = XSYMBOL (variable); start: - switch (sym->redirect) + switch (sym->u.s.redirect) { case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; case SYMBOL_PLAINVAL: @@ -1914,7 +1914,7 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */) default: emacs_abort (); } - if (sym->trapped_write == SYMBOL_NOWRITE) + if (sym->u.s.trapped_write == SYMBOL_NOWRITE) error ("Symbol %s may not be buffer-local", SDATA (SYMBOL_NAME (variable))); @@ -1930,7 +1930,7 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */) if (!blv) { blv = make_blv (sym, forwarded, valcontents); - sym->redirect = SYMBOL_LOCALIZED; + sym->u.s.redirect = SYMBOL_LOCALIZED; SET_SYMBOL_BLV (sym, blv); } @@ -1987,7 +1987,7 @@ From now on the default value will apply in this buffer. Return VARIABLE. */) sym = XSYMBOL (variable); start: - switch (sym->redirect) + switch (sym->u.s.redirect) { case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; case SYMBOL_PLAINVAL: return variable; @@ -2014,7 +2014,7 @@ From now on the default value will apply in this buffer. Return VARIABLE. */) default: emacs_abort (); } - if (sym->trapped_write == SYMBOL_TRAPPED_WRITE) + if (sym->u.s.trapped_write == SYMBOL_TRAPPED_WRITE) notify_variable_watchers (variable, Qnil, Qmakunbound, Fcurrent_buffer ()); /* Get rid of this buffer's alist element, if any. */ @@ -2056,7 +2056,7 @@ BUFFER defaults to the current buffer. */) sym = XSYMBOL (variable); start: - switch (sym->redirect) + switch (sym->u.s.redirect) { case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; case SYMBOL_PLAINVAL: return Qnil; @@ -2110,7 +2110,7 @@ value in BUFFER, or if VARIABLE is automatically buffer-local (see sym = XSYMBOL (variable); start: - switch (sym->redirect) + switch (sym->u.s.redirect) { case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; case SYMBOL_PLAINVAL: return Qnil; @@ -2145,7 +2145,7 @@ If the current binding is global (the default), the value is nil. */) find_symbol_value (variable); start: - switch (sym->redirect) + switch (sym->u.s.redirect) { case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start; case SYMBOL_PLAINVAL: return Qnil; @@ -2163,7 +2163,7 @@ If the current binding is global (the default), the value is nil. */) buffer's or frame's value we are saving. */ if (!NILP (Flocal_variable_p (variable, Qnil))) return Fcurrent_buffer (); - else if (sym->redirect == SYMBOL_LOCALIZED + else if (sym->u.s.redirect == SYMBOL_LOCALIZED && blv_found (SYMBOL_BLV (sym))) return SYMBOL_BLV (sym)->where; else @@ -2234,12 +2234,12 @@ indirect_function (register Lisp_Object object) { if (!SYMBOLP (hare) || NILP (hare)) break; - hare = XSYMBOL (hare)->function; + hare = XSYMBOL (hare)->u.s.function; if (!SYMBOLP (hare) || NILP (hare)) break; - hare = XSYMBOL (hare)->function; + hare = XSYMBOL (hare)->u.s.function; - tortoise = XSYMBOL (tortoise)->function; + tortoise = XSYMBOL (tortoise)->u.s.function; if (EQ (hare, tortoise)) xsignal1 (Qcyclic_function_indirection, object); @@ -2261,7 +2261,7 @@ function chain of symbols. */) /* Optimize for no indirection. */ result = object; if (SYMBOLP (result) && !NILP (result) - && (result = XSYMBOL (result)->function, SYMBOLP (result))) + && (result = XSYMBOL (result)->u.s.function, SYMBOLP (result))) result = indirect_function (result); if (!NILP (result)) return result; @@ -3877,7 +3877,7 @@ syms_of_data (void) defsubr (&Sbool_vector_count_consecutive); defsubr (&Sbool_vector_count_population); - set_symbol_function (Qwholenump, XSYMBOL (Qnatnump)->function); + set_symbol_function (Qwholenump, XSYMBOL (Qnatnump)->u.s.function); DEFVAR_LISP ("most-positive-fixnum", Vmost_positive_fixnum, doc: /* The largest value that is representable in a Lisp integer. */); diff --git a/src/doc.c b/src/doc.c index e81740bfc1..0cd62172c3 100644 --- a/src/doc.c +++ b/src/doc.c @@ -472,7 +472,7 @@ store_function_docstring (Lisp_Object obj, EMACS_INT offset) { /* Don't use indirect_function here, or defaliases will apply their docstrings to the base functions (Bug#2603). */ - Lisp_Object fun = SYMBOLP (obj) ? XSYMBOL (obj)->function : obj; + Lisp_Object fun = SYMBOLP (obj) ? XSYMBOL (obj)->u.s.function : obj; /* The type determines where the docstring is stored. */ diff --git a/src/eval.c b/src/eval.c index 52e4c96d4b..40b47968be 100644 --- a/src/eval.c +++ b/src/eval.c @@ -603,7 +603,7 @@ The return value is BASE-VARIABLE. */) sym = XSYMBOL (new_alias); - switch (sym->redirect) + switch (sym->u.s.redirect) { case SYMBOL_FORWARDED: error ("Cannot make an internal variable an alias"); @@ -632,14 +632,14 @@ The return value is BASE-VARIABLE. */) error ("Don't know how to make a let-bound variable an alias"); } - if (sym->trapped_write == SYMBOL_TRAPPED_WRITE) + if (sym->u.s.trapped_write == SYMBOL_TRAPPED_WRITE) notify_variable_watchers (new_alias, base_variable, Qdefvaralias, Qnil); - sym->declared_special = 1; - XSYMBOL (base_variable)->declared_special = 1; - sym->redirect = SYMBOL_VARALIAS; + sym->u.s.declared_special = true; + XSYMBOL (base_variable)->u.s.declared_special = true; + sym->u.s.redirect = SYMBOL_VARALIAS; SET_SYMBOL_ALIAS (sym, XSYMBOL (base_variable)); - sym->trapped_write = XSYMBOL (base_variable)->trapped_write; + sym->u.s.trapped_write = XSYMBOL (base_variable)->u.s.trapped_write; LOADHIST_ATTACH (new_alias); /* Even if docstring is nil: remove old docstring. */ Fput (new_alias, Qvariable_documentation, docstring); @@ -745,7 +745,7 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) tem = Fdefault_boundp (sym); /* Do it before evaluating the initial value, for self-references. */ - XSYMBOL (sym)->declared_special = 1; + XSYMBOL (sym)->u.s.declared_special = true; if (NILP (tem)) Fset_default (sym, eval_sub (XCAR (tail))); @@ -769,7 +769,7 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */) LOADHIST_ATTACH (sym); } else if (!NILP (Vinternal_interpreter_environment) - && !XSYMBOL (sym)->declared_special) + && !XSYMBOL (sym)->u.s.declared_special) /* A simple (defvar foo) with lexical scoping does "nothing" except declare that var to be dynamically scoped *locally* (i.e. within the current file or let-block). */ @@ -818,7 +818,7 @@ usage: (defconst SYMBOL INITVALUE [DOCSTRING]) */) if (!NILP (Vpurify_flag)) tem = Fpurecopy (tem); Fset_default (sym, tem); - XSYMBOL (sym)->declared_special = 1; + XSYMBOL (sym)->u.s.declared_special = true; if (!NILP (docstring)) { if (!NILP (Vpurify_flag)) @@ -837,7 +837,7 @@ DEFUN ("internal-make-var-non-special", Fmake_var_non_special, (Lisp_Object symbol) { CHECK_SYMBOL (symbol); - XSYMBOL (symbol)->declared_special = 0; + XSYMBOL (symbol)->u.s.declared_special = false; return Qnil; } @@ -877,7 +877,7 @@ usage: (let* VARLIST BODY...) */) } if (!NILP (lexenv) && SYMBOLP (var) - && !XSYMBOL (var)->declared_special + && !XSYMBOL (var)->u.s.declared_special && NILP (Fmemq (var, Vinternal_interpreter_environment))) /* Lexically bind VAR by adding it to the interpreter's binding alist. */ @@ -953,7 +953,7 @@ usage: (let VARLIST BODY...) */) tem = temps[argnum]; if (!NILP (lexenv) && SYMBOLP (var) - && !XSYMBOL (var)->declared_special + && !XSYMBOL (var)->u.s.declared_special && NILP (Fmemq (var, Vinternal_interpreter_environment))) /* Lexically bind VAR by adding it to the lexenv alist. */ lexenv = Fcons (Fcons (var, tem), lexenv); @@ -1022,7 +1022,7 @@ definitions to shadow the loaded ones for use in file byte-compilation. */) tem = Fassq (sym, environment); if (NILP (tem)) { - def = XSYMBOL (sym)->function; + def = XSYMBOL (sym)->u.s.function; if (!NILP (def)) continue; } @@ -1932,8 +1932,8 @@ this does nothing and returns nil. */) CHECK_STRING (file); /* If function is defined and not as an autoload, don't override. */ - if (!NILP (XSYMBOL (function)->function) - && !AUTOLOADP (XSYMBOL (function)->function)) + if (!NILP (XSYMBOL (function)->u.s.function) + && !AUTOLOADP (XSYMBOL (function)->u.s.function)) return Qnil; if (!NILP (Vpurify_flag) && EQ (docstring, make_number (0))) @@ -2164,7 +2164,7 @@ eval_sub (Lisp_Object form) fun = original_fun; if (!SYMBOLP (fun)) fun = Ffunction (Fcons (fun, Qnil)); - else if (!NILP (fun) && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) + else if (!NILP (fun) && (fun = XSYMBOL (fun)->u.s.function, SYMBOLP (fun))) fun = indirect_function (fun); if (SUBRP (fun)) @@ -2347,7 +2347,7 @@ usage: (apply FUNCTION &rest ARGUMENTS) */) /* Optimize for no indirection. */ if (SYMBOLP (fun) && !NILP (fun) - && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) + && (fun = XSYMBOL (fun)->u.s.function, SYMBOLP (fun))) { fun = indirect_function (fun); if (NILP (fun)) @@ -2759,7 +2759,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) /* Optimize for no indirection. */ fun = original_fun; if (SYMBOLP (fun) && !NILP (fun) - && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) + && (fun = XSYMBOL (fun)->u.s.function, SYMBOLP (fun))) fun = indirect_function (fun); if (SUBRP (fun)) @@ -3075,7 +3075,7 @@ function with `&rest' args, or `unevalled' for a special form. */) function = original; if (SYMBOLP (function) && !NILP (function)) { - function = XSYMBOL (function)->function; + function = XSYMBOL (function)->u.s.function; if (SYMBOLP (function)) function = indirect_function (function); } @@ -3214,7 +3214,7 @@ let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol) if ((--p)->kind > SPECPDL_LET) { struct Lisp_Symbol *let_bound_symbol = XSYMBOL (specpdl_symbol (p)); - eassert (let_bound_symbol->redirect != SYMBOL_VARALIAS); + eassert (let_bound_symbol->u.s.redirect != SYMBOL_VARALIAS); if (symbol == let_bound_symbol && EQ (specpdl_where (p), buf)) return 1; @@ -3227,10 +3227,10 @@ static void do_specbind (struct Lisp_Symbol *sym, union specbinding *bind, Lisp_Object value, enum Set_Internal_Bind bindflag) { - switch (sym->redirect) + switch (sym->u.s.redirect) { case SYMBOL_PLAINVAL: - if (!sym->trapped_write) + if (!sym->u.s.trapped_write) SET_SYMBOL_VAL (sym, value); else set_internal (specpdl_symbol (bind), value, Qnil, bindflag); @@ -3274,7 +3274,7 @@ specbind (Lisp_Object symbol, Lisp_Object value) sym = XSYMBOL (symbol); start: - switch (sym->redirect) + switch (sym->u.s.redirect) { case SYMBOL_VARALIAS: sym = indirect_variable (sym); XSETSYMBOL (symbol, sym); goto start; @@ -3298,10 +3298,10 @@ specbind (Lisp_Object symbol, Lisp_Object value) specpdl_ptr->let.where = Fcurrent_buffer (); specpdl_ptr->let.saved_value = Qnil; - eassert (sym->redirect != SYMBOL_LOCALIZED + eassert (sym->u.s.redirect != SYMBOL_LOCALIZED || (EQ (SYMBOL_BLV (sym)->where, Fcurrent_buffer ()))); - if (sym->redirect == SYMBOL_LOCALIZED) + if (sym->u.s.redirect == SYMBOL_LOCALIZED) { if (!blv_found (SYMBOL_BLV (sym))) specpdl_ptr->let.kind = SPECPDL_LET_DEFAULT; @@ -3412,9 +3412,9 @@ do_one_unbind (union specbinding *this_binding, bool unwinding, { /* If variable has a trivial value (no forwarding), and isn't trapped, we can just set it. */ Lisp_Object sym = specpdl_symbol (this_binding); - if (SYMBOLP (sym) && XSYMBOL (sym)->redirect == SYMBOL_PLAINVAL) + if (SYMBOLP (sym) && XSYMBOL (sym)->u.s.redirect == SYMBOL_PLAINVAL) { - if (XSYMBOL (sym)->trapped_write == SYMBOL_UNTRAPPED_WRITE) + if (XSYMBOL (sym)->u.s.trapped_write == SYMBOL_UNTRAPPED_WRITE) SET_SYMBOL_VAL (XSYMBOL (sym), specpdl_old_value (this_binding)); else set_internal (sym, specpdl_old_value (this_binding), @@ -3546,7 +3546,7 @@ context where binding is lexical by default. */) (Lisp_Object symbol) { CHECK_SYMBOL (symbol); - return XSYMBOL (symbol)->declared_special ? Qt : Qnil; + return XSYMBOL (symbol)->u.s.declared_special ? Qt : Qnil; } @@ -3702,7 +3702,8 @@ backtrace_eval_unrewind (int distance) just set it. No need to check for constant symbols here, since that was already done by specbind. */ Lisp_Object sym = specpdl_symbol (tmp); - if (SYMBOLP (sym) && XSYMBOL (sym)->redirect == SYMBOL_PLAINVAL) + if (SYMBOLP (sym) + && XSYMBOL (sym)->u.s.redirect == SYMBOL_PLAINVAL) { Lisp_Object old_value = specpdl_old_value (tmp); set_specpdl_old_value (tmp, SYMBOL_VAL (XSYMBOL (sym))); diff --git a/src/fns.c b/src/fns.c index 2311a6e041..42859344bd 100644 --- a/src/fns.c +++ b/src/fns.c @@ -1993,7 +1993,7 @@ This is the last value stored with `(put SYMBOL PROPNAME VALUE)'. */) propname); if (!NILP (propval)) return propval; - return Fplist_get (XSYMBOL (symbol)->plist, propname); + return Fplist_get (XSYMBOL (symbol)->u.s.plist, propname); } DEFUN ("plist-put", Fplist_put, Splist_put, 3, 3, 0, @@ -2039,7 +2039,7 @@ It can be retrieved with `(get SYMBOL PROPNAME)'. */) { CHECK_SYMBOL (symbol); set_symbol_plist - (symbol, Fplist_put (XSYMBOL (symbol)->plist, propname, value)); + (symbol, Fplist_put (XSYMBOL (symbol)->u.s.plist, propname, value)); return value; } diff --git a/src/keyboard.c b/src/keyboard.c index 7ddd6b9674..57757cf211 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -7901,7 +7901,7 @@ parse_menu_item (Lisp_Object item, int inmenubar) (such as lmenu.el set it up), check if the original command matches the cached command. */ && !(SYMBOLP (def) - && EQ (tem, XSYMBOL (def)->function)))) + && EQ (tem, XSYMBOL (def)->u.s.function)))) keys = Qnil; } @@ -8761,9 +8761,9 @@ access_keymap_keyremap (Lisp_Object map, Lisp_Object key, Lisp_Object prompt, /* Handle a symbol whose function definition is a keymap or an array. */ if (SYMBOLP (next) && !NILP (Ffboundp (next)) - && (ARRAYP (XSYMBOL (next)->function) - || KEYMAPP (XSYMBOL (next)->function))) - next = Fautoload_do_load (XSYMBOL (next)->function, next, Qnil); + && (ARRAYP (XSYMBOL (next)->u.s.function) + || KEYMAPP (XSYMBOL (next)->u.s.function))) + next = Fautoload_do_load (XSYMBOL (next)->u.s.function, next, Qnil); /* If the keymap gives a function, not an array, then call the function with one arg and use @@ -11510,7 +11510,7 @@ for that character after that prefix key. */); doc: /* Form to evaluate when Emacs starts up. Useful to set before you dump a modified Emacs. */); Vtop_level = Qnil; - XSYMBOL (Qtop_level)->declared_special = false; + XSYMBOL (Qtop_level)->u.s.declared_special = false; DEFVAR_KBOARD ("keyboard-translate-table", Vkeyboard_translate_table, doc: /* Translate table for local keyboard input, or nil. diff --git a/src/lisp.h b/src/lisp.h index 1d6fd5a4fe..e9aec4c597 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -229,7 +229,7 @@ extern bool suppress_checking EXTERNALLY_VISIBLE; USE_LSB_TAG not only requires the least 3 bits of pointers returned by malloc to be 0 but also needs to be able to impose a mult-of-8 alignment on the few static Lisp_Objects used, all of which are aligned via - the GCALIGN macro defined below. */ + 'char alignas (GCALIGNMENT) gcaligned;' inside a union. */ enum Lisp_Bits { @@ -277,20 +277,6 @@ DEFINE_GDB_SYMBOL_END (VALMASK) error !; #endif -/* Use GCALIGNED immediately after the 'struct' keyword to require the - struct to have an address that is a multiple of GCALIGNMENT. This - is a no-op if the struct's natural alignment is already a multiple - of GCALIGNMENT. GCALIGNED's implementation uses the 'aligned' - attribute instead of 'alignas (GCALIGNMENT)', as the latter would - fail if an object's natural alignment exceeds GCALIGNMENT. The - implementation hopes that natural alignment suffices on platforms - lacking 'aligned'. */ -#ifdef HAVE_STRUCT_ATTRIBUTE_ALIGNED -# define GCALIGNED __attribute__ ((aligned (GCALIGNMENT))) -#else -# define GCALIGNED /* empty */ -#endif - /* Some operations are so commonly executed that they are implemented as macros, not functions, because otherwise runtime performance would suffer too much when compiling with GCC without optimization. @@ -338,15 +324,17 @@ error !; #define lisp_h_MISCP(x) (XTYPE (x) == Lisp_Misc) #define lisp_h_NILP(x) EQ (x, Qnil) #define lisp_h_SET_SYMBOL_VAL(sym, v) \ - (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value = (v)) -#define lisp_h_SYMBOL_CONSTANT_P(sym) (XSYMBOL (sym)->trapped_write == SYMBOL_NOWRITE) -#define lisp_h_SYMBOL_TRAPPED_WRITE_P(sym) (XSYMBOL (sym)->trapped_write) + (eassert ((sym)->u.s.redirect == SYMBOL_PLAINVAL), \ + (sym)->u.s.val.value = (v)) +#define lisp_h_SYMBOL_CONSTANT_P(sym) \ + (XSYMBOL (sym)->u.s.trapped_write == SYMBOL_NOWRITE) +#define lisp_h_SYMBOL_TRAPPED_WRITE_P(sym) (XSYMBOL (sym)->u.s.trapped_write) #define lisp_h_SYMBOL_VAL(sym) \ - (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value) + (eassert ((sym)->u.s.redirect == SYMBOL_PLAINVAL), (sym)->u.s.val.value) #define lisp_h_SYMBOLP(x) (XTYPE (x) == Lisp_Symbol) #define lisp_h_VECTORLIKEP(x) (XTYPE (x) == Lisp_Vectorlike) -#define lisp_h_XCAR(c) XCONS (c)->car -#define lisp_h_XCDR(c) XCONS (c)->u.cdr +#define lisp_h_XCAR(c) XCONS (c)->u.s.car +#define lisp_h_XCDR(c) XCONS (c)->u.s.u.cdr #define lisp_h_XCONS(a) \ (eassert (CONSP (a)), (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons)) #define lisp_h_XHASH(a) XUINT (a) @@ -677,52 +665,60 @@ enum symbol_trapped_write struct Lisp_Symbol { - bool_bf gcmarkbit : 1; - - /* Indicates where the value can be found: - 0 : it's a plain var, the value is in the `value' field. - 1 : it's a varalias, the value is really in the `alias' symbol. - 2 : it's a localized var, the value is in the `blv' object. - 3 : it's a forwarding variable, the value is in `forward'. */ - ENUM_BF (symbol_redirect) redirect : 3; - - /* 0 : normal case, just set the value - 1 : constant, cannot set, e.g. nil, t, :keywords. - 2 : trap the write, call watcher functions. */ - ENUM_BF (symbol_trapped_write) trapped_write : 2; - - /* Interned state of the symbol. This is an enumerator from - enum symbol_interned. */ - unsigned interned : 2; - - /* True means that this variable has been explicitly declared - special (with `defvar' etc), and shouldn't be lexically bound. */ - bool_bf declared_special : 1; - - /* True if pointed to from purespace and hence can't be GC'd. */ - bool_bf pinned : 1; - - /* The symbol's name, as a Lisp string. */ - Lisp_Object name; - - /* Value of the symbol or Qunbound if unbound. Which alternative of the - union is used depends on the `redirect' field above. */ - union { - Lisp_Object value; - struct Lisp_Symbol *alias; - struct Lisp_Buffer_Local_Value *blv; - union Lisp_Fwd *fwd; - } val; - - /* Function value of the symbol or Qnil if not fboundp. */ - Lisp_Object function; + union + { + struct + { + bool_bf gcmarkbit : 1; + + /* Indicates where the value can be found: + 0 : it's a plain var, the value is in the `value' field. + 1 : it's a varalias, the value is really in the `alias' symbol. + 2 : it's a localized var, the value is in the `blv' object. + 3 : it's a forwarding variable, the value is in `forward'. */ + ENUM_BF (symbol_redirect) redirect : 3; + + /* 0 : normal case, just set the value + 1 : constant, cannot set, e.g. nil, t, :keywords. + 2 : trap the write, call watcher functions. */ + ENUM_BF (symbol_trapped_write) trapped_write : 2; + + /* Interned state of the symbol. This is an enumerator from + enum symbol_interned. */ + unsigned interned : 2; + + /* True means that this variable has been explicitly declared + special (with `defvar' etc), and shouldn't be lexically bound. */ + bool_bf declared_special : 1; + + /* True if pointed to from purespace and hence can't be GC'd. */ + bool_bf pinned : 1; + + /* The symbol's name, as a Lisp string. */ + Lisp_Object name; + + /* Value of the symbol or Qunbound if unbound. Which alternative of the + union is used depends on the `redirect' field above. */ + union { + Lisp_Object value; + struct Lisp_Symbol *alias; + struct Lisp_Buffer_Local_Value *blv; + union Lisp_Fwd *fwd; + } val; + + /* Function value of the symbol or Qnil if not fboundp. */ + Lisp_Object function; - /* The symbol's property list. */ - Lisp_Object plist; + /* The symbol's property list. */ + Lisp_Object plist; - /* Next symbol in obarray bucket, if the symbol is interned. */ - struct Lisp_Symbol *next; + /* Next symbol in obarray bucket, if the symbol is interned. */ + struct Lisp_Symbol *next; + } s; + char alignas (GCALIGNMENT) gcaligned; + } u; }; +verify (alignof (struct Lisp_Symbol) % GCALIGNMENT == 0); /* Declare a Lisp-callable function. The MAXARGS parameter has the same meaning as in the DEFUN macro, and is used to construct a prototype. */ @@ -802,7 +798,7 @@ struct Lisp_Symbol Bug#8546. */ union vectorlike_header { - /* The only field contains various pieces of information: + /* The main member contains various pieces of information: - The MSB (ARRAY_MARK_FLAG) holds the gcmarkbit. - The next bit (PSEUDOVECTOR_FLAG) indicates whether this is a plain vector (0) or a pseudovector (1). @@ -822,7 +818,9 @@ union vectorlike_header Current layout limits the pseudovectors to 63 PVEC_xxx subtypes, 4095 Lisp_Objects in GC-ed area and 4095 word-sized other slots. */ ptrdiff_t size; + char alignas (GCALIGNMENT) gcaligned; }; +verify (alignof (union vectorlike_header) % GCALIGNMENT == 0); INLINE bool (SYMBOLP) (Lisp_Object x) @@ -854,7 +852,7 @@ make_lisp_symbol (struct Lisp_Symbol *sym) INLINE Lisp_Object builtin_lisp_symbol (int index) { - return make_lisp_symbol (&lispsym[index].s); + return make_lisp_symbol (&lispsym[index]); } INLINE void @@ -1144,20 +1142,28 @@ make_pointer_integer (void *p) typedef struct interval *INTERVAL; -struct GCALIGNED Lisp_Cons +struct Lisp_Cons +{ + union { - /* Car of this cons cell. */ - Lisp_Object car; - - union + struct { - /* Cdr of this cons cell. */ - Lisp_Object cdr; - - /* Used to chain conses on a free list. */ - struct Lisp_Cons *chain; - } u; - }; + /* Car of this cons cell. */ + Lisp_Object car; + + union + { + /* Cdr of this cons cell. */ + Lisp_Object cdr; + + /* Used to chain conses on a free list. */ + struct Lisp_Cons *chain; + } u; + } s; + char alignas (GCALIGNMENT) gcaligned; + } u; +}; +verify (alignof (struct Lisp_Cons) % GCALIGNMENT == 0); INLINE bool (NILP) (Lisp_Object x) @@ -1193,12 +1199,12 @@ INLINE struct Lisp_Cons * INLINE Lisp_Object * xcar_addr (Lisp_Object c) { - return &XCONS (c)->car; + return &XCONS (c)->u.s.car; } INLINE Lisp_Object * xcdr_addr (Lisp_Object c) { - return &XCONS (c)->u.cdr; + return &XCONS (c)->u.s.u.cdr; } /* Use these from normal code. */ @@ -1262,15 +1268,24 @@ CDR_SAFE (Lisp_Object c) return CONSP (c) ? XCDR (c) : Qnil; } -/* In a string or vector, the sign bit of the `size' is the gc mark bit. */ +/* In a string or vector, the sign bit of u.s.size is the gc mark bit. */ -struct GCALIGNED Lisp_String +struct Lisp_String +{ + union { - ptrdiff_t size; - ptrdiff_t size_byte; - INTERVAL intervals; /* Text properties in this string. */ - unsigned char *data; - }; + struct + { + ptrdiff_t size; + ptrdiff_t size_byte; + INTERVAL intervals; /* Text properties in this string. */ + unsigned char *data; + } s; + struct Lisp_String *next; + char alignas (GCALIGNMENT) gcaligned; + } u; +}; +verify (alignof (struct Lisp_String) % GCALIGNMENT == 0); INLINE bool STRINGP (Lisp_Object x) @@ -1295,7 +1310,7 @@ XSTRING (Lisp_Object a) INLINE bool STRING_MULTIBYTE (Lisp_Object str) { - return 0 <= XSTRING (str)->size_byte; + return 0 <= XSTRING (str)->u.s.size_byte; } /* An upper bound on the number of bytes in a Lisp string, not @@ -1317,20 +1332,20 @@ STRING_MULTIBYTE (Lisp_Object str) /* Mark STR as a unibyte string. */ #define STRING_SET_UNIBYTE(STR) \ do { \ - if (XSTRING (STR)->size == 0) \ + if (XSTRING (STR)->u.s.size == 0) \ (STR) = empty_unibyte_string; \ else \ - XSTRING (STR)->size_byte = -1; \ + XSTRING (STR)->u.s.size_byte = -1; \ } while (false) /* Mark STR as a multibyte string. Assure that STR contains only ASCII characters in advance. */ #define STRING_SET_MULTIBYTE(STR) \ do { \ - if (XSTRING (STR)->size == 0) \ + if (XSTRING (STR)->u.s.size == 0) \ (STR) = empty_multibyte_string; \ else \ - XSTRING (STR)->size_byte = XSTRING (STR)->size; \ + XSTRING (STR)->u.s.size_byte = XSTRING (STR)->u.s.size; \ } while (false) /* Convenience functions for dealing with Lisp strings. */ @@ -1338,7 +1353,7 @@ STRING_MULTIBYTE (Lisp_Object str) INLINE unsigned char * SDATA (Lisp_Object string) { - return XSTRING (string)->data; + return XSTRING (string)->u.s.data; } INLINE char * SSDATA (Lisp_Object string) @@ -1359,7 +1374,7 @@ SSET (Lisp_Object string, ptrdiff_t index, unsigned char new) INLINE ptrdiff_t SCHARS (Lisp_Object string) { - ptrdiff_t nchars = XSTRING (string)->size; + ptrdiff_t nchars = XSTRING (string)->u.s.size; eassume (0 <= nchars); return nchars; } @@ -1373,7 +1388,7 @@ STRING_BYTES (struct Lisp_String *s) #ifdef GC_CHECK_STRING_BYTES ptrdiff_t nbytes = string_bytes (s); #else - ptrdiff_t nbytes = s->size_byte < 0 ? s->size : s->size_byte; + ptrdiff_t nbytes = s->u.s.size_byte < 0 ? s->u.s.size : s->u.s.size_byte; #endif eassume (0 <= nbytes); return nbytes; @@ -1392,7 +1407,7 @@ STRING_SET_CHARS (Lisp_Object string, ptrdiff_t newsize) eassert (STRING_MULTIBYTE (string) ? 0 <= newsize && newsize <= SBYTES (string) : newsize == SCHARS (string)); - XSTRING (string)->size = newsize; + XSTRING (string)->u.s.size = newsize; } /* A regular vector is just a header plus an array of Lisp_Objects. */ @@ -1910,20 +1925,20 @@ INLINE Lisp_Object INLINE struct Lisp_Symbol * SYMBOL_ALIAS (struct Lisp_Symbol *sym) { - eassume (sym->redirect == SYMBOL_VARALIAS && sym->val.alias); - return sym->val.alias; + eassume (sym->u.s.redirect == SYMBOL_VARALIAS && sym->u.s.val.alias); + return sym->u.s.val.alias; } INLINE struct Lisp_Buffer_Local_Value * SYMBOL_BLV (struct Lisp_Symbol *sym) { - eassume (sym->redirect == SYMBOL_LOCALIZED && sym->val.blv); - return sym->val.blv; + eassume (sym->u.s.redirect == SYMBOL_LOCALIZED && sym->u.s.val.blv); + return sym->u.s.val.blv; } INLINE union Lisp_Fwd * SYMBOL_FWD (struct Lisp_Symbol *sym) { - eassume (sym->redirect == SYMBOL_FORWARDED && sym->val.fwd); - return sym->val.fwd; + eassume (sym->u.s.redirect == SYMBOL_FORWARDED && sym->u.s.val.fwd); + return sym->u.s.val.fwd; } INLINE void @@ -1935,26 +1950,26 @@ INLINE void INLINE void SET_SYMBOL_ALIAS (struct Lisp_Symbol *sym, struct Lisp_Symbol *v) { - eassume (sym->redirect == SYMBOL_VARALIAS && v); - sym->val.alias = v; + eassume (sym->u.s.redirect == SYMBOL_VARALIAS && v); + sym->u.s.val.alias = v; } INLINE void SET_SYMBOL_BLV (struct Lisp_Symbol *sym, struct Lisp_Buffer_Local_Value *v) { - eassume (sym->redirect == SYMBOL_LOCALIZED && v); - sym->val.blv = v; + eassume (sym->u.s.redirect == SYMBOL_LOCALIZED && v); + sym->u.s.val.blv = v; } INLINE void SET_SYMBOL_FWD (struct Lisp_Symbol *sym, union Lisp_Fwd *v) { - eassume (sym->redirect == SYMBOL_FORWARDED && v); - sym->val.fwd = v; + eassume (sym->u.s.redirect == SYMBOL_FORWARDED && v); + sym->u.s.val.fwd = v; } INLINE Lisp_Object SYMBOL_NAME (Lisp_Object sym) { - return XSYMBOL (sym)->name; + return XSYMBOL (sym)->u.s.name; } /* Value is true if SYM is an interned symbol. */ @@ -1962,7 +1977,7 @@ SYMBOL_NAME (Lisp_Object sym) INLINE bool SYMBOL_INTERNED_P (Lisp_Object sym) { - return XSYMBOL (sym)->interned != SYMBOL_UNINTERNED; + return XSYMBOL (sym)->u.s.interned != SYMBOL_UNINTERNED; } /* Value is true if SYM is interned in initial_obarray. */ @@ -1970,7 +1985,7 @@ SYMBOL_INTERNED_P (Lisp_Object sym) INLINE bool SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (Lisp_Object sym) { - return XSYMBOL (sym)->interned == SYMBOL_INTERNED_IN_INITIAL_OBARRAY; + return XSYMBOL (sym)->u.s.interned == SYMBOL_INTERNED_IN_INITIAL_OBARRAY; } /* Value is non-zero if symbol cannot be changed through a simple set, @@ -2948,7 +2963,7 @@ CHECK_NUMBER_CDR (Lisp_Object x) #ifdef _MSC_VER #define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \ - static struct GCALIGNED Lisp_Subr sname = \ + static struct Lisp_Subr sname = \ { { (PVEC_SUBR << PSEUDOVECTOR_AREA_BITS) \ | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)) }, \ { (Lisp_Object (__cdecl *)(void))fnname }, \ @@ -2956,7 +2971,7 @@ CHECK_NUMBER_CDR (Lisp_Object x) Lisp_Object fnname #else /* not _MSC_VER */ #define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ - static struct GCALIGNED Lisp_Subr sname = \ + static struct Lisp_Subr sname = \ { { PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, \ { .a ## maxargs = fnname }, \ minargs, maxargs, lname, intspec, 0}; \ @@ -3224,25 +3239,25 @@ set_hash_value_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val) INLINE void set_symbol_function (Lisp_Object sym, Lisp_Object function) { - XSYMBOL (sym)->function = function; + XSYMBOL (sym)->u.s.function = function; } INLINE void set_symbol_plist (Lisp_Object sym, Lisp_Object plist) { - XSYMBOL (sym)->plist = plist; + XSYMBOL (sym)->u.s.plist = plist; } INLINE void set_symbol_next (Lisp_Object sym, struct Lisp_Symbol *next) { - XSYMBOL (sym)->next = next; + XSYMBOL (sym)->u.s.next = next; } INLINE void make_symbol_constant (Lisp_Object sym) { - XSYMBOL (sym)->trapped_write = SYMBOL_NOWRITE; + XSYMBOL (sym)->u.s.trapped_write = SYMBOL_NOWRITE; } /* Buffer-local variable access functions. */ @@ -3267,7 +3282,7 @@ set_overlay_plist (Lisp_Object overlay, Lisp_Object plist) INLINE INTERVAL string_intervals (Lisp_Object s) { - return XSTRING (s)->intervals; + return XSTRING (s)->u.s.intervals; } /* Set text properties of S to I. */ @@ -3275,7 +3290,7 @@ string_intervals (Lisp_Object s) INLINE void set_string_intervals (Lisp_Object s, INTERVAL i) { - XSTRING (s)->intervals = i; + XSTRING (s)->u.s.intervals = i; } /* 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 }; enum { defined_GC_CHECK_STRING_BYTES = false }; #endif -/* Struct inside unions that are typically no larger and aligned enough. */ - -union Aligned_Cons -{ - struct Lisp_Cons s; - double d; intmax_t i; void *p; -}; - -union Aligned_String -{ - struct Lisp_String s; - double d; intmax_t i; void *p; -}; - /* True for stack-based cons and string implementations, respectively. Use stack-based strings only if stack-based cons also works. Otherwise, STACK_CONS would create heap-based cons cells that @@ -4621,18 +4622,16 @@ union Aligned_String enum { - USE_STACK_CONS = (USE_STACK_LISP_OBJECTS - && alignof (union Aligned_Cons) % GCALIGNMENT == 0), + USE_STACK_CONS = USE_STACK_LISP_OBJECTS, USE_STACK_STRING = (USE_STACK_CONS - && !defined_GC_CHECK_STRING_BYTES - && alignof (union Aligned_String) % GCALIGNMENT == 0) + && !defined_GC_CHECK_STRING_BYTES) }; /* Auxiliary macros used for auto allocation of Lisp objects. Please use these only in macros like AUTO_CONS that declare a local variable whose lifetime will be clear to the programmer. */ #define STACK_CONS(a, b) \ - make_lisp_ptr (&((union Aligned_Cons) { { a, { b } } }).s, Lisp_Cons) + make_lisp_ptr (&((struct Lisp_Cons) {{{a, {b}}}}), Lisp_Cons) #define AUTO_CONS_EXPR(a, b) \ (USE_STACK_CONS ? STACK_CONS (a, b) : Fcons (a, b)) @@ -4678,7 +4677,7 @@ enum Lisp_Object name = \ (USE_STACK_STRING \ ? (make_lisp_ptr \ - ((&((union Aligned_String) {{len, -1, 0, (unsigned char *) (str)}}).s), \ + ((&(struct Lisp_String) {{{len, -1, 0, (unsigned char *) (str)}}}), \ Lisp_String)) \ : make_unibyte_string (str, len)) diff --git a/src/lread.c b/src/lread.c index 33da866722..b056f4aaf3 100644 --- a/src/lread.c +++ b/src/lread.c @@ -4043,14 +4043,14 @@ intern_sym (Lisp_Object sym, Lisp_Object obarray, Lisp_Object index) { Lisp_Object *ptr; - XSYMBOL (sym)->interned = (EQ (obarray, initial_obarray) - ? SYMBOL_INTERNED_IN_INITIAL_OBARRAY - : SYMBOL_INTERNED); + XSYMBOL (sym)->u.s.interned = (EQ (obarray, initial_obarray) + ? SYMBOL_INTERNED_IN_INITIAL_OBARRAY + : SYMBOL_INTERNED); if (SREF (SYMBOL_NAME (sym), 0) == ':' && EQ (obarray, initial_obarray)) { make_symbol_constant (sym); - XSYMBOL (sym)->redirect = SYMBOL_PLAINVAL; + XSYMBOL (sym)->u.s.redirect = SYMBOL_PLAINVAL; SET_SYMBOL_VAL (XSYMBOL (sym), sym); } @@ -4203,16 +4203,16 @@ usage: (unintern NAME OBARRAY) */) /* if (EQ (tem, Qnil) || EQ (tem, Qt)) error ("Attempt to unintern t or nil"); */ - XSYMBOL (tem)->interned = SYMBOL_UNINTERNED; + XSYMBOL (tem)->u.s.interned = SYMBOL_UNINTERNED; hash = oblookup_last_bucket_number; if (EQ (AREF (obarray, hash), tem)) { - if (XSYMBOL (tem)->next) + if (XSYMBOL (tem)->u.s.next) { Lisp_Object sym; - XSETSYMBOL (sym, XSYMBOL (tem)->next); + XSETSYMBOL (sym, XSYMBOL (tem)->u.s.next); ASET (obarray, hash, sym); } else @@ -4223,13 +4223,13 @@ usage: (unintern NAME OBARRAY) */) Lisp_Object tail, following; for (tail = AREF (obarray, hash); - XSYMBOL (tail)->next; + XSYMBOL (tail)->u.s.next; tail = following) { - XSETSYMBOL (following, XSYMBOL (tail)->next); + XSETSYMBOL (following, XSYMBOL (tail)->u.s.next); if (EQ (following, tem)) { - set_symbol_next (tail, XSYMBOL (following)->next); + set_symbol_next (tail, XSYMBOL (following)->u.s.next); break; } } @@ -4264,13 +4264,13 @@ oblookup (Lisp_Object obarray, register const char *ptr, ptrdiff_t size, ptrdiff else if (!SYMBOLP (bucket)) error ("Bad data in guts of obarray"); /* Like CADR error message. */ else - for (tail = bucket; ; XSETSYMBOL (tail, XSYMBOL (tail)->next)) + for (tail = bucket; ; XSETSYMBOL (tail, XSYMBOL (tail)->u.s.next)) { if (SBYTES (SYMBOL_NAME (tail)) == size_byte && SCHARS (SYMBOL_NAME (tail)) == size && !memcmp (SDATA (SYMBOL_NAME (tail)), ptr, size_byte)) return tail; - else if (XSYMBOL (tail)->next == 0) + else if (XSYMBOL (tail)->u.s.next == 0) break; } XSETINT (tem, hash); @@ -4290,9 +4290,9 @@ map_obarray (Lisp_Object obarray, void (*fn) (Lisp_Object, Lisp_Object), Lisp_Ob while (1) { (*fn) (tail, arg); - if (XSYMBOL (tail)->next == 0) + if (XSYMBOL (tail)->u.s.next == 0) break; - XSETSYMBOL (tail, XSYMBOL (tail)->next); + XSETSYMBOL (tail, XSYMBOL (tail)->u.s.next); } } } @@ -4332,12 +4332,12 @@ init_obarray (void) DEFSYM (Qnil, "nil"); SET_SYMBOL_VAL (XSYMBOL (Qnil), Qnil); make_symbol_constant (Qnil); - XSYMBOL (Qnil)->declared_special = true; + XSYMBOL (Qnil)->u.s.declared_special = true; DEFSYM (Qt, "t"); SET_SYMBOL_VAL (XSYMBOL (Qt), Qt); make_symbol_constant (Qt); - XSYMBOL (Qt)->declared_special = true; + XSYMBOL (Qt)->u.s.declared_special = true; /* Qt is correct even if CANNOT_DUMP. loadup.el will set to nil at end. */ Vpurify_flag = Qt; @@ -4361,7 +4361,7 @@ defalias (struct Lisp_Subr *sname, char *string) { Lisp_Object sym; sym = intern (string); - XSETSUBR (XSYMBOL (sym)->function, sname); + XSETSUBR (XSYMBOL (sym)->u.s.function, sname); } #endif /* NOTDEF */ @@ -4376,8 +4376,8 @@ defvar_int (struct Lisp_Intfwd *i_fwd, sym = intern_c_string (namestring); i_fwd->type = Lisp_Fwd_Int; i_fwd->intvar = address; - XSYMBOL (sym)->declared_special = 1; - XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; + XSYMBOL (sym)->u.s.declared_special = true; + XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)i_fwd); } @@ -4391,8 +4391,8 @@ defvar_bool (struct Lisp_Boolfwd *b_fwd, sym = intern_c_string (namestring); b_fwd->type = Lisp_Fwd_Bool; b_fwd->boolvar = address; - XSYMBOL (sym)->declared_special = 1; - XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; + XSYMBOL (sym)->u.s.declared_special = true; + XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)b_fwd); Vbyte_boolean_vars = Fcons (sym, Vbyte_boolean_vars); } @@ -4410,8 +4410,8 @@ defvar_lisp_nopro (struct Lisp_Objfwd *o_fwd, sym = intern_c_string (namestring); o_fwd->type = Lisp_Fwd_Obj; o_fwd->objvar = address; - XSYMBOL (sym)->declared_special = 1; - XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; + XSYMBOL (sym)->u.s.declared_special = true; + XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)o_fwd); } @@ -4434,8 +4434,8 @@ defvar_kboard (struct Lisp_Kboard_Objfwd *ko_fwd, sym = intern_c_string (namestring); ko_fwd->type = Lisp_Fwd_Kboard_Obj; ko_fwd->offset = offset; - XSYMBOL (sym)->declared_special = 1; - XSYMBOL (sym)->redirect = SYMBOL_FORWARDED; + XSYMBOL (sym)->u.s.declared_special = true; + XSYMBOL (sym)->u.s.redirect = SYMBOL_FORWARDED; SET_SYMBOL_FWD (XSYMBOL (sym), (union Lisp_Fwd *)ko_fwd); } @@ -4769,7 +4769,7 @@ to find all the symbols in an obarray, use `mapatoms'. */); DEFVAR_LISP ("values", Vvalues, doc: /* List of values of all expressions which were read, evaluated and printed. Order is reverse chronological. */); - XSYMBOL (intern ("values"))->declared_special = 0; + XSYMBOL (intern ("values"))->u.s.declared_special = true; DEFVAR_LISP ("standard-input", Vstandard_input, doc: /* Stream for read to get input from. diff --git a/src/minibuf.c b/src/minibuf.c index a2f3324f99..913c93001e 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -1280,8 +1280,8 @@ is used to further constrain the set of candidates. */) error ("Bad data in guts of obarray"); elt = bucket; eltstring = elt; - if (XSYMBOL (bucket)->next) - XSETSYMBOL (bucket, XSYMBOL (bucket)->next); + if (XSYMBOL (bucket)->u.s.next) + XSETSYMBOL (bucket, XSYMBOL (bucket)->u.s.next); else XSETFASTINT (bucket, 0); } @@ -1533,8 +1533,8 @@ with a space are ignored unless STRING itself starts with a space. */) error ("Bad data in guts of obarray"); elt = bucket; eltstring = elt; - if (XSYMBOL (bucket)->next) - XSETSYMBOL (bucket, XSYMBOL (bucket)->next); + if (XSYMBOL (bucket)->u.s.next) + XSETSYMBOL (bucket, XSYMBOL (bucket)->u.s.next); else XSETFASTINT (bucket, 0); } @@ -1754,9 +1754,9 @@ the values STRING, PREDICATE and `lambda'. */) tem = tail; break; } - if (XSYMBOL (tail)->next == 0) + if (XSYMBOL (tail)->u.s.next == 0) break; - XSETSYMBOL (tail, XSYMBOL (tail)->next); + XSETSYMBOL (tail, XSYMBOL (tail)->u.s.next); } } } diff --git a/src/thread.c b/src/thread.c index 7335833cf9..c03cdda0fa 100644 --- a/src/thread.c +++ b/src/thread.c @@ -26,7 +26,7 @@ along with GNU Emacs. If not, see . */ #include "coding.h" #include "syssignal.h" -static struct GCALIGNED thread_state main_thread; +static struct thread_state main_thread; struct thread_state *current_thread = &main_thread; diff --git a/src/xterm.c b/src/xterm.c index dbb8349452..dd184eedfc 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -12504,7 +12504,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) { terminal->kboard = allocate_kboard (Qx); - if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->function, Qunbound)) + if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->u.s.function, Qunbound)) { char *vendor = ServerVendor (dpy); -- 2.13.6