]> code.delx.au - gnu-emacs/blobdiff - src/lisp.h
Merge from origin/emacs-25
[gnu-emacs] / src / lisp.h
index b730619726bda4450a161cd6c96f11e622bfd26d..02b8078a9fd513ad861e775dcc397970864db8b7 100644 (file)
@@ -1,6 +1,6 @@
-/* Fundamental definitions for GNU Emacs Lisp interpreter.
+/* Fundamental definitions for GNU Emacs Lisp interpreter. -*- coding: utf-8 -*-
 
-Copyright (C) 1985-1987, 1993-1995, 1997-2015 Free Software Foundation,
+Copyright (C) 1985-1987, 1993-1995, 1997-2016 Free Software Foundation,
 Inc.
 
 This file is part of GNU Emacs.
@@ -258,7 +258,7 @@ enum Lisp_Bits
 
 /* The maximum value that can be stored in a EMACS_INT, assuming all
    bits other than the type bits contribute to a nonnegative signed value.
-   This can be used in #if, e.g., '#if USB_TAG' below expands to an
+   This can be used in #if, e.g., '#if USE_LSB_TAG' below expands to an
    expression involving VAL_MAX.  */
 #define VAL_MAX (EMACS_INT_MAX >> (GCTYPEBITS - 1))
 
@@ -278,10 +278,7 @@ error !;
 #endif
 
 #ifndef alignas
-# define alignas(alignment) /* empty */
-# if USE_LSB_TAG
-#  error "USE_LSB_TAG requires alignas"
-# endif
+# error "alignas not defined"
 #endif
 
 #ifdef HAVE_STRUCT_ATTRIBUTE_ALIGNED
@@ -304,10 +301,6 @@ error !;
 
    and/or via a function definition like this:
 
-     LISP_MACRO_DEFUN (OP, Lisp_Object, (Lisp_Object x), (x))
-
-   which macro-expands to this:
-
      Lisp_Object (OP) (Lisp_Object x) { return lisp_h_OP (x); }
 
    without worrying about the implementations diverging, since
@@ -354,8 +347,6 @@ error !;
 #define lisp_h_XCONS(a) \
    (eassert (CONSP (a)), (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons))
 #define lisp_h_XHASH(a) XUINT (a)
-#define lisp_h_XPNTR(a) \
-   (SYMBOLP (a) ? XSYMBOL (a) : (void *) ((intptr_t) (XLI (a) & VALMASK)))
 #ifndef GC_CHECK_CONS_LIST
 # define lisp_h_check_cons_list() ((void) 0)
 #endif
@@ -366,7 +357,7 @@ error !;
 # define lisp_h_XINT(a) (XLI (a) >> INTTYPEBITS)
 # define lisp_h_XSYMBOL(a) \
     (eassert (SYMBOLP (a)), \
-     (struct Lisp_Symbol *) ((uintptr_t) XLI (a) - Lisp_Symbol \
+     (struct Lisp_Symbol *) ((intptr_t) XLI (a) - Lisp_Symbol \
                             + (char *) lispsym))
 # define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK))
 # define lisp_h_XUNTAG(a, type) ((void *) (intptr_t) (XLI (a) - (type)))
@@ -378,6 +369,12 @@ error !;
 #if (defined __NO_INLINE__ \
      && ! defined __OPTIMIZE__ && ! defined __OPTIMIZE_SIZE__ \
      && ! (defined INLINING && ! INLINING))
+# define DEFINE_KEY_OPS_AS_MACROS true
+#else
+# define DEFINE_KEY_OPS_AS_MACROS false
+#endif
+
+#if DEFINE_KEY_OPS_AS_MACROS
 # define XLI(o) lisp_h_XLI (o)
 # define XIL(i) lisp_h_XIL (i)
 # define CHECK_LIST_CONS(x, y) lisp_h_CHECK_LIST_CONS (x, y)
@@ -400,7 +397,6 @@ error !;
 # define XCDR(c) lisp_h_XCDR (c)
 # define XCONS(a) lisp_h_XCONS (a)
 # define XHASH(a) lisp_h_XHASH (a)
-# define XPNTR(a) lisp_h_XPNTR (a)
 # ifndef GC_CHECK_CONS_LIST
 #  define check_cons_list() lisp_h_check_cons_list ()
 # endif
@@ -414,17 +410,6 @@ error !;
 # endif
 #endif
 
-/* Define NAME as a lisp.h inline function that returns TYPE and has
-   arguments declared as ARGDECLS and passed as ARGS.  ARGDECLS and
-   ARGS should be parenthesized.  Implement the function by calling
-   lisp_h_NAME ARGS.  */
-#define LISP_MACRO_DEFUN(name, type, argdecls, 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) \
-  INLINE void (name) argdecls { lisp_h_##name args; }
-
 
 /* Define the fundamental Lisp data structures.  */
 
@@ -489,6 +474,9 @@ enum Lisp_Misc_Type
     Lisp_Misc_Overlay,
     Lisp_Misc_Save_Value,
     Lisp_Misc_Finalizer,
+#ifdef HAVE_MODULES
+    Lisp_Misc_User_Ptr,
+#endif
     /* Currently floats are not a misc type,
        but let's define this in case we want to change that.  */
     Lisp_Misc_Float,
@@ -602,6 +590,12 @@ 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);
@@ -725,15 +719,19 @@ struct Lisp_Symbol
 #define DEFUN_ARGS_8   (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \
                         Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object)
 
-/* Yield an integer that contains TAG along with PTR.  */
+/* Yield a signed integer that contains TAG along with PTR.
+
+   Sign-extend pointers when USE_LSB_TAG (this simplifies emacs-module.c),
+   and zero-extend otherwise (that’s a bit faster here).
+   Sign extension matters only when EMACS_INT is wider than a pointer.  */
 #define TAG_PTR(tag, ptr) \
