summaryrefslogtreecommitdiff
path: root/src/lisp.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lisp.h')
-rw-r--r--src/lisp.h277
1 files changed, 138 insertions, 139 deletions
diff --git a/src/lisp.h b/src/lisp.h
index 1d6fd5a4fe2..e9aec4c5979 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -229,7 +229,7 @@ extern bool suppress_checking EXTERNALLY_VISIBLE;
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))