emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master f5b9c1e: Reorder lisp.h to declare types before usi


From: Paul Eggert
Subject: [Emacs-diffs] master f5b9c1e: Reorder lisp.h to declare types before using them
Date: Sun, 25 Dec 2016 17:17:54 +0000 (UTC)

branch: master
commit f5b9c1e59653ac687806f6f84181fc3f5020e6ba
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    Reorder lisp.h to declare types before using them
    
    This puts 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 (Bug#25128).
    * 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/termhooks.h (TERMINALP, XTERMINAL):
    * src/window.h (WINDOWP, CHECK_WINDOW, XWINDOW):
    * src/thread.h (THREADP, CHECK_THREAD, XTHREAD, MUTEXP, CHECK_MUTEX)
    (XMUTEX, CONDVARP, CHECK_CONDVAR, XCONDVAR):
    Move here from lisp.h.
    * src/intervals.h: Include buffer.h, for BUFFERP.
    Include lisp.h, for Lisp_Object.
    * src/lisp.h: Reorder declarations and definitions as described
    above.  Move thread includes to be later, so that they can use the
    reordered definitions.  Move some symbols to other headers (noted
    elsewhere).  Remove forward decls that are no longer needed.
    * src/thread.h: Include systhread.h here, not in lisp.h,
    since lisp.h itself does not need systhread.h.
---
 src/buffer.c    |    1 +
 src/buffer.h    |   19 ++
 src/data.c      |    1 +
 src/image.c     |    1 +
 src/intervals.h |    3 +
 src/lisp.h      |  887 +++++++++++++++++++++++--------------------------------
 src/process.h   |   19 ++
 src/termhooks.h |   13 +
 src/thread.h    |   58 ++++
 src/window.h    |   19 ++
 10 files changed, 501 insertions(+), 520 deletions(-)

diff --git a/src/buffer.c b/src/buffer.c
index babfba3..28cf702 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -32,6 +32,7 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 
 #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 854b5b5..e2f94f1 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 821fc37..e2c1a28 100644
--- a/src/data.c
+++ b/src/data.c
@@ -31,6 +31,7 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #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 
<http://www.gnu.org/licenses/>.  */
 
 #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 
<http://www.gnu.org/licenses/>.  */
 #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 75a7fd3..23d3ae4 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -34,8 +34,6 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 #include <intprops.h>
 #include <verify.h>
 
-#include "systhread.h"
-
 INLINE_HEADER_BEGIN
 
 /* Define a TYPE constant ID as an externally visible name.  Use like this:
@@ -260,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."
@@ -558,45 +561,8 @@ 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 bool THREADP (Lisp_Object);
-INLINE bool MUTEXP (Lisp_Object);
-INLINE bool CONDVARP (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);
@@ -604,9 +570,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
@@ -625,6 +588,56 @@ extern bool generating_ldefs_boot;
 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
@@ -753,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
@@ -794,21 +811,43 @@ struct vectorlike_header
     ptrdiff_t size;
   };
 
-#include "thread.h"
+INLINE bool
+(SYMBOLP) (Lisp_Object x)
+{
+  return lisp_h_SYMBOLP (x);
+}
 
-/* Convert a Lisp_Object to the corresponding EMACS_INT and vice versa.
-   At the machine level, these operations are no-ops.  */
+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 EMACS_INT
-(XLI) (Lisp_Object o)
+INLINE Lisp_Object
+make_lisp_symbol (struct Lisp_Symbol *sym)
 {
-  return lisp_h_XLI (o);
+  Lisp_Object a = XIL (TAG_SYMOFFSET ((char *) sym - (char *) lispsym));
+  eassert (XSYMBOL (a) == sym);
+  return a;
 }
 
 INLINE Lisp_Object
-(XIL) (EMACS_INT i)
+builtin_lisp_symbol (int index)
 {
-  return lisp_h_XIL (i);
+  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.  */
@@ -879,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)
@@ -911,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
@@ -980,24 +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)
@@ -1056,119 +1054,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);
-}
-
-INLINE struct thread_state *
-XTHREAD (Lisp_Object a)
-{
-  eassert (THREADP (a));
-  return XUNTAG (a, Lisp_Vectorlike);
-}
-
-INLINE struct Lisp_Mutex *
-XMUTEX (Lisp_Object a)
-{
-  eassert (MUTEXP (a));
-  return XUNTAG (a, Lisp_Vectorlike);
-}
-
-INLINE struct Lisp_CondVar *
-XCONDVAR (Lisp_Object a)
-{
-  eassert (CONDVARP (a));
-  return XUNTAG (a, Lisp_Vectorlike);
-}
-
 /* Construct a Lisp_Object from a value or address.  */
 
 INLINE Lisp_Object
@@ -1179,18 +1064,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))
@@ -1258,14 +1135,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;
@@ -1285,10 +1154,34 @@ 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
+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
+   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.)  */
@@ -1374,6 +1267,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)
@@ -1477,6 +1389,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
@@ -1493,6 +1461,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)
 {
@@ -1513,22 +1526,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
@@ -1561,16 +1558,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
@@ -1586,14 +1573,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.  */
@@ -1710,6 +1689,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
@@ -1731,6 +1723,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)
 {
@@ -1796,6 +1801,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
@@ -1822,6 +1840,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
  ***********************************************************************/
@@ -2106,6 +2126,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 */
@@ -2263,6 +2302,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)
@@ -2343,8 +2395,21 @@ struct Lisp_Finalizer
     Lisp_Object function;
   };
 