-  ((USE_LSB_TAG ? (tag) : (EMACS_UINT) (tag) << VALBITS) + (uintptr_t) (ptr))
+  (USE_LSB_TAG \
+   ? (intptr_t) (ptr) + (tag) \
+   : (EMACS_INT) (((EMACS_UINT) (tag) << VALBITS) + (uintptr_t) (ptr)))
 
 /* Yield an integer that contains a symbol tag along with OFFSET.
    OFFSET should be the offset in bytes from 'lispsym' to the symbol.  */
-#define TAG_SYMOFFSET(offset)                              \
-  TAG_PTR (Lisp_Symbol,                                            \
-          ((uintptr_t) (offset) >> (USE_LSB_TAG ? 0 : GCTYPEBITS)))
+#define TAG_SYMOFFSET(offset) TAG_PTR (Lisp_Symbol, offset)
 
 /* XLI_BUILTIN_LISPSYM (iQwhatever) is equivalent to
    XLI (builtin_lisp_symbol (Qwhatever)),
@@ -759,8 +757,18 @@ struct Lisp_Symbol
 
 /* Convert a Lisp_Object to the corresponding EMACS_INT and vice versa.
    At the machine level, these operations are no-ops.  */
-LISP_MACRO_DEFUN (XLI, EMACS_INT, (Lisp_Object o), (o))
-LISP_MACRO_DEFUN (XIL, Lisp_Object, (EMACS_INT i), (i))
+
+INLINE EMACS_INT
+(XLI) (Lisp_Object o)
+{
+  return lisp_h_XLI (o);
+}
+
+INLINE Lisp_Object
+(XIL) (EMACS_INT i)
+{
+  return lisp_h_XIL (i);
+}
 
 /* In the size word of a vector, this bit means the vector has been marked.  */
 
@@ -836,12 +844,43 @@ DEFINE_GDB_SYMBOL_END (VALMASK)
 
 #if USE_LSB_TAG
 
-LISP_MACRO_DEFUN (make_number, Lisp_Object, (EMACS_INT n), (n))
-LISP_MACRO_DEFUN (XINT, EMACS_INT, (Lisp_Object a), (a))
-LISP_MACRO_DEFUN (XFASTINT, EMACS_INT, (Lisp_Object a), (a))
-LISP_MACRO_DEFUN (XSYMBOL, struct Lisp_Symbol *, (Lisp_Object a), (a))
-LISP_MACRO_DEFUN (XTYPE, enum Lisp_Type, (Lisp_Object a), (a))
-LISP_MACRO_DEFUN (XUNTAG, void *, (Lisp_Object a, int type), (a, type))
+INLINE Lisp_Object
+(make_number) (EMACS_INT n)
+{
+  return lisp_h_make_number (n);
+}
+
+INLINE EMACS_INT
+(XINT) (Lisp_Object a)
+{
+  return lisp_h_XINT (a);
+}
+
+INLINE EMACS_INT
+(XFASTINT) (Lisp_Object a)
+{
+  EMACS_INT n = lisp_h_XFASTINT (a);
+  eassume (0 <= n);
+  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 */
 
@@ -890,21 +929,10 @@ XFASTINT (Lisp_Object a)
 {
   EMACS_INT int0 = Lisp_Int0;
   EMACS_INT n = USE_LSB_TAG ? XINT (a) : XLI (a) - (int0 << VALBITS);
-  eassert (0 <= n);
+  eassume (0 <= n);
   return n;
 }
 
-/* Extract A's value as a symbol.  */
-INLINE struct Lisp_Symbol *
-XSYMBOL (Lisp_Object a)
-{
-  uintptr_t i = (uintptr_t) XUNTAG (a, Lisp_Symbol);
-  if (! USE_LSB_TAG)
-    i <<= GCTYPEBITS;
-  void *p = (char *) lispsym + i;
-  return p;
-}
-
 /* Extract A's type.  */
 INLINE enum Lisp_Type
 XTYPE (Lisp_Object a)
@@ -913,6 +941,16 @@ XTYPE (Lisp_Object 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)
@@ -923,9 +961,6 @@ XUNTAG (Lisp_Object a, int type)
 
 #endif /* ! USE_LSB_TAG */
 
-/* Extract the pointer hidden within A.  */
-LISP_MACRO_DEFUN (XPNTR, void *, (Lisp_Object a), (a))
-
 /* Extract A's value as an unsigned integer.  */
 INLINE EMACS_UINT
 XUINT (Lisp_Object a)
@@ -937,7 +972,12 @@ XUINT (Lisp_Object a)
 /* Return A's (Lisp-integer sized) hash.  Happens to be like XUINT
    right now, but XUINT should only be applied to objects we know are
    integers.  */
-LISP_MACRO_DEFUN (XHASH, EMACS_INT, (Lisp_Object a), (a))
+
+INLINE EMACS_INT
+(XHASH) (Lisp_Object a)
+{
+  return lisp_h_XHASH (a);
+}
 
 /* Like make_number (N), but may be faster.  N must be in nonnegative range.  */
 INLINE Lisp_Object
@@ -949,7 +989,12 @@ make_natnum (EMACS_INT n)
 }
 
 /* Return true if X and Y are the same object.  */
-LISP_MACRO_DEFUN (EQ, bool, (Lisp_Object x, Lisp_Object y), (x, y))
+
+INLINE bool
+(EQ) (Lisp_Object x, Lisp_Object y)
+{
+  return lisp_h_EQ (x, y);
+}
 
 /* Value is true if I doesn't fit into a Lisp fixnum.  It is
    written this way so that it also works if I is of unsigned
@@ -967,7 +1012,11 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper)
 
 /* Extract a value or address from a Lisp_Object.  */
 
