From d9627a9df1ef0e27df0e7eefa40aad85eeeb056c Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 6 Dec 2016 22:12:43 -0800 Subject: [PATCH] Reorder lisp.h to declare types before using them Reorder lisp.h to put basic functions for types to be after the corresponding type definitions. This is a more-common programming style in C, and will make it easier to port Emacs to gcc -fcheck-pointer-bounds, since the functions now have access to the corresponding types' sizes. This patch does not change the code; it just moves declarations and definitions and removes no-longer-needed forward declarations. * src/buffer.c, src/data.c, src/image.c: Include process.h, for PROCESSP. * src/buffer.h (BUFFERP, CHECK_BUFFER, XBUFFER): * src/process.h (PROCESSP, CHECK_PROCESS, XPROCESS): * src/terminal.h (TERMINALP, XTERMINAL): * src/window.h (WINDOWP, CHECK_WINDOW, XWINDOW): Move here from lisp.h. * src/intervals.h: Include buffer.h, for BUFFERP. * src/lisp.h: Reorder declarations and definitions as described above. Move some symbols to other headers (noted above). Remove forward decls that are no longer needed. --- src/buffer.c | 1 + src/buffer.h | 19 ++ src/data.c | 1 + src/image.c | 1 + src/intervals.h | 3 + src/lisp.h | 832 +++++++++++++++++++++++++------------------------------- src/process.h | 19 ++ src/termhooks.h | 13 + src/window.h | 19 ++ 9 files changed, 448 insertions(+), 460 deletions(-) diff --git a/src/buffer.c b/src/buffer.c index 6815aa7..0ae0221 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -32,6 +32,7 @@ along with GNU Emacs. If not, see . */ #include "lisp.h" #include "intervals.h" +#include "process.h" #include "systime.h" #include "window.h" #include "commands.h" diff --git a/src/buffer.h b/src/buffer.h index 6ac161c..a8ca6a3 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -881,6 +881,25 @@ struct buffer Lisp_Object undo_list_; }; +INLINE bool +BUFFERP (Lisp_Object a) +{ + return PSEUDOVECTORP (a, PVEC_BUFFER); +} + +INLINE void +CHECK_BUFFER (Lisp_Object x) +{ + CHECK_TYPE (BUFFERP (x), Qbufferp, x); +} + +INLINE struct buffer * +XBUFFER (Lisp_Object a) +{ + eassert (BUFFERP (a)); + return XUNTAG (a, Lisp_Vectorlike); +} + /* Most code should use these functions to set Lisp fields in struct buffer. (Some setters that are private to a single .c file are defined as static in those files.) */ diff --git a/src/data.c b/src/data.c index 64cd8b2..405234e 100644 --- a/src/data.c +++ b/src/data.c @@ -31,6 +31,7 @@ along with GNU Emacs. If not, see . */ #include "character.h" #include "buffer.h" #include "keyboard.h" +#include "process.h" #include "frame.h" #include "keymap.h" diff --git a/src/image.c b/src/image.c index 89572b8..45010e7 100644 --- a/src/image.c +++ b/src/image.c @@ -36,6 +36,7 @@ along with GNU Emacs. If not, see . */ #include "lisp.h" #include "frame.h" +#include "process.h" #include "window.h" #include "buffer.h" #include "dispextern.h" diff --git a/src/intervals.h b/src/intervals.h index 9a38d84..b56c050 100644 --- a/src/intervals.h +++ b/src/intervals.h @@ -19,6 +19,9 @@ along with GNU Emacs. If not, see . */ #ifndef EMACS_INTERVALS_H #define EMACS_INTERVALS_H +#include "buffer.h" +#include "lisp.h" + INLINE_HEADER_BEGIN /* Basic data type for use of intervals. */ diff --git a/src/lisp.h b/src/lisp.h index b9c6289..c3eaf42 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -258,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." @@ -556,42 +561,9 @@ enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = false }; /* 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 (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); @@ -600,8 +572,6 @@ extern void char_table_set (Lisp_Object, int, Lisp_Object); /* Defined in data.c. */ extern _Noreturn void wrong_type_argument (Lisp_Object, Lisp_Object); extern _Noreturn void wrong_choice (Lisp_Object, Lisp_Object); -extern void notify_variable_watchers (Lisp_Object symbol, Lisp_Object newval, - Lisp_Object operation, Lisp_Object where); #ifdef CANNOT_DUMP @@ -618,6 +588,56 @@ extern bool initialized; 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 @@ -746,6 +766,10 @@ struct Lisp_Symbol DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, 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 define DEFINE_NON_NIL_Q_SYMBOL_MACROS to be false, to be portable to @@ -756,19 +780,43 @@ 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. */ +INLINE bool +(SYMBOLP) (Lisp_Object x) +{ + return lisp_h_SYMBOLP (x); +} -INLINE EMACS_INT -(XLI) (Lisp_Object o) +INLINE struct Lisp_Symbol * +(XSYMBOL) (Lisp_Object a) { - return lisp_h_XLI (o); +#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. */ @@ -836,11 +884,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) @@ -868,24 +911,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 @@ -937,24 +962,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) @@ -1014,97 +1021,6 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t 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 @@ -1115,18 +1031,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)) @@ -1191,14 +1099,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; @@ -1218,22 +1118,46 @@ struct GCALIGNED Lisp_Cons } u; }; -/* 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 - part of the basic lisp implementation should assume that the car and cdr - 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.) */ -INLINE Lisp_Object * -xcar_addr (Lisp_Object c) +INLINE bool +(NILP) (Lisp_Object x) { - return &XCONS (c)->car; + return lisp_h_NILP (x); } -INLINE Lisp_Object * -xcdr_addr (Lisp_Object c) + +INLINE bool +(CONSP) (Lisp_Object x) { - return &XCONS (c)->u.cdr; + 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 + part of the basic lisp implementation should assume that the car and cdr + 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.) */ +INLINE Lisp_Object * +xcar_addr (Lisp_Object c) +{ + return &XCONS (c)->car; +} +INLINE Lisp_Object * +xcdr_addr (Lisp_Object c) +{ + return &XCONS (c)->u.cdr; } /* Use these from normal code. */ @@ -1307,6 +1231,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) @@ -1441,6 +1384,62 @@ struct Lisp_Vector Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER]; }; +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. */ struct Lisp_Bool_Vector @@ -1457,6 +1456,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) { @@ -1477,22 +1521,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 @@ -1525,16 +1553,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 @@ -1550,14 +1568,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. */ @@ -1674,6 +1684,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 @@ -1695,6 +1718,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) { @@ -1760,6 +1796,19 @@ struct Lisp_Subr 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 @@ -2070,6 +2119,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 */ @@ -2227,6 +2295,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) @@ -2307,6 +2388,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 { @@ -2338,53 +2432,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 @@ -2502,6 +2587,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) { @@ -2519,6 +2610,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) { @@ -2582,12 +2686,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); @@ -2610,109 +2708,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. */ @@ -2723,60 +2723,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); @@ -2809,42 +2761,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) @@ -2861,23 +2787,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); @@ -3380,6 +3289,8 @@ set_sub_char_table_contents (Lisp_Object table, ptrdiff_t idx, Lisp_Object val) } /* Defined in data.c. */ +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 { @@ -4194,6 +4105,7 @@ 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); diff --git a/src/process.h b/src/process.h index 24c6282..8f28ddb 100644 --- a/src/process.h +++ b/src/process.h @@ -199,6 +199,25 @@ struct Lisp_Process #endif }; +INLINE bool +PROCESSP (Lisp_Object a) +{ + return PSEUDOVECTORP (a, PVEC_PROCESS); +} + +INLINE void +CHECK_PROCESS (Lisp_Object x) +{ + CHECK_TYPE (PROCESSP (x), Qprocessp, x); +} + +INLINE struct Lisp_Process * +XPROCESS (Lisp_Object a) +{ + eassert (PROCESSP (a)); + return XUNTAG (a, Lisp_Vectorlike); +} + /* Every field in the preceding structure except for the first two must be a Lisp_Object, for GC's sake. */ diff --git a/src/termhooks.h b/src/termhooks.h index 03416cb..81e06d9 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -654,6 +654,19 @@ struct terminal void (*delete_terminal_hook) (struct terminal *); }; +INLINE bool +TERMINALP (Lisp_Object a) +{ + return PSEUDOVECTORP (a, PVEC_TERMINAL); +} + +INLINE struct terminal * +XTERMINAL (Lisp_Object a) +{ + eassert (TERMINALP (a)); + return XUNTAG (a, Lisp_Vectorlike); +} + /* Most code should use these functions to set Lisp fields in struct terminal. */ INLINE void diff --git a/src/window.h b/src/window.h index 4a102f2..717f972 100644 --- a/src/window.h +++ b/src/window.h @@ -397,6 +397,25 @@ struct window ptrdiff_t window_end_bytepos; }; +INLINE bool +WINDOWP (Lisp_Object a) +{ + return PSEUDOVECTORP (a, PVEC_WINDOW); +} + +INLINE void +CHECK_WINDOW (Lisp_Object x) +{ + CHECK_TYPE (WINDOWP (x), Qwindowp, x); +} + +INLINE struct window * +XWINDOW (Lisp_Object a) +{ + eassert (WINDOWP (a)); + return XUNTAG (a, Lisp_Vectorlike); +} + /* Most code should use these functions to set Lisp fields in struct window. */ INLINE void -- 2.9.3