Port to stricter C99 platforms.
[bpt/emacs.git] / src / lisp.h
index 1071504..f538cec 100644 (file)
@@ -31,10 +31,26 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <limits.h>
 
 #include <intprops.h>
+#include <verify.h>
 
 INLINE_HEADER_BEGIN
-#ifndef LISP_INLINE
-# define LISP_INLINE INLINE
+
+/* Define a TYPE constant ID as an externally visible name.  Use like this:
+
+      DEFINE_GDB_SYMBOL_BEGIN (TYPE, ID)
+      #define ID something
+      DEFINE_GDB_SYMBOL_END (ID)
+
+   This hack is for the benefit of compilers that do not make macro
+   definitions visible to the debugger.  It's used for symbols that
+   .gdbinit needs, symbols whose values may not fit in 'int' (where an
+   enum would suffice).  */
+#ifdef MAIN_PROGRAM
+# define DEFINE_GDB_SYMBOL_BEGIN(type, id) type const id EXTERNALLY_VISIBLE
+# define DEFINE_GDB_SYMBOL_END(id) = id;
+#else
+# define DEFINE_GDB_SYMBOL_BEGIN(type, id)
+# define DEFINE_GDB_SYMBOL_END(val)
 #endif
 
 /* The ubiquitous max and min macros.  */
@@ -55,7 +71,7 @@ typedef unsigned long long int EMACS_UINT;
 #  define pI "ll"
 # elif INT_MAX < LONG_MAX
 typedef long int EMACS_INT;
-typedef unsigned long int EMACS_UINT;
+typedef unsigned long EMACS_UINT;
 #  define EMACS_INT_MAX LONG_MAX
 #  define pI "l"
 # else
@@ -66,6 +82,11 @@ typedef unsigned int EMACS_UINT;
 # endif
 #endif
 
+/* An unsigned integer type representing a fixed-length bit sequence,
+   suitable for words in a Lisp bool vector.  */
+typedef size_t bits_word;
+#define BITS_WORD_MAX SIZE_MAX
+
 /* Number of bits in some machine integer types.  */
 enum
   {
@@ -73,6 +94,7 @@ enum
     BITS_PER_SHORT     = CHAR_BIT * sizeof (short),
     BITS_PER_INT       = CHAR_BIT * sizeof (int),
     BITS_PER_LONG      = CHAR_BIT * sizeof (long int),
+    BITS_PER_BITS_WORD = CHAR_BIT * sizeof (bits_word),
     BITS_PER_EMACS_INT = CHAR_BIT * sizeof (EMACS_INT)
   };
 
@@ -110,30 +132,50 @@ 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 Emacs versions of <assert.h>'s 'assert (COND)' and <verify.h>'s
+   'assume (COND)'.  COND should be free of side effects, as it may or
+   may not be evaluated.
+
+   'eassert (COND)' checks COND at runtime if ENABLE_CHECKING is
+   defined and suppress_checking is false, and does nothing otherwise.
+   Emacs dies if COND is checked and is false.  The suppress_checking
+   variable is initialized to 0 in alloc.c.  Set it to 1 using a
+   debugger to temporarily disable aborting on detected internal
+   inconsistencies or error conditions.
+
+   In some cases, a good compiler may be able to optimize away the
+   eassert macro even if ENABLE_CHECKING is true, e.g., if XSTRING (x)
+   uses eassert to test STRINGP (x), but a particular use of XSTRING
+   is invoked only after testing that STRINGP (x) is true, making the
+   test redundant.
+
+   eassume is like eassert except that it also causes the compiler to
+   assume that COND is true afterwards, regardless of whether runtime
+   checking is enabled.  This can improve performance in some cases,
+   though it can degrade performance in others.  It's often suboptimal
+   for COND to call external functions or access volatile storage.  */
+
 #ifndef ENABLE_CHECKING
-# define eassert(X) ((void) (0 && (X))) /* Check that X compiles.  */
+# define eassert(cond) ((void) (0 && (cond))) /* Check that COND compiles.  */
+# define eassume(cond) assume (cond)
 #else /* ENABLE_CHECKING */
 
 extern _Noreturn void die (const char *, const char *, int);
 
