]> code.delx.au - gnu-emacs/blobdiff - src/lisp.h
Merge branch 'master' into xwidget
[gnu-emacs] / src / lisp.h
index 1f18b5e077501dc62753f245d19e38533e738bad..f1e6945f43abf270094db42c7d01f2854ad98b8f 100644 (file)
@@ -233,8 +233,8 @@ extern bool suppress_checking EXTERNALLY_VISIBLE;
 
    USE_LSB_TAG not only requires the least 3 bits of pointers returned by
    malloc to be 0 but also needs to be able to impose a mult-of-8 alignment
-   on the few static Lisp_Objects used: all the defsubr as well
-   as the two special buffers buffer_defaults and buffer_local_symbols.  */
+   on the few static Lisp_Objects used: lispsym, all the defsubr, and
+   the two special buffers buffer_defaults and buffer_local_symbols.  */
 
 enum Lisp_Bits
   {
@@ -356,9 +356,6 @@ error !;
 #define lisp_h_XHASH(a) XUINT (a)
 #define lisp_h_XPNTR(a) \
    (SYMBOLP (a) ? XSYMBOL (a) : (void *) ((intptr_t) (XLI (a) & VALMASK)))
-#define lisp_h_XSYMBOL(a) \
-   (eassert (SYMBOLP (a)), \
-    (struct Lisp_Symbol *) XUNTAGBASE (a, Lisp_Symbol, lispsym))
 #ifndef GC_CHECK_CONS_LIST
 # define lisp_h_check_cons_list() ((void) 0)
 #endif
@@ -367,10 +364,12 @@ error !;
     XIL ((EMACS_INT) (((EMACS_UINT) (n) << INTTYPEBITS) + Lisp_Int0))
 # define lisp_h_XFASTINT(a) XINT (a)
 # 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 \
+                            + (char *) lispsym))
 # define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK))
-# define lisp_h_XUNTAG(a, type) XUNTAGBASE (a, type, 0)
-# define lisp_h_XUNTAGBASE(a, type, base) \
-    ((void *) ((char *) (base) - (type) + (intptr_t) XLI (a)))
+# define lisp_h_XUNTAG(a, type) ((void *) (intptr_t) (XLI (a) - (type)))
 #endif
 
 /* When compiling via gcc -O0, define the key operations as macros, as
@@ -402,7 +401,6 @@ error !;
 # define XCONS(a) lisp_h_XCONS (a)
 # define XHASH(a) lisp_h_XHASH (a)
 # define XPNTR(a) lisp_h_XPNTR (a)
-# define XSYMBOL(a) lisp_h_XSYMBOL (a)
 # ifndef GC_CHECK_CONS_LIST
 #  define check_cons_list() lisp_h_check_cons_list ()
 # endif
@@ -410,9 +408,9 @@ error !;
 #  define make_number(n) lisp_h_make_number (n)
 #  define XFASTINT(a) lisp_h_XFASTINT (a)
 #  define XINT(a) lisp_h_XINT (a)
+#  define XSYMBOL(a) lisp_h_XSYMBOL (a)
 #  define XTYPE(a) lisp_h_XTYPE (a)
 #  define XUNTAG(a, type) lisp_h_XUNTAG (a, type)
-#  define XUNTAGBASE(a, type, base) lisp_h_XUNTAGBASE (a, type, base)
 # endif
 #endif
 
@@ -610,9 +608,10 @@ INLINE bool SUBRP (Lisp_Object);
 INLINE bool (SYMBOLP) (Lisp_Object);
 INLINE bool (VECTORLIKEP) (Lisp_Object);
 INLINE bool WINDOWP (Lisp_Object);
+INLINE bool TERMINALP (Lisp_Object);
 INLINE struct Lisp_Save_Value *XSAVE_VALUE (Lisp_Object);
 INLINE struct Lisp_Symbol *(XSYMBOL) (Lisp_Object);
-INLINE void *(XUNTAGBASE) (Lisp_Object, int, void *);
+INLINE void *(XUNTAG) (Lisp_Object, int);
 
 /* Defined in chartab.c.  */
 extern Lisp_Object char_table_ref (Lisp_Object, int);