-LISP_MACRO_DEFUN (XCONS, struct Lisp_Cons *, (Lisp_Object a), (a))
+INLINE struct Lisp_Cons *
+(XCONS) (Lisp_Object a)
+{
+  return lisp_h_XCONS (a);
+}
 
 INLINE struct Lisp_Vector *
 XVECTOR (Lisp_Object a)
@@ -1140,13 +1189,11 @@ make_pointer_integer (void *p)
 
 /* Type checking.  */
 
-LISP_MACRO_DEFUN_VOID (CHECK_TYPE,
-                      (int ok, Lisp_Object predicate, Lisp_Object x),
-                      (ok, predicate, x))
-
-/* Deprecated and will be removed soon.  */
-
-#define INTERNAL_FIELD(field) field ## _
+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.  */
 
@@ -1186,8 +1233,18 @@ xcdr_addr (Lisp_Object c)
 }
 
 /* Use these from normal code.  */
-LISP_MACRO_DEFUN (XCAR, Lisp_Object, (Lisp_Object c), (c))
-LISP_MACRO_DEFUN (XCDR, Lisp_Object, (Lisp_Object c), (c))
+
+INLINE Lisp_Object
+(XCAR) (Lisp_Object c)
+{
+  return lisp_h_XCAR (c);
+}
+
+INLINE Lisp_Object
+(XCDR) (Lisp_Object c)
+{
+  return lisp_h_XCDR (c);
+}
 
 /* Use these to set the fields of a cons cell.
 
@@ -1268,7 +1325,7 @@ STRING_MULTIBYTE (Lisp_Object str)
 /* Mark STR as a unibyte string.  */
 #define STRING_SET_UNIBYTE(STR)                                \
   do {                                                 \
-    if (EQ (STR, empty_multibyte_string))              \
+    if (XSTRING (STR)->size == 0)                      \
       (STR) = empty_unibyte_string;                    \
     else                                               \
       XSTRING (STR)->size_byte = -1;                   \
@@ -1278,7 +1335,7 @@ STRING_MULTIBYTE (Lisp_Object str)
    ASCII characters in advance.  */
 #define STRING_SET_MULTIBYTE(STR)                      \
   do {                                                 \
-    if (EQ (STR, empty_unibyte_string))                        \
+    if (XSTRING (STR)->size == 0)                      \
       (STR) = empty_multibyte_string;                  \
     else                                               \
       XSTRING (STR)->size_byte = XSTRING (STR)->size;  \
@@ -1494,7 +1551,16 @@ aref_addr (Lisp_Object array, ptrdiff_t idx)
 INLINE ptrdiff_t
 ASIZE (Lisp_Object array)
 {
-  return XVECTOR (array)->header.size;
+  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.  */
+  return XVECTOR (array)->header.size & ~ARRAY_MARK_FLAG;
 }
 
 INLINE void
@@ -1509,7 +1575,7 @@ gc_aset (Lisp_Object array, ptrdiff_t idx, Lisp_Object val)
 {
   /* Like ASET, but also can be used in the garbage collector:
      sweep_weak_table calls set_hash_key etc. while the table is marked.  */
-  eassert (0 <= idx && idx < (ASIZE (array) & ~ARRAY_MARK_FLAG));
+  eassert (0 <= idx && idx < gc_asize (array));
   XVECTOR (array)->contents[idx] = val;
 }
 
@@ -1724,7 +1790,11 @@ verify (offsetof (struct Lisp_Sub_Char_Table, contents)
 
 /* Value is name of symbol.  */
 
-LISP_MACRO_DEFUN (SYMBOL_VAL, Lisp_Object, (struct Lisp_Symbol *sym), (sym))
+INLINE Lisp_Object
+(SYMBOL_VAL) (struct Lisp_Symbol *sym)
+{
+  return lisp_h_SYMBOL_VAL (sym);
+}
 
 INLINE struct Lisp_Symbol *
 SYMBOL_ALIAS (struct Lisp_Symbol *sym)
@@ -1745,8 +1815,11 @@ SYMBOL_FWD (struct Lisp_Symbol *sym)
   return sym->val.fwd;
 }
 
-LISP_MACRO_DEFUN_VOID (SET_SYMBOL_VAL,
-                      (struct Lisp_Symbol *sym, Lisp_Object v), (sym, v))
+INLINE void
+(SET_SYMBOL_VAL) (struct Lisp_Symbol *sym, Lisp_Object v)
+{
+  lisp_h_SET_SYMBOL_VAL (sym, v);
+}
 
 INLINE void
 SET_SYMBOL_ALIAS (struct Lisp_Symbol *sym, struct Lisp_Symbol *v)
@@ -1793,7 +1866,11 @@ SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (Lisp_Object sym)
    value cannot be changed (there is an exception for keyword symbols,
    whose value can be set to the keyword symbol itself).  */
 
-LISP_MACRO_DEFUN (SYMBOL_CONSTANT_P, int, (Lisp_Object sym), (sym))
+INLINE int
+(SYMBOL_CONSTANT_P) (Lisp_Object sym)
+{
+  return lisp_h_SYMBOL_CONSTANT_P (sym);
+}
 
 /* Placeholder for make-docfile to process.  The actual symbol
    definition is done by lread.c's defsym.  */
@@ -1880,21 +1957,22 @@ struct Lisp_Hash_Table
 };
 
 
+INLINE bool
+HASH_TABLE_P (Lisp_Object a)
+{
+  return PSEUDOVECTORP (a, PVEC_HASH_TABLE);
+}
+
 INLINE struct Lisp_Hash_Table *
 XHASH_TABLE (Lisp_Object a)
 {
+  eassert (HASH_TABLE_P (a));
   return XUNTAG (a, Lisp_Vectorlike);
 }
 
 #define XSET_HASH_TABLE(VAR, PTR) \
      (XSETPSEUDOVECTOR (VAR, PTR, PVEC_HASH_TABLE))
 
-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.  */
 INLINE Lisp_Object
 HASH_KEY (struct Lisp_Hash_Table *h, ptrdiff_t idx)
@@ -2186,6 +2264,18 @@ XSAVE_OBJECT (Lisp_Object obj, int n)
   return XSAVE_VALUE (obj)->data[n].object;
 }
 