-/* The suppress_checking variable is initialized to 0 in alloc.c.  Set
-   it to 1 using a debugger to temporarily disable aborting on
-   detected internal inconsistencies or error conditions.
-
-   In some cases, a good compiler may be able to optimize away the
-   eassert macro altogether, e.g., if XSTRING (x) uses eassert to test
-   STRINGP (x), but a particular use of XSTRING is invoked only after
-   testing that STRINGP (x) is true, making the test redundant.  */
 extern bool suppress_checking EXTERNALLY_VISIBLE;
 
 # define eassert(cond)                                         \
    (suppress_checking || (cond)                                \
     ? (void) 0                                                 \
     : die (# cond, __FILE__, __LINE__))
+# define eassume(cond)                                         \
+   (suppress_checking                                          \
+    ? assume (cond)                                            \
+    : (cond)                                                   \
+    ? (void) 0                                                 \
+    : die (# cond, __FILE__, __LINE__))
 #endif /* ENABLE_CHECKING */
+
 \f
 /* 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 +387,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.  */
@@ -364,8 +406,10 @@ enum enum_USE_LSB_TAG { USE_LSB_TAG = 0 };
 #define case_Lisp_Int case Lisp_Int0: case Lisp_Int1
 
 /* Idea stolen from GDB.  Pedantic GCC complains about enum bitfields,
-   MSVC doesn't support them, and xlc complains vociferously about them.  */
-#if defined __STRICT_ANSI__ || defined _MSC_VER || defined __IBMC__
+   MSVC doesn't support them, and xlc and Oracle Studio c99 complain
+   vociferously about them.  */
+#if (defined __STRICT_ANSI__ || defined _MSC_VER || defined __IBMC__ \
+     || (defined __SUNPRO_C && __STDC__))
 #define ENUM_BF(TYPE) unsigned int
 #else
 #define ENUM_BF(TYPE) enum TYPE
@@ -509,15 +553,15 @@ LISP_MACRO_DEFUN (XIL, Lisp_Object, (EMACS_INT i), (i))
 
 /* In the size word of a vector, this bit means the vector has been marked.  */
 
-static ptrdiff_t const ARRAY_MARK_FLAG
+DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG)
 #define ARRAY_MARK_FLAG PTRDIFF_MIN
-      = ARRAY_MARK_FLAG;
+DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG)
 
 /* In the size word of a struct Lisp_Vector, this bit means it's really
    some other vector-like object.  */
-static ptrdiff_t const PSEUDOVECTOR_FLAG
+DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG)
 #define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2)
-      = PSEUDOVECTOR_FLAG;
+DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
 
 /* In a pseudovector, the size field actually contains a word with one
    PSEUDOVECTOR_FLAG bit set, and one of the following values extracted
@@ -579,12 +623,13 @@ enum More_Lisp_Bits
   };
 \f
 /* These functions extract various sorts of values from a Lisp_Object.
- For example, if tem is a Lisp_Object whose type is Lisp_Cons,
- XCONS (tem) is the struct Lisp_Cons * pointing to the memory for that cons.  */
+   For example, if tem is a Lisp_Object whose type is Lisp_Cons,
+   XCONS (tem) is the struct Lisp_Cons * pointing to the memory for
+   that cons.  */
 
-static EMACS_INT const VALMASK
+DEFINE_GDB_SYMBOL_BEGIN (EMACS_INT, VALMASK)
 #define VALMASK (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX)
-      = VALMASK;
+DEFINE_GDB_SYMBOL_END (VALMASK)
 
 /* Largest and smallest representable fixnum values.  These are the C
    values.  They are macros for use in static initializers.  */
@@ -610,14 +655,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 +672,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 +681,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 +689,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 +703,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 +716,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 +733,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 +743,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 +778,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 +807,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 +823,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 +832,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 +889,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 +899,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 +912,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 +983,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 +1002,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 +1030,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 +1052,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 +1089,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 +1119,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 +1129,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,7 +1177,7 @@ struct vectorlike_header
     ptrdiff_t size;
   };
 
-/* Regular vector is just a header plus array of Lisp_Objects.  */
+/* A regular vector is just a header plus an array of Lisp_Objects.  */
 
 struct Lisp_Vector
   {
@@ -1143,7 +1185,14 @@ struct Lisp_Vector
     Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER];
   };
 
-/* A boolvector is a kind of vectorlike, with contents are like a string.  */
+/* C11 prohibits alignof (struct Lisp_Vector), so compute it manually.  */
+enum
+  {
+    ALIGNOF_STRUCT_LISP_VECTOR
+      = alignof (union { struct vectorlike_header a; Lisp_Object b; })
+  };
+
+/* A boolvector is a kind of vectorlike, with contents like a string.  */
 
 struct Lisp_Bool_Vector
   {
@@ -1156,6 +1205,14 @@ struct Lisp_Bool_Vector
     unsigned char data[FLEXIBLE_ARRAY_MEMBER];
   };
 
