]> code.delx.au - gnu-emacs/blobdiff - src/lisp.h
[USE_LSB_TAG && !DECL_ALIGN]: Signal an error.
[gnu-emacs] / src / lisp.h
index eb3502bd1451336540c356d89abc9cc216ab6f71..917634525d7b1105c04874eec8b850d46b42de65 100644 (file)
@@ -1,5 +1,5 @@
 /* Fundamental definitions for GNU Emacs Lisp interpreter.
-   Copyright (C) 1985,86,87,93,94,95,97,98,1999,2000, 2001, 2002, 2003
+   Copyright (C) 1985,86,87,93,94,95,97,98,1999,2000,01,02,03,2004
      Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -19,6 +19,9 @@ along with GNU Emacs; see the file COPYING.  If not, write to
 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
+#ifndef EMACS_LISP_H
+#define EMACS_LISP_H
+
 /* Declare the prototype for a general external function.  */
 #if defined (PROTOTYPES) || defined (WINDOWSNT)
 #define P_(proto) proto
@@ -32,7 +35,7 @@ Boston, MA 02111-1307, USA.  */
    be compared to the sizes recorded in Lisp strings.  */
 
 #define GC_CHECK_STRING_BYTES 1
-#endif /* 0*/
+#endif /* 0 */
 
 
 /* These are default choices for the types to use.  */
@@ -64,10 +67,6 @@ extern void die P_((const char *, const char *, int));
                           ? (void) 0                           \
                           : die ((msg), __FILE__, __LINE__)),  \
                          0)
-
-/* Let's get some compile-time checking too.  */
-#undef NO_UNION_TYPE
-
 #else
 
 /* Produce same side effects and result, but don't complain.  */
@@ -154,15 +153,15 @@ enum Lisp_Misc_Type
     Lisp_Misc_Limit
   };
 
-/* These values are overridden by the m- file on some machines.  */
-#ifndef VALBITS
-#define VALBITS (BITS_PER_EMACS_INT - 4)
-#endif
-
 #ifndef GCTYPEBITS
 #define GCTYPEBITS 3
 #endif
 
+/* These values are overridden by the m- file on some machines.  */
+#ifndef VALBITS
+#define VALBITS (BITS_PER_EMACS_INT - GCTYPEBITS)
+#endif
+
 #ifndef NO_UNION_TYPE
 
 #ifndef WORDS_BIG_ENDIAN
@@ -179,20 +178,17 @@ union Lisp_Object
     struct
       {
        EMACS_INT val  : VALBITS;
-       EMACS_INT type : GCTYPEBITS + 1;
+       EMACS_UINT type : GCTYPEBITS;
       } s;
     struct
       {
        EMACS_UINT val : VALBITS;
-       EMACS_INT type : GCTYPEBITS + 1;
+       EMACS_UINT type : GCTYPEBITS;
       } u;
     struct
       {
        EMACS_UINT val          : VALBITS;
        enum Lisp_Type type     : GCTYPEBITS;
-       /* The markbit is not really part of the value of a Lisp_Object,
-          and is always zero except during garbage collection.  */
-       EMACS_UINT markbit      : 1;
       } gu;
   }
 Lisp_Object;
@@ -208,19 +204,16 @@ union Lisp_Object
 
     struct
       {
-       EMACS_INT type : GCTYPEBITS+1;
+       EMACS_UINT type : GCTYPEBITS;
        EMACS_INT val  : VALBITS;
       } s;
     struct
       {
-       EMACS_INT type : GCTYPEBITS+1;
+       EMACS_UINT type : GCTYPEBITS;
        EMACS_UINT val : VALBITS;
       } u;
     struct
       {
-       /* The markbit is not really part of the value of a Lisp_Object,
-          and is always zero except during garbage collection.  */
-       EMACS_UINT markbit      : 1;
        enum Lisp_Type type     : GCTYPEBITS;
        EMACS_UINT val          : VALBITS;
       } gu;
@@ -253,32 +246,13 @@ LISP_MAKE_RVALUE (Lisp_Object o)
 #define LISP_MAKE_RVALUE(o) (0+(o))
 #endif /* NO_UNION_TYPE */
 
-#ifndef VALMASK
-#define VALMASK ((((EMACS_INT) 1)<<VALBITS) - 1)
-#endif
-#define GCTYPEMASK ((((EMACS_INT) 1)<<GCTYPEBITS) - 1)
-
 /* Two flags that are set during GC.  On some machines, these flags
    are defined differently by the m- file.  */
 
