summaryrefslogtreecommitdiff
path: root/src/lisp.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lisp.h')
-rw-r--r--src/lisp.h177
1 files changed, 85 insertions, 92 deletions
diff --git a/src/lisp.h b/src/lisp.h
index 92294ac1d33..7b4f484b9b7 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -251,12 +251,6 @@ 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."
-error !;
-#endif
-
/* Minimum alignment requirement for Lisp objects, imposed by the
internal representation of tagged pointers. It is 2**GCTYPEBITS if
USE_LSB_TAG, 1 otherwise. It must be a literal integer constant,
@@ -277,7 +271,8 @@ error !;
allocation in a containing union that has GCALIGNED_UNION_MEMBER)
and does not contain a GC-aligned struct or union, putting
GCALIGNED_STRUCT after its closing '}' can help the compiler
- generate better code.
+ generate better code. Also, such structs should be added to the
+ emacs_align_type union in alloc.c.
Although these macros are reasonably portable, they are not
guaranteed on non-GCC platforms, as C11 does not require support
@@ -331,8 +326,8 @@ typedef EMACS_INT Lisp_Word;
used elsewhere.
FIXME: Remove the lisp_h_OP macros, and define just the inline OP
- functions, once "gcc -Og" (new to GCC 4.8) works well enough for
- Emacs developers. Maybe in the year 2020. See Bug#11935.
+ functions, once "gcc -Og" (new to GCC 4.8) or equivalent works well
+ enough for Emacs developers. Maybe in the year 2025. See Bug#11935.
For the macros that have corresponding functions (defined later),
see these functions for commentary. */
@@ -411,15 +406,19 @@ typedef EMACS_INT Lisp_Word;
# define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK))
#endif
-/* When compiling via gcc -O0, define the key operations as macros, as
- Emacs is too slow otherwise. To disable this optimization, compile
- with -DINLINING=false. */
-#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
+/* When DEFINE_KEY_OPS_AS_MACROS, define key operations as macros to
+ cajole the compiler into inlining them; otherwise define them as
+ inline functions as this is cleaner and can be more efficient.
+ The default is true if the compiler is GCC-like and if function
+ inlining is disabled because the compiler is not optimizing or is
+ optimizing for size. Otherwise the default is false. */
+#ifndef DEFINE_KEY_OPS_AS_MACROS
+# if (defined __NO_INLINE__ \
+ && ! defined __OPTIMIZE__ && ! defined __OPTIMIZE_SIZE__)
+# define DEFINE_KEY_OPS_AS_MACROS true
+# else
+# define DEFINE_KEY_OPS_AS_MACROS false
+# endif
#endif
#if DEFINE_KEY_OPS_AS_MACROS
@@ -481,6 +480,7 @@ enum Lisp_Type
Lisp_Symbol = 0,
/* Type 1 is currently unused. */
+ Lisp_Type_Unused0 = 1,
/* Fixnum. XFIXNUM (obj) is the integer value. */
Lisp_Int0 = 2,
@@ -584,15 +584,19 @@ INLINE void set_sub_char_table_contents (Lisp_Object, ptrdiff_t,
Lisp_Object);
/* Defined in bignum.c. */
-extern double bignum_to_double (Lisp_Object);
+extern int check_int_nonnegative (Lisp_Object);
+extern intmax_t check_integer_range (Lisp_Object, intmax_t, intmax_t);
+extern double bignum_to_double (Lisp_Object) ATTRIBUTE_CONST;
extern Lisp_Object make_bigint (intmax_t);
extern Lisp_Object make_biguint (uintmax_t);
+extern uintmax_t check_uinteger_max (Lisp_Object, uintmax_t);
/* Defined in chartab.c. */
-extern Lisp_Object char_table_ref (Lisp_Object, int);
+extern Lisp_Object char_table_ref (Lisp_Object, int) ATTRIBUTE_PURE;
extern void char_table_set (Lisp_Object, int, Lisp_Object);
/* Defined in data.c. */
+extern AVOID args_out_of_range_3 (Lisp_Object, Lisp_Object, Lisp_Object);
extern AVOID wrong_type_argument (Lisp_Object, Lisp_Object);
extern Lisp_Object default_value (Lisp_Object symbol);
@@ -1070,7 +1074,7 @@ DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
with PVEC_TYPE_MASK to indicate the actual type. */
enum pvec_type
{
- PVEC_NORMAL_VECTOR,
+ PVEC_NORMAL_VECTOR, /* Should be first, for sxhash_obj. */
PVEC_FREE,
PVEC_BIGNUM,
PVEC_MARKER,
@@ -1095,7 +1099,7 @@ enum pvec_type
PVEC_CONDVAR,
PVEC_MODULE_FUNCTION,
- /* These should be last, check internal_equal to see why. */
+ /* These should be last, for internal_equal and sxhash_obj. */
PVEC_COMPILED,
PVEC_CHAR_TABLE,
PVEC_SUB_CHAR_TABLE,
@@ -1332,7 +1336,6 @@ dead_object (void)
#define XSETWINDOW(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW))
#define XSETTERMINAL(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL))
#define XSETSUBR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_SUBR))
-#define XSETCOMPILED(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_COMPILED))
#define XSETBUFFER(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BUFFER))
#define XSETCHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE))
#define XSETBOOL_VECTOR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR))
@@ -1669,6 +1672,13 @@ ASIZE (Lisp_Object array)
}
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 ptrdiff_t
PVSIZE (Lisp_Object pv)
{
return ASIZE (pv) & PSEUDOVECTOR_SIZE_MASK;
@@ -1850,22 +1860,17 @@ bool_vector_set (Lisp_Object a, EMACS_INT i, bool b)
INLINE Lisp_Object
AREF (Lisp_Object array, ptrdiff_t idx)
{
+ eassert (0 <= idx && idx < gc_asize (array));
return XVECTOR (array)->contents[idx];
}
INLINE Lisp_Object *
aref_addr (Lisp_Object array, ptrdiff_t idx)
{
+ eassert (0 <= idx && idx <= gc_asize (array));
return & XVECTOR (array)->contents[idx];
}
-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
ASET (Lisp_Object array, ptrdiff_t idx, Lisp_Object val)
{
@@ -1914,18 +1919,12 @@ memclear (void *p, ptrdiff_t nbytes)
(offsetof (type, lastlispfield) + word_size < header_size \
? 0 : (offsetof (type, lastlispfield) + word_size - header_size) / word_size)
-/* Compute A OP B, using the unsigned comparison operator OP. A and B
- should be integer expressions. This is not the same as
- mathematical comparison; for example, UNSIGNED_CMP (0, <, -1)
- returns true. For efficiency, prefer plain unsigned comparison if A
- and B's sizes both fit (after integer promotion). */
-#define UNSIGNED_CMP(a, op, b) \
- (max (sizeof ((a) + 0), sizeof ((b) + 0)) <= sizeof (unsigned) \
- ? ((a) + (unsigned) 0) op ((b) + (unsigned) 0) \
- : ((a) + (uintmax_t) 0) op ((b) + (uintmax_t) 0))
-
/* True iff C is an ASCII character. */
-#define ASCII_CHAR_P(c) UNSIGNED_CMP (c, <, 0x80)
+INLINE bool
+ASCII_CHAR_P (intmax_t c)
+{
+ return 0 <= c && c < 0x80;
+}
/* A char-table is a kind of vectorlike, with contents are like a
vector but with a few other slots. For some purposes, it makes
@@ -2798,8 +2797,10 @@ struct Lisp_Float
{
double data;
struct Lisp_Float *chain;
+ GCALIGNED_UNION_MEMBER
} u;
- } GCALIGNED_STRUCT;
+ };
+verify (GCALIGNED (struct Lisp_Float));
INLINE bool
(FLOATP) (Lisp_Object x)
@@ -2997,28 +2998,6 @@ CHECK_FIXNAT (Lisp_Object x)
CHECK_TYPE (FIXNATP (x), Qwholenump, x);
}
-#define CHECK_RANGED_INTEGER(x, lo, hi) \
- do { \
- CHECK_FIXNUM (x); \
- if (! ((lo) <= XFIXNUM (x) && XFIXNUM (x) <= (hi))) \
- args_out_of_range_3 (x, INT_TO_INTEGER (lo), INT_TO_INTEGER (hi)); \
- } while (false)
-#define CHECK_TYPE_RANGED_INTEGER(type, x) \
- do { \
- if (TYPE_SIGNED (type)) \
- CHECK_RANGED_INTEGER (x, TYPE_MINIMUM (type), TYPE_MAXIMUM (type)); \
- else \
- CHECK_RANGED_INTEGER (x, 0, TYPE_MAXIMUM (type)); \
- } while (false)
-
-#define CHECK_FIXNUM_COERCE_MARKER(x) \
- do { \
- if (MARKERP ((x))) \
- XSETFASTINT (x, marker_position (x)); \
- else \
- CHECK_TYPE (FIXNUMP (x), Qinteger_or_marker_p, x); \
- } while (false)
-
INLINE double
XFLOATINT (Lisp_Object n)
{
@@ -3038,22 +3017,6 @@ CHECK_INTEGER (Lisp_Object x)
{
CHECK_TYPE (INTEGERP (x), Qnumberp, x);
}
-
-#define CHECK_NUMBER_COERCE_MARKER(x) \
- do { \
- if (MARKERP (x)) \
- XSETFASTINT (x, marker_position (x)); \
- else \
- CHECK_TYPE (NUMBERP (x), Qnumber_or_marker_p, x); \
- } while (false)
-
-#define CHECK_INTEGER_COERCE_MARKER(x) \
- do { \
- if (MARKERP (x)) \
- XSETFASTINT (x, marker_position (x)); \
- else \
- CHECK_TYPE (INTEGERP (x), Qnumber_or_marker_p, x); \
- } while (false)
/* If we're not dumping using the legacy dumper and we might be using
@@ -3385,6 +3348,27 @@ struct frame;
#define HAVE_EXT_TOOL_BAR true
#endif
+/* Return the address of vector A's element at index I. */
+
+INLINE Lisp_Object *
+xvector_contents_addr (Lisp_Object a, ptrdiff_t i)
+{
+ /* This should return &XVECTOR (a)->contents[i], but that would run
+ afoul of GCC bug 95072. */
+ void *v = XVECTOR (a);
+ char *p = v;
+ void *w = p + header_size + i * word_size;
+ return w;
+}
+
+/* Return the address of vector A's elements. */
+
+INLINE Lisp_Object *
+xvector_contents (Lisp_Object a)
+{
+ return xvector_contents_addr (a, 0);
+}
+
/* Copy COUNT Lisp_Objects from ARGS to contents of V starting from OFFSET. */
INLINE void
@@ -3392,7 +3376,7 @@ vcopy (Lisp_Object v, ptrdiff_t offset, Lisp_Object const *args,
ptrdiff_t count)
{
eassert (0 <= offset && 0 <= count && offset + count <= ASIZE (v));
- memcpy (XVECTOR (v)->contents + offset, args, count * sizeof *args);
+ memcpy (xvector_contents_addr (v, offset), args, count * sizeof *args);
}
/* Functions to modify hash tables. */
@@ -3507,9 +3491,9 @@ set_sub_char_table_contents (Lisp_Object table, ptrdiff_t idx, Lisp_Object val)
/* Defined in bignum.c. This part of bignum.c's API does not require
the caller to access bignum internals; see bignum.h for that. */
-extern intmax_t bignum_to_intmax (Lisp_Object);
-extern uintmax_t bignum_to_uintmax (Lisp_Object);
-extern ptrdiff_t bignum_bufsize (Lisp_Object, int);
+extern intmax_t bignum_to_intmax (Lisp_Object) ATTRIBUTE_CONST;
+extern uintmax_t bignum_to_uintmax (Lisp_Object) ATTRIBUTE_CONST;
+extern ptrdiff_t bignum_bufsize (Lisp_Object, int) ATTRIBUTE_CONST;
extern ptrdiff_t bignum_to_c_string (char *, ptrdiff_t, Lisp_Object, int);
extern Lisp_Object bignum_to_string (Lisp_Object, int);
extern Lisp_Object make_bignum_str (char const *, int);
@@ -3600,7 +3584,6 @@ extern uintmax_t cons_to_unsigned (Lisp_Object, uintmax_t);
extern struct Lisp_Symbol *indirect_variable (struct Lisp_Symbol *);
extern AVOID args_out_of_range (Lisp_Object, Lisp_Object);
-extern AVOID args_out_of_range_3 (Lisp_Object, Lisp_Object, Lisp_Object);
extern AVOID circular_list (Lisp_Object);
extern Lisp_Object do_symval_forwarding (lispfwd);
enum Set_Internal_Bind {
@@ -3653,7 +3636,7 @@ extern bool sweep_weak_table (struct Lisp_Hash_Table *, bool);
extern void hexbuf_digest (char *, void const *, int);
extern char *extract_data_from_object (Lisp_Object, ptrdiff_t *, ptrdiff_t *);
EMACS_UINT hash_string (char const *, ptrdiff_t);
-EMACS_UINT sxhash (Lisp_Object, int);
+EMACS_UINT sxhash (Lisp_Object);
Lisp_Object hashfn_eql (Lisp_Object, struct Lisp_Hash_Table *);
Lisp_Object hashfn_equal (Lisp_Object, struct Lisp_Hash_Table *);
Lisp_Object hashfn_user_defined (Lisp_Object, struct Lisp_Hash_Table *);
@@ -3813,7 +3796,7 @@ extern void parse_str_as_multibyte (const unsigned char *, ptrdiff_t,
/* Defined in alloc.c. */
extern void *my_heap_start (void);
extern void check_pure_size (void);
-extern void allocate_string_data (struct Lisp_String *, EMACS_INT, EMACS_INT);
+unsigned char *resize_string_data (Lisp_Object, ptrdiff_t, int, int);
extern void malloc_warning (const char *);
extern AVOID memory_full (size_t);
extern AVOID buffer_memory_full (ptrdiff_t);
@@ -3826,7 +3809,15 @@ extern void alloc_unexec_pre (void);
extern void alloc_unexec_post (void);
extern void mark_maybe_objects (Lisp_Object const *, ptrdiff_t);
extern void mark_stack (char const *, char const *);
-extern void flush_stack_call_func (void (*func) (void *arg), void *arg);
+extern void flush_stack_call_func1 (void (*func) (void *arg), void *arg);
+
+INLINE void
+flush_stack_call_func (void (*func) (void *arg), void *arg)
+{
+ __builtin_unwind_init ();
+ flush_stack_call_func1 (func, arg);
+}
+
extern void garbage_collect (void);
extern void maybe_garbage_collect (void);
extern const char *pending_malloc_warning;
@@ -3941,8 +3932,8 @@ build_string (const char *str)
extern Lisp_Object pure_cons (Lisp_Object, Lisp_Object);
extern Lisp_Object make_vector (ptrdiff_t, Lisp_Object);
-extern void make_byte_code (struct Lisp_Vector *);
extern struct Lisp_Vector *allocate_vector (ptrdiff_t);
+extern struct Lisp_Vector *allocate_nil_vector (ptrdiff_t);
/* Make an uninitialized vector for SIZE objects. NOTE: you must
be sure that GC cannot happen until the vector is completely
@@ -3978,9 +3969,7 @@ make_uninit_sub_char_table (int depth, int min_char)
INLINE Lisp_Object
make_nil_vector (ptrdiff_t size)
{
- Lisp_Object vec = make_uninit_vector (size);
- memclear (XVECTOR (vec)->contents, size * word_size);
- return vec;
+ return make_lisp_ptr (allocate_nil_vector (size), Lisp_Vectorlike);
}
extern struct Lisp_Vector *allocate_pseudovector (int, int, int,
@@ -4246,6 +4235,8 @@ extern Lisp_Object module_function_documentation
(struct Lisp_Module_Function const *);
extern module_funcptr module_function_address
(struct Lisp_Module_Function const *);
+extern void *module_function_data (const struct Lisp_Module_Function *);
+extern void module_finalize_function (const struct Lisp_Module_Function *);
extern void mark_modules (void);
extern void init_module_assertions (bool);
extern void syms_of_module (void);
@@ -4605,6 +4596,8 @@ extern void seed_random (void *, ptrdiff_t);
extern void init_random (void);
extern void emacs_backtrace (int);
extern AVOID emacs_abort (void) NO_INLINE;
+extern int emacs_fstatat (int, char const *, void *, int);
+extern int emacs_openat (int, char const *, int, int);
extern int emacs_open (const char *, int, int);
extern int emacs_pipe (int[2]);
extern int emacs_close (int);