+#ifdef HAVE_MODULES
+struct Lisp_User_Ptr
+{
+  ENUM_BF (Lisp_Misc_Type) type : 16;       /* = Lisp_Misc_User_Ptr */
+  bool_bf gcmarkbit : 1;
+  unsigned spacer : 15;
+
+  void (*finalizer) (void *);
+  void *p;
+};
+#endif
+
 /* A finalizer sentinel.  */
 struct Lisp_Finalizer
   {
@@ -2221,6 +2311,9 @@ union Lisp_Misc
     struct Lisp_Overlay u_overlay;
     struct Lisp_Save_Value u_save_value;
     struct Lisp_Finalizer u_finalizer;
+#ifdef HAVE_MODULES
+    struct Lisp_User_Ptr u_user_ptr;
+#endif
   };
 
 INLINE union Lisp_Misc *
@@ -2270,6 +2363,15 @@ XFINALIZER (Lisp_Object a)
   return & XMISC (a)->u_finalizer;
 }
 
+#ifdef HAVE_MODULES
+INLINE struct Lisp_User_Ptr *
+XUSER_PTR (Lisp_Object a)
+{
+  eassert (USER_PTRP (a));
+  return & XMISC (a)->u_user_ptr;
+}
+#endif
+
 \f
 /* Forwarding pointer to an int variable.
    This is allowed only in the value cell of a symbol,
@@ -2463,7 +2565,11 @@ enum char_bits
 \f
 /* Data type checking.  */
 
-LISP_MACRO_DEFUN (NILP, bool, (Lisp_Object x), (x))
+INLINE bool
+(NILP) (Lisp_Object x)
+{
+  return lisp_h_NILP (x);
+}
 
 INLINE bool
 NUMBERP (Lisp_Object x)
@@ -2487,13 +2593,41 @@ RANGED_INTEGERP (intmax_t lo, Lisp_Object x, intmax_t hi)
    && (TYPE_SIGNED (type) ? TYPE_MINIMUM (type) <= XINT (x) : 0 <= XINT (x)) \
    && XINT (x) <= TYPE_MAXIMUM (type))
 
-LISP_MACRO_DEFUN (CONSP, bool, (Lisp_Object x), (x))
-LISP_MACRO_DEFUN (FLOATP, bool, (Lisp_Object x), (x))
-LISP_MACRO_DEFUN (MISCP, bool, (Lisp_Object x), (x))
-LISP_MACRO_DEFUN (SYMBOLP, bool, (Lisp_Object x), (x))
-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))
+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)
@@ -2522,6 +2656,14 @@ 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)
 {
@@ -2644,9 +2786,23 @@ CHECK_LIST (Lisp_Object x)
   CHECK_TYPE (CONSP (x) || NILP (x), Qlistp, x);
 }
 
-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))
+INLINE void
+(CHECK_LIST_CONS) (Lisp_Object x, Lisp_Object y)
+{
+  lisp_h_CHECK_LIST_CONS (x, y);
+}
+
+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)
@@ -2747,7 +2903,7 @@ XFLOATINT (Lisp_Object n)
 INLINE void
 CHECK_NUMBER_OR_FLOAT (Lisp_Object x)
 {
-  CHECK_TYPE (FLOATP (x) || INTEGERP (x), Qnumberp, x);
+  CHECK_TYPE (NUMBERP (x), Qnumberp, x);
 }
 
 #define CHECK_NUMBER_OR_FLOAT_COERCE_MARKER(x)                         \
@@ -2755,7 +2911,7 @@ CHECK_NUMBER_OR_FLOAT (Lisp_Object x)
     if (MARKERP (x))                                                   \
       XSETFASTINT (x, marker_position (x));                            \
     else                                                               \
-      CHECK_TYPE (INTEGERP (x) || FLOATP (x), Qnumber_or_marker_p, x); \
+      CHECK_TYPE (NUMBERP (x), Qnumber_or_marker_p, x);                        \
   } while (false)
 
 /* Since we can't assign directly to the CAR or CDR fields of a cons
@@ -3014,7 +3170,9 @@ SPECPDL_INDEX (void)
    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.
+   of the catch form.  If there is a handler of type CATCHER_ALL, it will
+   be treated as a handler for all invocations of `throw'; in this case
+   `val' will be set to (TAG . VAL).
 
    All the other members are concerned with restoring the interpreter
    state.
@@ -3022,7 +3180,7 @@ SPECPDL_INDEX (void)
    Members are volatile if their values need to survive _longjmp when
    a 'struct handler' is a local variable.  */
 
-enum handlertype { CATCHER, CONDITION_CASE };
+enum handlertype { CATCHER, CONDITION_CASE, CATCHER_ALL };
 
 struct handler
 {
@@ -3042,9 +3200,6 @@ struct handler
 
   /* Most global vars are reset to their value via the specpdl mechanism,
      but a few others are handled by storing their value here.  */
-#if true /* GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS, but defined later.  */
-  struct gcpro *gcpro;
-#endif
   sys_jmp_buf jmp;
   EMACS_INT lisp_eval_depth;
   ptrdiff_t pdlcount;
@@ -3053,29 +3208,6 @@ struct handler
   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->nextfree)                           \