-/* A miscellaneous object, when it's on the free list.  */
-struct Lisp_Free
+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
   {
     ENUM_BF (Lisp_Misc_Type) type : 16;        /* = Lisp_Misc_Free */
     bool_bf gcmarkbit : 1;
@@ -2374,53 +2439,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
 
@@ -2535,6 +2591,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)
 {
@@ -2552,6 +2614,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)
 {
@@ -2615,12 +2690,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);
@@ -2643,109 +2712,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.  */
 
@@ -2756,83 +2727,17 @@ 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);
 }
 
-INLINE bool
-THREADP (Lisp_Object a)
-{
-  return PSEUDOVECTORP (a, PVEC_THREAD);
-}
-
-INLINE bool
-MUTEXP (Lisp_Object a)
-{
-  return PSEUDOVECTORP (a, PVEC_MUTEX);
-}
-
-INLINE bool
-CONDVARP (Lisp_Object a)
-{
-  return PSEUDOVECTORP (a, PVEC_CONDVAR);
-}
-
 /* Test for image (image . spec)  */
 INLINE bool
 IMAGEP (Lisp_Object x)
@@ -2860,42 +2765,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)
@@ -2912,23 +2791,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);
@@ -2981,25 +2843,6 @@ CHECK_NUMBER_OR_FLOAT (Lisp_Object x)
       CHECK_TYPE (NUMBERP (x), Qnumber_or_marker_p, x);                        
\
   } while (false)
 
-
-INLINE void
-CHECK_THREAD (Lisp_Object x)
-{
-  CHECK_TYPE (THREADP (x), Qthreadp, x);
-}
-
-INLINE void
-CHECK_MUTEX (Lisp_Object x)
-{
-  CHECK_TYPE (MUTEXP (x), Qmutexp, x);
-}
-
-INLINE void
-CHECK_CONDVAR (Lisp_Object x)
-{
-  CHECK_TYPE (CONDVARP (x), Qcondition_variable_p, 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.  */
 INLINE void
@@ -3450,6 +3293,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 {
@@ -4273,6 +4119,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 e497ebc..5ef327a 100644
--- a/src/process.h
+++ b/src/process.h
@@ -202,6 +202,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/thread.h b/src/thread.h
index b852401..6d1af5c 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -28,6 +28,7 @@ along with GNU Emacs.  If not, see 
<http://www.gnu.org/licenses/>.  */
 
 #include "sysselect.h"         /* FIXME */
 #include "systime.h"           /* FIXME */
+#include "systhread.h"
 
 struct thread_state
 {
@@ -175,6 +176,25 @@ struct thread_state
   struct thread_state *next_thread;
 };
 
+INLINE bool
+THREADP (Lisp_Object a)
+{
+  return PSEUDOVECTORP (a, PVEC_THREAD);
+}
+
+INLINE void
+CHECK_THREAD (Lisp_Object x)
+{
+  CHECK_TYPE (THREADP (x), Qthreadp, x);
+}
+
+INLINE struct thread_state *
+XTHREAD (Lisp_Object a)
+{
+  eassert (THREADP (a));
+  return XUNTAG (a, Lisp_Vectorlike);
+}
+
 /* A mutex in lisp is represented by a system condition variable.
    The system mutex associated with this condition variable is the
    global lock.
@@ -203,6 +223,25 @@ struct Lisp_Mutex
   lisp_mutex_t mutex;
 };
 
+INLINE bool
+MUTEXP (Lisp_Object a)
+{
+  return PSEUDOVECTORP (a, PVEC_MUTEX);
+}
+
+INLINE void
+CHECK_MUTEX (Lisp_Object x)
+{
+  CHECK_TYPE (MUTEXP (x), Qmutexp, x);
+}
+
+INLINE struct Lisp_Mutex *
+XMUTEX (Lisp_Object a)
+{
+  eassert (MUTEXP (a));
+  return XUNTAG (a, Lisp_Vectorlike);
+}
+
 /* A condition variable as a lisp object.  */
 struct Lisp_CondVar
 {
@@ -218,6 +257,25 @@ struct Lisp_CondVar
   sys_cond_t cond;
 };
 
+INLINE bool
+CONDVARP (Lisp_Object a)
+{
+  return PSEUDOVECTORP (a, PVEC_CONDVAR);
+}
+
+INLINE void
+CHECK_CONDVAR (Lisp_Object x)
+{
+  CHECK_TYPE (CONDVARP (x), Qcondition_variable_p, x);
+}
+
+INLINE struct Lisp_CondVar *
+XCONDVAR (Lisp_Object a)
+{
+  eassert (CONDVARP (a));
+  return XUNTAG (a, Lisp_Vectorlike);
+}
+
 extern struct thread_state *current_thread;
 
 extern void finalize_one_thread (struct thread_state *state);
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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]