-/* This is set in the car of a cons and in the plist slot of a symbol
-   to indicate it is marked.  Likewise in the plist slot of an interval,
-   the chain slot of a marker, the type slot of a float, and the name
-   slot of a buffer.
-
-   In strings, this bit in the size field indicates that the string
-   is a "large" one, one which was separately malloc'd
-   rather than being part of a string block.  */
-
-#ifndef MARKBIT
-#define MARKBIT ((EMACS_INT) ((EMACS_UINT) 1 << (VALBITS + GCTYPEBITS)))
-#endif /*MARKBIT */
-
-/* In the size word of a vector, this bit means the vector has been marked.
-   In the size word of a large string, likewise.  */
+/* In the size word of a vector, this bit means the vector has been marked.  */
 
 #ifndef ARRAY_MARK_FLAG
-#define ARRAY_MARK_FLAG ((MARKBIT >> 1) & ~MARKBIT)
+#define ARRAY_MARK_FLAG ((EMACS_INT) ((EMACS_UINT) 1 << (VALBITS + GCTYPEBITS - 1)))
 #endif /* no ARRAY_MARK_FLAG */
 
 /* In the size word of a struct Lisp_Vector, this bit means it's really
@@ -314,6 +288,28 @@ enum pvec_type
 
 /* For convenience, we also store the number of elements in these bits.  */
 #define PSEUDOVECTOR_SIZE_MASK 0x1ff
+\f
+/***** Select the tagging scheme.  *****/
+
+/* First, try and define DECL_ALIGN(type,var) which declares a static
+   variable VAR of type TYPE with the added requirement that it be
+   TYPEBITS-aligned. */
+#if defined USE_LSB_TAG && !defined DECL_ALIGN
+/* What compiler directive should we use for non-gcc compilers?  -stef  */
+# if defined (__GNUC__)
+#  define DECL_ALIGN(type, var) \
+    type __attribute__ ((__aligned__ (1 << GCTYPEBITS))) var
+# else
+#  error "USE_LSB_TAG used without defining DECL_ALIGN"
+# endif
+#endif
+
+#ifndef USE_LSB_TAG
+/* Just remove the alignment annotation if we don't use it.  */
+#undef DECL_ALIGN
+#define DECL_ALIGN(type, var) type var
+#endif
+
 \f
 /* These macros extract various sorts of values from a Lisp_Object.
  For example, if tem is a Lisp_Object whose type is Lisp_Cons,
@@ -321,32 +317,46 @@ enum pvec_type
 
 #ifdef NO_UNION_TYPE
 
+#ifdef USE_LSB_TAG
+
+#define TYPEMASK ((((EMACS_INT) 1) << GCTYPEBITS) - 1)
+#define XTYPE(a) ((enum Lisp_Type) (((EMACS_UINT) (a)) & TYPEMASK))
+#define XINT(a) (((EMACS_INT) (a)) >> GCTYPEBITS)
+#define XUINT(a) (((EMACS_UINT) (a)) >> GCTYPEBITS)
+#define XSET(var, type, ptr)                                   \
+    (eassert (XTYPE (ptr) == 0), /* Check alignment.  */       \
+     (var) = ((EMACS_INT) (type)) | ((EMACS_INT) (ptr)))
+#define make_number(N) (((EMACS_INT) (N)) << GCTYPEBITS)
+
+/* XFASTINT and XSETFASTINT are for use when the integer is known to be
+   positive, in which case the implementation can sometimes be faster
+   depending on the tagging scheme.  With USE_LSB_TAG, there's no benefit.  */
+#define XFASTINT(a) XINT (a)
+#define XSETFASTINT(a, b) ((a) = make_number (b))
+
+#define XPNTR(a) ((EMACS_INT) ((a) & ~TYPEMASK))
+
+#else  /* not USE_LSB_TAG */
+
+#define VALMASK ((((EMACS_INT) 1) << VALBITS) - 1)
+
 /* One need to override this if there must be high bits set in data space
    (doing the result of the below & ((1 << (GCTYPE + 1)) - 1) would work
     on all machines, but would penalize machines which don't need it)
  */