@@ -727,18 +726,24 @@ struct Lisp_Symbol
 #define TAG_PTR(tag, ptr) \
   ((USE_LSB_TAG ? (tag) : (EMACS_UINT) (tag) << VALBITS) + (uintptr_t) (ptr))
 
-/* Yield an integer that tags PTR as a symbol.  */
-#define TAG_SYMPTR(ptr) \
-  TAG_PTR (Lisp_Symbol, (char *) (ptr) - (char *) (USE_LSB_TAG ? lispsym : 0))
+/* 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)))
+
+/* XLI_BUILTIN_LISPSYM (iQwhatever) is equivalent to
+   XLI (builtin_lisp_symbol (Qwhatever)),
+   except the former expands to an integer constant expression.  */
+#define XLI_BUILTIN_LISPSYM(iname) TAG_SYMOFFSET ((iname) * sizeof *lispsym)
 
 /* Declare extern constants for Lisp symbols.  These can be helpful
    when using a debugger like GDB, on older platforms where the debug
-   format does not represent C macros.  Athough these symbols are
-   useless on modern platforms, they don't hurt performance all that much.  */
+   format does not represent C macros.  */
 #define DEFINE_LISP_SYMBOL_BEGIN(name) \
-   DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name)
+  DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name)
 #define DEFINE_LISP_SYMBOL_END(name) \
-   DEFINE_GDB_SYMBOL_END (LISP_INITIALLY (TAG_SYMPTR (name)))
+  DEFINE_GDB_SYMBOL_END (LISP_INITIALLY (XLI_BUILTIN_LISPSYM (i##name)))
 
 #include "globals.h"
 
@@ -776,6 +781,11 @@ enum pvec_type
   PVEC_WINDOW_CONFIGURATION,
   PVEC_SUBR,
   PVEC_OTHER,
+#ifdef HAVE_XWIDGETS
+  PVEC_XWIDGET,
+  PVEC_XWIDGET_VIEW,
+#endif
+
   /* These should be last, check internal_equal to see why.  */
   PVEC_COMPILED,
   PVEC_CHAR_TABLE,
@@ -819,18 +829,14 @@ DEFINE_GDB_SYMBOL_END (VALMASK)
 #define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS)
 #define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM)
 
-/* Extract the pointer hidden within A.  */
-LISP_MACRO_DEFUN (XPNTR, void *, (Lisp_Object a), (a))
-
 #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))
-LISP_MACRO_DEFUN (XUNTAGBASE, void *, (Lisp_Object a, int type, void *base),
-                 (a, type, base))
 
 #else /* ! USE_LSB_TAG */
 
@@ -883,6 +889,17 @@ XFASTINT (Lisp_Object a)
   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)
@@ -891,25 +908,19 @@ XTYPE (Lisp_Object a)
   return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS;
 }
 
-/* Extract A's pointer value, assuming A's type is TYPE.
-   If USE_LSB_TAG, add BASE to A's pointer value while extracting.  */
-INLINE void *
-XUNTAGBASE (Lisp_Object a, int type, void *base)
-{
-  char *b = USE_LSB_TAG ? base : 0;
-  intptr_t i = USE_LSB_TAG ? XLI (a) - type : XLI (a) & VALMASK;
-  return b + i;
-}
-
 /* Extract A's pointer value, assuming A's type is TYPE.  */
 INLINE void *
 XUNTAG (Lisp_Object a, int type)
 {
-  return XUNTAGBASE (a, type, 0);
+  intptr_t i = USE_LSB_TAG ? XLI (a) - type : XLI (a) & VALMASK;
+  return (void *) i;
 }
 
 #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)
@@ -967,11 +978,9 @@ XSTRING (Lisp_Object a)
   return XUNTAG (a, Lisp_String);
 }
 
