Disallow bool vector operations on mixed-length operands.
[bpt/emacs.git] / src / lisp.h
index 0556a95..d25904b 100644 (file)
@@ -64,6 +64,11 @@ typedef unsigned int EMACS_UINT;
 # endif
 #endif
 
+/* An unsigned integer type representing a fixed-length bit sequence,
+   suitable for words in a Lisp bool vector.  */
+typedef size_t bits_word;
+#define BITS_WORD_MAX SIZE_MAX
+
 /* Number of bits in some machine integer types.  */
 enum
   {
@@ -71,6 +76,7 @@ enum
     BITS_PER_SHORT     = CHAR_BIT * sizeof (short),
     BITS_PER_INT       = CHAR_BIT * sizeof (int),
     BITS_PER_LONG      = CHAR_BIT * sizeof (long int),
+    BITS_PER_BITS_WORD = CHAR_BIT * sizeof (bits_word),
     BITS_PER_EMACS_INT = CHAR_BIT * sizeof (EMACS_INT)
   };
 
@@ -108,37 +114,50 @@ typedef EMACS_UINT uprintmax_t;
 
 /* Extra internal type checking?  */
 
-/* Define an Emacs version of 'assert (COND)', since some
-   system-defined 'assert's are flaky.  COND should be free of side
-   effects; it may or may not be evaluated.  */
+/* Define Emacs versions of <assert.h>'s 'assert (COND)' and <verify.h>'s
+   'assume (COND)'.  COND should be free of side effects, as it may or
+   may not be evaluated.
+
+   'eassert (COND)' checks COND at runtime if ENABLE_CHECKING is
+   defined and suppress_checking is false, and does nothing otherwise.
+   Emacs dies if COND is checked and is false.  The suppress_checking
+   variable is initialized to 0 in alloc.c.  Set it to 1 using a
+   debugger to temporarily disable aborting on detected internal
+   inconsistencies or error conditions.
+
+   In some cases, a good compiler may be able to optimize away the
+   eassert macro even if ENABLE_CHECKING is true, e.g., if XSTRING (x)
+   uses eassert to test STRINGP (x), but a particular use of XSTRING
+   is invoked only after testing that STRINGP (x) is true, making the
+   test redundant.
+
+   eassume is like eassert except that it also causes the compiler to
+   assume that COND is true afterwards, regardless of whether runtime
+   checking is enabled.  This can improve performance in some cases,
+   though it can degrade performance in others.  It's often suboptimal
+   for COND to call external functions or access volatile storage.  */
+
 #ifndef ENABLE_CHECKING
-# define eassert(X) ((void) (0 && (X))) /* Check that X compiles.  */
+# define eassert(cond) ((void) (0 && (cond))) /* Check that COND compiles.  */
+# define eassume(cond) assume (cond)
 #else /* ENABLE_CHECKING */
 
 extern _Noreturn void die (const char *, const char *, int);
 
-/* The suppress_checking variable is initialized to 0 in alloc.c.  Set
-   it to 1 using a debugger to temporarily disable aborting on
-   detected internal inconsistencies or error conditions.
-
-   In some cases, a good compiler may be able to optimize away the
-   eassert macro altogether, e.g., if XSTRING (x) uses eassert to test
-   STRINGP (x), but a particular use of XSTRING is invoked only after
-   testing that STRINGP (x) is true, making the test redundant.  */
 extern bool suppress_checking EXTERNALLY_VISIBLE;
 
 # define eassert(cond)                                         \
    (suppress_checking || (cond)                                \
     ? (void) 0                                                 \
     : die (# cond, __FILE__, __LINE__))
+# define eassume(cond)                                         \
+   (suppress_checking                                          \
+    ? assume (cond)                                            \
+    : (cond)                                                   \
+    ? (void) 0                                                 \
+    : die (# cond, __FILE__, __LINE__))
 #endif /* ENABLE_CHECKING */
 
-/* When checking is enabled, identical to eassert.  When checking is
- * disabled, instruct the compiler (when the compiler has such
- * capability) to assume that cond is true and optimize
- * accordingly.  */
-#define eassert_and_assume(cond) (eassert (cond), assume (cond))
-
 \f
 /* Use the configure flag --enable-check-lisp-object-type to make
    Lisp_Object use a struct type instead of the default int.  The flag
@@ -1165,6 +1184,14 @@ struct Lisp_Bool_Vector
     unsigned char data[FLEXIBLE_ARRAY_MEMBER];
   };
 
+INLINE EMACS_INT
+bool_vector_size (Lisp_Object a)
+{
+  EMACS_INT size = XBOOL_VECTOR (a)->size;
+  eassume (0 <= size);
+  return size;
+}
+
 /* Some handy constants for calculating sizes
    and offsets, mostly of vectorlike objects.   */
 
@@ -3904,6 +3931,7 @@ extern bool detect_input_pending_run_timers (bool);
 extern void safe_run_hooks (Lisp_Object);
 extern void cmd_error_internal (Lisp_Object, const char *);
 extern Lisp_Object command_loop_1 (void);
+extern Lisp_Object read_menu_command (void);
 extern Lisp_Object recursive_edit_1 (void);
 extern void record_auto_save (void);
 extern void force_auto_save_soon (void);
@@ -4090,9 +4118,9 @@ extern _Noreturn void emacs_abort (void) NO_INLINE;
 extern int emacs_open (const char *, int, int);
 extern int emacs_pipe (int[2]);
 extern int emacs_close (int);
-extern ptrdiff_t emacs_read (int, char *, ptrdiff_t);
-extern ptrdiff_t emacs_write (int, const char *, ptrdiff_t);
-extern ptrdiff_t emacs_write_sig (int, char const *, ptrdiff_t);
+extern ptrdiff_t emacs_read (int, void *, ptrdiff_t);
+extern ptrdiff_t emacs_write (int, void const *, ptrdiff_t);
+extern ptrdiff_t emacs_write_sig (int, void const *, ptrdiff_t);
 extern void emacs_perror (char const *);
 
 extern void unlock_all_files (void);
@@ -4371,36 +4399,6 @@ functionp (Lisp_Object object)
     return 0;
 }
 
-INLINE uint16_t
-swap16 (uint16_t val)
-{
-    return (val << 8) | (val & 0xFF);
-}
-
-INLINE uint32_t
-swap32 (uint32_t val)
-{
-  uint32_t low = swap16 (val & 0xFFFF);
-  uint32_t high = swap16 (val >> 16);
-  return (low << 16) | high;
-}
-
-#ifdef UINT64_MAX
-INLINE uint64_t
-swap64 (uint64_t val)
-{
-  uint64_t low = swap32 (val & 0xFFFFFFFF);
-  uint64_t high = swap32 (val >> 32);
-  return (low << 32) | high;
-}
-#endif
-
-#if ((SIZE_MAX >> 31) >> 1) & 1
-# define BITS_PER_SIZE_T 64
-#else
-# define BITS_PER_SIZE_T 32
-#endif
-
 /* Round x to the next multiple of y.  Does not overflow.  Evaluates
    arguments repeatedly.  */
 #define ROUNDUP(x,y) ((y)*((x)/(y) + ((x)%(y)!=0)))