-#ifndef XTYPE
-#define XTYPE(a) ((enum Lisp_Type) ((a) >> VALBITS))
-#endif
-
-#ifndef XSETTYPE
-#define XSETTYPE(a, b) ((a)  =  XUINT (a) | ((EMACS_INT)(b) << VALBITS))
-#endif
+#define XTYPE(a) ((enum Lisp_Type) (((EMACS_UINT) (a)) >> VALBITS))
 
 /* For integers known to be positive, XFASTINT provides fast retrieval
    and XSETFASTINT provides fast storage.  This takes advantage of the
-   fact that Lisp_Int is 0.
-   Beware: XFASTINT applied to a non-positive integer or to something
-   else than an integer should return something that preserves all the
-   info that was in the Lisp_Object, because it is used in EQ.  */
+   fact that Lisp_Int is 0.  */
 #define XFASTINT(a) ((a) + 0)
 #define XSETFASTINT(a, b) ((a) = (b))
 
 /* Extract the value of a Lisp_Object as a signed integer.  */
 
 #ifndef XINT   /* Some machines need to do this differently.  */
-#define XINT(a) ((EMACS_INT) (((a) << (BITS_PER_EMACS_INT - VALBITS)) \
-                             >> (BITS_PER_EMACS_INT - VALBITS)))
+#define XINT(a) ((((EMACS_INT) (a)) << (BITS_PER_EMACS_INT - VALBITS)) \
+                >> (BITS_PER_EMACS_INT - VALBITS))
 #endif
 
 /* Extract the value as an unsigned integer.  This is a basis
@@ -366,45 +376,13 @@ enum pvec_type
 #define make_number(N)         \
   ((((EMACS_INT) (N)) & VALMASK) | ((EMACS_INT) Lisp_Int) << VALBITS)
 
-/* During garbage collection, XGCTYPE must be used for extracting types
- so that the mark bit is ignored.  XMARKBIT accesses the markbit.
- Markbits are used only in particular slots of particular structure types.
- Other markbits are always zero.
- Outside of garbage collection, all mark bits are always zero.  */
-
-#ifndef XGCTYPE
-#define XGCTYPE(a) ((enum Lisp_Type) (((a) >> VALBITS) & GCTYPEMASK))
-#endif
-
-#if VALBITS + GCTYPEBITS == BITS_PER_EMACS_INT - 1
-/* Make XMARKBIT faster if mark bit is sign bit.  */
-#ifndef XMARKBIT
-#define XMARKBIT(a) ((a) < 0)
-#endif
-#endif /* markbit is sign bit */
-
-#ifndef XMARKBIT
-#define XMARKBIT(a) ((a) & MARKBIT)
-#endif
-
-#ifndef XSETMARKBIT
-#define XSETMARKBIT(a,b) ((a) = ((a) & ~MARKBIT) | ((b) ? MARKBIT : 0))
-#endif
-
-#ifndef XMARK
-#define XMARK(a) ((a) |= MARKBIT)
-#endif
-
-#ifndef XUNMARK
-#define XUNMARK(a) ((a) &= ~MARKBIT)
-#endif
+#endif /* not USE_LSB_TAG */
 
-#endif /* NO_UNION_TYPE */
+#define EQ(x, y) ((x) == (y))
 
-#ifndef NO_UNION_TYPE
+#else /* not NO_UNION_TYPE */
 
 #define XTYPE(a) ((enum Lisp_Type) (a).u.type)
-#define XSETTYPE(a, b) ((a).u.type = (char) (b))
 
 /* For integers known to be positive, XFASTINT provides fast retrieval
    and XSETFASTINT provides fast storage.  This takes advantage of the
@@ -432,19 +410,20 @@ enum pvec_type
 extern Lisp_Object make_number ();
 #endif
 
+#define EQ(x, y) ((x).s.val == (y).s.val)
+
+#endif /* NO_UNION_TYPE */
+
 /* During garbage collection, XGCTYPE must be used for extracting types
- so that the mark bit is ignored.  XMARKBIT access the markbit.
+ so that the mark bit is ignored.  XMARKBIT accesses the markbit.
  Markbits are used only in particular slots of particular structure types.
  Other markbits are always zero.
  Outside of garbage collection, all mark bits are always zero.  */
 
-#define XGCTYPE(a) ((a).gu.type)
-#define XMARKBIT(a) ((a).gu.markbit)
-#define XSETMARKBIT(a,b) (XMARKBIT(a) = (b))
-#define XMARK(a) (XMARKBIT(a) = 1)
-#define XUNMARK(a) (XMARKBIT(a) = 0)
-
-#endif /* NO_UNION_TYPE */
+#ifndef XGCTYPE
+/* The distinction does not exist now that the MARKBIT has been eliminated.  */
+#define XGCTYPE(a) XTYPE (a)
+#endif
 
 #ifndef XPNTR
 #ifdef HAVE_SHM