-LISP_MACRO_DEFUN (XSYMBOL, struct Lisp_Symbol *, (Lisp_Object a), (a))
-
-/* XSYMBOL_INIT (Qfoo) is like XSYMBOL (Qfoo), except it is valid in
-   static initializers, and SYM must be a C-defined symbol.  */
-#define XSYMBOL_INIT(sym) a##sym
+/* The index of the C-defined Lisp symbol SYM.
+   This can be used in a static initializer.  */
+#define SYMBOL_INDEX(sym) i##sym
 
 INLINE struct Lisp_Float *
 XFLOAT (Lisp_Object a)
@@ -999,6 +1008,7 @@ XWINDOW (Lisp_Object a)
 INLINE struct terminal *
 XTERMINAL (Lisp_Object a)
 {
+  eassert (TERMINALP (a));
   return XUNTAG (a, Lisp_Vectorlike);
 }
 
@@ -1050,16 +1060,15 @@ make_lisp_ptr (void *ptr, enum Lisp_Type type)
 INLINE Lisp_Object
 make_lisp_symbol (struct Lisp_Symbol *sym)
 {
-  Lisp_Object a = XIL (TAG_SYMPTR (sym));
-  eassert (XTYPE (a) == Lisp_Symbol
-          && XUNTAGBASE (a, Lisp_Symbol, lispsym) == sym);
+  Lisp_Object a = XIL (TAG_SYMOFFSET ((char *) sym - (char *) lispsym));
+  eassert (XSYMBOL (a) == sym);
   return a;
 }
 
 INLINE Lisp_Object
-make_lisp_proc (struct Lisp_Process *p)
+builtin_lisp_symbol (int index)
 {
-  return make_lisp_ptr (p, Lisp_Vectorlike);
+  return make_lisp_symbol (lispsym + index);
 }
 
 #define XSETINT(a, b) ((a) = make_number (b))
@@ -1105,6 +1114,25 @@ make_lisp_proc (struct Lisp_Process *p)
 #define XSETBOOL_VECTOR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR))
 #define XSETSUB_CHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_SUB_CHAR_TABLE))
 
+/* Efficiently convert a pointer to a Lisp object and back.  The
+   pointer is represented as a Lisp integer, so the garbage collector
+   does not know about it.  The pointer should not have both Lisp_Int1
+   bits set, which makes this conversion inherently unportable.  */
+
+INLINE void *
+XINTPTR (Lisp_Object a)
+{
+  return XUNTAG (a, Lisp_Int0);
+}
+
+INLINE Lisp_Object
+make_pointer_integer (void *p)
+{
+  Lisp_Object a = XIL (TAG_PTR (Lisp_Int0, p));
+  eassert (INTEGERP (a) && XINTPTR (a) == p);
+  return a;
+}
+
 /* Type checking.  */
 
 LISP_MACRO_DEFUN_VOID (CHECK_TYPE,
@@ -1480,6 +1508,20 @@ gc_aset (Lisp_Object array, ptrdiff_t idx, Lisp_Object val)
   XVECTOR (array)->contents[idx] = val;
 }
 
+/* True, since Qnil's representation is zero.  Every place in the code
+   that assumes Qnil is zero should verify (NIL_IS_ZERO), to make it easy
+   to find such assumptions later if we change Qnil to be nonzero.  */
+enum { NIL_IS_ZERO = XLI_BUILTIN_LISPSYM (iQnil) == 0 };
+
+/* Set a Lisp_Object array V's N entries to nil.  */
+INLINE void
+memsetnil (Lisp_Object *v, ptrdiff_t n)
+{
+  eassert (0 <= n);
+  verify (NIL_IS_ZERO);
+  memset (v, 0, n * sizeof *v);
+}
+
 /* If a struct is made to look like a vector, this macro returns the length
    of the shortest vector that would hold that struct.  */
 