+INLINE EMACS_INT
+bool_vector_size (Lisp_Object a)
+{
+  EMACS_INT size = XBOOL_VECTOR (a)->size;
+  eassume (0 <= size);
+  return size;
+}
+
 /* Some handy constants for calculating sizes
    and offsets, mostly of vectorlike objects.   */
 
@@ -1168,32 +1225,32 @@ enum
 
 /* 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];
 }
 
-LISP_INLINE Lisp_Object *
+INLINE Lisp_Object *
 aref_addr (Lisp_Object array, ptrdiff_t idx)
 {
   return & XVECTOR (array)->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;
 }
 
-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:
@@ -1300,7 +1357,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 +1377,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 +1387,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 +1432,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 +1511,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 +1533,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 +1560,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 +1568,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 +1664,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 +1673,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 +1695,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 +1710,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 +1740,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 +1748,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;
@@ -1703,14 +1760,14 @@ struct Lisp_Misc_Any            /* Supertype of all Misc types.  */
 {
   ENUM_BF (Lisp_Misc_Type) type : 16;          /* = Lisp_Misc_??? */
   unsigned gcmarkbit : 1;
-  int spacer : 15;
+  unsigned spacer : 15;
 };
 
 struct Lisp_Marker
 {
   ENUM_BF (Lisp_Misc_Type) type : 16;          /* = Lisp_Misc_Marker */
   unsigned gcmarkbit : 1;
-  int spacer : 13;
+  unsigned spacer : 13;
   /* This flag is temporarily used in the functions
      decode/encode_coding_object to record that the marker position
      must be adjusted after the conversion.  */
@@ -1764,7 +1821,7 @@ struct Lisp_Overlay
   {
     ENUM_BF (Lisp_Misc_Type) type : 16;        /* = Lisp_Misc_Overlay */
     unsigned gcmarkbit : 1;
-    int spacer : 15;
+    unsigned spacer : 15;
     struct Lisp_Overlay *next;
     Lisp_Object start;
     Lisp_Object end;
@@ -1842,7 +1899,7 @@ struct Lisp_Save_Value
   {
     ENUM_BF (Lisp_Misc_Type) type : 16;        /* = Lisp_Misc_Save_Value */
     unsigned gcmarkbit : 1;
-    int spacer : 32 - (16 + 1 + SAVE_TYPE_BITS);
+    unsigned spacer : 32 - (16 + 1 + SAVE_TYPE_BITS);
 
     /* V->data may hold up to SAVE_VALUE_SLOTS entries.  The type of
        V's data entries are determined by V->save_type.  E.g., if
@@ -1861,7 +1918,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 +1927,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 +1948,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 +1963,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);
@@ -1918,7 +1975,7 @@ struct Lisp_Free
   {
     ENUM_BF (Lisp_Misc_Type) type : 16;        /* = Lisp_Misc_Free */
     unsigned gcmarkbit : 1;
-    int spacer : 15;
+    unsigned spacer : 15;
     union Lisp_Misc *chain;
   };
 
@@ -1934,40 +1991,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 +2138,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 +2161,7 @@ struct Lisp_Float
     } u;
   };
 
-LISP_INLINE double
+INLINE double
 XFLOAT_DATA (Lisp_Object f)
 {
   return XFLOAT (f)->u.data;
@@ -2164,54 +2221,22 @@ enum char_bits
     CHARACTERBITS = 22
   };
 \f