@@ -471,6 +450,9 @@ extern size_t pure_size;
 
 #define MOST_NEGATIVE_FIXNUM   - ((EMACS_INT) 1 << (VALBITS - 1))
 #define MOST_POSITIVE_FIXNUM   (((EMACS_INT) 1 << (VALBITS - 1)) - 1)
+/* Mask indicating the significant bits of a Lisp_Int.
+   I.e. (x & INTMASK) == XUINT (make_number (x)).  */
+#define INTMASK ((((EMACS_INT) 1) << VALBITS) - 1)
 
 /* Value is non-zero if C integer I doesn't fit into a Lisp fixnum.  */
 
@@ -511,7 +493,7 @@ extern size_t pure_size;
 
 /* Construct a Lisp_Object from a value or address.  */
 
-#define XSETINT(a, b) XSET (a, Lisp_Int, b)
+#define XSETINT(a, b) (a) = make_number (b)
 #define XSETCONS(a, b) XSET (a, Lisp_Cons, b)
 #define XSETVECTOR(a, b) XSET (a, Lisp_Vectorlike, b)
 #define XSETSTRING(a, b) XSET (a, Lisp_String, b)
@@ -558,55 +540,7 @@ extern size_t pure_size;
     bcopy (new, XSTRING (string)->data + index, count)
 
 \f
-/* Basic data type for use of intervals.  See the macros in intervals.h.  */
-
-struct interval
-{
-  /* The first group of entries deal with the tree structure.  */
-
-  unsigned int total_length;   /* Length of myself and both children.  */
-  unsigned int position;       /* Cache of interval's character position.  */
-                               /* This field is usually updated
-                                  simultaneously with an interval
-                                  traversal, there is no guarantee
-                                  that it is valid for a random
-                                  interval.  */
-  struct interval *left;       /* Intervals which precede me.  */
-  struct interval *right;      /* Intervals which succeed me.  */
-
-  /* Parent in the tree, or the Lisp_Object containing this interval tree.
-
-     The mark bit on the root interval of an interval tree says
-     whether we have started (and possibly finished) marking the
-     tree.  If GC comes across an interval tree whose root's parent
-     field has its markbit set, it leaves the tree alone.
-
-     You'd think we could store this information in the parent object
-     somewhere (after all, that should be visited once and then
-     ignored too, right?), but strings are GC'd strangely.  */
-  union
-  {
-    struct interval *interval;
-    Lisp_Object obj;
-  } up;
-  unsigned int up_obj : 1;
-
-  /* The remaining components are `properties' of the interval.
-     The first four are duplicates for things which can be on the list,
-     for purposes of speed.  */
-
-  unsigned int write_protect : 1;   /* Non-zero means can't modify.  */
-  unsigned int visible : 1;        /* Zero means don't display.  */
-  unsigned int front_sticky : 1;    /* Non-zero means text inserted just
-                                      before this interval goes into it.  */
-  unsigned int rear_sticky : 1;            /* Likewise for just after it.  */
-
-  /* Properties of this interval.
-     The mark bit on this field says whether this particular interval
-     tree node has been visited.  Since intervals should never be
-     shared, GC aborts if it seems to have visited an interval twice.  */
-  Lisp_Object plist;
-};
+/* See the macros in intervals.h.  */
 
 typedef struct interval *INTERVAL;
 