-    (c) = handlerlist->nextfree;                       \
-  else                                                 \
-    {                                                  \
-      (c) = xmalloc (sizeof (struct handler));         \
-      (c)->nextfree = NULL;                            \
-      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.
@@ -3118,262 +3250,6 @@ extern void process_quit_flag (void);
 extern Lisp_Object Vascii_downcase_table;
 extern Lisp_Object Vascii_canon_table;
 \f
-/* Structure for recording stack slots that need marking.  */
-
-/* This is a chain of structures, each of which points at a Lisp_Object
-   variable whose value should be marked in garbage collection.
-   Normally every link of the chain is an automatic variable of a function,
-   and its `val' points to some argument or local variable of the function.
-   On exit to the function, the chain is set back to the value it had on entry.
-   This way, no link remains in the chain when the stack frame containing the
-   link disappears.
-
-   Every function that can call Feval must protect in this fashion all
-   Lisp_Object variables whose contents will be used again.  */
-
-extern struct gcpro *gcprolist;
-
-struct gcpro
-{
-  struct gcpro *next;
-
-  /* Address of first protected variable.  */
-  volatile Lisp_Object *var;
-
-  /* Number of consecutive protected variables.  */
-  ptrdiff_t nvars;
-
-#ifdef DEBUG_GCPRO
-  /* File name where this record is used.  */
-  const char *name;
-
-  /* Line number in this file.  */
-  int lineno;
-
-  /* Index in the local chain of records.  */
-  int idx;
-
-  /* Nesting level.  */
-  int level;
-#endif
-};
-
-/* Values of GC_MARK_STACK during compilation:
-
-   0   Use GCPRO as before
-   1   Do the real thing, make GCPROs and UNGCPRO no-ops.
-   2    Mark the stack, and check that everything GCPRO'd is
-       marked.
-   3   Mark using GCPRO's, mark stack last, and count how many
-       dead objects are kept alive.
-
-   Formerly, method 0 was used.  Currently, method 1 is used unless
-   otherwise specified by hand when building, e.g.,
-   "make CPPFLAGS='-DGC_MARK_STACK=GC_USE_GCPROS_AS_BEFORE'".
-   Methods 2 and 3 are present mainly to debug the transition from 0 to 1.  */
-
-#define GC_USE_GCPROS_AS_BEFORE                0
-#define GC_MAKE_GCPROS_NOOPS           1
-#define GC_MARK_STACK_CHECK_GCPROS     2
-#define GC_USE_GCPROS_CHECK_ZOMBIES    3
-
-#ifndef GC_MARK_STACK
-#define GC_MARK_STACK GC_MAKE_GCPROS_NOOPS
-#endif
-
-/* Whether we do the stack marking manually.  */
-#define BYTE_MARK_STACK !(GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS                \
-                         || GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS)
-
-
-#if GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS
-
-/* Do something silly with gcproN vars just so gcc shuts up.  */
-/* You get warnings from MIPSPro...  */
-
-#define GCPRO1(varname) ((void) gcpro1)
-#define GCPRO2(varname1, varname2) ((void) gcpro2, (void) gcpro1)
-#define GCPRO3(varname1, varname2, varname3) \
-  ((void) gcpro3, (void) gcpro2, (void) gcpro1)
-#define GCPRO4(varname1, varname2, varname3, varname4) \
-  ((void) gcpro4, (void) gcpro3, (void) gcpro2, (void) gcpro1)
-#define GCPRO5(varname1, varname2, varname3, varname4, varname5) \
-  ((void) gcpro5, (void) gcpro4, (void) gcpro3, (void) gcpro2, (void) gcpro1)
-#define GCPRO6(varname1, varname2, varname3, varname4, varname5, varname6) \
-  ((void) gcpro6, (void) gcpro5, (void) gcpro4, (void) gcpro3, (void) gcpro2, \
-   (void) gcpro1)
-#define GCPRO7(a, b, c, d, e, f, g) (GCPRO6 (a, b, c, d, e, f), (void) gcpro7)
-#define UNGCPRO ((void) 0)
-
-#else /* GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS */
-
-#ifndef DEBUG_GCPRO
-
-#define GCPRO1(a)                                                      \
-  { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1;      \
-    gcprolist = &gcpro1; }
-
-#define GCPRO2(a, b)                                                   \
-  { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1;      \
-    gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1;                \
-    gcprolist = &gcpro2; }
-
-#define GCPRO3(a, b, c)                                                        \
-  { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1;      \
-    gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1;                \
-    gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1;                \
-    gcprolist = &gcpro3; }
-
-#define GCPRO4(a, b, c, d)                                             \
-  { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1;      \
-    gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1;                \
-    gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1;                \
-    gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1;                \
-    gcprolist = &gcpro4; }
-
-#define GCPRO5(a, b, c, d, e)                                          \
-  { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1;      \
-    gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1;                \
-    gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1;                \
-    gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1;                \
-    gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1;                \
-    gcprolist = &gcpro5; }
-
-#define GCPRO6(a, b, c, d, e, f)                                       \
-  { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1;      \
-    gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1;                \
-    gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1;                \
-    gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1;                \
-    gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1;                \
-    gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1;                \
-    gcprolist = &gcpro6; }
-
-#define GCPRO7(a, b, c, d, e, f, g)                                    \
-  { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1;      \
-    gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1;                \
-    gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1;                \
-    gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1;                \
-    gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1;                \
-    gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1;                \
-    gcpro7.next = &gcpro6; gcpro7.var = &(g); gcpro7.nvars = 1;                \
-    gcprolist = &gcpro7; }
-
-#define UNGCPRO (gcprolist = gcpro1.next)
-
-#else /* !DEBUG_GCPRO */
-
-extern int gcpro_level;
-
-#define GCPRO1(a)                                                      \
-  { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1;      \
-    gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1;  \
-    gcpro1.level = gcpro_level++;                                      \
-    gcprolist = &gcpro1; }
-
-#define GCPRO2(a, b)                                                   \
-  { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1;      \
-    gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1;  \
-    gcpro1.level = gcpro_level;                                                \
-    gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1;                \
-    gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2;  \
-    gcpro2.level = gcpro_level++;                                      \
-    gcprolist = &gcpro2; }
-
-#define GCPRO3(a, b, c)                                                        \
-  { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1;      \
-    gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1;  \
-    gcpro1.level = gcpro_level;                                                \
-    gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1;                \
-    gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2;  \
-    gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1;                \
-    gcpro3.name = __FILE__; gcpro3.lineno = __LINE__; gcpro3.idx = 3;  \
-    gcpro3.level = gcpro_level++;                                      \
-    gcprolist = &gcpro3; }
-
-#define GCPRO4(a, b, c, d)                                             \
-  { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1;      \
-    gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1;  \
-    gcpro1.level = gcpro_level;                                                \
-    gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1;                \
-    gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2;  \
-    gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1;                \
-    gcpro3.name = __FILE__; gcpro3.lineno = __LINE__; gcpro3.idx = 3;  \
-    gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1;                \
-    gcpro4.name = __FILE__; gcpro4.lineno = __LINE__; gcpro4.idx = 4;  \
-    gcpro4.level = gcpro_level++;                                      \
-    gcprolist = &gcpro4; }
-
-#define GCPRO5(a, b, c, d, e)                                          \
-  { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1;      \
-    gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1;  \
-    gcpro1.level = gcpro_level;                                                \
-    gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1;                \
-    gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2;  \
-    gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1;                \
-    gcpro3.name = __FILE__; gcpro3.lineno = __LINE__; gcpro3.idx = 3;  \
-    gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1;                \
-    gcpro4.name = __FILE__; gcpro4.lineno = __LINE__; gcpro4.idx = 4;  \
-    gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1;                \
-    gcpro5.name = __FILE__; gcpro5.lineno = __LINE__; gcpro5.idx = 5;  \
-    gcpro5.level = gcpro_level++;                                      \
-    gcprolist = &gcpro5; }
-
-#define GCPRO6(a, b, c, d, e, f)                                       \
-  { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1;      \
-    gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1;  \
-    gcpro1.level = gcpro_level;                                                \
-    gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1;                \
-    gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2;  \
-    gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1;                \
-    gcpro3.name = __FILE__; gcpro3.lineno = __LINE__; gcpro3.idx = 3;  \
-    gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1;                \
-    gcpro4.name = __FILE__; gcpro4.lineno = __LINE__; gcpro4.idx = 4;  \
-    gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1;                \
-    gcpro5.name = __FILE__; gcpro5.lineno = __LINE__; gcpro5.idx = 5;  \
-    gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1;                \
-    gcpro6.name = __FILE__; gcpro6.lineno = __LINE__; gcpro6.idx = 6;  \
-    gcpro6.level = gcpro_level++;                                      \
-    gcprolist = &gcpro6; }
-
-#define GCPRO7(a, b, c, d, e, f, g)                                    \
-  { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1;      \
-    gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1;  \
-    gcpro1.level = gcpro_level;                                                \
-    gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1;                \
-    gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2;  \
-    gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1;                \
-    gcpro3.name = __FILE__; gcpro3.lineno = __LINE__; gcpro3.idx = 3;  \
-    gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1;                \
-    gcpro4.name = __FILE__; gcpro4.lineno = __LINE__; gcpro4.idx = 4;  \
-    gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1;                \
-    gcpro5.name = __FILE__; gcpro5.lineno = __LINE__; gcpro5.idx = 5;  \
-    gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1;                \
-    gcpro6.name = __FILE__; gcpro6.lineno = __LINE__; gcpro6.idx = 6;  \
-    gcpro7.next = &gcpro6; gcpro7.var = &(g); gcpro7.nvars = 1;                \
-    gcpro7.name = __FILE__; gcpro7.lineno = __LINE__; gcpro7.idx = 7;  \
-    gcpro7.level = gcpro_level++;                                      \
-    gcprolist = &gcpro7; }
-
-#define UNGCPRO                                        \
-  (--gcpro_level != gcpro1.level               \
-   ? emacs_abort ()                            \
-   : (void) (gcprolist = gcpro1.next))
-
-#endif /* DEBUG_GCPRO */
-#endif /* GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS */
-
-
-/* Evaluate expr, UNGCPRO, and then return the value of expr.  */
-#define RETURN_UNGCPRO(expr)                   \
-  do                                           \
-    {                                          \
-      Lisp_Object ret_ungc_val;                        \
-      ret_ungc_val = (expr);                   \
-      UNGCPRO;                                 \
-      return ret_ungc_val;                     \
-    }                                          \
-  while (false)
-
 /* Call staticpro (&var) to protect static variable `var'.  */
 
 void staticpro (Lisp_Object *);