@@ -1665,10 +1707,9 @@ CHAR_TABLE_EXTRA_SLOTS (struct Lisp_Char_Table *ct)
          - CHAR_TABLE_STANDARD_SLOTS);
 }
 
-/* Make sure that sub char-table contents slot
-   is aligned on a multiple of Lisp_Objects.  */
-verify ((offsetof (struct Lisp_Sub_Char_Table, contents)
-        - offsetof (struct Lisp_Sub_Char_Table, depth)) % word_size == 0);
+/* Make sure that sub char-table contents slot is where we think it is.  */
+verify (offsetof (struct Lisp_Sub_Char_Table, contents)
+       == offsetof (struct Lisp_Vector, contents[SUB_CHAR_TABLE_OFFSET]));
 
 /***********************************************************************
                               Symbols
@@ -3758,16 +3799,25 @@ make_uninit_sub_char_table (int depth, int min_char)
   return v;
 }
 
-extern struct Lisp_Vector *allocate_pseudovector (int, int, enum pvec_type);
-#define ALLOCATE_PSEUDOVECTOR(typ,field,tag)                           \
-  ((typ*)                                                              \
-   allocate_pseudovector                                               \
-       (VECSIZE (typ), PSEUDOVECSIZE (typ, field), tag))
-extern struct Lisp_Hash_Table *allocate_hash_table (void);
-extern struct window *allocate_window (void);
-extern struct frame *allocate_frame (void);
-extern struct Lisp_Process *allocate_process (void);
-extern struct terminal *allocate_terminal (void);
+extern struct Lisp_Vector *allocate_pseudovector (int, int, int,
+                                                 enum pvec_type);
+
+/* Allocate partially initialized pseudovector where all Lisp_Object
+   slots are set to Qnil but the rest (if any) is left uninitialized.  */
+
+#define ALLOCATE_PSEUDOVECTOR(type, field, tag)                               \
+  ((type *) allocate_pseudovector (VECSIZE (type),                    \
+                                  PSEUDOVECSIZE (type, field),        \
+                                  PSEUDOVECSIZE (type, field), tag))
+
+/* Allocate fully initialized pseudovector where all Lisp_Object
+   slots are set to Qnil and the rest (if any) is zeroed.  */
+
+#define ALLOCATE_ZEROED_PSEUDOVECTOR(type, field, tag)                \
+  ((type *) allocate_pseudovector (VECSIZE (type),                    \
+                                  PSEUDOVECSIZE (type, field),        \
+                                  VECSIZE (type), tag))
+
 extern bool gc_in_progress;
 extern bool abort_on_gc;
 extern Lisp_Object make_float (double);
@@ -4031,10 +4081,23 @@ struct re_registers;
 extern struct re_pattern_buffer *compile_pattern (Lisp_Object,
                                                  struct re_registers *,
                                                  Lisp_Object, bool, bool);
-extern ptrdiff_t fast_string_match (Lisp_Object, Lisp_Object);
+extern ptrdiff_t fast_string_match_internal (Lisp_Object, Lisp_Object,
+                                            Lisp_Object);
+
+INLINE ptrdiff_t
+fast_string_match (Lisp_Object regexp, Lisp_Object string)
+{
+  return fast_string_match_internal (regexp, string, Qnil);
+}
+
+INLINE ptrdiff_t
+fast_string_match_ignore_case (Lisp_Object regexp, Lisp_Object string)
+{
+  return fast_string_match_internal (regexp, string, Vascii_canon_table);
+}
+
 extern ptrdiff_t fast_c_string_match_ignore_case (Lisp_Object, const char *,
                                                  ptrdiff_t);
-extern ptrdiff_t fast_string_match_ignore_case (Lisp_Object, Lisp_Object);
 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,