@@ -879,6 +813,8 @@ enum symbol_interned
 
 struct Lisp_Symbol
 {
+  unsigned gcmarkbit : 1;
+
   /* Non-zero means symbol serves as a variable alias.  The symbol
      holding the real value is found in the value slot.  */
   unsigned indirect_variable : 1;
@@ -1084,19 +1020,11 @@ struct Lisp_Hash_Table
 \f
 /* These structures are used for various misc types.  */
 
-/* A miscellaneous object, when it's on the free list.  */
-struct Lisp_Free
-  {
-    int type : 16;     /* = Lisp_Misc_Free */
-    int spacer : 16;
-    union Lisp_Misc *chain;
-  };
-
-/* In a marker, the markbit of the chain field is used as the gc mark bit.  */
 struct Lisp_Marker
 {
   int type : 16;               /* = Lisp_Misc_Marker */
-  int spacer : 15;
+  unsigned gcmarkbit : 1;
+  int spacer : 14;
   /* 1 means normal insertion at the marker's position
      leaves the marker after the inserted text.  */
   unsigned int insertion_type : 1;
@@ -1109,11 +1037,11 @@ struct Lisp_Marker
 
   /* For markers that point somewhere,
      this is used to chain of all the markers in a given buffer.  */
-  Lisp_Object chain;
+  struct Lisp_Marker *next;
   /* This is the char position where the marker points.  */
-  int charpos;
+  EMACS_INT charpos;
   /* This is the byte position.  */
-  int bytepos;
+  EMACS_INT bytepos;
 };
 
 /* Forwarding pointer to an int variable.
@@ -1123,7 +1051,8 @@ struct Lisp_Marker
 struct Lisp_Intfwd
   {
     int type : 16;     /* = Lisp_Misc_Intfwd */
-    int spacer : 16;
+    unsigned gcmarkbit : 1;
+    int spacer : 15;
     EMACS_INT *intvar;
   };
 
@@ -1134,7 +1063,8 @@ struct Lisp_Intfwd
 struct Lisp_Boolfwd
   {
     int type : 16;     /* = Lisp_Misc_Boolfwd */
-    int spacer : 16;
+    unsigned gcmarkbit : 1;
+    int spacer : 15;
     int *boolvar;
   };
 
@@ -1145,7 +1075,8 @@ struct Lisp_Boolfwd
 struct Lisp_Objfwd
   {
     int type : 16;     /* = Lisp_Misc_Objfwd */
-    int spacer : 16;
+    unsigned gcmarkbit : 1;
+    int spacer : 15;
     Lisp_Object *objvar;
   };
 
@@ -1154,7 +1085,8 @@ struct Lisp_Objfwd
 struct Lisp_Buffer_Objfwd
   {
     int type : 16;     /* = Lisp_Misc_Buffer_Objfwd */
-    int spacer : 16;
+    unsigned gcmarkbit : 1;
+    int spacer : 15;
     int offset;
   };
 
@@ -1188,7 +1120,8 @@ struct Lisp_Buffer_Local_Value
   {
     int type : 16;      /* = Lisp_Misc_Buffer_Local_Value
                           or Lisp_Misc_Some_Buffer_Local_Value */
-    int spacer : 13;
+    unsigned gcmarkbit : 1;
+    int spacer : 12;
 
     /* 1 means this variable is allowed to have frame-local bindings,
        so check for them when looking for the proper binding.  */
@@ -1218,13 +1151,14 @@ struct Lisp_Buffer_Local_Value
     Lisp_Object cdr;
   };
 
-/* In an overlay object, the mark bit of the plist is used as the GC mark.
-   START and END are markers in the overlay's buffer, and
+/* START and END are markers in the overlay's buffer, and
    PLIST is the overlay's property list.  */
 struct Lisp_Overlay
   {
     int type : 16;     /* = Lisp_Misc_Overlay */
-    int spacer : 16;
+    unsigned gcmarkbit : 1;
+    int spacer : 15;
+    struct Lisp_Overlay *next;
     Lisp_Object start, end, plist;
   };
 
@@ -1233,7 +1167,8 @@ struct Lisp_Overlay
 struct Lisp_Kboard_Objfwd
   {
     int type : 16;     /* = Lisp_Misc_Kboard_Objfwd */
-    int spacer : 16;
+    unsigned gcmarkbit : 1;
+    int spacer : 15;
     int offset;
   };
 
@@ -1242,12 +1177,29 @@ struct Lisp_Kboard_Objfwd
 struct Lisp_Save_Value
   {
     int type : 16;     /* = Lisp_Misc_Save_Value */
-    int spacer : 16;
+    unsigned gcmarkbit : 1;
+    int spacer : 15;
     void *pointer;
     int integer;
   };
 
 
+/* A miscellaneous object, when it's on the free list.  */
+struct Lisp_Free
+  {
+    int type : 16;     /* = Lisp_Misc_Free */
+    unsigned gcmarkbit : 1;
+    int spacer : 15;
+    union Lisp_Misc *chain;
+#ifdef USE_LSB_TAG
+    /* Try to make sure that sizeof(Lisp_Misc) preserves TYPEBITS-alignment.
+       This assumes that Lisp_Marker is the largest of the alternatives and
+       that Lisp_Intfwd has the same size as "Lisp_Free w/o padding".  */
+    char padding[((((sizeof (struct Lisp_Marker) - 1) >> GCTYPEBITS) + 1)
+                 << GCTYPEBITS) - sizeof (struct Lisp_Intfwd)];
+#endif
+  };
+
 /* To get the type field of a union Lisp_Misc, use XMISCTYPE.
    It uses one of these struct subtypes to get the type field.  */
 