@@ -3515,17 +3391,9 @@ extern Lisp_Object arithcompare (Lisp_Object num1, Lisp_Object num2,
 #define INTEGER_TO_CONS(i)                                         \
   (! FIXNUM_OVERFLOW_P (i)                                         \
    ? make_number (i)                                               \
-   : ! ((FIXNUM_OVERFLOW_P (INTMAX_MIN >> 16)                      \
-        || FIXNUM_OVERFLOW_P (UINTMAX_MAX >> 16))                  \
-       && FIXNUM_OVERFLOW_P ((i) >> 16))                           \
-   ? Fcons (make_number ((i) >> 16), make_number ((i) & 0xffff))    \
-   : ! ((FIXNUM_OVERFLOW_P (INTMAX_MIN >> 16 >> 24)                \
-        || FIXNUM_OVERFLOW_P (UINTMAX_MAX >> 16 >> 24))            \
-       && FIXNUM_OVERFLOW_P ((i) >> 16 >> 24))                     \
-   ? Fcons (make_number ((i) >> 16 >> 24),                         \
-           Fcons (make_number ((i) >> 16 & 0xffffff),              \
-                  make_number ((i) & 0xffff)))                     \
-   : make_float (i))
+   : EXPR_SIGNED (i) ? intbig_to_lisp (i) : uintbig_to_lisp (i))
+extern Lisp_Object intbig_to_lisp (intmax_t);
+extern Lisp_Object uintbig_to_lisp (uintmax_t);
 
 /* Convert the Emacs representation CONS back to an integer of type
    TYPE, storing the result the variable VAR.  Signal an error if CONS
@@ -3585,7 +3453,8 @@ Lisp_Object make_hash_table (struct hash_table_test, Lisp_Object, Lisp_Object,
 ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *);
 ptrdiff_t hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object,
                    EMACS_UINT);
-extern struct hash_table_test hashtest_eql, hashtest_equal;
+void hash_remove_from_table (struct Lisp_Hash_Table *, Lisp_Object);
+extern struct hash_table_test hashtest_eq, hashtest_eql, hashtest_equal;
 extern void validate_subarray (Lisp_Object, Lisp_Object, Lisp_Object,
                               ptrdiff_t, ptrdiff_t *, ptrdiff_t *);
 extern Lisp_Object substring_both (Lisp_Object, ptrdiff_t, ptrdiff_t,
@@ -3678,7 +3547,8 @@ extern Lisp_Object sit_for (Lisp_Object, bool, int);
 /* Defined in xdisp.c.  */
 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 add_to_log (char const *, ...);