-/* 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;
-\f
 /* 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 +2255,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 +2296,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 +2312,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);
 }
 \f
-LISP_INLINE void
+INLINE void
 CHECK_LIST (Lisp_Object x)
 {
   CHECK_TYPE (CONSP (x) || NILP (x), Qlistp, x);
@@ -2377,52 +2402,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 +2481,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 +2499,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 +2507,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 +2585,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 +2684,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 +2694,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.  */
@@ -2724,7 +2739,7 @@ union specbinding
     } let;
     struct {
       ENUM_BF (specbind_tag) kind : CHAR_BIT;
-      bool debug_on_exit : 1;
+      unsigned debug_on_exit : 1;
       Lisp_Object function;
       Lisp_Object *args;
       ptrdiff_t nargs;
@@ -2735,52 +2750,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.
-
-   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;
-  };
-
-/* 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.
+/* 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.
 
-   catchtag structures are chained together in the C calling stack;
-   the `next' member points to the next outer catchtag.
+   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).
 
-   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 +2774,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,7 +3087,7 @@ 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));
@@ -3072,13 +3096,13 @@ vcopy (Lisp_Object v, ptrdiff_t offset, Lisp_Object *args, ptrdiff_t count)
 
 /* 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 +3111,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 +3131,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 +3140,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 +3148,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 +3156,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 +3165,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 +3178,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 +3233,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 +3422,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 +3437,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 +3507,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 +3534,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 +3552,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 +3561,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 +3582,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 +3629,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 +3697,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 +3713,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 +3732,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:
 
@@ -3746,11 +3773,12 @@ extern Lisp_Object internal_condition_case_n
      Lisp_Object, Lisp_Object (*) (Lisp_Object, ptrdiff_t, Lisp_Object *));
 extern void specbind (Lisp_Object, Lisp_Object);
 extern void record_unwind_protect (void (*) (Lisp_Object), Lisp_Object);
-extern void record_unwind_protect_int (void (*) (int), int);
 extern void record_unwind_protect_ptr (void (*) (void *), void *);
+extern void record_unwind_protect_int (void (*) (int), int);
 extern void record_unwind_protect_void (void (*) (void));
 extern void record_unwind_protect_nothing (void);
 extern void clear_unwind_protect (ptrdiff_t);
+extern void set_unwind_protect (ptrdiff_t, void (*) (Lisp_Object), Lisp_Object);
 extern void set_unwind_protect_ptr (ptrdiff_t, void (*) (void *), void *);
 extern Lisp_Object unbind_to (ptrdiff_t, Lisp_Object);
 extern _Noreturn void error (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2);
@@ -3830,6 +3858,9 @@ extern Lisp_Object Qfile_directory_p;
 extern Lisp_Object Qinsert_file_contents;
 extern Lisp_Object Qfile_name_history;
 extern Lisp_Object expand_and_dir_to_file (Lisp_Object, Lisp_Object);
+extern Lisp_Object write_region (Lisp_Object, Lisp_Object, Lisp_Object,
+                                Lisp_Object, Lisp_Object, Lisp_Object,
+                                Lisp_Object, int);
 EXFUN (Fread_file_name, 6);     /* Not a normal DEFUN.  */
 extern void close_file_unwind (int);
 extern void fclose_unwind (void *);
@@ -3844,7 +3875,6 @@ extern void init_fileio (void);
 extern void syms_of_fileio (void);
 extern Lisp_Object make_temp_name (Lisp_Object, bool);
 extern Lisp_Object Qdelete_file;
-extern bool check_existing (const char *);
 
 /* Defined in search.c.  */
 extern void shrink_regexp_cache (void);
@@ -3862,8 +3892,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,
@@ -3921,6 +3951,7 @@ extern bool detect_input_pending_run_timers (bool);
 extern void safe_run_hooks (Lisp_Object);
 extern void cmd_error_internal (Lisp_Object, const char *);
 extern Lisp_Object command_loop_1 (void);
+extern Lisp_Object read_menu_command (void);
 extern Lisp_Object recursive_edit_1 (void);
 extern void record_auto_save (void);
 extern void force_auto_save_soon (void);
@@ -3965,9 +3996,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);
 
@@ -4096,7 +4127,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);
@@ -4108,9 +4138,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);
@@ -4251,10 +4281,17 @@ extern void *xnrealloc (void *, ptrdiff_t, ptrdiff_t);
 extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t);
 
 extern char *xstrdup (const char *);
+extern char *xlispstrdup (Lisp_Object);
 extern void xputenv (const char *);
 
 extern char *egetenv (const char *);
 
+/* Copy Lisp string to temporary (allocated on stack) C string.  */
+
+#define xlispstrdupa(string)                   \
+  memcpy (alloca (SBYTES (string) + 1),                \
+         SSDATA (string), SBYTES (string) + 1)
+
 /* Set up the name of the machine we're running on.  */
 extern void init_system_name (void);
 
@@ -4331,10 +4368,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
@@ -4344,7 +4387,7 @@ maybe_gc (void)
     Fgarbage_collect ();
 }
 
-LISP_INLINE bool
+INLINE bool
 functionp (Lisp_Object object)
 {
   if (SYMBOLP (object) && !NILP (Ffboundp (object)))
@@ -4376,6 +4419,10 @@ functionp (Lisp_Object object)
     return 0;
 }
 
+/* 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 */