@@ -1268,8 +1220,6 @@ union Lisp_Misc
 /* Lisp floating point type */
 struct Lisp_Float
   {
-    Lisp_Object type;          /* essentially used for mark-bit
-                                  and chaining when on free-list */
 #ifdef HIDE_LISP_IMPLEMENTATION
     double data_;
 #else
@@ -1409,7 +1359,7 @@ typedef unsigned char UCHAR;
 #define GC_NATNUMP(x) (GC_INTEGERP (x) && XINT (x) >= 0)
 
 #define INTEGERP(x) (XTYPE ((x)) == Lisp_Int)
-#define GC_INTEGERP(x) (XGCTYPE ((x)) == Lisp_Int)
+#define GC_INTEGERP(x) INTEGERP (x)
 #define SYMBOLP(x) (XTYPE ((x)) == Lisp_Symbol)
 #define GC_SYMBOLP(x) (XGCTYPE ((x)) == Lisp_Symbol)
 #define MISCP(x) (XTYPE ((x)) == Lisp_Misc)
@@ -1479,9 +1429,12 @@ typedef unsigned char UCHAR;
 #define GC_FRAMEP(x) GC_PSEUDOVECTORP (x, PVEC_FRAME)
 
 #define SUB_CHAR_TABLE_P(x) (CHAR_TABLE_P (x) && NILP (XCHAR_TABLE (x)->top))
+
+/* Test for image (image . spec)  */
+#define IMAGEP(x) (CONSP (x) && EQ (XCAR (x), Qimage))
+
 \f
-#define EQ(x, y) (XFASTINT (x) == XFASTINT (y))
-#define GC_EQ(x, y) (XGCTYPE (x) == XGCTYPE (y) && XPNTR (x) == XPNTR (y))
+#define GC_EQ(x, y) EQ (x, y)
 
 #define CHECK_LIST(x) \
   do { if (!CONSP ((x)) && !NILP (x)) x = wrong_type_argument (Qlistp, (x)); } while (0)
@@ -1612,7 +1565,7 @@ typedef unsigned char UCHAR;
 
 #define DEFUN(lname, fnname, sname, minargs, maxargs, prompt, doc)     \
   Lisp_Object fnname ();                                               \
-  struct Lisp_Subr sname =                                             \
+  DECL_ALIGN (struct Lisp_Subr, sname) =                               \
     { PVEC_SUBR | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)),    \
       fnname, minargs, maxargs, lname, prompt, 0};                     \
   Lisp_Object fnname
@@ -1623,7 +1576,7 @@ typedef unsigned char UCHAR;
    arguments, so we can catch errors with maxargs at compile-time.  */
 #define DEFUN(lname, fnname, sname, minargs, maxargs, prompt, doc)     \
   Lisp_Object fnname DEFUN_ARGS_ ## maxargs ;                          \
-  struct Lisp_Subr sname =                                             \
+  DECL_ALIGN (struct Lisp_Subr, sname) =                               \
     { PVEC_SUBR | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)),    \
       fnname, minargs, maxargs, lname, prompt, 0};                     \
   Lisp_Object fnname
@@ -1770,6 +1723,9 @@ extern char *stack_bottom;
    This is a good thing to do around a loop that has no side effects
    and (in particular) cannot call arbitrary Lisp code.  */
 
+#ifdef SYNC_INPUT
+extern void handle_async_input P_ ((void));
+extern int interrupt_input_pending;
 #define QUIT                                           \
   do {                                                 \
     if (!NILP (Vquit_flag) && NILP (Vinhibit_quit))    \
@@ -1777,8 +1733,24 @@ extern char *stack_bottom;
        Vquit_flag = Qnil;                              \
        Fsignal (Qquit, Qnil);                          \
       }                                                        \
+    else if (interrupt_input_pending)                  \
+      handle_async_input ();                           \
   } while (0)
 
+#else  /* not SYNC_INPUT */
+
+#define QUIT                                           \
+  do {                                                 \
+    if (!NILP (Vquit_flag) && NILP (Vinhibit_quit))    \
+      {                                                        \
+       Vquit_flag = Qnil;                              \
+       Fsignal (Qquit, Qnil);                          \
+      }                                                        \
+  } while (0)
+
+#endif /* not SYNC_INPUT */
+
+
 /* Nonzero if ought to quit now.  */
 
 #define QUITP (!NILP (Vquit_flag) && NILP (Vinhibit_quit))
