"#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);
}
/* 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)
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
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;
}
{
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;
}
/* 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,
/* 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);
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);
{
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))
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);
/* 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;
{
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. */
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;
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++;
/* 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
{
struct Lisp_Cons *tail = cons_free_list;
while (tail)
- tail = tail->u.chain;
+ tail = tail->u.s.u.chain;
}
#endif
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;
};
static void
set_symbol_name (Lisp_Object sym, Lisp_Object name)
{
- XSYMBOL (sym)->name = name;
+ XSYMBOL (sym)->u.s.name = name;
}
void
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,
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
{
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++;
}
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);
}
}
|| 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);
}
}
|| 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);
}
}
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;
}
{
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;
}
{
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;
}
|| 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);
}
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. */
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;
}
{
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))
{
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. */
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:
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;
}
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 ();
break;
case Lisp_Symbol:
- survives_p = XSYMBOL (obj)->gcmarkbit;
+ survives_p = XSYMBOL (obj)->u.s.gcmarkbit;
break;
case Lisp_Misc:
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
{
{
*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
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));
}
}
{
*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
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)));
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);
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.
/* 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. */
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);
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 ());
}
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;
{
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. */
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))
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);
{
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);
/* 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
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;
}
}
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;
}
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;
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,
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,
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);
{ /* 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));
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);
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);
CHECK_SYMBOL (symbol);
sym = XSYMBOL (symbol);
- switch (sym->trapped_write)
+ switch (sym->u.s.trapped_write)
{
case SYMBOL_NOWRITE:
if (NILP (Fkeywordp (symbol))
}
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;
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
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
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,
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);
CHECK_SYMBOL (symbol);
sym = XSYMBOL (symbol);
- switch (sym->trapped_write)
+ switch (sym->u.s.trapped_write)
{
case SYMBOL_NOWRITE:
if (NILP (Fkeywordp (symbol))
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);
}
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;
sym = XSYMBOL (variable);
start:
- switch (sym->redirect)
+ switch (sym->u.s.redirect)
{
case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
case SYMBOL_PLAINVAL:
if (!blv)
{
blv = make_blv (sym, forwarded, valcontents);
- sym->redirect = SYMBOL_LOCALIZED;
+ sym->u.s.redirect = SYMBOL_LOCALIZED;
SET_SYMBOL_BLV (sym, blv);
}
sym = XSYMBOL (variable);
start:
- switch (sym->redirect)
+ switch (sym->u.s.redirect)
{
case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
case SYMBOL_PLAINVAL:
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)));
if (!blv)
{
blv = make_blv (sym, forwarded, valcontents);
- sym->redirect = SYMBOL_LOCALIZED;
+ sym->u.s.redirect = SYMBOL_LOCALIZED;
SET_SYMBOL_BLV (sym, blv);
}
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;
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. */
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;
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;
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;
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
{
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);
/* 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;
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. */);
{
/* 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. */
sym = XSYMBOL (new_alias);
- switch (sym->redirect)
+ switch (sym->u.s.redirect)
{
case SYMBOL_FORWARDED:
error ("Cannot make an internal variable an alias");
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);
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)));
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). */
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))
(Lisp_Object symbol)
{
CHECK_SYMBOL (symbol);
- XSYMBOL (symbol)->declared_special = 0;
+ XSYMBOL (symbol)->u.s.declared_special = false;
return Qnil;
}
}
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. */
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);
tem = Fassq (sym, environment);
if (NILP (tem))
{
- def = XSYMBOL (sym)->function;
+ def = XSYMBOL (sym)->u.s.function;
if (!NILP (def))
continue;
}
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)))
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))
/* 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))
/* 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))
function = original;
if (SYMBOLP (function) && !NILP (function))
{
- function = XSYMBOL (function)->function;
+ function = XSYMBOL (function)->u.s.function;
if (SYMBOLP (function))
function = indirect_function (function);
}
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;
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);
sym = XSYMBOL (symbol);
start:
- switch (sym->redirect)
+ switch (sym->u.s.redirect)
{
case SYMBOL_VARALIAS:
sym = indirect_variable (sym); XSETSYMBOL (symbol, sym); goto start;
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;
{ /* 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),
(Lisp_Object symbol)
{
CHECK_SYMBOL (symbol);
- return XSYMBOL (symbol)->declared_special ? Qt : Qnil;
+ return XSYMBOL (symbol)->u.s.declared_special ? Qt : Qnil;
}
\f
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)));
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,
{
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;
}
\f
(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;
}
/* 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
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.
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
{
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.
#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)
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. */
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).
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)
INLINE Lisp_Object
builtin_lisp_symbol (int index)
{
- return make_lisp_symbol (&lispsym[index].s);
+ return make_lisp_symbol (&lispsym[index]);
}
INLINE void
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)
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. */
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)
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
/* 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. */
INLINE unsigned char *
SDATA (Lisp_Object string)
{
- return XSTRING (string)->data;
+ return XSTRING (string)->u.s.data;
}
INLINE char *
SSDATA (Lisp_Object string)
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;
}
#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;
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. */
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
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. */
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. */
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,
#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 }, \
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}; \
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. */
INLINE INTERVAL
string_intervals (Lisp_Object s)
{
- return XSTRING (s)->intervals;
+ return XSTRING (s)->u.s.intervals;
}
/* Set text properties of S to I. */
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
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
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))
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))
{
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);
}
/* 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
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;
}
}
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);
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);
}
}
}
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;
{
Lisp_Object sym;
sym = intern (string);
- XSETSUBR (XSYMBOL (sym)->function, sname);
+ XSETSUBR (XSYMBOL (sym)->u.s.function, sname);
}
#endif /* NOTDEF */
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);
}
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);
}
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);
}
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);
}
\f
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.
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);
}
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);
}
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);
}
}
}
#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;
{
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);