From: Paul Eggert <eggert@cs.ucla.edu>
To: 25128@debbugs.gnu.org
Subject: bug#25128: Reorder lisp.h to declare types before using them
Date: Tue, 6 Dec 2016 23:19:19 -0800 [thread overview]
Message-ID: <04822678-e178-4b23-1a5b-ff452cbd88a3@cs.ucla.edu> (raw)
[-- Attachment #1: Type: text/plain, Size: 793 bytes --]
Tags: patch
Attached is a patch to reorder src/lisp.h so that more types are declared before
use. The main motivation is to eventually add support for
-fcheck-pointer-bounds; future changes will need access to type sizes (e.g.,
XCONS might need sizeof (struct Lisp_Cons)), which should be easy after this
change. Also, the change shortens lisp.h a bit and (if you ask me) makes it
easier to read, since the basic functions for a type are now declared next to
the type.
I would like to install this soon, and am posting this as a bug report to give
Eli and others a heads-up, in case some MS-Windows module now needs to include
process.h. This may be needed because XPROCESS is now defined in process.h
instead of lisp.h; similarly for buffer.h, window.h, termhooks.h.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Reorder-lisp.h-to-declare-types-before-using-them.patch --]
[-- Type: text/x-diff; name="0001-Reorder-lisp.h-to-declare-types-before-using-them.patch", Size: 32524 bytes --]
From d9627a9df1ef0e27df0e7eefa40aad85eeeb056c Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Tue, 6 Dec 2016 22:12:43 -0800
Subject: [PATCH] Reorder lisp.h to declare types before using them
Reorder lisp.h to put basic functions for types to be after the
corresponding type definitions. This is a more-common programming
style in C, and will make it easier to port Emacs to gcc
-fcheck-pointer-bounds, since the functions now have access to the
corresponding types' sizes. This patch does not change the code; it
just moves declarations and definitions and removes no-longer-needed
forward declarations.
* src/buffer.c, src/data.c, src/image.c:
Include process.h, for PROCESSP.
* src/buffer.h (BUFFERP, CHECK_BUFFER, XBUFFER):
* src/process.h (PROCESSP, CHECK_PROCESS, XPROCESS):
* src/terminal.h (TERMINALP, XTERMINAL):
* src/window.h (WINDOWP, CHECK_WINDOW, XWINDOW):
Move here from lisp.h.
* src/intervals.h: Include buffer.h, for BUFFERP.
* src/lisp.h: Reorder declarations and definitions as described above.
Move some symbols to other headers (noted above).
Remove forward decls that are no longer needed.
---
src/buffer.c | 1 +
src/buffer.h | 19 ++
src/data.c | 1 +
src/image.c | 1 +
src/intervals.h | 3 +
src/lisp.h | 832 +++++++++++++++++++++++++-------------------------------
src/process.h | 19 ++
src/termhooks.h | 13 +
src/window.h | 19 ++
9 files changed, 448 insertions(+), 460 deletions(-)
diff --git a/src/buffer.c b/src/buffer.c
index 6815aa7..0ae0221 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -32,6 +32,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "lisp.h"
#include "intervals.h"
+#include "process.h"
#include "systime.h"
#include "window.h"
#include "commands.h"
diff --git a/src/buffer.h b/src/buffer.h
index 6ac161c..a8ca6a3 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -881,6 +881,25 @@ struct buffer
Lisp_Object undo_list_;
};
+INLINE bool
+BUFFERP (Lisp_Object a)
+{
+ return PSEUDOVECTORP (a, PVEC_BUFFER);
+}
+
+INLINE void
+CHECK_BUFFER (Lisp_Object x)
+{
+ CHECK_TYPE (BUFFERP (x), Qbufferp, x);
+}
+
+INLINE struct buffer *
+XBUFFER (Lisp_Object a)
+{
+ eassert (BUFFERP (a));
+ return XUNTAG (a, Lisp_Vectorlike);
+}
+
/* Most code should use these functions to set Lisp fields in struct
buffer. (Some setters that are private to a single .c file are
defined as static in those files.) */
diff --git a/src/data.c b/src/data.c
index 64cd8b2..405234e 100644
--- a/src/data.c
+++ b/src/data.c
@@ -31,6 +31,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "character.h"
#include "buffer.h"
#include "keyboard.h"
+#include "process.h"
#include "frame.h"
#include "keymap.h"
diff --git a/src/image.c b/src/image.c
index 89572b8..45010e7 100644
--- a/src/image.c
+++ b/src/image.c
@@ -36,6 +36,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "lisp.h"
#include "frame.h"
+#include "process.h"
#include "window.h"
#include "buffer.h"
#include "dispextern.h"
diff --git a/src/intervals.h b/src/intervals.h
index 9a38d84..b56c050 100644
--- a/src/intervals.h
+++ b/src/intervals.h
@@ -19,6 +19,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#ifndef EMACS_INTERVALS_H
#define EMACS_INTERVALS_H
+#include "buffer.h"
+#include "lisp.h"
+
INLINE_HEADER_BEGIN
/* Basic data type for use of intervals. */
diff --git a/src/lisp.h b/src/lisp.h
index b9c6289..c3eaf42 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -258,6 +258,11 @@ DEFINE_GDB_SYMBOL_BEGIN (bool, USE_LSB_TAG)
#define USE_LSB_TAG (VAL_MAX / 2 < INTPTR_MAX)
DEFINE_GDB_SYMBOL_END (USE_LSB_TAG)
+/* Mask for the value (as opposed to the type bits) of a Lisp object. */
+DEFINE_GDB_SYMBOL_BEGIN (EMACS_INT, VALMASK)
+# define VALMASK (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX)
+DEFINE_GDB_SYMBOL_END (VALMASK)
+
#if !USE_LSB_TAG && !defined WIDE_EMACS_INT
# error "USE_LSB_TAG not supported on this platform; please report this." \
"Try 'configure --with-wide-int' to work around the problem."
@@ -556,42 +561,9 @@ enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = false };
/* Forward declarations. */
/* Defined in this file. */
-union Lisp_Fwd;
-INLINE bool BOOL_VECTOR_P (Lisp_Object);
-INLINE bool BUFFER_OBJFWDP (union Lisp_Fwd *);
-INLINE bool BUFFERP (Lisp_Object);
-INLINE bool CHAR_TABLE_P (Lisp_Object);
-INLINE Lisp_Object CHAR_TABLE_REF_ASCII (Lisp_Object, ptrdiff_t);
-INLINE bool (CONSP) (Lisp_Object);
-INLINE bool (FLOATP) (Lisp_Object);
-INLINE bool (INTEGERP) (Lisp_Object);
-INLINE bool (MARKERP) (Lisp_Object);
-INLINE bool (MISCP) (Lisp_Object);
-INLINE bool (NILP) (Lisp_Object);
-INLINE bool OVERLAYP (Lisp_Object);
-INLINE bool PROCESSP (Lisp_Object);
-INLINE bool PSEUDOVECTORP (Lisp_Object, int);
-INLINE bool SAVE_VALUEP (Lisp_Object);
-INLINE bool FINALIZERP (Lisp_Object);
-
-#ifdef HAVE_MODULES
-INLINE bool USER_PTRP (Lisp_Object);
-INLINE struct Lisp_User_Ptr *(XUSER_PTR) (Lisp_Object);
-#endif
INLINE void set_sub_char_table_contents (Lisp_Object, ptrdiff_t,
Lisp_Object);
-INLINE bool STRINGP (Lisp_Object);
-INLINE bool SUB_CHAR_TABLE_P (Lisp_Object);
-INLINE bool SUBRP (Lisp_Object);
-INLINE bool (SYMBOLP) (Lisp_Object);
-INLINE bool (VECTORLIKEP) (Lisp_Object);
-INLINE bool WINDOWP (Lisp_Object);
-INLINE bool TERMINALP (Lisp_Object);
-INLINE struct Lisp_Save_Value *XSAVE_VALUE (Lisp_Object);
-INLINE struct Lisp_Finalizer *XFINALIZER (Lisp_Object);
-INLINE struct Lisp_Symbol *(XSYMBOL) (Lisp_Object);
-INLINE void *(XUNTAG) (Lisp_Object, int);
/* Defined in chartab.c. */
extern Lisp_Object char_table_ref (Lisp_Object, int);
@@ -600,8 +572,6 @@ extern void char_table_set (Lisp_Object, int, Lisp_Object);
/* Defined in data.c. */
extern _Noreturn void wrong_type_argument (Lisp_Object, Lisp_Object);
extern _Noreturn void wrong_choice (Lisp_Object, Lisp_Object);
-extern void notify_variable_watchers (Lisp_Object symbol, Lisp_Object newval,
- Lisp_Object operation, Lisp_Object where);
#ifdef CANNOT_DUMP
@@ -618,6 +588,56 @@ extern bool initialized;
extern double extract_float (Lisp_Object);
\f
+/* Low-level conversion and type checking. */
+
+/* Convert a Lisp_Object to the corresponding EMACS_INT and vice versa.
+ At the machine level, these operations are no-ops. */
+
+INLINE EMACS_INT
+(XLI) (Lisp_Object o)
+{
+ return lisp_h_XLI (o);
+}
+
+INLINE Lisp_Object
+(XIL) (EMACS_INT i)
+{
+ return lisp_h_XIL (i);
+}
+
+/* Extract A's type. */
+
+INLINE enum Lisp_Type
+(XTYPE) (Lisp_Object a)
+{
+#if USE_LSB_TAG
+ return lisp_h_XTYPE (a);
+#else
+ EMACS_UINT i = XLI (a);
+ return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS;
+#endif
+}
+
+INLINE void
+(CHECK_TYPE) (int ok, Lisp_Object predicate, Lisp_Object x)
+{
+ lisp_h_CHECK_TYPE (ok, predicate, x);
+}
+
+/* Extract A's pointer value, assuming A's type is TYPE. */
+
+INLINE void *
+(XUNTAG) (Lisp_Object a, int type)
+{
+#if USE_LSB_TAG
+ return lisp_h_XUNTAG (a, type);
+#else
+ intptr_t i = USE_LSB_TAG ? XLI (a) - type : XLI (a) & VALMASK;
+ return (void *) i;
+#endif
+}
+
+\f
/* Interned state of a symbol. */
enum symbol_interned
@@ -746,6 +766,10 @@ struct Lisp_Symbol
DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) \
DEFINE_GDB_SYMBOL_END (LISPSYM_INITIALLY (name))
+/* The index of the C-defined Lisp symbol SYM.
+ This can be used in a static initializer. */
+#define SYMBOL_INDEX(sym) i##sym
+
/* By default, define macros for Qt, etc., as this leads to a bit
better performance in the core Emacs interpreter. A plugin can
define DEFINE_NON_NIL_Q_SYMBOL_MACROS to be false, to be portable to
@@ -756,19 +780,43 @@ struct Lisp_Symbol
#include "globals.h"
-/* Convert a Lisp_Object to the corresponding EMACS_INT and vice versa.
- At the machine level, these operations are no-ops. */
+INLINE bool
+(SYMBOLP) (Lisp_Object x)
+{
+ return lisp_h_SYMBOLP (x);
+}
-INLINE EMACS_INT
-(XLI) (Lisp_Object o)
+INLINE struct Lisp_Symbol *
+(XSYMBOL) (Lisp_Object a)
{
- return lisp_h_XLI (o);
+#if USE_LSB_TAG
+ return lisp_h_XSYMBOL (a);
+#else
+ eassert (SYMBOLP (a));
+ intptr_t i = (intptr_t) XUNTAG (a, Lisp_Symbol);
+ void *p = (char *) lispsym + i;
+ return p;
+#endif
}
INLINE Lisp_Object
-(XIL) (EMACS_INT i)
+make_lisp_symbol (struct Lisp_Symbol *sym)
{
- return lisp_h_XIL (i);
+ Lisp_Object a = XIL (TAG_SYMOFFSET ((char *) sym - (char *) lispsym));
+ eassert (XSYMBOL (a) == sym);
+ return a;
+}
+
+INLINE Lisp_Object
+builtin_lisp_symbol (int index)
+{
+ return make_lisp_symbol (lispsym + index);
+}
+
+INLINE void
+(CHECK_SYMBOL) (Lisp_Object x)
+{
+ lisp_h_CHECK_SYMBOL (x);
}
/* In the size word of a vector, this bit means the vector has been marked. */
@@ -836,11 +884,6 @@ enum More_Lisp_Bits
XCONS (tem) is the struct Lisp_Cons * pointing to the memory for
that cons. */
-/* Mask for the value (as opposed to the type bits) of a Lisp object. */
-DEFINE_GDB_SYMBOL_BEGIN (EMACS_INT, VALMASK)
-# define VALMASK (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX)
-DEFINE_GDB_SYMBOL_END (VALMASK)
-
/* Largest and smallest representable fixnum values. These are the C
values. They are macros for use in static initializers. */
#define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS)
@@ -868,24 +911,6 @@ INLINE EMACS_INT
return n;
}
-INLINE struct Lisp_Symbol *
-(XSYMBOL) (Lisp_Object a)
-{
- return lisp_h_XSYMBOL (a);
-}
-
-INLINE enum Lisp_Type
-(XTYPE) (Lisp_Object a)
-{
- return lisp_h_XTYPE (a);
-}
-
-INLINE void *
-(XUNTAG) (Lisp_Object a, int type)
-{
- return lisp_h_XUNTAG (a, type);
-}
-
#else /* ! USE_LSB_TAG */
/* Although compiled only if ! USE_LSB_TAG, the following functions
@@ -937,24 +962,6 @@ XFASTINT (Lisp_Object a)
return n;
}
-/* Extract A's type. */
-INLINE enum Lisp_Type
-XTYPE (Lisp_Object a)
-{
- EMACS_UINT i = XLI (a);
- return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS;
-}
-
-/* Extract A's value as a symbol. */
-INLINE struct Lisp_Symbol *
-XSYMBOL (Lisp_Object a)
-{
- eassert (SYMBOLP (a));
- intptr_t i = (intptr_t) XUNTAG (a, Lisp_Symbol);
- void *p = (char *) lispsym + i;
- return p;
-}
-
/* Extract A's pointer value, assuming A's type is TYPE. */
INLINE void *
XUNTAG (Lisp_Object a, int type)
@@ -1014,97 +1021,6 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper)
}
\f
-/* Extract a value or address from a Lisp_Object. */
-
-INLINE struct Lisp_Cons *
-(XCONS) (Lisp_Object a)
-{
- return lisp_h_XCONS (a);
-}
-
-INLINE struct Lisp_Vector *
-XVECTOR (Lisp_Object a)
-{
- eassert (VECTORLIKEP (a));
- return XUNTAG (a, Lisp_Vectorlike);
-}
-
-INLINE struct Lisp_String *
-XSTRING (Lisp_Object a)
-{
- eassert (STRINGP (a));
- return XUNTAG (a, Lisp_String);
-}
-
-/* The index of the C-defined Lisp symbol SYM.
- This can be used in a static initializer. */
-#define SYMBOL_INDEX(sym) i##sym
-
-INLINE struct Lisp_Float *
-XFLOAT (Lisp_Object a)
-{
- eassert (FLOATP (a));
- return XUNTAG (a, Lisp_Float);
-}
-
-/* Pseudovector types. */
-
-INLINE struct Lisp_Process *
-XPROCESS (Lisp_Object a)
-{
- eassert (PROCESSP (a));
- return XUNTAG (a, Lisp_Vectorlike);
-}
-
-INLINE struct window *
-XWINDOW (Lisp_Object a)
-{
- eassert (WINDOWP (a));
- return XUNTAG (a, Lisp_Vectorlike);
-}
-
-INLINE struct terminal *
-XTERMINAL (Lisp_Object a)
-{
- eassert (TERMINALP (a));
- return XUNTAG (a, Lisp_Vectorlike);
-}
-
-INLINE struct Lisp_Subr *
-XSUBR (Lisp_Object a)
-{
- eassert (SUBRP (a));
- return XUNTAG (a, Lisp_Vectorlike);
-}
-
-INLINE struct buffer *
-XBUFFER (Lisp_Object a)
-{
- eassert (BUFFERP (a));
- return XUNTAG (a, Lisp_Vectorlike);
-}
-
-INLINE struct Lisp_Char_Table *
-XCHAR_TABLE (Lisp_Object a)
-{
- eassert (CHAR_TABLE_P (a));
- return XUNTAG (a, Lisp_Vectorlike);
-}
-
-INLINE struct Lisp_Sub_Char_Table *
-XSUB_CHAR_TABLE (Lisp_Object a)
-{
- eassert (SUB_CHAR_TABLE_P (a));
- return XUNTAG (a, Lisp_Vectorlike);
-}
-
-INLINE struct Lisp_Bool_Vector *
-XBOOL_VECTOR (Lisp_Object a)
-{
- eassert (BOOL_VECTOR_P (a));
- return XUNTAG (a, Lisp_Vectorlike);
-}
-
/* Construct a Lisp_Object from a value or address. */
INLINE Lisp_Object
@@ -1115,18 +1031,10 @@ make_lisp_ptr (void *ptr, enum Lisp_Type type)
return a;
}
-INLINE Lisp_Object
-make_lisp_symbol (struct Lisp_Symbol *sym)
-{
- Lisp_Object a = XIL (TAG_SYMOFFSET ((char *) sym - (char *) lispsym));
- eassert (XSYMBOL (a) == sym);
- return a;
-}
-
-INLINE Lisp_Object
-builtin_lisp_symbol (int index)
+INLINE bool
+(INTEGERP) (Lisp_Object x)
{
- return make_lisp_symbol (lispsym + index);
+ return lisp_h_INTEGERP (x);
}
#define XSETINT(a, b) ((a) = make_number (b))
@@ -1191,14 +1099,6 @@ make_pointer_integer (void *p)
return a;
}
-/* Type checking. */
-
-INLINE void
-(CHECK_TYPE) (int ok, Lisp_Object predicate, Lisp_Object x)
-{
- lisp_h_CHECK_TYPE (ok, predicate, x);
-}
-
/* See the macros in intervals.h. */
typedef struct interval *INTERVAL;
@@ -1218,22 +1118,46 @@ struct GCALIGNED Lisp_Cons
} u;
};
-/* Take the car or cdr of something known to be a cons cell. */
-/* The _addr functions shouldn't be used outside of the minimal set
- of code that has to know what a cons cell looks like. Other code not
- part of the basic lisp implementation should assume that the car and cdr
- 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.) */
-INLINE Lisp_Object *
-xcar_addr (Lisp_Object c)
+INLINE bool
+(NILP) (Lisp_Object x)
{
- return &XCONS (c)->car;
+ return lisp_h_NILP (x);
}
-INLINE Lisp_Object *
-xcdr_addr (Lisp_Object c)
+
+INLINE bool
+(CONSP) (Lisp_Object x)
{
- return &XCONS (c)->u.cdr;
+ return lisp_h_CONSP (x);
+}
+
+INLINE void
+CHECK_CONS (Lisp_Object x)
+{
+ CHECK_TYPE (CONSP (x), Qconsp, x);
+}
+
+INLINE struct Lisp_Cons *
+(XCONS) (Lisp_Object a)
+{
+ return lisp_h_XCONS (a);
+}
+
+/* Take the car or cdr of something known to be a cons cell. */
+/* The _addr functions shouldn't be used outside of the minimal set
+ of code that has to know what a cons cell looks like. Other code not
+ part of the basic lisp implementation should assume that the car and cdr
+ fields are not accessible. (What if we want to switch to
+ a copying collector someday? Cached cons cell field addresses may be
+ invalidated at arbitrary points.) */
+INLINE Lisp_Object *
+xcar_addr (Lisp_Object c)
+{
+ return &XCONS (c)->car;
+}
+INLINE Lisp_Object *
+xcdr_addr (Lisp_Object c)
+{
+ return &XCONS (c)->u.cdr;
}
/* Use these from normal code. */
@@ -1307,6 +1231,25 @@ struct GCALIGNED Lisp_String
unsigned char *data;
};
+INLINE bool
+STRINGP (Lisp_Object x)
+{
+ return XTYPE (x) == Lisp_String;
+}
+
+INLINE void
+CHECK_STRING (Lisp_Object x)
+{
+ CHECK_TYPE (STRINGP (x), Qstringp, x);
+}
+
+INLINE struct Lisp_String *
+XSTRING (Lisp_Object a)
+{
+ eassert (STRINGP (a));
+ return XUNTAG (a, Lisp_String);
+}
+
/* True if STR is a multibyte string. */
INLINE bool
STRING_MULTIBYTE (Lisp_Object str)
@@ -1441,6 +1384,62 @@ struct Lisp_Vector
Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER];
};
+INLINE bool
+(VECTORLIKEP) (Lisp_Object x)
+{
+ return lisp_h_VECTORLIKEP (x);
+}
+
+INLINE struct Lisp_Vector *
+XVECTOR (Lisp_Object a)
+{
+ eassert (VECTORLIKEP (a));
+ return XUNTAG (a, Lisp_Vectorlike);
+}
+
+INLINE ptrdiff_t
+ASIZE (Lisp_Object array)
+{
+ ptrdiff_t size = XVECTOR (array)->header.size;
+ eassume (0 <= size);
+ return size;
+}
+
+INLINE bool
+VECTORP (Lisp_Object x)
+{
+ return VECTORLIKEP (x) && ! (ASIZE (x) & PSEUDOVECTOR_FLAG);
+}
+
+INLINE void
+CHECK_VECTOR (Lisp_Object x)
+{
+ CHECK_TYPE (VECTORP (x), Qvectorp, x);
+}
+
+/* A pseudovector is like a vector, but has other non-Lisp components. */
+
+INLINE bool
+PSEUDOVECTOR_TYPEP (struct vectorlike_header *a, int code)
+{
+ return ((a->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
+ == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_AREA_BITS)));
+}
+
+/* True if A is a pseudovector whose code is CODE. */
+INLINE bool
+PSEUDOVECTORP (Lisp_Object a, int code)
+{
+ if (! VECTORLIKEP (a))
+ return false;
+ else
+ {
+ /* Converting to struct vectorlike_header * avoids aliasing issues. */
+ struct vectorlike_header *h = XUNTAG (a, Lisp_Vectorlike);
+ return PSEUDOVECTOR_TYPEP (h, code);
+ }
+}
+
/* A boolvector is a kind of vectorlike, with contents like a string. */
struct Lisp_Bool_Vector
@@ -1457,6 +1456,51 @@ struct Lisp_Bool_Vector
bits_word data[FLEXIBLE_ARRAY_MEMBER];
};
+/* Some handy constants for calculating sizes
+ and offsets, mostly of vectorlike objects. */
+
+enum
+ {
+ header_size = offsetof (struct Lisp_Vector, contents),
+ bool_header_size = offsetof (struct Lisp_Bool_Vector, data),
+ word_size = sizeof (Lisp_Object)
+ };
+
+/* The number of data words and bytes in a bool vector with SIZE bits. */
+
+INLINE EMACS_INT
+bool_vector_words (EMACS_INT size)
+{
+ eassume (0 <= size && size <= EMACS_INT_MAX - (BITS_PER_BITS_WORD - 1));
+ return (size + BITS_PER_BITS_WORD - 1) / BITS_PER_BITS_WORD;
+}
+
+INLINE EMACS_INT
+bool_vector_bytes (EMACS_INT size)
+{
+ eassume (0 <= size && size <= EMACS_INT_MAX - (BITS_PER_BITS_WORD - 1));
+ return (size + BOOL_VECTOR_BITS_PER_CHAR - 1) / BOOL_VECTOR_BITS_PER_CHAR;
+}
+
+INLINE bool
+BOOL_VECTOR_P (Lisp_Object a)
+{
+ return PSEUDOVECTORP (a, PVEC_BOOL_VECTOR);
+}
+
+INLINE void
+CHECK_BOOL_VECTOR (Lisp_Object x)
+{
+ CHECK_TYPE (BOOL_VECTOR_P (x), Qbool_vector_p, x);
+}
+
+INLINE struct Lisp_Bool_Vector *
+XBOOL_VECTOR (Lisp_Object a)
+{
+ eassert (BOOL_VECTOR_P (a));
+ return XUNTAG (a, Lisp_Vectorlike);
+}
+
INLINE EMACS_INT
bool_vector_size (Lisp_Object a)
{
@@ -1477,22 +1521,6 @@ bool_vector_uchar_data (Lisp_Object a)
return (unsigned char *) bool_vector_data (a);
}
-/* The number of data words and bytes in a bool vector with SIZE bits. */
-
-INLINE EMACS_INT
-bool_vector_words (EMACS_INT size)
-{
- eassume (0 <= size && size <= EMACS_INT_MAX - (BITS_PER_BITS_WORD - 1));
- return (size + BITS_PER_BITS_WORD - 1) / BITS_PER_BITS_WORD;
-}
-
-INLINE EMACS_INT
-bool_vector_bytes (EMACS_INT size)
-{
- eassume (0 <= size && size <= EMACS_INT_MAX - (BITS_PER_BITS_WORD - 1));
- return (size + BOOL_VECTOR_BITS_PER_CHAR - 1) / BOOL_VECTOR_BITS_PER_CHAR;
-}
-
/* True if A's Ith bit is set. */
INLINE bool
@@ -1525,16 +1553,6 @@ bool_vector_set (Lisp_Object a, EMACS_INT i, bool b)
*addr &= ~ (1 << (i % BOOL_VECTOR_BITS_PER_CHAR));
}
-/* Some handy constants for calculating sizes
- and offsets, mostly of vectorlike objects. */
-
-enum
- {
- header_size = offsetof (struct Lisp_Vector, contents),
- bool_header_size = offsetof (struct Lisp_Bool_Vector, data),
- word_size = sizeof (Lisp_Object)
- };
-
/* Conveniences for dealing with Lisp arrays. */
INLINE Lisp_Object
@@ -1550,14 +1568,6 @@ aref_addr (Lisp_Object array, ptrdiff_t idx)
}
INLINE ptrdiff_t
-ASIZE (Lisp_Object array)
-{
- ptrdiff_t size = XVECTOR (array)->header.size;
- eassume (0 <= size);
- return size;
-}
-
-INLINE ptrdiff_t
gc_asize (Lisp_Object array)
{
/* Like ASIZE, but also can be used in the garbage collector. */
@@ -1674,6 +1684,19 @@ struct Lisp_Char_Table
Lisp_Object extras[FLEXIBLE_ARRAY_MEMBER];
};
+INLINE bool
+CHAR_TABLE_P (Lisp_Object a)
+{
+ return PSEUDOVECTORP (a, PVEC_CHAR_TABLE);
+}
+
+INLINE struct Lisp_Char_Table *
+XCHAR_TABLE (Lisp_Object a)
+{
+ eassert (CHAR_TABLE_P (a));
+ return XUNTAG (a, Lisp_Vectorlike);
+}
+
struct Lisp_Sub_Char_Table
{
/* HEADER.SIZE is the vector's size field, which also holds the
@@ -1695,6 +1718,19 @@ struct Lisp_Sub_Char_Table
Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER];
};
+INLINE bool
+SUB_CHAR_TABLE_P (Lisp_Object a)
+{
+ return PSEUDOVECTORP (a, PVEC_SUB_CHAR_TABLE);
+}
+
+INLINE struct Lisp_Sub_Char_Table *
+XSUB_CHAR_TABLE (Lisp_Object a)
+{
+ eassert (SUB_CHAR_TABLE_P (a));
+ return XUNTAG (a, Lisp_Vectorlike);
+}
+
INLINE Lisp_Object
CHAR_TABLE_REF_ASCII (Lisp_Object ct, ptrdiff_t idx)
{
@@ -1760,6 +1796,19 @@ struct Lisp_Subr
EMACS_INT doc;
};
+INLINE bool
+SUBRP (Lisp_Object a)
+{
+ return PSEUDOVECTORP (a, PVEC_SUBR);
+}
+
+INLINE struct Lisp_Subr *
+XSUBR (Lisp_Object a)
+{
+ eassert (SUBRP (a));
+ return XUNTAG (a, Lisp_Vectorlike);
+}
+
enum char_table_specials
{
/* This is the number of slots that every char table must have. This
@@ -2070,6 +2119,25 @@ struct Lisp_Misc_Any /* Supertype of all Misc types. */
unsigned spacer : 15;
};
+INLINE bool
+(MISCP) (Lisp_Object x)
+{
+ return lisp_h_MISCP (x);
+}
+
+INLINE struct Lisp_Misc_Any *
+XMISCANY (Lisp_Object a)
+{
+ eassert (MISCP (a));
+ return XUNTAG (a, Lisp_Misc);
+}
+
+INLINE enum Lisp_Misc_Type
+XMISCTYPE (Lisp_Object a)
+{
+ return XMISCANY (a)->type;
+}
+
struct Lisp_Marker
{
ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Marker */
@@ -2227,6 +2295,19 @@ struct Lisp_Save_Value
} data[SAVE_VALUE_SLOTS];
};
+INLINE bool
+SAVE_VALUEP (Lisp_Object x)
+{
+ return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value;
+}
+
+INLINE struct Lisp_Save_Value *
+XSAVE_VALUE (Lisp_Object a)
+{
+ eassert (SAVE_VALUEP (a));
+ return XUNTAG (a, Lisp_Misc);
+}
+
/* Return the type of V's Nth saved value. */
INLINE int
save_type (struct Lisp_Save_Value *v, int n)
@@ -2307,6 +2388,19 @@ struct Lisp_Finalizer
Lisp_Object function;
};
+INLINE bool
+FINALIZERP (Lisp_Object x)
+{
+ return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Finalizer;
+}
+
+INLINE struct Lisp_Finalizer *
+XFINALIZER (Lisp_Object a)
+{
+ eassert (FINALIZERP (a));
+ return XUNTAG (a, Lisp_Misc);
+}
+
/* A miscellaneous object, when it's on the free list. */
struct Lisp_Free
{
@@ -2338,53 +2432,44 @@ XMISC (Lisp_Object a)
return XUNTAG (a, Lisp_Misc);
}
-INLINE struct Lisp_Misc_Any *
-XMISCANY (Lisp_Object a)
-{
- eassert (MISCP (a));
- return & XMISC (a)->u_any;
-}
-
-INLINE enum Lisp_Misc_Type
-XMISCTYPE (Lisp_Object a)
+INLINE bool
+(MARKERP) (Lisp_Object x)
{
- return XMISCANY (a)->type;
+ return lisp_h_MARKERP (x);
}
INLINE struct Lisp_Marker *
XMARKER (Lisp_Object a)
{
eassert (MARKERP (a));
- return & XMISC (a)->u_marker;
+ return XUNTAG (a, Lisp_Misc);
}
-INLINE struct Lisp_Overlay *
-XOVERLAY (Lisp_Object a)
+INLINE bool
+OVERLAYP (Lisp_Object x)
{
- eassert (OVERLAYP (a));
- return & XMISC (a)->u_overlay;
+ return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay;
}
-INLINE struct Lisp_Save_Value *
-XSAVE_VALUE (Lisp_Object a)
+INLINE struct Lisp_Overlay *
+XOVERLAY (Lisp_Object a)
{
- eassert (SAVE_VALUEP (a));
- return & XMISC (a)->u_save_value;
+ eassert (OVERLAYP (a));
+ return XUNTAG (a, Lisp_Misc);
}
-INLINE struct Lisp_Finalizer *
-XFINALIZER (Lisp_Object a)
+#ifdef HAVE_MODULES
+INLINE bool
+USER_PTRP (Lisp_Object x)
{
- eassert (FINALIZERP (a));
- return & XMISC (a)->u_finalizer;
+ return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_User_Ptr;
}
-#ifdef HAVE_MODULES
INLINE struct Lisp_User_Ptr *
XUSER_PTR (Lisp_Object a)
{
eassert (USER_PTRP (a));
- return & XMISC (a)->u_user_ptr;
+ return XUNTAG (a, Lisp_Misc);
}
#endif
@@ -2502,6 +2587,12 @@ XFWDTYPE (union Lisp_Fwd *a)
return a->u_intfwd.type;
}
+INLINE bool
+BUFFER_OBJFWDP (union Lisp_Fwd *a)
+{
+ return XFWDTYPE (a) == Lisp_Fwd_Buffer_Obj;
+}
+
INLINE struct Lisp_Buffer_Objfwd *
XBUFFER_OBJFWD (union Lisp_Fwd *a)
{
@@ -2519,6 +2610,19 @@ struct Lisp_Float
} u;
};
+INLINE bool
+(FLOATP) (Lisp_Object x)
+{
+ return lisp_h_FLOATP (x);
+}
+
+INLINE struct Lisp_Float *
+XFLOAT (Lisp_Object a)
+{
+ eassert (FLOATP (a));
+ return XUNTAG (a, Lisp_Float);
+}
+
INLINE double
XFLOAT_DATA (Lisp_Object f)
{
@@ -2582,12 +2686,6 @@ enum char_bits
/* Data type checking. */
INLINE bool
-(NILP) (Lisp_Object x)
-{
- return lisp_h_NILP (x);
-}
-
-INLINE bool
NUMBERP (Lisp_Object x)
{
return INTEGERP (x) || FLOATP (x);
@@ -2610,109 +2708,11 @@ RANGED_INTEGERP (intmax_t lo, Lisp_Object x, intmax_t hi)
&& XINT (x) <= TYPE_MAXIMUM (type))
INLINE bool
-(CONSP) (Lisp_Object x)
-{
- return lisp_h_CONSP (x);
-}
-INLINE bool
-(FLOATP) (Lisp_Object x)
-{
- return lisp_h_FLOATP (x);
-}
-INLINE bool
-(MISCP) (Lisp_Object x)
-{
- return lisp_h_MISCP (x);
-}
-INLINE bool
-(SYMBOLP) (Lisp_Object x)
-{
- return lisp_h_SYMBOLP (x);
-}
-INLINE bool
-(INTEGERP) (Lisp_Object x)
-{
- return lisp_h_INTEGERP (x);
-}
-INLINE bool
-(VECTORLIKEP) (Lisp_Object x)
-{
- return lisp_h_VECTORLIKEP (x);
-}
-INLINE bool
-(MARKERP) (Lisp_Object x)
-{
- return lisp_h_MARKERP (x);
-}
-
-INLINE bool
-STRINGP (Lisp_Object x)
-{
- return XTYPE (x) == Lisp_String;
-}
-INLINE bool
-VECTORP (Lisp_Object x)
-{
- return VECTORLIKEP (x) && ! (ASIZE (x) & PSEUDOVECTOR_FLAG);
-}
-INLINE bool
-OVERLAYP (Lisp_Object x)
-{
- return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay;
-}
-INLINE bool
-SAVE_VALUEP (Lisp_Object x)
-{
- return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value;
-}
-
-INLINE bool
-FINALIZERP (Lisp_Object x)
-{
- return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Finalizer;
-}
-
-#ifdef HAVE_MODULES
-INLINE bool
-USER_PTRP (Lisp_Object x)
-{
- return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_User_Ptr;
-}
-#endif
-
-INLINE bool
AUTOLOADP (Lisp_Object x)
{
return CONSP (x) && EQ (Qautoload, XCAR (x));
}
-INLINE bool
-BUFFER_OBJFWDP (union Lisp_Fwd *a)
-{
- return XFWDTYPE (a) == Lisp_Fwd_Buffer_Obj;
-}
-
-INLINE bool
-PSEUDOVECTOR_TYPEP (struct vectorlike_header *a, int code)
-{
- return ((a->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK))
- == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_AREA_BITS)));
-}
-
-/* True if A is a pseudovector whose code is CODE. */
-INLINE bool
-PSEUDOVECTORP (Lisp_Object a, int code)
-{
- if (! VECTORLIKEP (a))
- return false;
- else
- {
- /* Converting to struct vectorlike_header * avoids aliasing issues. */
- struct vectorlike_header *h = XUNTAG (a, Lisp_Vectorlike);
- return PSEUDOVECTOR_TYPEP (h, code);
- }
-}
-
/* Test for specific pseudovector types. */
@@ -2723,60 +2723,12 @@ WINDOW_CONFIGURATIONP (Lisp_Object a)
}
INLINE bool
-PROCESSP (Lisp_Object a)
-{
- return PSEUDOVECTORP (a, PVEC_PROCESS);
-}
-
-INLINE bool
-WINDOWP (Lisp_Object a)
-{
- return PSEUDOVECTORP (a, PVEC_WINDOW);
-}
-
-INLINE bool
-TERMINALP (Lisp_Object a)
-{
- return PSEUDOVECTORP (a, PVEC_TERMINAL);
-}
-
-INLINE bool
-SUBRP (Lisp_Object a)
-{
- return PSEUDOVECTORP (a, PVEC_SUBR);
-}
-
-INLINE bool
COMPILEDP (Lisp_Object a)
{
return PSEUDOVECTORP (a, PVEC_COMPILED);
}
INLINE bool
-BUFFERP (Lisp_Object a)
-{
- return PSEUDOVECTORP (a, PVEC_BUFFER);
-}
-
-INLINE bool
-CHAR_TABLE_P (Lisp_Object a)
-{
- return PSEUDOVECTORP (a, PVEC_CHAR_TABLE);
-}
-
-INLINE bool
-SUB_CHAR_TABLE_P (Lisp_Object a)
-{
- return PSEUDOVECTORP (a, PVEC_SUB_CHAR_TABLE);
-}
-
-INLINE bool
-BOOL_VECTOR_P (Lisp_Object a)
-{
- return PSEUDOVECTORP (a, PVEC_BOOL_VECTOR);
-}
-
-INLINE bool
FRAMEP (Lisp_Object a)
{
return PSEUDOVECTORP (a, PVEC_FRAME);
@@ -2809,42 +2761,16 @@ INLINE void
}
INLINE void
-(CHECK_SYMBOL) (Lisp_Object x)
-{
- lisp_h_CHECK_SYMBOL (x);
-}
-
-INLINE void
(CHECK_NUMBER) (Lisp_Object x)
{
lisp_h_CHECK_NUMBER (x);
}
INLINE void
-CHECK_STRING (Lisp_Object x)
-{
- CHECK_TYPE (STRINGP (x), Qstringp, x);
-}
-INLINE void
CHECK_STRING_CAR (Lisp_Object x)
{
CHECK_TYPE (STRINGP (XCAR (x)), Qstringp, XCAR (x));
}
-INLINE void
-CHECK_CONS (Lisp_Object x)
-{
- CHECK_TYPE (CONSP (x), Qconsp, x);
-}
-INLINE void
-CHECK_VECTOR (Lisp_Object x)
-{
- CHECK_TYPE (VECTORP (x), Qvectorp, x);
-}
-INLINE void
-CHECK_BOOL_VECTOR (Lisp_Object x)
-{
- CHECK_TYPE (BOOL_VECTOR_P (x), Qbool_vector_p, x);
-}
/* This is a bit special because we always need size afterwards. */
INLINE ptrdiff_t
CHECK_VECTOR_OR_STRING (Lisp_Object x)
@@ -2861,23 +2787,6 @@ CHECK_ARRAY (Lisp_Object x, Lisp_Object predicate)
CHECK_TYPE (ARRAYP (x), predicate, x);
}
INLINE void
-CHECK_BUFFER (Lisp_Object x)
-{
- CHECK_TYPE (BUFFERP (x), Qbufferp, x);
-}
-INLINE void
-CHECK_WINDOW (Lisp_Object x)
-{
- CHECK_TYPE (WINDOWP (x), Qwindowp, x);
-}
-#ifdef subprocesses
-INLINE void
-CHECK_PROCESS (Lisp_Object x)
-{
- CHECK_TYPE (PROCESSP (x), Qprocessp, x);
-}
-#endif
-INLINE void
CHECK_NATNUM (Lisp_Object x)
{
CHECK_TYPE (NATNUMP (x), Qwholenump, x);
@@ -3380,6 +3289,8 @@ set_sub_char_table_contents (Lisp_Object table, ptrdiff_t idx, Lisp_Object val)
}
/* Defined in data.c. */
+extern void notify_variable_watchers (Lisp_Object, Lisp_Object,
+ Lisp_Object, Lisp_Object);
extern Lisp_Object indirect_function (Lisp_Object);
extern Lisp_Object find_symbol_value (Lisp_Object);
enum Arith_Comparison {
@@ -4194,6 +4105,7 @@ extern bool inhibit_window_system;
extern bool running_asynch_code;
/* Defined in process.c. */
+struct Lisp_Process;
extern void kill_buffer_processes (Lisp_Object);
extern int wait_reading_process_output (intmax_t, int, int, bool, Lisp_Object,
struct Lisp_Process *, int);
diff --git a/src/process.h b/src/process.h
index 24c6282..8f28ddb 100644
--- a/src/process.h
+++ b/src/process.h
@@ -199,6 +199,25 @@ struct Lisp_Process
#endif
};
+INLINE bool
+PROCESSP (Lisp_Object a)
+{
+ return PSEUDOVECTORP (a, PVEC_PROCESS);
+}
+
+INLINE void
+CHECK_PROCESS (Lisp_Object x)
+{
+ CHECK_TYPE (PROCESSP (x), Qprocessp, x);
+}
+
+INLINE struct Lisp_Process *
+XPROCESS (Lisp_Object a)
+{
+ eassert (PROCESSP (a));
+ return XUNTAG (a, Lisp_Vectorlike);
+}
+
/* Every field in the preceding structure except for the first two
must be a Lisp_Object, for GC's sake. */
diff --git a/src/termhooks.h b/src/termhooks.h
index 03416cb..81e06d9 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -654,6 +654,19 @@ struct terminal
void (*delete_terminal_hook) (struct terminal *);
};
+INLINE bool
+TERMINALP (Lisp_Object a)
+{
+ return PSEUDOVECTORP (a, PVEC_TERMINAL);
+}
+
+INLINE struct terminal *
+XTERMINAL (Lisp_Object a)
+{
+ eassert (TERMINALP (a));
+ return XUNTAG (a, Lisp_Vectorlike);
+}
+
/* Most code should use these functions to set Lisp fields in struct
terminal. */
INLINE void
diff --git a/src/window.h b/src/window.h
index 4a102f2..717f972 100644
--- a/src/window.h
+++ b/src/window.h
@@ -397,6 +397,25 @@ struct window
ptrdiff_t window_end_bytepos;
};
+INLINE bool
+WINDOWP (Lisp_Object a)
+{
+ return PSEUDOVECTORP (a, PVEC_WINDOW);
+}
+
+INLINE void
+CHECK_WINDOW (Lisp_Object x)
+{
+ CHECK_TYPE (WINDOWP (x), Qwindowp, x);
+}
+
+INLINE struct window *
+XWINDOW (Lisp_Object a)
+{
+ eassert (WINDOWP (a));
+ return XUNTAG (a, Lisp_Vectorlike);
+}
+
/* Most code should use these functions to set Lisp fields in struct
window. */
INLINE void
--
2.9.3
next reply other threads:[~2016-12-07 7:19 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-12-07 7:19 Paul Eggert [this message]
2016-12-07 16:09 ` bug#25128: Reorder lisp.h to declare types before using them Eli Zaretskii
2016-12-07 16:30 ` Paul Eggert
2016-12-25 17:38 ` Paul Eggert
2016-12-25 17:59 ` Eli Zaretskii
2016-12-25 18:15 ` Paul Eggert
2016-12-25 18:19 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=04822678-e178-4b23-1a5b-ff452cbd88a3@cs.ucla.edu \
--to=eggert@cs.ucla.edu \
--cc=25128@debbugs.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.