@@ -2050,29 +2022,32 @@ extern Lisp_Object Qerror, Qquit, Qwrong_type_argument, Qargs_out_of_range;
 extern Lisp_Object Qvoid_variable, Qvoid_function;
 extern Lisp_Object Qsetting_constant, Qinvalid_read_syntax;
 extern Lisp_Object Qinvalid_function, Qwrong_number_of_arguments, Qno_catch;
-extern Lisp_Object Qend_of_file, Qarith_error;
+extern Lisp_Object Qend_of_file, Qarith_error, Qmark_inactive;
 extern Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only;
-extern Lisp_Object Qmark_inactive, Qtext_read_only;
-
-extern Lisp_Object Qrange_error, Qdomain_error, Qsingularity_error;
-extern Lisp_Object Qoverflow_error, Qunderflow_error;
+extern Lisp_Object Qtext_read_only;
 
-extern Lisp_Object Qintegerp, Qnumberp, Qnatnump, Qwholenump;
-extern Lisp_Object Qsymbolp, Qlistp, Qconsp;
+extern Lisp_Object Qintegerp, Qnatnump, Qwholenump, Qsymbolp, Qlistp, Qconsp;
 extern Lisp_Object Qstringp, Qarrayp, Qsequencep, Qbufferp;
-extern Lisp_Object Qchar_or_string_p, Qmarkerp, Qvectorp;
-extern Lisp_Object Qinteger_or_marker_p, Qnumber_or_marker_p;
-extern Lisp_Object Qchar_table_p, Qvector_or_char_table_p;
-extern Lisp_Object Qboundp, Qfboundp;
+extern Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qvectorp;
 extern Lisp_Object Qbuffer_or_string_p;
+extern Lisp_Object Qboundp, Qfboundp;
+extern Lisp_Object Qchar_table_p, Qvector_or_char_table_p;
+
 extern Lisp_Object Qcdr;
 
-extern Lisp_Object Qfloatp, Qinteger_or_floatp, Qinteger_or_float_or_marker_p;
+extern Lisp_Object Qrange_error, Qdomain_error, Qsingularity_error;
+extern Lisp_Object Qoverflow_error, Qunderflow_error;
+
+extern Lisp_Object Qfloatp;
+extern Lisp_Object Qnumberp, Qnumber_or_marker_p;
 
-extern Lisp_Object Qframep;
+extern Lisp_Object Qinteger;
 
 extern void circular_list_error P_ ((Lisp_Object));
 
+/* Defined in frame.c */
+extern Lisp_Object Qframep;
+
 EXFUN (Feq, 2);
 EXFUN (Fnull, 1);
 EXFUN (Flistp, 1);
@@ -2171,7 +2146,6 @@ extern void swap_in_global_binding P_ ((Lisp_Object));
 EXFUN (Fend_of_line, 1);
 EXFUN (Fforward_char, 1);
 EXFUN (Fforward_line, 1);
-extern int forward_point P_ ((int));
 extern int internal_self_insert P_ ((int, int));
 extern void syms_of_cmds P_ ((void));
 extern void keys_of_cmds P_ ((void));
@@ -2380,6 +2354,7 @@ extern Lisp_Object Qinhibit_point_motion_hooks;
 extern Lisp_Object Qinhibit_redisplay, Qdisplay;
 extern Lisp_Object Qinhibit_eval_during_redisplay;
 extern Lisp_Object Qmessage_truncate_lines;
+extern Lisp_Object Qimage;
 extern Lisp_Object Vmessage_log_max;
 extern int message_enable_multibyte;
 extern Lisp_Object echo_area_buffer[2];
@@ -2430,7 +2405,7 @@ extern void malloc_warning P_ ((char *));
 extern void memory_full P_ ((void));
 extern void buffer_memory_full P_ ((void));
 extern int survives_gc_p P_ ((Lisp_Object));
-extern void mark_object P_ ((Lisp_Object *));
+extern void mark_object P_ ((Lisp_Object));
 extern Lisp_Object Vpurify_flag;
 extern Lisp_Object Vmemory_full;
 EXFUN (Fcons, 2);
