X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/5b71542de3ef7f08b7c30e93340502d7cc120910..ddb317ba828f05eb48e98fda530443955485e75d:/src/lisp.h diff --git a/src/lisp.h b/src/lisp.h index 6d79bb1d6a..c7f13e21e5 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -31,11 +31,9 @@ along with GNU Emacs. If not, see . */ #include #include +#include INLINE_HEADER_BEGIN -#ifndef LISP_INLINE -# define LISP_INLINE INLINE -#endif /* The ubiquitous max and min macros. */ #undef min @@ -110,11 +108,12 @@ typedef EMACS_UINT uprintmax_t; /* Extra internal type checking? */ -/* Define an Emacs version of 'assert (COND)', since some - system-defined 'assert's are flaky. COND should be free of side - effects; it may or may not be evaluated. */ +/* Define an Emacs version of 'assert (COND)'. COND should be free of + side effects; it may be evaluated zero or more times. If COND is false, + Emacs reliably crashes if ENABLE_CHECKING is defined and behavior + is undefined if not. The compiler may assume COND while optimizing. */ #ifndef ENABLE_CHECKING -# define eassert(X) ((void) (0 && (X))) /* Check that X compiles. */ +# define eassert(cond) assume (cond) #else /* ENABLE_CHECKING */ extern _Noreturn void die (const char *, const char *, int); @@ -131,9 +130,10 @@ extern bool suppress_checking EXTERNALLY_VISIBLE; # define eassert(cond) \ (suppress_checking || (cond) \ - ? (void) 0 \ + ? assume (cond) \ : die (# cond, __FILE__, __LINE__)) #endif /* ENABLE_CHECKING */ + /* Use the configure flag --enable-check-lisp-object-type to make Lisp_Object use a struct type instead of the default int. The flag @@ -345,11 +345,11 @@ enum enum_USE_LSB_TAG { USE_LSB_TAG = 0 }; ARGS should be parenthesized. Implement the function by calling lisp_h_NAME ARGS. */ #define LISP_MACRO_DEFUN(name, type, argdecls, args) \ - LISP_INLINE type (name) argdecls { return lisp_h_##name args; } + INLINE type (name) argdecls { return lisp_h_##name args; } /* like LISP_MACRO_DEFUN, except NAME returns void. */ #define LISP_MACRO_DEFUN_VOID(name, argdecls, args) \ - LISP_INLINE void (name) argdecls { lisp_h_##name args; } + INLINE void (name) argdecls { lisp_h_##name args; } /* Define the fundamental Lisp data structures. */ @@ -610,14 +610,14 @@ LISP_MACRO_DEFUN (XUNTAG, void *, (Lisp_Object a, int type), (a, type)) /* Make a Lisp integer representing the value of the low order bits of N. */ -LISP_INLINE Lisp_Object +INLINE Lisp_Object make_number (EMACS_INT n) { return XIL (USE_LSB_TAG ? n << INTTYPEBITS : n & INTMASK); } /* Extract A's value as a signed integer. */ -LISP_INLINE EMACS_INT +INLINE EMACS_INT XINT (Lisp_Object a) { EMACS_INT i = XLI (a); @@ -627,7 +627,7 @@ XINT (Lisp_Object a) /* Like XINT (A), but may be faster. A must be nonnegative. If ! USE_LSB_TAG, this takes advantage of the fact that Lisp integers have zero-bits in their tags. */ -LISP_INLINE EMACS_INT +INLINE EMACS_INT XFASTINT (Lisp_Object a) { EMACS_INT n = USE_LSB_TAG ? XINT (a) : XLI (a); @@ -636,7 +636,7 @@ XFASTINT (Lisp_Object a) } /* Extract A's type. */ -LISP_INLINE enum Lisp_Type +INLINE enum Lisp_Type XTYPE (Lisp_Object a) { EMACS_UINT i = XLI (a); @@ -644,7 +644,7 @@ XTYPE (Lisp_Object a) } /* Extract A's pointer value, assuming A's type is TYPE. */ -LISP_INLINE void * +INLINE void * XUNTAG (Lisp_Object a, int type) { if (USE_LSB_TAG) @@ -658,7 +658,7 @@ XUNTAG (Lisp_Object a, int type) #endif /* ! USE_LSB_TAG */ /* Extract A's value as an unsigned integer. */ -LISP_INLINE EMACS_UINT +INLINE EMACS_UINT XUINT (Lisp_Object a) { EMACS_UINT i = XLI (a); @@ -671,7 +671,7 @@ XUINT (Lisp_Object a) LISP_MACRO_DEFUN (XHASH, EMACS_INT, (Lisp_Object a), (a)) /* Like make_number (N), but may be faster. N must be in nonnegative range. */ -LISP_INLINE Lisp_Object +INLINE Lisp_Object make_natnum (EMACS_INT n) { eassert (0 <= n && n <= MOST_POSITIVE_FIXNUM); @@ -688,7 +688,7 @@ LISP_MACRO_DEFUN (EQ, bool, (Lisp_Object x, Lisp_Object y), (x, y)) #define FIXNUM_OVERFLOW_P(i) \ (! ((0 <= (i) || MOST_NEGATIVE_FIXNUM <= (i)) && (i) <= MOST_POSITIVE_FIXNUM)) -LISP_INLINE ptrdiff_t +INLINE ptrdiff_t clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper) { return num < lower ? lower : num <= upper ? num : upper; @@ -698,31 +698,31 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper) /* Defined in this file. */ union Lisp_Fwd; -LISP_INLINE bool BOOL_VECTOR_P (Lisp_Object); -LISP_INLINE bool BUFFER_OBJFWDP (union Lisp_Fwd *); -LISP_INLINE bool BUFFERP (Lisp_Object); -LISP_INLINE bool CHAR_TABLE_P (Lisp_Object); -LISP_INLINE Lisp_Object CHAR_TABLE_REF_ASCII (Lisp_Object, ptrdiff_t); -LISP_INLINE bool (CONSP) (Lisp_Object); -LISP_INLINE bool (FLOATP) (Lisp_Object); -LISP_INLINE bool functionp (Lisp_Object); -LISP_INLINE bool (INTEGERP) (Lisp_Object); -LISP_INLINE bool (MARKERP) (Lisp_Object); -LISP_INLINE bool (MISCP) (Lisp_Object); -LISP_INLINE bool (NILP) (Lisp_Object); -LISP_INLINE bool OVERLAYP (Lisp_Object); -LISP_INLINE bool PROCESSP (Lisp_Object); -LISP_INLINE bool PSEUDOVECTORP (Lisp_Object, int); -LISP_INLINE bool SAVE_VALUEP (Lisp_Object); -LISP_INLINE void set_sub_char_table_contents (Lisp_Object, ptrdiff_t, +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 void set_sub_char_table_contents (Lisp_Object, ptrdiff_t, Lisp_Object); -LISP_INLINE bool STRINGP (Lisp_Object); -LISP_INLINE bool SUB_CHAR_TABLE_P (Lisp_Object); -LISP_INLINE bool SUBRP (Lisp_Object); -LISP_INLINE bool (SYMBOLP) (Lisp_Object); -LISP_INLINE bool (VECTORLIKEP) (Lisp_Object); -LISP_INLINE bool WINDOWP (Lisp_Object); -LISP_INLINE struct Lisp_Save_Value *XSAVE_VALUE (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 struct Lisp_Save_Value *XSAVE_VALUE (Lisp_Object); /* Defined in chartab.c. */ extern Lisp_Object char_table_ref (Lisp_Object, int); @@ -733,6 +733,7 @@ extern int char_table_translate (Lisp_Object, int); extern Lisp_Object Qarrayp, Qbufferp, Qbuffer_or_string_p, Qchar_table_p; extern Lisp_Object Qconsp, Qfloatp, Qintegerp, Qlambda, Qlistp, Qmarkerp, Qnil; extern Lisp_Object Qnumberp, Qstringp, Qsymbolp, Qvectorp; +extern Lisp_Object Qbool_vector_p; extern Lisp_Object Qvector_or_char_table_p, Qwholenump; extern Lisp_Object Qwindow; extern Lisp_Object Ffboundp (Lisp_Object); @@ -761,14 +762,14 @@ extern Lisp_Object Qimage; LISP_MACRO_DEFUN (XCONS, struct Lisp_Cons *, (Lisp_Object a), (a)) -LISP_INLINE struct Lisp_Vector * +INLINE struct Lisp_Vector * XVECTOR (Lisp_Object a) { eassert (VECTORLIKEP (a)); return XUNTAG (a, Lisp_Vectorlike); } -LISP_INLINE struct Lisp_String * +INLINE struct Lisp_String * XSTRING (Lisp_Object a) { eassert (STRINGP (a)); @@ -777,7 +778,7 @@ XSTRING (Lisp_Object a) LISP_MACRO_DEFUN (XSYMBOL, struct Lisp_Symbol *, (Lisp_Object a), (a)) -LISP_INLINE struct Lisp_Float * +INLINE struct Lisp_Float * XFLOAT (Lisp_Object a) { eassert (FLOATP (a)); @@ -786,55 +787,55 @@ XFLOAT (Lisp_Object a) /* Pseudovector types. */ -LISP_INLINE struct Lisp_Process * +INLINE struct Lisp_Process * XPROCESS (Lisp_Object a) { eassert (PROCESSP (a)); return XUNTAG (a, Lisp_Vectorlike); } -LISP_INLINE struct window * +INLINE struct window * XWINDOW (Lisp_Object a) { eassert (WINDOWP (a)); return XUNTAG (a, Lisp_Vectorlike); } -LISP_INLINE struct terminal * +INLINE struct terminal * XTERMINAL (Lisp_Object a) { return XUNTAG (a, Lisp_Vectorlike); } -LISP_INLINE struct Lisp_Subr * +INLINE struct Lisp_Subr * XSUBR (Lisp_Object a) { eassert (SUBRP (a)); return XUNTAG (a, Lisp_Vectorlike); } -LISP_INLINE struct buffer * +INLINE struct buffer * XBUFFER (Lisp_Object a) { eassert (BUFFERP (a)); return XUNTAG (a, Lisp_Vectorlike); } -LISP_INLINE struct Lisp_Char_Table * +INLINE struct Lisp_Char_Table * XCHAR_TABLE (Lisp_Object a) { eassert (CHAR_TABLE_P (a)); return XUNTAG (a, Lisp_Vectorlike); } -LISP_INLINE struct Lisp_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); } -LISP_INLINE struct Lisp_Bool_Vector * +INLINE struct Lisp_Bool_Vector * XBOOL_VECTOR (Lisp_Object a) { eassert (BOOL_VECTOR_P (a)); @@ -843,7 +844,7 @@ XBOOL_VECTOR (Lisp_Object a) /* Construct a Lisp_Object from a value or address. */ -LISP_INLINE Lisp_Object +INLINE Lisp_Object make_lisp_ptr (void *ptr, enum Lisp_Type type) { EMACS_UINT utype = type; @@ -853,7 +854,7 @@ make_lisp_ptr (void *ptr, enum Lisp_Type type) return a; } -LISP_INLINE Lisp_Object +INLINE Lisp_Object make_lisp_proc (struct Lisp_Process *p) { return make_lisp_ptr (p, Lisp_Vectorlike); @@ -866,11 +867,7 @@ make_lisp_proc (struct Lisp_Process *p) #define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String)) #define XSETSYMBOL(a, b) ((a) = make_lisp_ptr (b, Lisp_Symbol)) #define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float)) - -/* Misc types. */ - #define XSETMISC(a, b) ((a) = make_lisp_ptr (b, Lisp_Misc)) -#define XSETMARKER(a, b) (XSETMISC (a, b), XMISCTYPE (a) = Lisp_Misc_Marker) /* Pseudovector types. */ @@ -941,12 +938,12 @@ struct Lisp_Cons fields are not accessible. (What if we want to switch to a copying collector someday? Cached cons cell field addresses may be invalidated at arbitrary points.) */ -LISP_INLINE Lisp_Object * +INLINE Lisp_Object * xcar_addr (Lisp_Object c) { return &XCONS (c)->car; } -LISP_INLINE Lisp_Object * +INLINE Lisp_Object * xcdr_addr (Lisp_Object c) { return &XCONS (c)->u.cdr; @@ -960,26 +957,26 @@ LISP_MACRO_DEFUN (XCDR, Lisp_Object, (Lisp_Object c), (c)) Note that both arguments may refer to the same object, so 'n' should not be read after 'c' is first modified. */ -LISP_INLINE void +INLINE void XSETCAR (Lisp_Object c, Lisp_Object n) { *xcar_addr (c) = n; } -LISP_INLINE void +INLINE void XSETCDR (Lisp_Object c, Lisp_Object n) { *xcdr_addr (c) = n; } /* Take the car or cdr of something whose type is not known. */ -LISP_INLINE Lisp_Object +INLINE Lisp_Object CAR (Lisp_Object c) { return (CONSP (c) ? XCAR (c) : NILP (c) ? Qnil : wrong_type_argument (Qlistp, c)); } -LISP_INLINE Lisp_Object +INLINE Lisp_Object CDR (Lisp_Object c) { return (CONSP (c) ? XCDR (c) @@ -988,12 +985,12 @@ CDR (Lisp_Object c) } /* Take the car or cdr of something whose type is not known. */ -LISP_INLINE Lisp_Object +INLINE Lisp_Object CAR_SAFE (Lisp_Object c) { return CONSP (c) ? XCAR (c) : Qnil; } -LISP_INLINE Lisp_Object +INLINE Lisp_Object CDR_SAFE (Lisp_Object c) { return CONSP (c) ? XCDR (c) : Qnil; @@ -1010,7 +1007,7 @@ struct Lisp_String }; /* True if STR is a multibyte string. */ -LISP_INLINE bool +INLINE bool STRING_MULTIBYTE (Lisp_Object str) { return 0 <= XSTRING (str)->size_byte; @@ -1047,28 +1044,28 @@ STRING_MULTIBYTE (Lisp_Object str) /* Convenience functions for dealing with Lisp strings. */ -LISP_INLINE unsigned char * +INLINE unsigned char * SDATA (Lisp_Object string) { return XSTRING (string)->data; } -LISP_INLINE char * +INLINE char * SSDATA (Lisp_Object string) { /* Avoid "differ in sign" warnings. */ return (char *) SDATA (string); } -LISP_INLINE unsigned char +INLINE unsigned char SREF (Lisp_Object string, ptrdiff_t index) { return SDATA (string)[index]; } -LISP_INLINE void +INLINE void SSET (Lisp_Object string, ptrdiff_t index, unsigned char new) { SDATA (string)[index] = new; } -LISP_INLINE ptrdiff_t +INLINE ptrdiff_t SCHARS (Lisp_Object string) { return XSTRING (string)->size; @@ -1077,7 +1074,7 @@ SCHARS (Lisp_Object string) #ifdef GC_CHECK_STRING_BYTES extern ptrdiff_t string_bytes (struct Lisp_String *); #endif -LISP_INLINE ptrdiff_t +INLINE ptrdiff_t STRING_BYTES (struct Lisp_String *s) { #ifdef GC_CHECK_STRING_BYTES @@ -1087,17 +1084,17 @@ STRING_BYTES (struct Lisp_String *s) #endif } -LISP_INLINE ptrdiff_t +INLINE ptrdiff_t SBYTES (Lisp_Object string) { return STRING_BYTES (XSTRING (string)); } -LISP_INLINE void +INLINE void STRING_SET_CHARS (Lisp_Object string, ptrdiff_t newsize) { XSTRING (string)->size = newsize; } -LISP_INLINE void +INLINE void STRING_COPYIN (Lisp_Object string, ptrdiff_t index, char const *new, ptrdiff_t count) { @@ -1135,12 +1132,19 @@ struct vectorlike_header ptrdiff_t size; }; -/* Regular vector is just a header plus array of Lisp_Objects. */ +/* Regular vector is just a header plus array of Lisp_Objects... */ struct Lisp_Vector { struct vectorlike_header header; - Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER]; + union { + /* ...but sometimes there is also a pointer internally used in + vector allocation code. Usually you don't want to touch this. */ + struct Lisp_Vector *next; + + /* We can't use FLEXIBLE_ARRAY_MEMBER here. */ + Lisp_Object contents[1]; + } u; }; /* A boolvector is a kind of vectorlike, with contents are like a string. */ @@ -1161,45 +1165,45 @@ struct Lisp_Bool_Vector enum { - header_size = offsetof (struct Lisp_Vector, contents), + header_size = offsetof (struct Lisp_Vector, u.contents), bool_header_size = offsetof (struct Lisp_Bool_Vector, data), word_size = sizeof (Lisp_Object) }; /* Conveniences for dealing with Lisp arrays. */ -LISP_INLINE Lisp_Object +INLINE Lisp_Object AREF (Lisp_Object array, ptrdiff_t idx) { - return XVECTOR (array)->contents[idx]; + return XVECTOR (array)->u.contents[idx]; } -LISP_INLINE Lisp_Object * +INLINE Lisp_Object * aref_addr (Lisp_Object array, ptrdiff_t idx) { - return & XVECTOR (array)->contents[idx]; + return & XVECTOR (array)->u.contents[idx]; } -LISP_INLINE ptrdiff_t +INLINE ptrdiff_t ASIZE (Lisp_Object array) { return XVECTOR (array)->header.size; } -LISP_INLINE void +INLINE void ASET (Lisp_Object array, ptrdiff_t idx, Lisp_Object val) { eassert (0 <= idx && idx < ASIZE (array)); - XVECTOR (array)->contents[idx] = val; + XVECTOR (array)->u.contents[idx] = val; } -LISP_INLINE void +INLINE void gc_aset (Lisp_Object array, ptrdiff_t idx, Lisp_Object val) { /* Like ASET, but also can be used in the garbage collector: sweep_weak_table calls set_hash_key etc. while the table is marked. */ eassert (0 <= idx && idx < (ASIZE (array) & ~ARRAY_MARK_FLAG)); - XVECTOR (array)->contents[idx] = val; + XVECTOR (array)->u.contents[idx] = val; } /* If a struct is made to look like a vector, this macro returns the length @@ -1300,7 +1304,7 @@ struct Lisp_Sub_Char_Table Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER]; }; -LISP_INLINE Lisp_Object +INLINE Lisp_Object CHAR_TABLE_REF_ASCII (Lisp_Object ct, ptrdiff_t idx) { struct Lisp_Char_Table *tbl = NULL; @@ -1320,7 +1324,7 @@ CHAR_TABLE_REF_ASCII (Lisp_Object ct, ptrdiff_t idx) /* Almost equivalent to Faref (CT, IDX) with optimization for ASCII characters. Do not check validity of CT. */ -LISP_INLINE Lisp_Object +INLINE Lisp_Object CHAR_TABLE_REF (Lisp_Object ct, int idx) { return (ASCII_CHAR_P (idx) @@ -1330,7 +1334,7 @@ CHAR_TABLE_REF (Lisp_Object ct, int idx) /* Equivalent to Faset (CT, IDX, VAL) with optimization for ASCII and 8-bit European characters. Do not check validity of CT. */ -LISP_INLINE void +INLINE void CHAR_TABLE_SET (Lisp_Object ct, int idx, Lisp_Object val) { if (ASCII_CHAR_P (idx) && SUB_CHAR_TABLE_P (XCHAR_TABLE (ct)->ascii)) @@ -1375,7 +1379,7 @@ enum CHAR_TABLE_STANDARD_SLOTS /* Return the number of "extra" slots in the char table CT. */ -LISP_INLINE int +INLINE int CHAR_TABLE_EXTRA_SLOTS (struct Lisp_Char_Table *ct) { return ((ct->header.size & PSEUDOVECTOR_SIZE_MASK) @@ -1454,19 +1458,19 @@ struct Lisp_Symbol LISP_MACRO_DEFUN (SYMBOL_VAL, Lisp_Object, (struct Lisp_Symbol *sym), (sym)) -LISP_INLINE struct Lisp_Symbol * +INLINE struct Lisp_Symbol * SYMBOL_ALIAS (struct Lisp_Symbol *sym) { eassert (sym->redirect == SYMBOL_VARALIAS); return sym->val.alias; } -LISP_INLINE struct Lisp_Buffer_Local_Value * +INLINE struct Lisp_Buffer_Local_Value * SYMBOL_BLV (struct Lisp_Symbol *sym) { eassert (sym->redirect == SYMBOL_LOCALIZED); return sym->val.blv; } -LISP_INLINE union Lisp_Fwd * +INLINE union Lisp_Fwd * SYMBOL_FWD (struct Lisp_Symbol *sym) { eassert (sym->redirect == SYMBOL_FORWARDED); @@ -1476,26 +1480,26 @@ SYMBOL_FWD (struct Lisp_Symbol *sym) LISP_MACRO_DEFUN_VOID (SET_SYMBOL_VAL, (struct Lisp_Symbol *sym, Lisp_Object v), (sym, v)) -LISP_INLINE void +INLINE void SET_SYMBOL_ALIAS (struct Lisp_Symbol *sym, struct Lisp_Symbol *v) { eassert (sym->redirect == SYMBOL_VARALIAS); sym->val.alias = v; } -LISP_INLINE void +INLINE void SET_SYMBOL_BLV (struct Lisp_Symbol *sym, struct Lisp_Buffer_Local_Value *v) { eassert (sym->redirect == SYMBOL_LOCALIZED); sym->val.blv = v; } -LISP_INLINE void +INLINE void SET_SYMBOL_FWD (struct Lisp_Symbol *sym, union Lisp_Fwd *v) { eassert (sym->redirect == SYMBOL_FORWARDED); sym->val.fwd = v; } -LISP_INLINE Lisp_Object +INLINE Lisp_Object SYMBOL_NAME (Lisp_Object sym) { return XSYMBOL (sym)->name; @@ -1503,7 +1507,7 @@ SYMBOL_NAME (Lisp_Object sym) /* Value is true if SYM is an interned symbol. */ -LISP_INLINE bool +INLINE bool SYMBOL_INTERNED_P (Lisp_Object sym) { return XSYMBOL (sym)->interned != SYMBOL_UNINTERNED; @@ -1511,7 +1515,7 @@ SYMBOL_INTERNED_P (Lisp_Object sym) /* Value is true if SYM is interned in initial_obarray. */ -LISP_INLINE bool +INLINE bool SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (Lisp_Object sym) { return XSYMBOL (sym)->interned == SYMBOL_INTERNED_IN_INITIAL_OBARRAY; @@ -1607,7 +1611,7 @@ struct Lisp_Hash_Table }; -LISP_INLINE struct Lisp_Hash_Table * +INLINE struct Lisp_Hash_Table * XHASH_TABLE (Lisp_Object a) { return XUNTAG (a, Lisp_Vectorlike); @@ -1616,21 +1620,21 @@ XHASH_TABLE (Lisp_Object a) #define XSET_HASH_TABLE(VAR, PTR) \ (XSETPSEUDOVECTOR (VAR, PTR, PVEC_HASH_TABLE)) -LISP_INLINE bool +INLINE bool HASH_TABLE_P (Lisp_Object a) { return PSEUDOVECTORP (a, PVEC_HASH_TABLE); } /* Value is the key part of entry IDX in hash table H. */ -LISP_INLINE Lisp_Object +INLINE Lisp_Object HASH_KEY (struct Lisp_Hash_Table *h, ptrdiff_t idx) { return AREF (h->key_and_value, 2 * idx); } /* Value is the value part of entry IDX in hash table H. */ -LISP_INLINE Lisp_Object +INLINE Lisp_Object HASH_VALUE (struct Lisp_Hash_Table *h, ptrdiff_t idx) { return AREF (h->key_and_value, 2 * idx + 1); @@ -1638,14 +1642,14 @@ HASH_VALUE (struct Lisp_Hash_Table *h, ptrdiff_t idx) /* Value is the index of the next entry following the one at IDX in hash table H. */ -LISP_INLINE Lisp_Object +INLINE Lisp_Object HASH_NEXT (struct Lisp_Hash_Table *h, ptrdiff_t idx) { return AREF (h->next, idx); } /* Value is the hash code computed for entry IDX in hash table H. */ -LISP_INLINE Lisp_Object +INLINE Lisp_Object HASH_HASH (struct Lisp_Hash_Table *h, ptrdiff_t idx) { return AREF (h->hash, idx); @@ -1653,14 +1657,14 @@ HASH_HASH (struct Lisp_Hash_Table *h, ptrdiff_t idx) /* Value is the index of the element in hash table H that is the start of the collision list at index IDX in the index vector of H. */ -LISP_INLINE Lisp_Object +INLINE Lisp_Object HASH_INDEX (struct Lisp_Hash_Table *h, ptrdiff_t idx) { return AREF (h->index, idx); } /* Value is the size of hash table H. */ -LISP_INLINE ptrdiff_t +INLINE ptrdiff_t HASH_TABLE_SIZE (struct Lisp_Hash_Table *h) { return ASIZE (h->next); @@ -1683,7 +1687,7 @@ static double const DEFAULT_REHASH_SIZE = 1.5; /* Combine two integers X and Y for hashing. The result might not fit into a Lisp integer. */ -LISP_INLINE EMACS_UINT +INLINE EMACS_UINT sxhash_combine (EMACS_UINT x, EMACS_UINT y) { return (x << 4) + (x >> (BITS_PER_EMACS_INT - 4)) + y; @@ -1691,7 +1695,7 @@ sxhash_combine (EMACS_UINT x, EMACS_UINT y) /* Hash X, returning a value that fits into a fixnum. */ -LISP_INLINE EMACS_UINT +INLINE EMACS_UINT SXHASH_REDUCE (EMACS_UINT x) { return (x ^ x >> (BITS_PER_EMACS_INT - FIXNUM_BITS)) & INTMASK; @@ -1861,7 +1865,7 @@ struct Lisp_Save_Value }; /* Return the type of V's Nth saved value. */ -LISP_INLINE int +INLINE int save_type (struct Lisp_Save_Value *v, int n) { eassert (0 <= n && n < SAVE_VALUE_SLOTS); @@ -1870,19 +1874,19 @@ save_type (struct Lisp_Save_Value *v, int n) /* Get and set the Nth saved pointer. */ -LISP_INLINE void * +INLINE void * XSAVE_POINTER (Lisp_Object obj, int n) { eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_POINTER); return XSAVE_VALUE (obj)->data[n].pointer; } -LISP_INLINE void +INLINE void set_save_pointer (Lisp_Object obj, int n, void *val) { eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_POINTER); XSAVE_VALUE (obj)->data[n].pointer = val; } -LISP_INLINE voidfuncptr +INLINE voidfuncptr XSAVE_FUNCPOINTER (Lisp_Object obj, int n) { eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_FUNCPOINTER); @@ -1891,13 +1895,13 @@ XSAVE_FUNCPOINTER (Lisp_Object obj, int n) /* Likewise for the saved integer. */ -LISP_INLINE ptrdiff_t +INLINE ptrdiff_t XSAVE_INTEGER (Lisp_Object obj, int n) { eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_INTEGER); return XSAVE_VALUE (obj)->data[n].integer; } -LISP_INLINE void +INLINE void set_save_integer (Lisp_Object obj, int n, ptrdiff_t val) { eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_INTEGER); @@ -1906,7 +1910,7 @@ set_save_integer (Lisp_Object obj, int n, ptrdiff_t val) /* Extract Nth saved object. */ -LISP_INLINE Lisp_Object +INLINE Lisp_Object XSAVE_OBJECT (Lisp_Object obj, int n) { eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_OBJECT); @@ -1934,40 +1938,40 @@ union Lisp_Misc struct Lisp_Save_Value u_save_value; }; -LISP_INLINE union Lisp_Misc * +INLINE union Lisp_Misc * XMISC (Lisp_Object a) { return XUNTAG (a, Lisp_Misc); } -LISP_INLINE struct Lisp_Misc_Any * +INLINE struct Lisp_Misc_Any * XMISCANY (Lisp_Object a) { eassert (MISCP (a)); return & XMISC (a)->u_any; } -LISP_INLINE enum Lisp_Misc_Type +INLINE enum Lisp_Misc_Type XMISCTYPE (Lisp_Object a) { return XMISCANY (a)->type; } -LISP_INLINE struct Lisp_Marker * +INLINE struct Lisp_Marker * XMARKER (Lisp_Object a) { eassert (MARKERP (a)); return & XMISC (a)->u_marker; } -LISP_INLINE struct Lisp_Overlay * +INLINE struct Lisp_Overlay * XOVERLAY (Lisp_Object a) { eassert (OVERLAYP (a)); return & XMISC (a)->u_overlay; } -LISP_INLINE struct Lisp_Save_Value * +INLINE struct Lisp_Save_Value * XSAVE_VALUE (Lisp_Object a) { eassert (SAVE_VALUEP (a)); @@ -2081,13 +2085,13 @@ union Lisp_Fwd struct Lisp_Kboard_Objfwd u_kboard_objfwd; }; -LISP_INLINE enum Lisp_Fwd_Type +INLINE enum Lisp_Fwd_Type XFWDTYPE (union Lisp_Fwd *a) { return a->u_intfwd.type; } -LISP_INLINE struct Lisp_Buffer_Objfwd * +INLINE struct Lisp_Buffer_Objfwd * XBUFFER_OBJFWD (union Lisp_Fwd *a) { eassert (BUFFER_OBJFWDP (a)); @@ -2104,7 +2108,7 @@ struct Lisp_Float } u; }; -LISP_INLINE double +INLINE double XFLOAT_DATA (Lisp_Object f) { return XFLOAT (f)->u.data; @@ -2164,54 +2168,22 @@ enum char_bits CHARACTERBITS = 22 }; -/* Structure to hold mouse highlight data. This is here because other - header files need it for defining struct x_output etc. */ -typedef struct { - /* These variables describe the range of text currently shown in its - mouse-face, together with the window they apply to. As long as - the mouse stays within this range, we need not redraw anything on - its account. Rows and columns are glyph matrix positions in - MOUSE_FACE_WINDOW. */ - int mouse_face_beg_row, mouse_face_beg_col; - int mouse_face_beg_x, mouse_face_beg_y; - int mouse_face_end_row, mouse_face_end_col; - int mouse_face_end_x, mouse_face_end_y; - Lisp_Object mouse_face_window; - int mouse_face_face_id; - Lisp_Object mouse_face_overlay; - - /* FRAME and X, Y position of mouse when last checked for - highlighting. X and Y can be negative or out of range for the frame. */ - struct frame *mouse_face_mouse_frame; - int mouse_face_mouse_x, mouse_face_mouse_y; - - /* Nonzero if part of the text currently shown in - its mouse-face is beyond the window end. */ - unsigned mouse_face_past_end : 1; - - /* Nonzero means defer mouse-motion highlighting. */ - unsigned mouse_face_defer : 1; - - /* Nonzero means that the mouse highlight should not be shown. */ - unsigned mouse_face_hidden : 1; -} Mouse_HLInfo; - /* Data type checking. */ LISP_MACRO_DEFUN (NILP, bool, (Lisp_Object x), (x)) -LISP_INLINE bool +INLINE bool NUMBERP (Lisp_Object x) { return INTEGERP (x) || FLOATP (x); } -LISP_INLINE bool +INLINE bool NATNUMP (Lisp_Object x) { return INTEGERP (x) && 0 <= XINT (x); } -LISP_INLINE bool +INLINE bool RANGED_INTEGERP (intmax_t lo, Lisp_Object x, intmax_t hi) { return INTEGERP (x) && lo <= XINT (x) && XINT (x) <= hi; @@ -2230,40 +2202,40 @@ LISP_MACRO_DEFUN (INTEGERP, bool, (Lisp_Object x), (x)) LISP_MACRO_DEFUN (VECTORLIKEP, bool, (Lisp_Object x), (x)) LISP_MACRO_DEFUN (MARKERP, bool, (Lisp_Object x), (x)) -LISP_INLINE bool +INLINE bool STRINGP (Lisp_Object x) { return XTYPE (x) == Lisp_String; } -LISP_INLINE bool +INLINE bool VECTORP (Lisp_Object x) { return VECTORLIKEP (x) && ! (ASIZE (x) & PSEUDOVECTOR_FLAG); } -LISP_INLINE bool +INLINE bool OVERLAYP (Lisp_Object x) { return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay; } -LISP_INLINE bool +INLINE bool SAVE_VALUEP (Lisp_Object x) { return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value; } -LISP_INLINE bool +INLINE bool AUTOLOADP (Lisp_Object x) { return CONSP (x) && EQ (Qautoload, XCAR (x)); } -LISP_INLINE bool +INLINE bool BUFFER_OBJFWDP (union Lisp_Fwd *a) { return XFWDTYPE (a) == Lisp_Fwd_Buffer_Obj; } -LISP_INLINE bool +INLINE bool PSEUDOVECTOR_TYPEP (struct vectorlike_header *a, int code) { return ((a->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) @@ -2271,7 +2243,7 @@ PSEUDOVECTOR_TYPEP (struct vectorlike_header *a, int code) } /* True if A is a pseudovector whose code is CODE. */ -LISP_INLINE bool +INLINE bool PSEUDOVECTORP (Lisp_Object a, int code) { if (! VECTORLIKEP (a)) @@ -2287,87 +2259,87 @@ PSEUDOVECTORP (Lisp_Object a, int code) /* Test for specific pseudovector types. */ -LISP_INLINE bool +INLINE bool WINDOW_CONFIGURATIONP (Lisp_Object a) { return PSEUDOVECTORP (a, PVEC_WINDOW_CONFIGURATION); } -LISP_INLINE bool +INLINE bool PROCESSP (Lisp_Object a) { return PSEUDOVECTORP (a, PVEC_PROCESS); } -LISP_INLINE bool +INLINE bool WINDOWP (Lisp_Object a) { return PSEUDOVECTORP (a, PVEC_WINDOW); } -LISP_INLINE bool +INLINE bool TERMINALP (Lisp_Object a) { return PSEUDOVECTORP (a, PVEC_TERMINAL); } -LISP_INLINE bool +INLINE bool SUBRP (Lisp_Object a) { return PSEUDOVECTORP (a, PVEC_SUBR); } -LISP_INLINE bool +INLINE bool COMPILEDP (Lisp_Object a) { return PSEUDOVECTORP (a, PVEC_COMPILED); } -LISP_INLINE bool +INLINE bool BUFFERP (Lisp_Object a) { return PSEUDOVECTORP (a, PVEC_BUFFER); } -LISP_INLINE bool +INLINE bool CHAR_TABLE_P (Lisp_Object a) { return PSEUDOVECTORP (a, PVEC_CHAR_TABLE); } -LISP_INLINE bool +INLINE bool SUB_CHAR_TABLE_P (Lisp_Object a) { return PSEUDOVECTORP (a, PVEC_SUB_CHAR_TABLE); } -LISP_INLINE bool +INLINE bool BOOL_VECTOR_P (Lisp_Object a) { return PSEUDOVECTORP (a, PVEC_BOOL_VECTOR); } -LISP_INLINE bool +INLINE bool FRAMEP (Lisp_Object a) { return PSEUDOVECTORP (a, PVEC_FRAME); } /* Test for image (image . spec) */ -LISP_INLINE bool +INLINE bool IMAGEP (Lisp_Object x) { return CONSP (x) && EQ (XCAR (x), Qimage); } /* Array types. */ -LISP_INLINE bool +INLINE bool ARRAYP (Lisp_Object x) { return VECTORP (x) || STRINGP (x) || CHAR_TABLE_P (x) || BOOL_VECTOR_P (x); } -LISP_INLINE void +INLINE void CHECK_LIST (Lisp_Object x) { CHECK_TYPE (CONSP (x) || NILP (x), Qlistp, x); @@ -2377,52 +2349,57 @@ LISP_MACRO_DEFUN_VOID (CHECK_LIST_CONS, (Lisp_Object x, Lisp_Object y), (x, y)) LISP_MACRO_DEFUN_VOID (CHECK_SYMBOL, (Lisp_Object x), (x)) LISP_MACRO_DEFUN_VOID (CHECK_NUMBER, (Lisp_Object x), (x)) -LISP_INLINE void +INLINE void CHECK_STRING (Lisp_Object x) { CHECK_TYPE (STRINGP (x), Qstringp, x); } -LISP_INLINE void +INLINE void CHECK_STRING_CAR (Lisp_Object x) { CHECK_TYPE (STRINGP (XCAR (x)), Qstringp, XCAR (x)); } -LISP_INLINE void +INLINE void CHECK_CONS (Lisp_Object x) { CHECK_TYPE (CONSP (x), Qconsp, x); } -LISP_INLINE void +INLINE void CHECK_VECTOR (Lisp_Object x) { CHECK_TYPE (VECTORP (x), Qvectorp, x); } -LISP_INLINE void +INLINE void +CHECK_BOOL_VECTOR (Lisp_Object x) +{ + CHECK_TYPE (BOOL_VECTOR_P (x), Qbool_vector_p, x); +} +INLINE void CHECK_VECTOR_OR_STRING (Lisp_Object x) { CHECK_TYPE (VECTORP (x) || STRINGP (x), Qarrayp, x); } -LISP_INLINE void +INLINE void CHECK_ARRAY (Lisp_Object x, Lisp_Object Qxxxp) { CHECK_TYPE (ARRAYP (x), Qxxxp, x); } -LISP_INLINE void +INLINE void CHECK_BUFFER (Lisp_Object x) { CHECK_TYPE (BUFFERP (x), Qbufferp, x); } -LISP_INLINE void +INLINE void CHECK_WINDOW (Lisp_Object x) { CHECK_TYPE (WINDOWP (x), Qwindowp, x); } -LISP_INLINE void +INLINE void CHECK_PROCESS (Lisp_Object x) { CHECK_TYPE (PROCESSP (x), Qprocessp, x); } -LISP_INLINE void +INLINE void CHECK_NATNUM (Lisp_Object x) { CHECK_TYPE (NATNUMP (x), Qwholenump, x); @@ -2451,13 +2428,13 @@ CHECK_NATNUM (Lisp_Object x) do { if (MARKERP ((x))) XSETFASTINT (x, marker_position (x)); \ else CHECK_TYPE (INTEGERP (x), Qinteger_or_marker_p, x); } while (0) -LISP_INLINE double +INLINE double XFLOATINT (Lisp_Object n) { return extract_float (n); } -LISP_INLINE void +INLINE void CHECK_NUMBER_OR_FLOAT (Lisp_Object x) { CHECK_TYPE (FLOATP (x) || INTEGERP (x), Qnumberp, x); @@ -2469,7 +2446,7 @@ CHECK_NUMBER_OR_FLOAT (Lisp_Object x) /* Since we can't assign directly to the CAR or CDR fields of a cons cell, use these when checking that those fields contain numbers. */ -LISP_INLINE void +INLINE void CHECK_NUMBER_CAR (Lisp_Object x) { Lisp_Object tmp = XCAR (x); @@ -2477,7 +2454,7 @@ CHECK_NUMBER_CAR (Lisp_Object x) XSETCAR (x, tmp); } -LISP_INLINE void +INLINE void CHECK_NUMBER_CDR (Lisp_Object x) { Lisp_Object tmp = XCDR (x); @@ -2555,7 +2532,7 @@ CHECK_NUMBER_CDR (Lisp_Object x) Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object) /* True if OBJ is a Lisp function. */ -LISP_INLINE bool +INLINE bool FUNCTIONP (Lisp_Object obj) { return functionp (obj); @@ -2654,11 +2631,9 @@ typedef jmp_buf sys_jmp_buf; - The specpdl stack: keeps track of active unwind-protect and dynamic-let-bindings. Allocated from the `specpdl' array, a manually managed stack. - - The catch stack: keeps track of active catch tags. - Allocated on the C stack. This is where the setmp data is kept. - - The handler stack: keeps track of active condition-case handlers. - Allocated on the C stack. Every entry there also uses an entry in - the catch stack. */ + - The handler stack: keeps track of active catch tags and condition-case + handlers. Allocated in a manually managed stack implemented by a + doubly-linked list allocated via xmalloc and never freed. */ /* Structure for recording Lisp call stack for backtrace purposes. */ @@ -2666,19 +2641,6 @@ typedef jmp_buf sys_jmp_buf; they are bound by a function application or a let form, stores the code to be executed for unwind-protect forms. - If func is non-zero, undoing this binding applies func to old_value; - This implements record_unwind_protect. - - Otherwise, the element is a variable binding. - - If the symbol field is a symbol, it is an ordinary variable binding. - - Otherwise, it should be a structure (SYMBOL WHERE . CURRENT-BUFFER), - which means having bound a local value while CURRENT-BUFFER was active. - If WHERE is nil this means we saw the default value when binding SYMBOL. - WHERE being a buffer or frame means we saw a buffer-local or frame-local - value. Other values of WHERE mean an internal error. - NOTE: The specbinding union is defined here, because SPECPDL_INDEX is used all over the place, needs to be fast, and needs to know the size of union specbinding. But only eval.c should access it. */ @@ -2735,52 +2697,22 @@ extern union specbinding *specpdl; extern union specbinding *specpdl_ptr; extern ptrdiff_t specpdl_size; -LISP_INLINE ptrdiff_t +INLINE ptrdiff_t SPECPDL_INDEX (void) { return specpdl_ptr - specpdl; } -/* Everything needed to describe an active condition case. +/* This structure helps implement the `catch/throw' and `condition-case/signal' + control structures. A struct handler contains all the information needed to + restore the state of the interpreter after a non-local jump. - Members are volatile if their values need to survive _longjmp when - a 'struct handler' is a local variable. */ -struct handler - { - /* The handler clauses and variable from the condition-case form. */ - /* For a handler set up in Lisp code, this is always a list. - For an internal handler set up by internal_condition_case*, - this can instead be the symbol t or `error'. - t: handle all conditions. - error: handle all conditions, and errors can run the debugger - or display a backtrace. */ - Lisp_Object handler; - - Lisp_Object volatile var; - - /* Fsignal stores here the condition-case clause that applies, - and Fcondition_case thus knows which clause to run. */ - Lisp_Object volatile chosen_clause; - - /* Used to effect the longjump out to the handler. */ - struct catchtag *tag; - - /* The next enclosing handler. */ - struct handler *next; - }; + handler structures are chained together in a doubly linked list; the `next' + member points to the next outer catchtag and the `nextfree' member points in + the other direction to the next inner element (which is typically the next + free element since we mostly use it on the deepest handler). -/* This structure helps implement the `catch' and `throw' control - structure. A struct catchtag contains all the information needed - to restore the state of the interpreter after a non-local jump. - - Handlers for error conditions (represented by `struct handler' - structures) just point to a catch tag to do the cleanup required - for their jumps. - - catchtag structures are chained together in the C calling stack; - the `next' member points to the next outer catchtag. - - A call like (throw TAG VAL) searches for a catchtag whose `tag' + A call like (throw TAG VAL) searches for a catchtag whose `tag_or_ch' member is TAG, and then unbinds to it. The `val' member is used to hold VAL while the stack is unwound; `val' is returned as the value of the catch form. @@ -2789,24 +2721,63 @@ struct handler state. Members are volatile if their values need to survive _longjmp when - a 'struct catchtag' is a local variable. */ -struct catchtag + a 'struct handler' is a local variable. */ + +enum handlertype { CATCHER, CONDITION_CASE }; + +struct handler { - Lisp_Object tag; - Lisp_Object volatile val; - struct catchtag *volatile next; + enum handlertype type; + Lisp_Object tag_or_ch; + Lisp_Object val; + struct handler *next; + struct handler *nextfree; + + /* The bytecode interpreter can have several handlers active at the same + time, so when we longjmp to one of them, it needs to know which handler + this was and what was the corresponding internal state. This is stored + here, and when we longjmp we make sure that handlerlist points to the + proper handler. */ + Lisp_Object *bytecode_top; + int bytecode_dest; + + /* Most global vars are reset to their value via the specpdl mechanism, + but a few others are handled by storing their value here. */ #if 1 /* GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS, but they're defined later. */ struct gcpro *gcpro; #endif sys_jmp_buf jmp; - struct handler *handlerlist; EMACS_INT lisp_eval_depth; - ptrdiff_t volatile pdlcount; + ptrdiff_t pdlcount; int poll_suppress_count; int interrupt_input_blocked; struct byte_stack *byte_stack; }; +/* Fill in the components of c, and put it on the list. */ +#define PUSH_HANDLER(c, tag_ch_val, handlertype) \ + if (handlerlist && handlerlist->nextfree) \ + (c) = handlerlist->nextfree; \ + else \ + { \ + (c) = xmalloc (sizeof (struct handler)); \ + (c)->nextfree = NULL; \ + if (handlerlist) \ + handlerlist->nextfree = (c); \ + } \ + (c)->type = (handlertype); \ + (c)->tag_or_ch = (tag_ch_val); \ + (c)->val = Qnil; \ + (c)->next = handlerlist; \ + (c)->lisp_eval_depth = lisp_eval_depth; \ + (c)->pdlcount = SPECPDL_INDEX (); \ + (c)->poll_suppress_count = poll_suppress_count; \ + (c)->interrupt_input_blocked = interrupt_input_blocked;\ + (c)->gcpro = gcprolist; \ + (c)->byte_stack = byte_stack_list; \ + handlerlist = (c); + + extern Lisp_Object memory_signal_data; /* An address near the bottom of the stack. @@ -3063,22 +3034,22 @@ struct frame; /* Copy COUNT Lisp_Objects from ARGS to contents of V starting from OFFSET. */ -LISP_INLINE void +INLINE void vcopy (Lisp_Object v, ptrdiff_t offset, Lisp_Object *args, ptrdiff_t count) { eassert (0 <= offset && 0 <= count && offset + count <= ASIZE (v)); - memcpy (XVECTOR (v)->contents + offset, args, count * sizeof *args); + memcpy (XVECTOR (v)->u.contents + offset, args, count * sizeof *args); } /* Functions to modify hash tables. */ -LISP_INLINE void +INLINE void set_hash_key_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val) { gc_aset (h->key_and_value, 2 * idx, val); } -LISP_INLINE void +INLINE void set_hash_value_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val) { gc_aset (h->key_and_value, 2 * idx + 1, val); @@ -3087,19 +3058,19 @@ set_hash_value_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val) /* Use these functions to set Lisp_Object or pointer slots of struct Lisp_Symbol. */ -LISP_INLINE void +INLINE void set_symbol_function (Lisp_Object sym, Lisp_Object function) { XSYMBOL (sym)->function = function; } -LISP_INLINE void +INLINE void set_symbol_plist (Lisp_Object sym, Lisp_Object plist) { XSYMBOL (sym)->plist = plist; } -LISP_INLINE void +INLINE void set_symbol_next (Lisp_Object sym, struct Lisp_Symbol *next) { XSYMBOL (sym)->next = next; @@ -3107,7 +3078,7 @@ set_symbol_next (Lisp_Object sym, struct Lisp_Symbol *next) /* Buffer-local (also frame-local) variable access functions. */ -LISP_INLINE int +INLINE int blv_found (struct Lisp_Buffer_Local_Value *blv) { eassert (blv->found == !EQ (blv->defcell, blv->valcell)); @@ -3116,7 +3087,7 @@ blv_found (struct Lisp_Buffer_Local_Value *blv) /* Set overlay's property list. */ -LISP_INLINE void +INLINE void set_overlay_plist (Lisp_Object overlay, Lisp_Object plist) { XOVERLAY (overlay)->plist = plist; @@ -3124,7 +3095,7 @@ set_overlay_plist (Lisp_Object overlay, Lisp_Object plist) /* Get text properties of S. */ -LISP_INLINE INTERVAL +INLINE INTERVAL string_intervals (Lisp_Object s) { return XSTRING (s)->intervals; @@ -3132,7 +3103,7 @@ string_intervals (Lisp_Object s) /* Set text properties of S to I. */ -LISP_INLINE void +INLINE void set_string_intervals (Lisp_Object s, INTERVAL i) { XSTRING (s)->intervals = i; @@ -3141,12 +3112,12 @@ set_string_intervals (Lisp_Object s, INTERVAL i) /* Set a Lisp slot in TABLE to VAL. Most code should use this instead of setting slots directly. */ -LISP_INLINE void +INLINE void set_char_table_defalt (Lisp_Object table, Lisp_Object val) { XCHAR_TABLE (table)->defalt = val; } -LISP_INLINE void +INLINE void set_char_table_purpose (Lisp_Object table, Lisp_Object val) { XCHAR_TABLE (table)->purpose = val; @@ -3154,21 +3125,21 @@ set_char_table_purpose (Lisp_Object table, Lisp_Object val) /* Set different slots in (sub)character tables. */ -LISP_INLINE void +INLINE void set_char_table_extras (Lisp_Object table, ptrdiff_t idx, Lisp_Object val) { eassert (0 <= idx && idx < CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (table))); XCHAR_TABLE (table)->extras[idx] = val; } -LISP_INLINE void +INLINE void set_char_table_contents (Lisp_Object table, ptrdiff_t idx, Lisp_Object val) { eassert (0 <= idx && idx < (1 << CHARTAB_SIZE_BITS_0)); XCHAR_TABLE (table)->contents[idx] = val; } -LISP_INLINE void +INLINE void set_sub_char_table_contents (Lisp_Object table, ptrdiff_t idx, Lisp_Object val) { XSUB_CHAR_TABLE (table)->contents[idx] = val; @@ -3209,6 +3180,16 @@ EXFUN (Fbyteorder, 0) ATTRIBUTE_CONST; /* Defined in data.c. */ extern Lisp_Object indirect_function (Lisp_Object); extern Lisp_Object find_symbol_value (Lisp_Object); +enum Arith_Comparison { + ARITH_EQUAL, + ARITH_NOTEQUAL, + ARITH_LESS, + ARITH_GRTR, + ARITH_LESS_OR_EQUAL, + ARITH_GRTR_OR_EQUAL +}; +extern Lisp_Object arithcompare (Lisp_Object num1, Lisp_Object num2, + enum Arith_Comparison comparison); /* Convert the integer I to an Emacs representation, either the integer itself, or a cons of two or three integers, or if all else fails a float. @@ -3388,7 +3369,6 @@ extern void syms_of_insdel (void); && (defined __FreeBSD__ || defined GNU_LINUX || defined __MINGW32__)) _Noreturn void __executable_start (void); #endif -extern Lisp_Object selected_frame; extern Lisp_Object Vwindow_system; extern Lisp_Object sit_for (Lisp_Object, bool, int); extern void init_display (void); @@ -3404,14 +3384,10 @@ extern Lisp_Object Qimage, Qtext, Qboth, Qboth_horiz, Qtext_image_horiz; extern Lisp_Object Qspace, Qcenter, QCalign_to; extern Lisp_Object Qbar, Qhbar, Qbox, Qhollow; extern Lisp_Object Qleft_margin, Qright_margin; -extern Lisp_Object Qglyphless_char; extern Lisp_Object QCdata, QCfile; extern Lisp_Object QCmap; extern Lisp_Object Qrisky_local_variable; -extern struct frame *last_glyphless_glyph_frame; -extern int last_glyphless_glyph_face_id; -extern int last_glyphless_glyph_merged_face_id; -extern int noninteractive_need_newline; +extern bool noninteractive_need_newline; extern Lisp_Object echo_area_buffer[2]; extern void add_to_log (const char *, Lisp_Object, Lisp_Object); extern void check_message_stack (void); @@ -3478,19 +3454,19 @@ extern Lisp_Object listn (enum constype, ptrdiff_t, Lisp_Object, ...); /* Build a frequently used 2/3/4-integer lists. */ -LISP_INLINE Lisp_Object +INLINE Lisp_Object list2i (EMACS_INT x, EMACS_INT y) { return list2 (make_number (x), make_number (y)); } -LISP_INLINE Lisp_Object +INLINE Lisp_Object list3i (EMACS_INT x, EMACS_INT y, EMACS_INT w) { return list3 (make_number (x), make_number (y), make_number (w)); } -LISP_INLINE Lisp_Object +INLINE Lisp_Object list4i (EMACS_INT x, EMACS_INT y, EMACS_INT w, EMACS_INT h) { return list4 (make_number (x), make_number (y), @@ -3505,14 +3481,14 @@ extern Lisp_Object make_unibyte_string (const char *, ptrdiff_t); /* Make unibyte string from C string when the length isn't known. */ -LISP_INLINE Lisp_Object +INLINE Lisp_Object build_unibyte_string (const char *str) { return make_unibyte_string (str, strlen (str)); } extern Lisp_Object make_multibyte_string (const char *, ptrdiff_t, ptrdiff_t); -extern Lisp_Object make_event_array (int, Lisp_Object *); +extern Lisp_Object make_event_array (ptrdiff_t, Lisp_Object *); extern Lisp_Object make_uninit_string (EMACS_INT); extern Lisp_Object make_uninit_multibyte_string (EMACS_INT, EMACS_INT); extern Lisp_Object make_string_from_bytes (const char *, ptrdiff_t, ptrdiff_t); @@ -3523,7 +3499,7 @@ extern Lisp_Object make_pure_c_string (const char *, ptrdiff_t); /* Make a string allocated in pure space, use STR as string data. */ -LISP_INLINE Lisp_Object +INLINE Lisp_Object build_pure_c_string (const char *str) { return make_pure_c_string (str, strlen (str)); @@ -3532,7 +3508,7 @@ build_pure_c_string (const char *str) /* Make a string from the data at STR, treating it as multibyte if the data warrants. */ -LISP_INLINE Lisp_Object +INLINE Lisp_Object build_string (const char *str) { return make_string (str, strlen (str)); @@ -3553,7 +3529,7 @@ extern struct Lisp_Vector *allocate_vector (EMACS_INT); ASET (v, 1, Ffunction_can_gc ()); ASET (v, 2, obj1); */ -LISP_INLINE Lisp_Object +INLINE Lisp_Object make_uninit_vector (ptrdiff_t size) { Lisp_Object v; @@ -3600,7 +3576,7 @@ extern int valid_lisp_object_p (Lisp_Object); #ifdef GC_CHECK_CONS_LIST extern void check_cons_list (void); #else -LISP_INLINE void (check_cons_list) (void) { lisp_h_check_cons_list (); } +INLINE void (check_cons_list) (void) { lisp_h_check_cons_list (); } #endif #ifdef REL_ALLOC @@ -3668,7 +3644,7 @@ extern Lisp_Object check_obarray (Lisp_Object); extern Lisp_Object intern_1 (const char *, ptrdiff_t); extern Lisp_Object intern_c_string_1 (const char *, ptrdiff_t); extern Lisp_Object oblookup (Lisp_Object, const char *, ptrdiff_t, ptrdiff_t); -LISP_INLINE void +INLINE void LOADHIST_ATTACH (Lisp_Object x) { if (initialized) @@ -3684,13 +3660,13 @@ extern void init_obarray (void); extern void init_lread (void); extern void syms_of_lread (void); -LISP_INLINE Lisp_Object +INLINE Lisp_Object intern (const char *str) { return intern_1 (str, strlen (str)); } -LISP_INLINE Lisp_Object +INLINE Lisp_Object intern_c_string (const char *str) { return intern_c_string_1 (str, strlen (str)); @@ -3703,10 +3679,8 @@ extern Lisp_Object Qand_rest; extern Lisp_Object Vautoload_queue; extern Lisp_Object Vsignaling_function; extern Lisp_Object inhibit_lisp_code; -#if BYTE_MARK_STACK -extern struct catchtag *catchlist; extern struct handler *handlerlist; -#endif + /* To run a normal hook, use the appropriate function from the list below. The calling convention: @@ -3866,8 +3840,8 @@ extern ptrdiff_t fast_looking_at (Lisp_Object, ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, Lisp_Object); extern ptrdiff_t find_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t *, ptrdiff_t *, bool); -extern EMACS_INT scan_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, - EMACS_INT, bool); +extern ptrdiff_t scan_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, + ptrdiff_t, bool); extern ptrdiff_t find_newline_no_quit (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t *); extern ptrdiff_t find_before_next_newline (ptrdiff_t, ptrdiff_t, @@ -3969,9 +3943,9 @@ void fixup_locale (void); void synchronize_system_messages_locale (void); void synchronize_system_time_locale (void); #else -LISP_INLINE void fixup_locale (void) {} -LISP_INLINE void synchronize_system_messages_locale (void) {} -LISP_INLINE void synchronize_system_time_locale (void) {} +INLINE void fixup_locale (void) {} +INLINE void synchronize_system_messages_locale (void) {} +INLINE void synchronize_system_time_locale (void) {} #endif extern void shut_down_emacs (int, Lisp_Object); @@ -4100,7 +4074,6 @@ extern void init_sys_modes (struct tty_display_info *); extern void reset_sys_modes (struct tty_display_info *); extern void init_all_sys_modes (void); extern void reset_all_sys_modes (void); -extern void flush_pending_output (int) ATTRIBUTE_CONST; extern void child_setup_tty (int); extern void setup_pty (int); extern int set_window_size (int, int, int); @@ -4112,9 +4085,9 @@ extern _Noreturn void emacs_abort (void) NO_INLINE; extern int emacs_open (const char *, int, int); extern int emacs_pipe (int[2]); extern int emacs_close (int); -extern ptrdiff_t emacs_read (int, char *, ptrdiff_t); -extern ptrdiff_t emacs_write (int, const char *, ptrdiff_t); -extern ptrdiff_t emacs_write_sig (int, char const *, ptrdiff_t); +extern ptrdiff_t emacs_read (int, void *, ptrdiff_t); +extern ptrdiff_t emacs_write (int, void const *, ptrdiff_t); +extern ptrdiff_t emacs_write_sig (int, void const *, ptrdiff_t); extern void emacs_perror (char const *); extern void unlock_all_files (void); @@ -4342,10 +4315,16 @@ extern void *record_xmalloc (size_t); memory_full (SIZE_MAX); \ } while (0) +/* Do a `for' loop over alist values. */ + +#define FOR_EACH_ALIST_VALUE(head_var, list_var, value_var) \ + for (list_var = head_var; \ + (CONSP (list_var) && (value_var = XCDR (XCAR (list_var)), 1)); \ + list_var = XCDR (list_var)) /* Check whether it's time for GC, and run it if so. */ -LISP_INLINE void +INLINE void maybe_gc (void) { if ((consing_since_gc > gc_cons_threshold @@ -4355,7 +4334,7 @@ maybe_gc (void) Fgarbage_collect (); } -LISP_INLINE bool +INLINE bool functionp (Lisp_Object object) { if (SYMBOLP (object) && !NILP (Ffboundp (object))) @@ -4387,6 +4366,16 @@ functionp (Lisp_Object object) return 0; } +#if ((SIZE_MAX >> 31) >> 1) & 1 +# define BITS_PER_SIZE_T 64 +#else +# define BITS_PER_SIZE_T 32 +#endif + +/* Round x to the next multiple of y. Does not overflow. Evaluates + arguments repeatedly. */ +#define ROUNDUP(x,y) ((y)*((x)/(y) + ((x)%(y)!=0))) + INLINE_HEADER_END #endif /* EMACS_LISP_H */