+extern void vadd_to_log (char const *, va_list);
 extern void check_message_stack (void);
 extern void setup_echo_area_for_printing (bool);
 extern bool push_message (void);
@@ -3887,7 +3757,6 @@ extern void init_alloc (void);
 extern void syms_of_alloc (void);
 extern struct buffer * allocate_buffer (void);
 extern int valid_lisp_object_p (Lisp_Object);
-extern int relocatable_string_data_p (const char *);
 #ifdef GC_CHECK_CONS_LIST
 extern void check_cons_list (void);
 #else
@@ -3923,7 +3792,7 @@ extern Lisp_Object Vprin1_to_string_buffer;
 extern void debug_print (Lisp_Object) EXTERNALLY_VISIBLE;
 extern void temp_output_buffer_setup (const char *);
 extern int print_level;
-extern void write_string (const char *, int);
+extern void write_string (const char *);
 extern void print_error_message (Lisp_Object, Lisp_Object, const char *,
                                 Lisp_Object);
 extern Lisp_Object internal_with_output_to_temp_buffer
@@ -3981,7 +3850,6 @@ intern_c_string (const char *str)
 }
 
 /* Defined in eval.c.  */
-extern EMACS_INT lisp_eval_depth;
 extern Lisp_Object Vautoload_queue;
 extern Lisp_Object Vrun_hooks;
 extern Lisp_Object Vsignaling_function;
@@ -4025,6 +3893,8 @@ extern Lisp_Object internal_condition_case_2 (Lisp_Object (*) (Lisp_Object, Lisp
 extern Lisp_Object internal_condition_case_n
     (Lisp_Object (*) (ptrdiff_t, Lisp_Object *), ptrdiff_t, Lisp_Object *,
      Lisp_Object, Lisp_Object (*) (Lisp_Object, ptrdiff_t, Lisp_Object *));
+extern struct handler *push_handler (Lisp_Object, enum handlertype);
+extern struct handler *push_handler_nosignal (Lisp_Object, enum handlertype);
 extern void specbind (Lisp_Object, Lisp_Object);
 extern void record_unwind_protect (void (*) (Lisp_Object), Lisp_Object);
 extern void record_unwind_protect_ptr (void (*) (void *), void *);
@@ -4040,6 +3910,7 @@ extern _Noreturn void verror (const char *, va_list)
   ATTRIBUTE_FORMAT_PRINTF (1, 0);
 extern void un_autoload (Lisp_Object);
 extern Lisp_Object call_debugger (Lisp_Object arg);
+extern void *near_C_stack_top (void);
 extern void init_eval_once (void);
 extern Lisp_Object safe_call (ptrdiff_t, Lisp_Object, ...);
 extern Lisp_Object safe_call1 (Lisp_Object, Lisp_Object);
@@ -4054,10 +3925,17 @@ Lisp_Object backtrace_top_function (void);
 extern bool let_shadows_buffer_binding_p (struct Lisp_Symbol *symbol);
 extern bool let_shadows_global_binding_p (Lisp_Object symbol);
 
+#ifdef HAVE_MODULES
+/* Defined in alloc.c.  */
+extern Lisp_Object make_user_ptr (void (*finalizer) (void *), void *p);
+
+/* Defined in emacs-module.c.  */
+extern void module_init (void);
+extern void syms_of_module (void);
+#endif
 
 /* Defined in editfns.c.  */
 extern void insert1 (Lisp_Object);
-extern Lisp_Object format2 (const char *, Lisp_Object, Lisp_Object);
 extern Lisp_Object save_excursion_save (void);
 extern Lisp_Object save_restriction_save (void);
 extern void save_excursion_restore (Lisp_Object);
@@ -4066,7 +3944,7 @@ extern _Noreturn void time_overflow (void);
 extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, bool);
 extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t,
                                            ptrdiff_t, bool);
-extern void init_editfns (void);
+extern void init_editfns (bool);
 extern void syms_of_editfns (void);
 
 /* Defined in buffer.c.  */