@@ -2681,8 +2656,8 @@ extern char *no_switch_window P_ ((Lisp_Object window));
 EXFUN (Fset_buffer_multibyte, 1);
 EXFUN (Foverlay_start, 1);
 EXFUN (Foverlay_end, 1);
-extern void adjust_overlays_for_insert P_ ((int, int));
-extern void adjust_overlays_for_delete P_ ((int, int));
+extern void adjust_overlays_for_insert P_ ((EMACS_INT, EMACS_INT));
+extern void adjust_overlays_for_delete P_ ((EMACS_INT, EMACS_INT));
 extern void fix_overlays_in_range P_ ((int, int));
 extern void report_overlay_modification P_ ((Lisp_Object, Lisp_Object, int,
                                             Lisp_Object, Lisp_Object, Lisp_Object));
@@ -2727,7 +2702,7 @@ extern void clear_charpos_cache P_ ((struct buffer *));
 extern int charpos_to_bytepos P_ ((int));
 extern int buf_charpos_to_bytepos P_ ((struct buffer *, int));
 extern int buf_bytepos_to_charpos P_ ((struct buffer *, int));
-extern void unchain_marker P_ ((Lisp_Object));
+extern void unchain_marker P_ ((struct Lisp_Marker *marker));
 extern Lisp_Object set_marker_restricted P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
 extern Lisp_Object set_marker_both P_ ((Lisp_Object, Lisp_Object, int, int));
 extern Lisp_Object set_marker_restricted_both P_ ((Lisp_Object, Lisp_Object,
@@ -2767,7 +2742,6 @@ extern Lisp_Object make_temp_name P_ ((Lisp_Object, int));
 
 /* Defined in abbrev.c */
 
-extern Lisp_Object Vfundamental_mode_abbrev_table;
 extern void syms_of_abbrev P_ ((void));
 
 /* defined in search.c */
@@ -3010,34 +2984,24 @@ extern void record_property_change P_ ((int, int, Lisp_Object, Lisp_Object,
 extern void syms_of_undo P_ ((void));
 
 /* defined in textprop.c */
-extern Lisp_Object Qmodification_hooks;
-extern Lisp_Object Qrear_nonsticky, Qfont, Qmouse_face;
+extern Lisp_Object Qfont, Qmouse_face;
 extern Lisp_Object Qinsert_in_front_hooks, Qinsert_behind_hooks;
-EXFUN (Fnext_property_change, 3);
 EXFUN (Fnext_single_property_change, 4);
 EXFUN (Fnext_single_char_property_change, 4);
 EXFUN (Fprevious_single_property_change, 4);
-EXFUN (Fget_text_property, 3);
 EXFUN (Fput_text_property, 5);
-EXFUN (Fset_text_properties, 4);
-EXFUN (Ftext_property_not_all, 5);
 EXFUN (Fprevious_char_property_change, 2);
 EXFUN (Fnext_char_property_change, 2);
 extern void report_interval_modification P_ ((Lisp_Object, Lisp_Object));
-extern void syms_of_textprop P_ ((void));
 extern Lisp_Object next_single_char_property_change P_ ((Lisp_Object,
                                                         Lisp_Object,
                                                         Lisp_Object,
                                                         Lisp_Object));
-extern Lisp_Object set_text_properties P_ ((Lisp_Object, Lisp_Object,
-                                           Lisp_Object, Lisp_Object,
-                                           Lisp_Object));
 
 /* defined in xmenu.c */
 EXFUN (Fx_popup_menu, 2);
 EXFUN (Fx_popup_dialog, 2);
 extern void syms_of_xmenu P_ ((void));
-extern int popup_activated_flag;
 
 /* defined in sysdep.c */
 extern void stuff_char P_ ((char c));
@@ -3086,7 +3050,7 @@ extern void syms_of_category P_ ((void));
 extern void syms_of_ccl P_ ((void));
 
 /* Defined in dired.c */
-EXFUN (Ffile_attributes, 1);
+EXFUN (Ffile_attributes, 2);
 extern void syms_of_dired P_ ((void));
 
 /* Defined in term.c */
@@ -3221,3 +3185,8 @@ extern Lisp_Object Vdirectory_sep_char;
    (FIXNUM_OVERFLOW_P (val) \
     ? make_float (val) \
     : make_number ((EMACS_INT)(val)))
+
+#endif /* EMACS_LISP_H */
+
+/* arch-tag: 9b2ed020-70eb-47ac-94ee-e1c2a5107d5e
+   (do not change this comment) */