summaryrefslogtreecommitdiff
path: root/src/lisp.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lisp.h')
-rw-r--r--src/lisp.h1259
1 files changed, 600 insertions, 659 deletions
diff --git a/src/lisp.h b/src/lisp.h
index b410ee45aed..e7747563085 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -21,10 +21,12 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#ifndef EMACS_LISP_H
#define EMACS_LISP_H
+#include <alloca.h>
#include <setjmp.h>
#include <stdalign.h>
#include <stdarg.h>
#include <stddef.h>
+#include <string.h>
#include <float.h>
#include <inttypes.h>
#include <limits.h>
@@ -68,6 +70,7 @@ DEFINE_GDB_SYMBOL_BEGIN (int, GCTYPEBITS)
DEFINE_GDB_SYMBOL_END (GCTYPEBITS)
/* EMACS_INT - signed integer wide enough to hold an Emacs value
+ EMACS_INT_WIDTH - width in bits of EMACS_INT
EMACS_INT_MAX - maximum value of EMACS_INT; can be used in #if
pI - printf length modifier for EMACS_INT
EMACS_UINT - unsigned variant of EMACS_INT */
@@ -77,18 +80,25 @@ DEFINE_GDB_SYMBOL_END (GCTYPEBITS)
# elif INTPTR_MAX <= INT_MAX && !defined WIDE_EMACS_INT
typedef int EMACS_INT;
typedef unsigned int EMACS_UINT;
+enum { EMACS_INT_WIDTH = INT_WIDTH };
# define EMACS_INT_MAX INT_MAX
# define pI ""
# elif INTPTR_MAX <= LONG_MAX && !defined WIDE_EMACS_INT
typedef long int EMACS_INT;
typedef unsigned long EMACS_UINT;
+enum { EMACS_INT_WIDTH = LONG_WIDTH };
# define EMACS_INT_MAX LONG_MAX
# define pI "l"
# elif INTPTR_MAX <= LLONG_MAX
typedef long long int EMACS_INT;
typedef unsigned long long int EMACS_UINT;
+enum { EMACS_INT_WIDTH = LLONG_WIDTH };
# define EMACS_INT_MAX LLONG_MAX
-# define pI "ll"
+# ifdef __MINGW32__
+# define pI "I64"
+# else
+# define pI "ll"
+# endif
# else
# error "INTPTR_MAX too large"
# endif
@@ -103,11 +113,12 @@ enum { BOOL_VECTOR_BITS_PER_CHAR =
/* An unsigned integer type representing a fixed-length bit sequence,
suitable for bool vector words, GC mark bits, etc. Normally it is size_t
- for speed, but it is unsigned char on weird platforms. */
+ for speed, but on weird platforms it is unsigned char and not all
+ its bits are used. */
#if BOOL_VECTOR_BITS_PER_CHAR == CHAR_BIT
typedef size_t bits_word;
# define BITS_WORD_MAX SIZE_MAX
-enum { BITS_PER_BITS_WORD = CHAR_BIT * sizeof (bits_word) };
+enum { BITS_PER_BITS_WORD = SIZE_WIDTH };
#else
typedef unsigned char bits_word;
# define BITS_WORD_MAX ((1u << BOOL_VECTOR_BITS_PER_CHAR) - 1)
@@ -115,15 +126,6 @@ enum { BITS_PER_BITS_WORD = BOOL_VECTOR_BITS_PER_CHAR };
#endif
verify (BITS_WORD_MAX >> (BITS_PER_BITS_WORD - 1) == 1);
-/* Number of bits in some machine integer types. */
-enum
- {
- BITS_PER_CHAR = CHAR_BIT,
- BITS_PER_SHORT = CHAR_BIT * sizeof (short),
- BITS_PER_LONG = CHAR_BIT * sizeof (long int),
- BITS_PER_EMACS_INT = CHAR_BIT * sizeof (EMACS_INT)
- };
-
/* printmax_t and uprintmax_t are types for printing large integers.
These are the widest integers that are supported for printing.
pMd etc. are conversions for printing them.
@@ -228,7 +230,7 @@ enum Lisp_Bits
#define GCALIGNMENT 8
/* Number of bits in a Lisp_Object value, not counting the tag. */
- VALBITS = BITS_PER_EMACS_INT - GCTYPEBITS,
+ VALBITS = EMACS_INT_WIDTH - GCTYPEBITS,
/* Number of bits in a Lisp fixnum tag. */
INTTYPEBITS = GCTYPEBITS - 1,
@@ -256,6 +258,11 @@ DEFINE_GDB_SYMBOL_BEGIN (bool, USE_LSB_TAG)
#define USE_LSB_TAG (VAL_MAX / 2 < INTPTR_MAX)
DEFINE_GDB_SYMBOL_END (USE_LSB_TAG)
+/* Mask for the value (as opposed to the type bits) of a Lisp object. */
+DEFINE_GDB_SYMBOL_BEGIN (EMACS_INT, VALMASK)
+# define VALMASK (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX)
+DEFINE_GDB_SYMBOL_END (VALMASK)
+
#if !USE_LSB_TAG && !defined WIDE_EMACS_INT
# error "USE_LSB_TAG not supported on this platform; please report this." \
"Try 'configure --with-wide-int' to work around the problem."
@@ -290,9 +297,8 @@ error !;
used elsewhere.
FIXME: Remove the lisp_h_OP macros, and define just the inline OP
- functions, once most developers have access to GCC 4.8 or later and
- can use "gcc -Og" to debug. Maybe in the year 2016. See
- Bug#11935.
+ functions, once "gcc -Og" (new to GCC 4.8) works well enough for
+ Emacs developers. Maybe in the year 2020. See Bug#11935.
Commentary for these macros can be found near their corresponding
functions, below. */
@@ -308,7 +314,7 @@ error !;
#define lisp_h_CHECK_NUMBER(x) CHECK_TYPE (INTEGERP (x), Qintegerp, x)
#define lisp_h_CHECK_SYMBOL(x) CHECK_TYPE (SYMBOLP (x), Qsymbolp, x)
#define lisp_h_CHECK_TYPE(ok, predicate, x) \
- ((ok) ? (void) 0 : (void) wrong_type_argument (predicate, x))
+ ((ok) ? (void) 0 : wrong_type_argument (predicate, x))
#define lisp_h_CONSP(x) (XTYPE (x) == Lisp_Cons)
#define lisp_h_EQ(x, y) (XLI (x) == XLI (y))
#define lisp_h_FLOATP(x) (XTYPE (x) == Lisp_Float)
@@ -318,7 +324,8 @@ error !;
#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)->constant)
+#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)
#define lisp_h_SYMBOL_VAL(sym) \
(eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value)
#define lisp_h_SYMBOLP(x) (XTYPE (x) == Lisp_Symbol)
@@ -341,7 +348,9 @@ error !;
(struct Lisp_Symbol *) ((intptr_t) XLI (a) - Lisp_Symbol \
+ (char *) lispsym))
# define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK))
-# define lisp_h_XUNTAG(a, type) ((void *) (intptr_t) (XLI (a) - (type)))
+# define lisp_h_XUNTAG(a, type) \
+ __builtin_assume_aligned ((void *) (intptr_t) (XLI (a) - (type)), \
+ GCALIGNMENT)
#endif
/* When compiling via gcc -O0, define the key operations as macros, as
@@ -371,6 +380,7 @@ error !;
# define NILP(x) lisp_h_NILP (x)
# define SET_SYMBOL_VAL(sym, v) lisp_h_SET_SYMBOL_VAL (sym, v)
# define SYMBOL_CONSTANT_P(sym) lisp_h_SYMBOL_CONSTANT_P (sym)
+# define SYMBOL_TRAPPED_WRITE_P(sym) lisp_h_SYMBOL_TRAPPED_WRITE_P (sym)
# define SYMBOL_VAL(sym) lisp_h_SYMBOL_VAL (sym)
# define SYMBOLP(x) lisp_h_SYMBOLP (x)
# define VECTORLIKEP(x) lisp_h_VECTORLIKEP (x)
@@ -547,68 +557,87 @@ typedef EMACS_INT Lisp_Object;
#define LISP_INITIALLY(i) (i)
enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = false };
#endif /* CHECK_LISP_OBJECT_TYPE */
-
-#define LISP_INITIALLY_ZERO LISP_INITIALLY (0)
/* Forward declarations. */
/* Defined in this file. */
-union Lisp_Fwd;
-INLINE bool BOOL_VECTOR_P (Lisp_Object);
-INLINE bool BUFFER_OBJFWDP (union Lisp_Fwd *);
-INLINE bool BUFFERP (Lisp_Object);
-INLINE bool CHAR_TABLE_P (Lisp_Object);
-INLINE Lisp_Object CHAR_TABLE_REF_ASCII (Lisp_Object, ptrdiff_t);
-INLINE bool (CONSP) (Lisp_Object);
-INLINE bool (FLOATP) (Lisp_Object);
-INLINE bool functionp (Lisp_Object);
-INLINE bool (INTEGERP) (Lisp_Object);
-INLINE bool (MARKERP) (Lisp_Object);
-INLINE bool (MISCP) (Lisp_Object);
-INLINE bool (NILP) (Lisp_Object);
-INLINE bool OVERLAYP (Lisp_Object);
-INLINE bool PROCESSP (Lisp_Object);
-INLINE bool PSEUDOVECTORP (Lisp_Object, int);
-INLINE bool SAVE_VALUEP (Lisp_Object);
-INLINE bool FINALIZERP (Lisp_Object);
-
-#ifdef HAVE_MODULES
-INLINE bool USER_PTRP (Lisp_Object);
-INLINE struct Lisp_User_Ptr *(XUSER_PTR) (Lisp_Object);
-#endif
-
INLINE void set_sub_char_table_contents (Lisp_Object, ptrdiff_t,
Lisp_Object);
-INLINE bool STRINGP (Lisp_Object);
-INLINE bool SUB_CHAR_TABLE_P (Lisp_Object);
-INLINE bool SUBRP (Lisp_Object);
-INLINE bool (SYMBOLP) (Lisp_Object);
-INLINE bool (VECTORLIKEP) (Lisp_Object);
-INLINE bool WINDOWP (Lisp_Object);
-INLINE bool TERMINALP (Lisp_Object);
-INLINE struct Lisp_Save_Value *XSAVE_VALUE (Lisp_Object);
-INLINE struct Lisp_Finalizer *XFINALIZER (Lisp_Object);
-INLINE struct Lisp_Symbol *(XSYMBOL) (Lisp_Object);
-INLINE void *(XUNTAG) (Lisp_Object, int);
/* Defined in chartab.c. */
extern Lisp_Object char_table_ref (Lisp_Object, int);
extern void char_table_set (Lisp_Object, int, Lisp_Object);
/* Defined in data.c. */
-extern _Noreturn Lisp_Object wrong_type_argument (Lisp_Object, Lisp_Object);
-extern _Noreturn void wrong_choice (Lisp_Object, Lisp_Object);
+extern _Noreturn void wrong_type_argument (Lisp_Object, Lisp_Object);
+
+#ifdef CANNOT_DUMP
+enum { might_dump = false };
+#elif defined DOUG_LEA_MALLOC
/* Defined in emacs.c. */
extern bool might_dump;
+#endif
/* True means Emacs has already been initialized.
Used during startup to detect startup of dumped Emacs. */
extern bool initialized;
+extern bool generating_ldefs_boot;
+
/* Defined in floatfns.c. */
extern double extract_float (Lisp_Object);
+/* Low-level conversion and type checking. */
+
+/* Convert a Lisp_Object to the corresponding EMACS_INT and vice versa.
+ At the machine level, these operations are no-ops. */
+
+INLINE EMACS_INT
+(XLI) (Lisp_Object o)
+{
+ return lisp_h_XLI (o);
+}
+
+INLINE Lisp_Object
+(XIL) (EMACS_INT i)
+{
+ return lisp_h_XIL (i);
+}
+
+/* Extract A's type. */
+
+INLINE enum Lisp_Type
+(XTYPE) (Lisp_Object a)
+{
+#if USE_LSB_TAG
+ return lisp_h_XTYPE (a);
+#else
+ EMACS_UINT i = XLI (a);
+ return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS;
+#endif
+}
+
+INLINE void
+(CHECK_TYPE) (int ok, Lisp_Object predicate, Lisp_Object x)
+{
+ lisp_h_CHECK_TYPE (ok, predicate, x);
+}
+
+/* Extract A's pointer value, assuming A's type is TYPE. */
+
+INLINE void *
+(XUNTAG) (Lisp_Object a, int type)
+{
+#if USE_LSB_TAG
+ return lisp_h_XUNTAG (a, type);
+#else
+ intptr_t i = USE_LSB_TAG ? XLI (a) - type : XLI (a) & VALMASK;
+ return (void *) i;
+#endif
+}
+
+
/* Interned state of a symbol. */
enum symbol_interned
@@ -626,6 +655,13 @@ enum symbol_redirect
SYMBOL_FORWARDED = 3
};
+enum symbol_trapped_write
+{
+ SYMBOL_UNTRAPPED_WRITE = 0,
+ SYMBOL_NOWRITE = 1,
+ SYMBOL_TRAPPED_WRITE = 2
+};
+
struct Lisp_Symbol
{
bool_bf gcmarkbit : 1;
@@ -637,10 +673,10 @@ struct Lisp_Symbol
3 : it's a forwarding variable, the value is in `forward'. */
ENUM_BF (symbol_redirect) redirect : 3;
- /* Non-zero means symbol is constant, i.e. changing its value
- should signal an error. If the value is 3, then the var
- can be changed, but only by `defconst'. */
- unsigned constant : 2;
+ /* 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. */
@@ -719,12 +755,20 @@ struct Lisp_Symbol
except the former expands to an integer constant expression. */
#define XLI_BUILTIN_LISPSYM(iname) TAG_SYMOFFSET ((iname) * sizeof *lispsym)
+/* LISPSYM_INITIALLY (Qfoo) is equivalent to Qfoo except it is
+ designed for use as an initializer, even for a constant initializer. */
+#define LISPSYM_INITIALLY(name) LISP_INITIALLY (XLI_BUILTIN_LISPSYM (i##name))
+
/* Declare extern constants for Lisp symbols. These can be helpful
when using a debugger like GDB, on older platforms where the debug
format does not represent C macros. */
#define DEFINE_LISP_SYMBOL(name) \
DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) \
- DEFINE_GDB_SYMBOL_END (LISP_INITIALLY (XLI_BUILTIN_LISPSYM (i##name)))
+ DEFINE_GDB_SYMBOL_END (LISPSYM_INITIALLY (name))
+
+/* The index of the C-defined Lisp symbol SYM.
+ This can be used in a static initializer. */
+#define SYMBOL_INDEX(sym) i##sym
/* By default, define macros for Qt, etc., as this leads to a bit
better performance in the core Emacs interpreter. A plugin can
@@ -736,19 +780,74 @@ struct Lisp_Symbol
#include "globals.h"
-/* Convert a Lisp_Object to the corresponding EMACS_INT and vice versa.
- At the machine level, these operations are no-ops. */
+/* Header of vector-like objects. This documents the layout constraints on
+ vectors and pseudovectors (objects of PVEC_xxx subtype). It also prevents
+ compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR
+ and PSEUDOVECTORP cast their pointers to struct vectorlike_header *,
+ because when two such pointers potentially alias, a compiler won't
+ incorrectly reorder loads and stores to their size fields. See
+ Bug#8546. */
+struct vectorlike_header
+ {
+ /* The only field 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).
+ - If PSEUDOVECTOR_FLAG is 0, the rest holds the size (number
+ of slots) of the vector.
+ - If PSEUDOVECTOR_FLAG is 1, the rest is subdivided into three fields:
+ - a) pseudovector subtype held in PVEC_TYPE_MASK field;
+ - b) number of Lisp_Objects slots at the beginning of the object
+ held in PSEUDOVECTOR_SIZE_MASK field. These objects are always
+ traced by the GC;
+ - c) size of the rest fields held in PSEUDOVECTOR_REST_MASK and
+ measured in word_size units. Rest fields may also include
+ Lisp_Objects, but these objects usually needs some special treatment
+ during GC.
+ There are some exceptions. For PVEC_FREE, b) is always zero. For
+ PVEC_BOOL_VECTOR and PVEC_SUBR, both b) and c) are always zero.
+ 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;
+ };
-INLINE EMACS_INT
-(XLI) (Lisp_Object o)
+INLINE bool
+(SYMBOLP) (Lisp_Object x)
{
- return lisp_h_XLI (o);
+ return lisp_h_SYMBOLP (x);
+}
+
+INLINE struct Lisp_Symbol *
+(XSYMBOL) (Lisp_Object a)
+{
+#if USE_LSB_TAG
+ return lisp_h_XSYMBOL (a);
+#else
+ eassert (SYMBOLP (a));
+ intptr_t i = (intptr_t) XUNTAG (a, Lisp_Symbol);
+ void *p = (char *) lispsym + i;
+ return p;
+#endif
}
INLINE Lisp_Object
-(XIL) (EMACS_INT i)
+make_lisp_symbol (struct Lisp_Symbol *sym)
{
- return lisp_h_XIL (i);
+ Lisp_Object a = XIL (TAG_SYMOFFSET ((char *) sym - (char *) lispsym));
+ eassert (XSYMBOL (a) == sym);
+ return a;
+}
+
+INLINE Lisp_Object
+builtin_lisp_symbol (int index)
+{
+ return make_lisp_symbol (lispsym + index);
+}
+
+INLINE void
+(CHECK_SYMBOL) (Lisp_Object x)
+{
+ lisp_h_CHECK_SYMBOL (x);
}
/* In the size word of a vector, this bit means the vector has been marked. */
@@ -782,6 +881,9 @@ enum pvec_type
PVEC_OTHER,
PVEC_XWIDGET,
PVEC_XWIDGET_VIEW,
+ PVEC_THREAD,
+ PVEC_MUTEX,
+ PVEC_CONDVAR,
/* These should be last, check internal_equal to see why. */
PVEC_COMPILED,
@@ -816,11 +918,6 @@ enum More_Lisp_Bits
XCONS (tem) is the struct Lisp_Cons * pointing to the memory for
that cons. */
-/* Mask for the value (as opposed to the type bits) of a Lisp object. */
-DEFINE_GDB_SYMBOL_BEGIN (EMACS_INT, VALMASK)
-# define VALMASK (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX)
-DEFINE_GDB_SYMBOL_END (VALMASK)
-
/* Largest and smallest representable fixnum values. These are the C
values. They are macros for use in static initializers. */
#define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS)
@@ -848,24 +945,6 @@ INLINE EMACS_INT
return n;
}
-INLINE struct Lisp_Symbol *
-(XSYMBOL) (Lisp_Object a)
-{
- return lisp_h_XSYMBOL (a);
-}
-
-INLINE enum Lisp_Type
-(XTYPE) (Lisp_Object a)
-{
- return lisp_h_XTYPE (a);
-}
-
-INLINE void *
-(XUNTAG) (Lisp_Object a, int type)
-{
- return lisp_h_XUNTAG (a, type);
-}
-
#else /* ! USE_LSB_TAG */
/* Although compiled only if ! USE_LSB_TAG, the following functions
@@ -917,32 +996,6 @@ XFASTINT (Lisp_Object a)
return n;
}
-/* Extract A's type. */
-INLINE enum Lisp_Type
-XTYPE (Lisp_Object a)
-{
- EMACS_UINT i = XLI (a);
- return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS;
-}
-
-/* Extract A's value as a symbol. */
-INLINE struct Lisp_Symbol *
-XSYMBOL (Lisp_Object a)
-{
- eassert (SYMBOLP (a));
- intptr_t i = (intptr_t) XUNTAG (a, Lisp_Symbol);
- void *p = (char *) lispsym + i;
- return p;
-}
-
-/* Extract A's pointer value, assuming A's type is TYPE. */
-INLINE void *
-XUNTAG (Lisp_Object a, int type)
-{
- intptr_t i = USE_LSB_TAG ? XLI (a) - type : XLI (a) & VALMASK;
- return (void *) i;
-}
-
#endif /* ! USE_LSB_TAG */
/* Extract A's value as an unsigned integer. */
@@ -993,98 +1046,6 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper)
return num < lower ? lower : num <= upper ? num : upper;
}
-
-/* Extract a value or address from a Lisp_Object. */
-
-INLINE struct Lisp_Cons *
-(XCONS) (Lisp_Object a)
-{
- return lisp_h_XCONS (a);
-}
-
-INLINE struct Lisp_Vector *
-XVECTOR (Lisp_Object a)
-{
- eassert (VECTORLIKEP (a));
- return XUNTAG (a, Lisp_Vectorlike);
-}
-
-INLINE struct Lisp_String *
-XSTRING (Lisp_Object a)
-{
- eassert (STRINGP (a));
- return XUNTAG (a, Lisp_String);
-}
-
-/* The index of the C-defined Lisp symbol SYM.
- This can be used in a static initializer. */
-#define SYMBOL_INDEX(sym) i##sym
-
-INLINE struct Lisp_Float *
-XFLOAT (Lisp_Object a)
-{
- eassert (FLOATP (a));
- return XUNTAG (a, Lisp_Float);
-}
-
-/* Pseudovector types. */
-
-INLINE struct Lisp_Process *
-XPROCESS (Lisp_Object a)
-{
- eassert (PROCESSP (a));
- return XUNTAG (a, Lisp_Vectorlike);
-}
-
-INLINE struct window *
-XWINDOW (Lisp_Object a)
-{
- eassert (WINDOWP (a));
- return XUNTAG (a, Lisp_Vectorlike);
-}
-
-INLINE struct terminal *
-XTERMINAL (Lisp_Object a)
-{
- eassert (TERMINALP (a));
- return XUNTAG (a, Lisp_Vectorlike);
-}
-
-INLINE struct Lisp_Subr *
-XSUBR (Lisp_Object a)
-{
- eassert (SUBRP (a));
- return XUNTAG (a, Lisp_Vectorlike);
-}
-
-INLINE struct buffer *
-XBUFFER (Lisp_Object a)
-{
- eassert (BUFFERP (a));
- return XUNTAG (a, Lisp_Vectorlike);
-}
-
-INLINE struct Lisp_Char_Table *
-XCHAR_TABLE (Lisp_Object a)
-{
- eassert (CHAR_TABLE_P (a));
- return XUNTAG (a, Lisp_Vectorlike);
-}
-
-INLINE struct Lisp_Sub_Char_Table *
-XSUB_CHAR_TABLE (Lisp_Object a)
-{
- eassert (SUB_CHAR_TABLE_P (a));
- return XUNTAG (a, Lisp_Vectorlike);
-}
-
-INLINE struct Lisp_Bool_Vector *
-XBOOL_VECTOR (Lisp_Object a)
-{
- eassert (BOOL_VECTOR_P (a));
- return XUNTAG (a, Lisp_Vectorlike);
-}
-
/* Construct a Lisp_Object from a value or address. */
INLINE Lisp_Object
@@ -1095,18 +1056,10 @@ make_lisp_ptr (void *ptr, enum Lisp_Type type)
return a;
}
-INLINE Lisp_Object
-make_lisp_symbol (struct Lisp_Symbol *sym)
-{
- Lisp_Object a = XIL (TAG_SYMOFFSET ((char *) sym - (char *) lispsym));
- eassert (XSYMBOL (a) == sym);
- return a;
-}
-
-INLINE Lisp_Object
-builtin_lisp_symbol (int index)
+INLINE bool
+(INTEGERP) (Lisp_Object x)
{
- return make_lisp_symbol (lispsym + index);
+ return lisp_h_INTEGERP (x);
}
#define XSETINT(a, b) ((a) = make_number (b))
@@ -1151,6 +1104,9 @@ builtin_lisp_symbol (int index)
#define XSETCHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE))
#define XSETBOOL_VECTOR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR))
#define XSETSUB_CHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_SUB_CHAR_TABLE))
+#define XSETTHREAD(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_THREAD))
+#define XSETMUTEX(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_MUTEX))
+#define XSETCONDVAR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CONDVAR))
/* Efficiently convert a pointer to a Lisp object and back. The
pointer is represented as a Lisp integer, so the garbage collector
@@ -1171,14 +1127,6 @@ make_pointer_integer (void *p)
return a;
}
-/* Type checking. */
-
-INLINE void
-(CHECK_TYPE) (int ok, Lisp_Object predicate, Lisp_Object x)
-{
- lisp_h_CHECK_TYPE (ok, predicate, x);
-}
-
/* See the macros in intervals.h. */
typedef struct interval *INTERVAL;
@@ -1198,6 +1146,30 @@ struct GCALIGNED Lisp_Cons
} u;
};
+INLINE bool
+(NILP) (Lisp_Object x)
+{
+ return lisp_h_NILP (x);
+}
+
+INLINE bool
+(CONSP) (Lisp_Object x)
+{
+ return lisp_h_CONSP (x);
+}
+
+INLINE void
+CHECK_CONS (Lisp_Object x)
+{
+ CHECK_TYPE (CONSP (x), Qconsp, x);
+}
+
+INLINE struct Lisp_Cons *
+(XCONS) (Lisp_Object a)
+{
+ return lisp_h_XCONS (a);
+}
+
/* Take the car or cdr of something known to be a cons cell. */
/* The _addr functions shouldn't be used outside of the minimal set
of code that has to know what a cons cell looks like. Other code not
@@ -1249,16 +1221,20 @@ XSETCDR (Lisp_Object c, Lisp_Object n)
INLINE Lisp_Object
CAR (Lisp_Object c)
{
- return (CONSP (c) ? XCAR (c)
- : NILP (c) ? Qnil
- : wrong_type_argument (Qlistp, c));
+ if (CONSP (c))
+ return XCAR (c);
+ if (!NILP (c))
+ wrong_type_argument (Qlistp, c);
+ return Qnil;
}
INLINE Lisp_Object
CDR (Lisp_Object c)
{
- return (CONSP (c) ? XCDR (c)
- : NILP (c) ? Qnil
- : wrong_type_argument (Qlistp, c));
+ if (CONSP (c))
+ return XCDR (c);
+ if (!NILP (c))
+ wrong_type_argument (Qlistp, c);
+ return Qnil;
}
/* Take the car or cdr of something whose type is not known. */
@@ -1283,6 +1259,25 @@ struct GCALIGNED Lisp_String
unsigned char *data;
};
+INLINE bool
+STRINGP (Lisp_Object x)
+{
+ return XTYPE (x) == Lisp_String;
+}
+
+INLINE void
+CHECK_STRING (Lisp_Object x)
+{
+ CHECK_TYPE (STRINGP (x), Qstringp, x);
+}
+
+INLINE struct Lisp_String *
+XSTRING (Lisp_Object a)
+{
+ eassert (STRINGP (a));
+ return XUNTAG (a, Lisp_String);
+}
+
/* True if STR is a multibyte string. */
INLINE bool
STRING_MULTIBYTE (Lisp_Object str)
@@ -1378,37 +1373,6 @@ STRING_SET_CHARS (Lisp_Object string, ptrdiff_t newsize)
XSTRING (string)->size = newsize;
}
-/* Header of vector-like objects. This documents the layout constraints on
- vectors and pseudovectors (objects of PVEC_xxx subtype). It also prevents
- compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR
- and PSEUDOVECTORP cast their pointers to struct vectorlike_header *,
- because when two such pointers potentially alias, a compiler won't
- incorrectly reorder loads and stores to their size fields. See
- Bug#8546. */
-struct vectorlike_header
- {
- /* The only field 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).
- - If PSEUDOVECTOR_FLAG is 0, the rest holds the size (number
- of slots) of the vector.
- - If PSEUDOVECTOR_FLAG is 1, the rest is subdivided into three fields:
- - a) pseudovector subtype held in PVEC_TYPE_MASK field;
- - b) number of Lisp_Objects slots at the beginning of the object
- held in PSEUDOVECTOR_SIZE_MASK field. These objects are always
- traced by the GC;
- - c) size of the rest fields held in PSEUDOVECTOR_REST_MASK and
- measured in word_size units. Rest fields may also include
- Lisp_Objects, but these objects usually needs some special treatment
- during GC.
- There are some exceptions. For PVEC_FREE, b) is always zero. For
- PVEC_BOOL_VECTOR and PVEC_SUBR, both b) and c) are always zero.
- 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;
- };
-
/* A regular vector is just a header plus an array of Lisp_Objects. */
struct Lisp_Vector
@@ -1417,12 +1381,61 @@ struct Lisp_Vector
Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER];
};
-/* C11 prohibits alignof (struct Lisp_Vector), so compute it manually. */
-enum
- {
- ALIGNOF_STRUCT_LISP_VECTOR
- = alignof (union { struct vectorlike_header a; Lisp_Object b; })
- };
+INLINE bool
+(VECTORLIKEP) (Lisp_Object x)
+{
+ return lisp_h_VECTORLIKEP (x);
+}
+
+INLINE struct Lisp_Vector *
+XVECTOR (Lisp_Object a)
+{
+ eassert (VECTORLIKEP (a));
+ return XUNTAG (a, Lisp_Vectorlike);
+}
+
+INLINE ptrdiff_t
+ASIZE (Lisp_Object array)
+{
+ ptrdiff_t size = XVECTOR (array)->header.size;
+ eassume (0 <= size);
+ return size;
+}
+
+INLINE bool
+VECTORP (Lisp_Object x)
+{
+ return VECTORLIKEP (x) && ! (ASIZE (x) & PSEUDOVECTOR_FLAG);
+}
+
+INLINE void
+CHECK_VECTOR (Lisp_Object x)
+{
+ CHECK_TYPE (VECTORP (x), Qvectorp, x);
+}
+
+/* A pseudovector is like a vector, but has other non-Lisp components. */
+
+INLINE bool
+PSEUDOVECTOR_TYPEP (struct vectorlike_header *a, int code)
+{
+ return ((a->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
+ == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_AREA_BITS)));
+}
+
+/* True if A is a pseudovector whose code is CODE. */
+INLINE bool
+PSEUDOVECTORP (Lisp_Object a, int code)
+{
+ if (! VECTORLIKEP (a))
+ return false;
+ else
+ {
+ /* Converting to struct vectorlike_header * avoids aliasing issues. */
+ struct vectorlike_header *h = XUNTAG (a, Lisp_Vectorlike);
+ return PSEUDOVECTOR_TYPEP (h, code);
+ }
+}
/* A boolvector is a kind of vectorlike, with contents like a string. */
@@ -1440,6 +1453,51 @@ struct Lisp_Bool_Vector
bits_word data[FLEXIBLE_ARRAY_MEMBER];
};
+/* Some handy constants for calculating sizes
+ and offsets, mostly of vectorlike objects. */
+
+enum
+ {
+ header_size = offsetof (struct Lisp_Vector, contents),
+ bool_header_size = offsetof (struct Lisp_Bool_Vector, data),
+ word_size = sizeof (Lisp_Object)
+ };
+
+/* The number of data words and bytes in a bool vector with SIZE bits. */
+
+INLINE EMACS_INT
+bool_vector_words (EMACS_INT size)
+{
+ eassume (0 <= size && size <= EMACS_INT_MAX - (BITS_PER_BITS_WORD - 1));
+ return (size + BITS_PER_BITS_WORD - 1) / BITS_PER_BITS_WORD;
+}
+
+INLINE EMACS_INT
+bool_vector_bytes (EMACS_INT size)
+{
+ eassume (0 <= size && size <= EMACS_INT_MAX - (BITS_PER_BITS_WORD - 1));
+ return (size + BOOL_VECTOR_BITS_PER_CHAR - 1) / BOOL_VECTOR_BITS_PER_CHAR;
+}
+
+INLINE bool
+BOOL_VECTOR_P (Lisp_Object a)
+{
+ return PSEUDOVECTORP (a, PVEC_BOOL_VECTOR);
+}
+
+INLINE void
+CHECK_BOOL_VECTOR (Lisp_Object x)
+{
+ CHECK_TYPE (BOOL_VECTOR_P (x), Qbool_vector_p, x);
+}
+
+INLINE struct Lisp_Bool_Vector *
+XBOOL_VECTOR (Lisp_Object a)
+{
+ eassert (BOOL_VECTOR_P (a));
+ return XUNTAG (a, Lisp_Vectorlike);
+}
+
INLINE EMACS_INT
bool_vector_size (Lisp_Object a)
{
@@ -1460,22 +1518,6 @@ bool_vector_uchar_data (Lisp_Object a)
return (unsigned char *) bool_vector_data (a);
}
-/* The number of data words and bytes in a bool vector with SIZE bits. */
-
-INLINE EMACS_INT
-bool_vector_words (EMACS_INT size)
-{
- eassume (0 <= size && size <= EMACS_INT_MAX - (BITS_PER_BITS_WORD - 1));
- return (size + BITS_PER_BITS_WORD - 1) / BITS_PER_BITS_WORD;
-}
-
-INLINE EMACS_INT
-bool_vector_bytes (EMACS_INT size)
-{
- eassume (0 <= size && size <= EMACS_INT_MAX - (BITS_PER_BITS_WORD - 1));
- return (size + BOOL_VECTOR_BITS_PER_CHAR - 1) / BOOL_VECTOR_BITS_PER_CHAR;
-}
-
/* True if A's Ith bit is set. */
INLINE bool
@@ -1508,16 +1550,6 @@ bool_vector_set (Lisp_Object a, EMACS_INT i, bool b)
*addr &= ~ (1 << (i % BOOL_VECTOR_BITS_PER_CHAR));
}
-/* Some handy constants for calculating sizes
- and offsets, mostly of vectorlike objects. */
-
-enum
- {
- header_size = offsetof (struct Lisp_Vector, contents),
- bool_header_size = offsetof (struct Lisp_Bool_Vector, data),
- word_size = sizeof (Lisp_Object)
- };
-
/* Conveniences for dealing with Lisp arrays. */
INLINE Lisp_Object
@@ -1533,14 +1565,6 @@ aref_addr (Lisp_Object array, ptrdiff_t idx)
}
INLINE ptrdiff_t
-ASIZE (Lisp_Object array)
-{
- ptrdiff_t size = XVECTOR (array)->header.size;
- eassume (0 <= size);
- return size;
-}
-
-INLINE ptrdiff_t
gc_asize (Lisp_Object array)
{
/* Like ASIZE, but also can be used in the garbage collector. */
@@ -1657,6 +1681,19 @@ struct Lisp_Char_Table
Lisp_Object extras[FLEXIBLE_ARRAY_MEMBER];
};
+INLINE bool
+CHAR_TABLE_P (Lisp_Object a)
+{
+ return PSEUDOVECTORP (a, PVEC_CHAR_TABLE);
+}
+
+INLINE struct Lisp_Char_Table *
+XCHAR_TABLE (Lisp_Object a)
+{
+ eassert (CHAR_TABLE_P (a));
+ return XUNTAG (a, Lisp_Vectorlike);
+}
+
struct Lisp_Sub_Char_Table
{
/* HEADER.SIZE is the vector's size field, which also holds the
@@ -1678,6 +1715,19 @@ struct Lisp_Sub_Char_Table
Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER];
};
+INLINE bool
+SUB_CHAR_TABLE_P (Lisp_Object a)
+{
+ return PSEUDOVECTORP (a, PVEC_SUB_CHAR_TABLE);
+}
+
+INLINE struct Lisp_Sub_Char_Table *
+XSUB_CHAR_TABLE (Lisp_Object a)
+{
+ eassert (SUB_CHAR_TABLE_P (a));
+ return XUNTAG (a, Lisp_Vectorlike);
+}
+
INLINE Lisp_Object
CHAR_TABLE_REF_ASCII (Lisp_Object ct, ptrdiff_t idx)
{
@@ -1740,9 +1790,22 @@ struct Lisp_Subr
short min_args, max_args;
const char *symbol_name;
const char *intspec;
- const char *doc;
+ EMACS_INT doc;
};
+INLINE bool
+SUBRP (Lisp_Object a)
+{
+ return PSEUDOVECTORP (a, PVEC_SUBR);
+}
+
+INLINE struct Lisp_Subr *
+XSUBR (Lisp_Object a)
+{
+ eassert (SUBRP (a));
+ return XUNTAG (a, Lisp_Vectorlike);
+}
+
enum char_table_specials
{
/* This is the number of slots that every char table must have. This
@@ -1769,6 +1832,8 @@ verify (offsetof (struct Lisp_Sub_Char_Table, contents)
== (offsetof (struct Lisp_Vector, contents)
+ SUB_CHAR_TABLE_OFFSET * sizeof (Lisp_Object)));
+#include "thread.h"
+
/***********************************************************************
Symbols
***********************************************************************/
@@ -1784,19 +1849,19 @@ INLINE Lisp_Object
INLINE struct Lisp_Symbol *
SYMBOL_ALIAS (struct Lisp_Symbol *sym)
{
- eassert (sym->redirect == SYMBOL_VARALIAS);
+ eassume (sym->redirect == SYMBOL_VARALIAS && sym->val.alias);
return sym->val.alias;
}
INLINE struct Lisp_Buffer_Local_Value *
SYMBOL_BLV (struct Lisp_Symbol *sym)
{
- eassert (sym->redirect == SYMBOL_LOCALIZED);
+ eassume (sym->redirect == SYMBOL_LOCALIZED && sym->val.blv);
return sym->val.blv;
}
INLINE union Lisp_Fwd *
SYMBOL_FWD (struct Lisp_Symbol *sym)
{
- eassert (sym->redirect == SYMBOL_FORWARDED);
+ eassume (sym->redirect == SYMBOL_FORWARDED && sym->val.fwd);
return sym->val.fwd;
}
@@ -1809,19 +1874,19 @@ INLINE void
INLINE void
SET_SYMBOL_ALIAS (struct Lisp_Symbol *sym, struct Lisp_Symbol *v)
{
- eassert (sym->redirect == SYMBOL_VARALIAS);
+ eassume (sym->redirect == SYMBOL_VARALIAS && v);
sym->val.alias = v;
}
INLINE void
SET_SYMBOL_BLV (struct Lisp_Symbol *sym, struct Lisp_Buffer_Local_Value *v)
{
- eassert (sym->redirect == SYMBOL_LOCALIZED);
+ eassume (sym->redirect == SYMBOL_LOCALIZED && v);
sym->val.blv = v;
}
INLINE void
SET_SYMBOL_FWD (struct Lisp_Symbol *sym, union Lisp_Fwd *v)
{
- eassert (sym->redirect == SYMBOL_FORWARDED);
+ eassume (sym->redirect == SYMBOL_FORWARDED && v);
sym->val.fwd = v;
}
@@ -1847,9 +1912,20 @@ SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (Lisp_Object sym)
return XSYMBOL (sym)->interned == SYMBOL_INTERNED_IN_INITIAL_OBARRAY;
}
-/* Value is non-zero if symbol is considered a constant, i.e. its
- value cannot be changed (there is an exception for keyword symbols,
- whose value can be set to the keyword symbol itself). */
+/* Value is non-zero if symbol cannot be changed through a simple set,
+ i.e. it's a constant (e.g. nil, t, :keywords), or it has some
+ watching functions. */
+
+INLINE int
+(SYMBOL_TRAPPED_WRITE_P) (Lisp_Object sym)
+{
+ return lisp_h_SYMBOL_TRAPPED_WRITE_P (sym);
+}
+
+/* Value is non-zero if symbol cannot be changed at all, i.e. it's a
+ constant (e.g. nil, t, :keywords). Code that actually wants to
+ write to SYM, should also check whether there are any watching
+ functions. */
INLINE int
(SYMBOL_CONSTANT_P) (Lisp_Object sym)
@@ -2022,7 +2098,7 @@ static double const DEFAULT_REHASH_SIZE = 1.5;
INLINE EMACS_UINT
sxhash_combine (EMACS_UINT x, EMACS_UINT y)
{
- return (x << 4) + (x >> (BITS_PER_EMACS_INT - 4)) + y;
+ return (x << 4) + (x >> (EMACS_INT_WIDTH - 4)) + y;
}
/* Hash X, returning a value that fits into a fixnum. */
@@ -2030,7 +2106,7 @@ sxhash_combine (EMACS_UINT x, EMACS_UINT y)
INLINE EMACS_UINT
SXHASH_REDUCE (EMACS_UINT x)
{
- return (x ^ x >> (BITS_PER_EMACS_INT - FIXNUM_BITS)) & INTMASK;
+ return (x ^ x >> (EMACS_INT_WIDTH - FIXNUM_BITS)) & INTMASK;
}
/* These structures are used for various misc types. */
@@ -2042,6 +2118,25 @@ struct Lisp_Misc_Any /* Supertype of all Misc types. */
unsigned spacer : 15;
};
+INLINE bool
+(MISCP) (Lisp_Object x)
+{
+ return lisp_h_MISCP (x);
+}
+
+INLINE struct Lisp_Misc_Any *
+XMISCANY (Lisp_Object a)
+{
+ eassert (MISCP (a));
+ return XUNTAG (a, Lisp_Misc);
+}
+
+INLINE enum Lisp_Misc_Type
+XMISCTYPE (Lisp_Object a)
+{
+ return XMISCANY (a)->type;
+}
+
struct Lisp_Marker
{
ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Marker */
@@ -2107,18 +2202,8 @@ struct Lisp_Overlay
Lisp_Object plist;
};
-/* Types of data which may be saved in a Lisp_Save_Value. */
-
-enum
- {
- SAVE_UNUSED,
- SAVE_INTEGER,
- SAVE_FUNCPOINTER,
- SAVE_POINTER,
- SAVE_OBJECT
- };
-
-/* Number of bits needed to store one of the above values. */
+/* Number of bits needed to store one of the values
+ SAVE_UNUSED..SAVE_OBJECT. */
enum { SAVE_SLOT_BITS = 3 };
/* Number of slots in a save value where save_type is nonzero. */
@@ -2128,8 +2213,15 @@ enum { SAVE_VALUE_SLOTS = 4 };
enum { SAVE_TYPE_BITS = SAVE_VALUE_SLOTS * SAVE_SLOT_BITS + 1 };
+/* Types of data which may be saved in a Lisp_Save_Value. */
+
enum Lisp_Save_Type
{
+ SAVE_UNUSED,
+ SAVE_INTEGER,
+ SAVE_FUNCPOINTER,
+ SAVE_POINTER,
+ SAVE_OBJECT,
SAVE_TYPE_INT_INT = SAVE_INTEGER + (SAVE_INTEGER << SAVE_SLOT_BITS),
SAVE_TYPE_INT_INT_INT
= (SAVE_INTEGER + (SAVE_TYPE_INT_INT << SAVE_SLOT_BITS)),
@@ -2147,6 +2239,12 @@ enum Lisp_Save_Type
SAVE_TYPE_MEMORY = SAVE_TYPE_PTR_INT + (1 << (SAVE_TYPE_BITS - 1))
};
+/* SAVE_SLOT_BITS must be large enough to represent these values. */
+verify (((SAVE_UNUSED | SAVE_INTEGER | SAVE_FUNCPOINTER
+ | SAVE_POINTER | SAVE_OBJECT)
+ >> SAVE_SLOT_BITS)
+ == 0);
+
/* Special object used to hold a different values for later use.
This is mostly used to package C integers and pointers to call
@@ -2196,6 +2294,19 @@ struct Lisp_Save_Value
} data[SAVE_VALUE_SLOTS];
};
+INLINE bool
+SAVE_VALUEP (Lisp_Object x)
+{
+ return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value;
+}
+
+INLINE struct Lisp_Save_Value *
+XSAVE_VALUE (Lisp_Object a)
+{
+ eassert (SAVE_VALUEP (a));
+ return XUNTAG (a, Lisp_Misc);
+}
+
/* Return the type of V's Nth saved value. */
INLINE int
save_type (struct Lisp_Save_Value *v, int n)
@@ -2276,6 +2387,19 @@ struct Lisp_Finalizer
Lisp_Object function;
};
+INLINE bool
+FINALIZERP (Lisp_Object x)
+{
+ return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Finalizer;
+}
+
+INLINE struct Lisp_Finalizer *
+XFINALIZER (Lisp_Object a)
+{
+ eassert (FINALIZERP (a));
+ return XUNTAG (a, Lisp_Misc);
+}
+
/* A miscellaneous object, when it's on the free list. */
struct Lisp_Free
{
@@ -2307,53 +2431,44 @@ XMISC (Lisp_Object a)
return XUNTAG (a, Lisp_Misc);
}
-INLINE struct Lisp_Misc_Any *
-XMISCANY (Lisp_Object a)
-{
- eassert (MISCP (a));
- return & XMISC (a)->u_any;
-}
-
-INLINE enum Lisp_Misc_Type
-XMISCTYPE (Lisp_Object a)
+INLINE bool
+(MARKERP) (Lisp_Object x)
{
- return XMISCANY (a)->type;
+ return lisp_h_MARKERP (x);
}
INLINE struct Lisp_Marker *
XMARKER (Lisp_Object a)
{
eassert (MARKERP (a));
- return & XMISC (a)->u_marker;
+ return XUNTAG (a, Lisp_Misc);
}
-INLINE struct Lisp_Overlay *
-XOVERLAY (Lisp_Object a)
+INLINE bool
+OVERLAYP (Lisp_Object x)
{
- eassert (OVERLAYP (a));
- return & XMISC (a)->u_overlay;
+ return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay;
}
-INLINE struct Lisp_Save_Value *
-XSAVE_VALUE (Lisp_Object a)
+INLINE struct Lisp_Overlay *
+XOVERLAY (Lisp_Object a)
{
- eassert (SAVE_VALUEP (a));
- return & XMISC (a)->u_save_value;
+ eassert (OVERLAYP (a));
+ return XUNTAG (a, Lisp_Misc);
}
-INLINE struct Lisp_Finalizer *
-XFINALIZER (Lisp_Object a)
+#ifdef HAVE_MODULES
+INLINE bool
+USER_PTRP (Lisp_Object x)
{
- eassert (FINALIZERP (a));
- return & XMISC (a)->u_finalizer;
+ return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_User_Ptr;
}
-#ifdef HAVE_MODULES
INLINE struct Lisp_User_Ptr *
XUSER_PTR (Lisp_Object a)
{
eassert (USER_PTRP (a));
- return & XMISC (a)->u_user_ptr;
+ return XUNTAG (a, Lisp_Misc);
}
#endif
@@ -2399,7 +2514,7 @@ struct Lisp_Buffer_Objfwd
};
/* struct Lisp_Buffer_Local_Value is used in a symbol value cell when
- the symbol has buffer-local or frame-local bindings. (Exception:
+ the symbol has buffer-local bindings. (Exception:
some buffer-local variables are built-in, with their values stored
in the buffer structure itself. They are handled differently,
using struct Lisp_Buffer_Objfwd.)
@@ -2427,9 +2542,6 @@ struct Lisp_Buffer_Local_Value
/* True means that merely setting the variable creates a local
binding for the current buffer. */
bool_bf local_if_set : 1;
- /* True means this variable can have frame-local bindings, otherwise, it is
- can have buffer-local bindings. The two cannot be combined. */
- bool_bf frame_local : 1;
/* True means that the binding now loaded was found.
Presumably equivalent to (defcell!=valcell). */
bool_bf found : 1;
@@ -2471,6 +2583,12 @@ XFWDTYPE (union Lisp_Fwd *a)
return a->u_intfwd.type;
}
+INLINE bool
+BUFFER_OBJFWDP (union Lisp_Fwd *a)
+{
+ return XFWDTYPE (a) == Lisp_Fwd_Buffer_Obj;
+}
+
INLINE struct Lisp_Buffer_Objfwd *
XBUFFER_OBJFWD (union Lisp_Fwd *a)
{
@@ -2488,6 +2606,19 @@ struct Lisp_Float
} u;
};
+INLINE bool
+(FLOATP) (Lisp_Object x)
+{
+ return lisp_h_FLOATP (x);
+}
+
+INLINE struct Lisp_Float *
+XFLOAT (Lisp_Object a)
+{
+ eassert (FLOATP (a));
+ return XUNTAG (a, Lisp_Float);
+}
+
INLINE double
XFLOAT_DATA (Lisp_Object f)
{
@@ -2551,12 +2682,6 @@ enum char_bits
/* Data type checking. */
INLINE bool
-(NILP) (Lisp_Object x)
-{
- return lisp_h_NILP (x);
-}
-
-INLINE bool
NUMBERP (Lisp_Object x)
{
return INTEGERP (x) || FLOATP (x);
@@ -2579,109 +2704,11 @@ RANGED_INTEGERP (intmax_t lo, Lisp_Object x, intmax_t hi)
&& XINT (x) <= TYPE_MAXIMUM (type))
INLINE bool
-(CONSP) (Lisp_Object x)
-{
- return lisp_h_CONSP (x);
-}
-INLINE bool
-(FLOATP) (Lisp_Object x)
-{
- return lisp_h_FLOATP (x);
-}
-INLINE bool
-(MISCP) (Lisp_Object x)
-{
- return lisp_h_MISCP (x);
-}
-INLINE bool
-(SYMBOLP) (Lisp_Object x)
-{
- return lisp_h_SYMBOLP (x);
-}
-INLINE bool
-(INTEGERP) (Lisp_Object x)
-{
- return lisp_h_INTEGERP (x);
-}
-INLINE bool
-(VECTORLIKEP) (Lisp_Object x)
-{
- return lisp_h_VECTORLIKEP (x);
-}
-INLINE bool
-(MARKERP) (Lisp_Object x)
-{
- return lisp_h_MARKERP (x);
-}
-
-INLINE bool
-STRINGP (Lisp_Object x)
-{
- return XTYPE (x) == Lisp_String;
-}
-INLINE bool
-VECTORP (Lisp_Object x)
-{
- return VECTORLIKEP (x) && ! (ASIZE (x) & PSEUDOVECTOR_FLAG);
-}
-INLINE bool
-OVERLAYP (Lisp_Object x)
-{
- return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay;
-}
-INLINE bool
-SAVE_VALUEP (Lisp_Object x)
-{
- return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value;
-}
-
-INLINE bool
-FINALIZERP (Lisp_Object x)
-{
- return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Finalizer;
-}
-
-#ifdef HAVE_MODULES
-INLINE bool
-USER_PTRP (Lisp_Object x)
-{
- return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_User_Ptr;
-}
-#endif
-
-INLINE bool
AUTOLOADP (Lisp_Object x)
{
return CONSP (x) && EQ (Qautoload, XCAR (x));
}
-INLINE bool
-BUFFER_OBJFWDP (union Lisp_Fwd *a)
-{
- return XFWDTYPE (a) == Lisp_Fwd_Buffer_Obj;
-}
-
-INLINE bool
-PSEUDOVECTOR_TYPEP (struct vectorlike_header *a, int code)
-{
- return ((a->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
- == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_AREA_BITS)));
-}
-
-/* True if A is a pseudovector whose code is CODE. */
-INLINE bool
-PSEUDOVECTORP (Lisp_Object a, int code)
-{
- if (! VECTORLIKEP (a))
- return false;
- else
- {
- /* Converting to struct vectorlike_header * avoids aliasing issues. */
- struct vectorlike_header *h = XUNTAG (a, Lisp_Vectorlike);
- return PSEUDOVECTOR_TYPEP (h, code);
- }
-}
-
/* Test for specific pseudovector types. */
@@ -2692,60 +2719,12 @@ WINDOW_CONFIGURATIONP (Lisp_Object a)
}
INLINE bool
-PROCESSP (Lisp_Object a)
-{
- return PSEUDOVECTORP (a, PVEC_PROCESS);
-}
-
-INLINE bool
-WINDOWP (Lisp_Object a)
-{
- return PSEUDOVECTORP (a, PVEC_WINDOW);
-}
-
-INLINE bool
-TERMINALP (Lisp_Object a)
-{
- return PSEUDOVECTORP (a, PVEC_TERMINAL);
-}
-
-INLINE bool
-SUBRP (Lisp_Object a)
-{
- return PSEUDOVECTORP (a, PVEC_SUBR);
-}
-
-INLINE bool
COMPILEDP (Lisp_Object a)
{
return PSEUDOVECTORP (a, PVEC_COMPILED);
}
INLINE bool
-BUFFERP (Lisp_Object a)
-{
- return PSEUDOVECTORP (a, PVEC_BUFFER);
-}
-
-INLINE bool
-CHAR_TABLE_P (Lisp_Object a)
-{
- return PSEUDOVECTORP (a, PVEC_CHAR_TABLE);
-}
-
-INLINE bool
-SUB_CHAR_TABLE_P (Lisp_Object a)
-{
- return PSEUDOVECTORP (a, PVEC_SUB_CHAR_TABLE);
-}
-
-INLINE bool
-BOOL_VECTOR_P (Lisp_Object a)
-{
- return PSEUDOVECTORP (a, PVEC_BOOL_VECTOR);
-}
-
-INLINE bool
FRAMEP (Lisp_Object a)
{
return PSEUDOVECTORP (a, PVEC_FRAME);
@@ -2778,42 +2757,16 @@ INLINE void
}
INLINE void
-(CHECK_SYMBOL) (Lisp_Object x)
-{
- lisp_h_CHECK_SYMBOL (x);
-}
-
-INLINE void
(CHECK_NUMBER) (Lisp_Object x)
{
lisp_h_CHECK_NUMBER (x);
}
INLINE void
-CHECK_STRING (Lisp_Object x)
-{
- CHECK_TYPE (STRINGP (x), Qstringp, x);
-}
-INLINE void
CHECK_STRING_CAR (Lisp_Object x)
{
CHECK_TYPE (STRINGP (XCAR (x)), Qstringp, XCAR (x));
}
-INLINE void
-CHECK_CONS (Lisp_Object x)
-{
- CHECK_TYPE (CONSP (x), Qconsp, x);
-}
-INLINE void
-CHECK_VECTOR (Lisp_Object x)
-{
- CHECK_TYPE (VECTORP (x), Qvectorp, x);
-}
-INLINE void
-CHECK_BOOL_VECTOR (Lisp_Object x)
-{
- CHECK_TYPE (BOOL_VECTOR_P (x), Qbool_vector_p, x);
-}
/* This is a bit special because we always need size afterwards. */
INLINE ptrdiff_t
CHECK_VECTOR_OR_STRING (Lisp_Object x)
@@ -2830,23 +2783,6 @@ CHECK_ARRAY (Lisp_Object x, Lisp_Object predicate)
CHECK_TYPE (ARRAYP (x), predicate, x);
}
INLINE void
-CHECK_BUFFER (Lisp_Object x)
-{
- CHECK_TYPE (BUFFERP (x), Qbufferp, x);
-}
-INLINE void
-CHECK_WINDOW (Lisp_Object x)
-{
- CHECK_TYPE (WINDOWP (x), Qwindowp, x);
-}
-#ifdef subprocesses
-INLINE void
-CHECK_PROCESS (Lisp_Object x)
-{
- CHECK_TYPE (PROCESSP (x), Qprocessp, x);
-}
-#endif
-INLINE void
CHECK_NATNUM (Lisp_Object x)
{
CHECK_TYPE (NATNUMP (x), Qwholenump, x);
@@ -2962,13 +2898,6 @@ CHECK_NUMBER_CDR (Lisp_Object x)
Lisp_Object fnname
#endif
-/* True if OBJ is a Lisp function. */
-INLINE bool
-FUNCTIONP (Lisp_Object obj)
-{
- return functionp (obj);
-}
-
/* defsubr (Sname);
is how we define the symbol for function `name' at start-up time. */
extern void defsubr (struct Lisp_Subr *);
@@ -3032,12 +2961,6 @@ extern void defvar_kboard (struct Lisp_Kboard_Objfwd *, const char *, int);
defvar_int (&i_fwd, lname, &globals.f_ ## vname); \
} while (false)
-#define DEFVAR_BUFFER_DEFAULTS(lname, vname, doc) \
- do { \
- static struct Lisp_Objfwd o_fwd; \
- defvar_lisp_nopro (&o_fwd, lname, &BVAR (&buffer_defaults, vname)); \
- } while (false)
-
#define DEFVAR_KBOARD(lname, vname, doc) \
do { \
static struct Lisp_Kboard_Objfwd ko_fwd; \
@@ -3123,6 +3046,9 @@ union specbinding
ENUM_BF (specbind_tag) kind : CHAR_BIT;
/* `where' is not used in the case of SPECPDL_LET. */
Lisp_Object symbol, old_value, where;
+ /* Normally this is unused; but it is set to the symbol's
+ current value when a thread is swapped out. */
+ Lisp_Object saved_value;
} let;
struct {
ENUM_BF (specbind_tag) kind : CHAR_BIT;
@@ -3133,9 +3059,10 @@ union specbinding
} bt;
};
-extern union specbinding *specpdl;
-extern union specbinding *specpdl_ptr;
-extern ptrdiff_t specpdl_size;
+/* These 3 are defined as macros in thread.h. */
+/* extern union specbinding *specpdl; */
+/* extern union specbinding *specpdl_ptr; */
+/* extern ptrdiff_t specpdl_size; */
INLINE ptrdiff_t
SPECPDL_INDEX (void)
@@ -3186,19 +3113,14 @@ struct handler
/* Most global vars are reset to their value via the specpdl mechanism,
but a few others are handled by storing their value here. */
sys_jmp_buf jmp;
- EMACS_INT lisp_eval_depth;
+ EMACS_INT f_lisp_eval_depth;
ptrdiff_t pdlcount;
int poll_suppress_count;
int interrupt_input_blocked;
- struct byte_stack *byte_stack;
};
extern Lisp_Object memory_signal_data;
-/* An address near the bottom of the stack.
- Tells GC how to save a copy of the stack. */
-extern char *stack_bottom;
-
/* Check quit-flag and quit if it is non-nil.
Typing C-g does not directly cause a quit; it only sets Vquit_flag.
So the program needs to do QUIT at times when it is safe to quit.
@@ -3287,7 +3209,13 @@ set_symbol_next (Lisp_Object sym, struct Lisp_Symbol *next)
XSYMBOL (sym)->next = next;
}
-/* Buffer-local (also frame-local) variable access functions. */
+INLINE void
+make_symbol_constant (Lisp_Object sym)
+{
+ XSYMBOL (sym)->trapped_write = SYMBOL_NOWRITE;
+}
+
+/* Buffer-local variable access functions. */
INLINE int
blv_found (struct Lisp_Buffer_Local_Value *blv)
@@ -3357,6 +3285,9 @@ set_sub_char_table_contents (Lisp_Object table, ptrdiff_t idx, Lisp_Object val)
}
/* Defined in data.c. */
+extern _Noreturn void wrong_choice (Lisp_Object, Lisp_Object);
+extern void notify_variable_watchers (Lisp_Object, Lisp_Object,
+ Lisp_Object, Lisp_Object);
extern Lisp_Object indirect_function (Lisp_Object);
extern Lisp_Object find_symbol_value (Lisp_Object);
enum Arith_Comparison {
@@ -3395,7 +3326,17 @@ extern _Noreturn void args_out_of_range (Lisp_Object, Lisp_Object);
extern _Noreturn void args_out_of_range_3 (Lisp_Object, Lisp_Object,
Lisp_Object);
extern Lisp_Object do_symval_forwarding (union Lisp_Fwd *);
-extern void set_internal (Lisp_Object, Lisp_Object, Lisp_Object, bool);
+enum Set_Internal_Bind {
+ SET_INTERNAL_SET,
+ SET_INTERNAL_BIND,
+ SET_INTERNAL_UNBIND,
+ SET_INTERNAL_THREAD_SWITCH
+};
+extern void set_internal (Lisp_Object, Lisp_Object, Lisp_Object,
+ enum Set_Internal_Bind);
+extern void set_default_internal (Lisp_Object, Lisp_Object,
+ enum Set_Internal_Bind bindflag);
+
extern void syms_of_data (void);
extern void swap_in_global_binding (struct Lisp_Symbol *);
@@ -3439,7 +3380,7 @@ ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *);
ptrdiff_t hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object,
EMACS_UINT);
void hash_remove_from_table (struct Lisp_Hash_Table *, Lisp_Object);
-extern struct hash_table_test hashtest_eq, hashtest_eql, hashtest_equal;
+extern struct hash_table_test const hashtest_eq, hashtest_eql, hashtest_equal;
extern void validate_subarray (Lisp_Object, Lisp_Object, Lisp_Object,
ptrdiff_t, ptrdiff_t *, ptrdiff_t *);
extern Lisp_Object substring_both (Lisp_Object, ptrdiff_t, ptrdiff_t,
@@ -3503,7 +3444,7 @@ extern void insert_from_string_before_markers (Lisp_Object, ptrdiff_t,
ptrdiff_t, bool);
extern void del_range (ptrdiff_t, ptrdiff_t);
extern Lisp_Object del_range_1 (ptrdiff_t, ptrdiff_t, bool, bool);
-extern void del_range_byte (ptrdiff_t, ptrdiff_t, bool);
+extern void del_range_byte (ptrdiff_t, ptrdiff_t);
extern void del_range_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool);
extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t,
ptrdiff_t, ptrdiff_t, bool);
@@ -3516,6 +3457,8 @@ extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t,
ptrdiff_t, ptrdiff_t);
extern void adjust_markers_for_delete (ptrdiff_t, ptrdiff_t,
ptrdiff_t, ptrdiff_t);
+extern void adjust_markers_bytepos (ptrdiff_t, ptrdiff_t,
+ ptrdiff_t, ptrdiff_t, int);
extern void replace_range (ptrdiff_t, ptrdiff_t, Lisp_Object, bool, bool, bool, bool);
extern void replace_range_2 (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t,
const char *, ptrdiff_t, ptrdiff_t, bool);
@@ -3584,16 +3527,12 @@ extern void mark_object (Lisp_Object);
#if defined REL_ALLOC && !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
extern void refill_memory_reserve (void);
#endif
-#ifdef DOUG_LEA_MALLOC
extern void alloc_unexec_pre (void);
extern void alloc_unexec_post (void);
-#else
-INLINE void alloc_unexec_pre (void) {}
-INLINE void alloc_unexec_post (void) {}
-#endif
+extern void mark_stack (char *, char *);
+extern void flush_stack_call_func (void (*func) (void *arg), void *arg);
extern const char *pending_malloc_warning;
extern Lisp_Object zero_vector;
-extern Lisp_Object *stack_base;
extern EMACS_INT consing_since_gc;
extern EMACS_INT gc_relative_threshold;
extern EMACS_INT memory_full_cons_threshold;
@@ -3728,7 +3667,6 @@ extern struct Lisp_Vector *allocate_pseudovector (int, int, int,
VECSIZE (type), tag))
extern bool gc_in_progress;
-extern bool abort_on_gc;
extern Lisp_Object make_float (double);
extern void display_malloc_warning (void);
extern ptrdiff_t inhibit_garbage_collection (void);
@@ -3756,6 +3694,15 @@ extern void check_cons_list (void);
INLINE void (check_cons_list) (void) { lisp_h_check_cons_list (); }
#endif
+/* Defined in gmalloc.c. */
+#if !defined DOUG_LEA_MALLOC && !defined HYBRID_MALLOC && !defined SYSTEM_MALLOC
+extern size_t __malloc_extra_blocks;
+#endif
+#if !HAVE_DECL_ALIGNED_ALLOC
+extern void *aligned_alloc (size_t, size_t) ATTRIBUTE_MALLOC_SIZE ((2));
+#endif
+extern void malloc_enable_thread (void);
+
#ifdef REL_ALLOC
/* Defined in ralloc.c. */
extern void *r_alloc (void **, size_t) ATTRIBUTE_ALLOC_SIZE ((2));
@@ -3847,7 +3794,6 @@ extern Lisp_Object Vautoload_queue;
extern Lisp_Object Vrun_hooks;
extern Lisp_Object Vsignaling_function;
extern Lisp_Object inhibit_lisp_code;
-extern struct handler *handlerlist;
/* To run a normal hook, use the appropriate function from the list below.
The calling convention:
@@ -3861,13 +3807,20 @@ extern void run_hook_with_args_2 (Lisp_Object, Lisp_Object, Lisp_Object);
extern Lisp_Object run_hook_with_args (ptrdiff_t nargs, Lisp_Object *args,
Lisp_Object (*funcall)
(ptrdiff_t nargs, Lisp_Object *args));
-extern _Noreturn void xsignal (Lisp_Object, Lisp_Object);
+extern Lisp_Object quit (void);
+INLINE _Noreturn void
+xsignal (Lisp_Object error_symbol, Lisp_Object data)
+{
+ Fsignal (error_symbol, data);
+}
extern _Noreturn void xsignal0 (Lisp_Object);
extern _Noreturn void xsignal1 (Lisp_Object, Lisp_Object);
extern _Noreturn void xsignal2 (Lisp_Object, Lisp_Object, Lisp_Object);
extern _Noreturn void xsignal3 (Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object);
extern _Noreturn void signal_error (const char *, Lisp_Object);
+extern bool FUNCTIONP (Lisp_Object);
+extern Lisp_Object funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *arg_vector);
extern Lisp_Object eval_sub (Lisp_Object form);
extern Lisp_Object apply1 (Lisp_Object, Lisp_Object);
extern Lisp_Object call0 (Lisp_Object);
@@ -3898,9 +3851,13 @@ extern void clear_unwind_protect (ptrdiff_t);
extern void set_unwind_protect (ptrdiff_t, void (*) (Lisp_Object), Lisp_Object);
extern void set_unwind_protect_ptr (ptrdiff_t, void (*) (void *), void *);
extern Lisp_Object unbind_to (ptrdiff_t, Lisp_Object);
+extern void rebind_for_thread_switch (void);
+extern void unbind_for_thread_switch (struct thread_state *);
extern _Noreturn void error (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2);
extern _Noreturn void verror (const char *, va_list)
ATTRIBUTE_FORMAT_PRINTF (1, 0);
+extern Lisp_Object vformat_string (const char *, va_list)
+ ATTRIBUTE_FORMAT_PRINTF (1, 0);
extern void un_autoload (Lisp_Object);
extern Lisp_Object call_debugger (Lisp_Object arg);
extern void *near_C_stack_top (void);
@@ -3910,9 +3867,9 @@ extern Lisp_Object safe_call1 (Lisp_Object, Lisp_Object);
extern Lisp_Object safe_call2 (Lisp_Object, Lisp_Object, Lisp_Object);
extern void init_eval (void);
extern void syms_of_eval (void);
-extern void unwind_body (Lisp_Object);
+extern void prog_ignore (Lisp_Object);
extern ptrdiff_t record_in_backtrace (Lisp_Object, Lisp_Object *, ptrdiff_t);
-extern void mark_specpdl (void);
+extern void mark_specpdl (union specbinding *first, union specbinding *ptr);
extern void get_backtrace (Lisp_Object array);
Lisp_Object backtrace_top_function (void);
extern bool let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol);
@@ -3923,10 +3880,12 @@ extern bool let_shadows_global_binding_p (Lisp_Object symbol);
extern Lisp_Object make_user_ptr (void (*finalizer) (void *), void *p);
/* Defined in emacs-module.c. */
-extern void module_init (void);
extern void syms_of_module (void);
#endif
+/* Defined in thread.c. */
+extern void mark_threads (void);
+
/* Defined in editfns.c. */
extern void insert1 (Lisp_Object);
extern Lisp_Object save_excursion_save (void);
@@ -4119,6 +4078,7 @@ INLINE void fixup_locale (void) {}
INLINE void synchronize_system_messages_locale (void) {}
INLINE void synchronize_system_time_locale (void) {}
#endif
+extern char *emacs_strerror (int);
extern void shut_down_emacs (int, Lisp_Object);
/* True means don't do interactive redisplay and don't change tty modes. */
@@ -4127,12 +4087,14 @@ extern bool noninteractive;
/* True means remove site-lisp directories from load-path. */
extern bool no_site_lisp;
-/* Pipe used to send exit notification to the daemon parent at
- startup. On Windows, we use a kernel event instead. */
+/* True means put details like time stamps into builds. */
+extern bool build_details;
+
#ifndef WINDOWSNT
-extern int daemon_pipe[2];
-#define IS_DAEMON (daemon_pipe[1] != 0)
-#define DAEMON_RUNNING (daemon_pipe[1] >= 0)
+/* 0 not a daemon, 1 new-style (foreground), 2 old-style (background). */
+extern int daemon_type;
+#define IS_DAEMON (daemon_type != 0)
+#define DAEMON_RUNNING (daemon_type >= 0)
#else /* WINDOWSNT */
extern void *w32_daemon_event;
#define IS_DAEMON (w32_daemon_event != NULL)
@@ -4148,12 +4110,13 @@ extern bool inhibit_window_system;
extern bool running_asynch_code;
/* Defined in process.c. */
+struct Lisp_Process;
extern void kill_buffer_processes (Lisp_Object);
extern int wait_reading_process_output (intmax_t, int, int, bool, Lisp_Object,
struct Lisp_Process *, int);
/* Max value for the first argument of wait_reading_process_output. */
-#if __GNUC__ == 3 || (__GNUC__ == 4 && __GNUC_MINOR__ <= 5)
-/* Work around a bug in GCC 3.4.2, known to be fixed in GCC 4.6.3.
+#if GNUC_PREREQ (3, 0, 0) && ! GNUC_PREREQ (4, 6, 0)
+/* Work around a bug in GCC 3.4.2, known to be fixed in GCC 4.6.0.
The bug merely causes a bogus warning, but the warning is annoying. */
# define WAIT_READING_MAX min (TYPE_MAXIMUM (time_t), INTMAX_MAX)
#else
@@ -4168,15 +4131,17 @@ extern void delete_keyboard_wait_descriptor (int);
extern void add_gpm_wait_descriptor (int);
extern void delete_gpm_wait_descriptor (int);
#endif
-extern void init_process_emacs (void);
+extern void init_process_emacs (int);
extern void syms_of_process (void);
extern void setup_process_coding_systems (Lisp_Object);
/* Defined in callproc.c. */
#ifndef DOS_NT
- _Noreturn
+# define CHILD_SETUP_TYPE _Noreturn void
+#else
+# define CHILD_SETUP_TYPE int
#endif
-extern int child_setup (int, int, int, char **, bool, Lisp_Object);
+extern CHILD_SETUP_TYPE child_setup (int, int, int, char **, bool, Lisp_Object);
extern void init_callproc_1 (void);
extern void init_callproc (void);
extern void set_initial_environment (void);
@@ -4202,10 +4167,9 @@ extern int read_bytecode_char (bool);
/* Defined in bytecode.c. */
extern void syms_of_bytecode (void);
-extern struct byte_stack *byte_stack_list;
-extern void relocate_byte_stack (void);
extern Lisp_Object exec_byte_code (Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object, ptrdiff_t, Lisp_Object *);
+extern Lisp_Object get_byte_code_arity (Lisp_Object);
/* Defined in macros.c. */
extern void init_macros (void);
@@ -4234,13 +4198,15 @@ extern void syms_of_xmenu (void);
/* Defined in termchar.h. */
struct tty_display_info;
-/* Defined in termhooks.h. */
-struct terminal;
-
/* Defined in sysdep.c. */
-#ifndef HAVE_GET_CURRENT_DIR_NAME
-extern char *get_current_dir_name (void);
+#ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE
+extern bool disable_address_randomization (void);
+#else
+INLINE bool disable_address_randomization (void) { return false; }
#endif
+extern int emacs_exec_file (char const *, char *const *, char *const *);
+extern void init_standard_fds (void);
+extern char *emacs_get_current_dir_name (void);
extern void stuff_char (char c);
extern void init_foreground_group (void);
extern void sys_subshell (void);
@@ -4495,12 +4461,14 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
} \
} while (false)
-/* SAFE_ALLOCA_LISP allocates an array of Lisp_Objects. */
+/* Set BUF to point to an allocated array of NELT Lisp_Objects,
+ immediately followed by EXTRA spare bytes. */
-#define SAFE_ALLOCA_LISP(buf, nelt) \
+#define SAFE_ALLOCA_LISP_EXTRA(buf, nelt, extra) \
do { \
ptrdiff_t alloca_nbytes; \
if (INT_MULTIPLY_WRAPV (nelt, word_size, &alloca_nbytes) \
+ || INT_ADD_WRAPV (alloca_nbytes, extra, &alloca_nbytes) \
|| SIZE_MAX < alloca_nbytes) \
memory_full (SIZE_MAX); \
else if (alloca_nbytes <= sa_avail) \
@@ -4515,6 +4483,10 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
} \
} while (false)
+/* Set BUF to point to an allocated array of NELT Lisp_Objects. */
+
+#define SAFE_ALLOCA_LISP(buf, nelt) SAFE_ALLOCA_LISP_EXTRA (buf, nelt, 0)
+
/* If USE_STACK_LISP_OBJECTS, define macros that and functions that allocate
block-scoped conses and strings. These objects are not
@@ -4526,8 +4498,7 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
Build with CPPFLAGS='-DUSE_STACK_LISP_OBJECTS=0' to disable it. */
#if (!defined USE_STACK_LISP_OBJECTS \
- && defined __GNUC__ && !defined __clang__ \
- && !(4 < __GNUC__ + (3 < __GNUC_MINOR__ + (2 <= __GNUC_PATCHLEVEL__))))
+ && defined __GNUC__ && !defined __clang__ && ! GNUC_PREREQ (4, 3, 2))
/* Work around GCC bugs 36584 and 35271, which were fixed in GCC 4.3.2. */
# define USE_STACK_LISP_OBJECTS false
#endif
@@ -4600,27 +4571,29 @@ enum
STACK_CONS (d, Qnil)))) \
: list4 (a, b, c, d))
-/* Check whether stack-allocated strings are ASCII-only. */
+/* Declare NAME as an auto Lisp string if possible, a GC-based one if not.
+ Take its unibyte value from the null-terminated string STR,
+ an expression that should not have side effects.
+ STR's value is not necessarily copied. The resulting Lisp string
+ should not be modified or made visible to user code. */
-#if defined (ENABLE_CHECKING) && USE_STACK_LISP_OBJECTS
-extern const char *verify_ascii (const char *);
-#else
-# define verify_ascii(str) (str)
-#endif
+#define AUTO_STRING(name, str) \
+ AUTO_STRING_WITH_LEN (name, str, strlen (str))
/* Declare NAME as an auto Lisp string if possible, a GC-based one if not.
- Take its value from STR. STR is not necessarily copied and should
- contain only ASCII characters. The resulting Lisp string should
- not be modified or made visible to user code. */
+ Take its unibyte value from the null-terminated string STR with length LEN.
+ STR may have side effects and may contain null bytes.
+ STR's value is not necessarily copied. The resulting Lisp string
+ should not be modified or made visible to user code. */
-#define AUTO_STRING(name, str) \
+#define AUTO_STRING_WITH_LEN(name, str, len) \
Lisp_Object name = \
(USE_STACK_STRING \
? (make_lisp_ptr \
((&(union Aligned_String) \
- {{strlen (str), -1, 0, (unsigned char *) verify_ascii (str)}}.s), \
- Lisp_String)) \
- : build_string (verify_ascii (str)))
+ {{len, -1, 0, (unsigned char *) (str)}}.s), \
+ Lisp_String)) \
+ : make_unibyte_string (str, len))
/* Loop over all tails of a list, checking for cycles.
FIXME: Make tortoise and n internal declarations.
@@ -4656,38 +4629,6 @@ maybe_gc (void)
Fgarbage_collect ();
}
-INLINE bool
-functionp (Lisp_Object object)
-{
- if (SYMBOLP (object) && !NILP (Ffboundp (object)))
- {
- object = Findirect_function (object, Qt);
-
- if (CONSP (object) && EQ (XCAR (object), Qautoload))
- {
- /* Autoloaded symbols are functions, except if they load
- macros or keymaps. */
- int i;
- for (i = 0; i < 4 && CONSP (object); i++)
- object = XCDR (object);
-
- return ! (CONSP (object) && !NILP (XCAR (object)));
- }
- }
-
- if (SUBRP (object))
- return XSUBR (object)->max_args != UNEVALLED;
- else if (COMPILEDP (object))
- return true;
- else if (CONSP (object))
- {
- Lisp_Object car = XCAR (object);
- return EQ (car, Qlambda) || EQ (car, Qclosure);
- }
- else
- return false;
-}
-
INLINE_HEADER_END
#endif /* EMACS_LISP_H */