@@ -4111,6 +3989,7 @@ extern void fclose_unwind (void *);
 extern void restore_point_unwind (Lisp_Object);
 extern _Noreturn void report_file_errno (const char *, Lisp_Object, int);
 extern _Noreturn void report_file_error (const char *, Lisp_Object);
+extern _Noreturn void report_file_notify_error (const char *, Lisp_Object);
 extern bool internal_delete_file (Lisp_Object);
 extern Lisp_Object emacs_readlinkat (int, const char *);
 extern bool file_directory_p (const char *);
@@ -4185,7 +4064,6 @@ extern void syms_of_casetab (void);
 extern Lisp_Object echo_message_buffer;
 extern struct kboard *echo_kboard;
 extern void cancel_echoing (void);
-extern Lisp_Object last_undo_boundary;
 extern bool input_pending;
 #ifdef HAVE_STACK_OVERFLOW_HANDLING
 extern sigjmp_buf return_to_command_loop;
@@ -4310,6 +4188,18 @@ extern void set_initial_environment (void);
 extern void syms_of_callproc (void);
 
 /* Defined in doc.c.  */
+enum text_quoting_style
+  {
+    /* Use curved single quotes ‘like this’.  */
+    CURVE_QUOTING_STYLE,
+
+    /* Use grave accent and apostrophe  `like this'.  */
+    GRAVE_QUOTING_STYLE,
+
+    /* Use apostrophes 'like this'.  */
+    STRAIGHT_QUOTING_STYLE
+  };
+extern enum text_quoting_style text_quoting_style (void);
 extern Lisp_Object read_doc_string (Lisp_Object);
 extern Lisp_Object get_doc_string (Lisp_Object, bool, bool);
 extern void syms_of_doc (void);
@@ -4318,10 +4208,7 @@ extern int read_bytecode_char (bool);
 /* Defined in bytecode.c.  */
 extern void syms_of_bytecode (void);
 extern struct byte_stack *byte_stack_list;
-#if BYTE_MARK_STACK
-extern void mark_byte_stack (void);
-#endif
-extern void unmark_byte_stack (void);
+extern void relocate_byte_stack (void);
 extern Lisp_Object exec_byte_code (Lisp_Object, Lisp_Object, Lisp_Object,
                                   Lisp_Object, ptrdiff_t, Lisp_Object *);
 
@@ -4426,17 +4313,23 @@ extern void init_font (void);
 extern void syms_of_fontset (void);
 #endif
 
+/* Defined in inotify.c */
+#ifdef HAVE_INOTIFY
+extern void syms_of_inotify (void);
+#endif
+
+/* Defined in kqueue.c */
+#ifdef HAVE_KQUEUE
+extern void globals_of_kqueue (void);
+extern void syms_of_kqueue (void);
+#endif
+
 /* Defined in gfilenotify.c */
 #ifdef HAVE_GFILENOTIFY
 extern void globals_of_gfilenotify (void);
 extern void syms_of_gfilenotify (void);
 #endif
 
-/* Defined in inotify.c */
-#ifdef HAVE_INOTIFY
-extern void syms_of_inotify (void);
-#endif
-
 #ifdef HAVE_W32NOTIFY
 /* Defined on w32notify.c.  */
 extern void syms_of_w32notify (void);
@@ -4607,39 +4500,24 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
     }                                  \
   } while (false)
 
-
-/* Return floor (NBYTES / WORD_SIZE).  */
-
-INLINE ptrdiff_t
-lisp_word_count (ptrdiff_t nbytes)
-{
-  if (-1 >> 1 == -1)
-    switch (word_size)
-      {
-      case 2: return nbytes >> 1;
-      case 4: return nbytes >> 2;
-      case 8: return nbytes >> 3;
-      case 16: return nbytes >> 4;
-      }
-  return nbytes / word_size - (nbytes % word_size < 0);
-}
-
 /* SAFE_ALLOCA_LISP allocates an array of Lisp_Objects.  */
 
 #define SAFE_ALLOCA_LISP(buf, nelt)                           \
   do {                                                        \
-    if ((nelt) <= lisp_word_count (sa_avail))                 \
-      (buf) = AVAIL_ALLOCA ((nelt) * word_size);              \
-    else if ((nelt) <= min (PTRDIFF_MAX, SIZE_MAX) / word_size) \
+    ptrdiff_t alloca_nbytes;                                  \
+    if (INT_MULTIPLY_WRAPV (nelt, word_size, &alloca_nbytes)   \
+       || SIZE_MAX < alloca_nbytes)                           \
+      memory_full (SIZE_MAX);                                 \
+    else if (alloca_nbytes <= sa_avail)                               \
+      (buf) = AVAIL_ALLOCA (alloca_nbytes);                   \
+    else                                                      \
       {                                                               \
        Lisp_Object arg_;                                      \
-       (buf) = xmalloc ((nelt) * word_size);                  \
+       (buf) = xmalloc (alloca_nbytes);                       \
        arg_ = make_save_memory (buf, nelt);                   \
        sa_must_free = true;                                   \
        record_unwind_protect (free_save_value, arg_);         \
       }                                                               \
-    else                                                      \
-      memory_full (SIZE_MAX);                                 \
   } while (false)
 
 
@@ -4656,13 +4534,6 @@ lisp_word_count (ptrdiff_t nbytes)
 # define USE_STACK_LISP_OBJECTS true
 #endif
 
-/* USE_STACK_LISP_OBJECTS requires GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS.  */
-
-#if GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS
-# undef USE_STACK_LISP_OBJECTS
-# define USE_STACK_LISP_OBJECTS false
-#endif
-
 #ifdef GC_CHECK_STRING_BYTES
 enum { defined_GC_CHECK_STRING_BYTES = true };
 #else