diff options
Diffstat (limited to 'src/lisp.h')
-rw-r--r-- | src/lisp.h | 755 |
1 files changed, 440 insertions, 315 deletions
diff --git a/src/lisp.h b/src/lisp.h index 2b632ad19f1..ba3c812f5d8 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -36,41 +36,15 @@ INLINE_HEADER_BEGIN /* Define a TYPE constant ID as an externally visible name. Use like this: - #define ID_val (some integer preprocessor expression) - #if ENUMABLE (ID_val) - DEFINE_GDB_SYMBOL_ENUM (ID) - #else DEFINE_GDB_SYMBOL_BEGIN (TYPE, ID) - # define ID ID_val + # define ID (some integer preprocessor expression of type TYPE) DEFINE_GDB_SYMBOL_END (ID) - #endif This hack is for the benefit of compilers that do not make macro - definitions visible to the debugger. It's used for symbols that - .gdbinit needs, symbols whose values may not fit in 'int' (where an - enum would suffice). + definitions or enums visible to the debugger. It's used for symbols + that .gdbinit needs. */ - Some GCC versions before GCC 4.2 omit enums in debugging output; - see GCC bug 23336. So don't use enums with older GCC. */ - -#if !defined __GNUC__ || 4 < __GNUC__ + (2 <= __GNUC_MINOR__) -# define ENUMABLE(val) (INT_MIN <= (val) && (val) <= INT_MAX) -#else -# define ENUMABLE(val) 0 -#endif - -/* On AIX 7.1 ENUMABLE should return true when possible, otherwise the - linker can optimize the symbols away, making it harder to debug. - This was discovered only late in the release process, so to play it - safe for now, non-AIX platforms do not use enums for debugging symbols. - FIXME: remove this comment and the following four lines of code. */ -#ifndef _AIX -# undef ENUMABLE -# define ENUMABLE(val) 0 -#endif - -#define DEFINE_GDB_SYMBOL_ENUM(id) enum { id = id##_val }; -#if defined MAIN_PROGRAM +#ifdef MAIN_PROGRAM # define DEFINE_GDB_SYMBOL_BEGIN(type, id) type const id EXTERNALLY_VISIBLE # define DEFINE_GDB_SYMBOL_END(id) = id; #else @@ -84,6 +58,27 @@ INLINE_HEADER_BEGIN #define max(a, b) ((a) > (b) ? (a) : (b)) #define min(a, b) ((a) < (b) ? (a) : (b)) +/* Number of elements in an array. */ +#define ARRAYELTS(arr) (sizeof (arr) / sizeof (arr)[0]) + +/* Number of bits in a Lisp_Object tag. */ +DEFINE_GDB_SYMBOL_BEGIN (int, GCTYPEBITS) +#define GCTYPEBITS 3 +DEFINE_GDB_SYMBOL_END (GCTYPEBITS) + +/* The number of bits needed in an EMACS_INT over and above the number + of bits in a pointer. This is 0 on systems where: + 1. We can specify multiple-of-8 alignment on static variables. + 2. We know malloc returns a multiple of 8. */ +#if (defined alignas \ + && (defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ \ + || defined DARWIN_OS || defined __sun || defined __MINGW32__ \ + || defined CYGWIN)) +# define NONPOINTER_BITS 0 +#else +# define NONPOINTER_BITS GCTYPEBITS +#endif + /* EMACS_INT - signed integer wide enough to hold an Emacs value EMACS_INT_MAX - maximum value of EMACS_INT; can be used in #if pI - printf length modifier for EMACS_INT @@ -91,16 +86,18 @@ INLINE_HEADER_BEGIN #ifndef EMACS_INT_MAX # if INTPTR_MAX <= 0 # error "INTPTR_MAX misconfigured" -# elif INTPTR_MAX <= INT_MAX && !defined WIDE_EMACS_INT +# elif INTPTR_MAX <= INT_MAX >> NONPOINTER_BITS && !defined WIDE_EMACS_INT typedef int EMACS_INT; typedef unsigned int EMACS_UINT; # define EMACS_INT_MAX INT_MAX # define pI "" -# elif INTPTR_MAX <= LONG_MAX && !defined WIDE_EMACS_INT +# elif INTPTR_MAX <= LONG_MAX >> NONPOINTER_BITS && !defined WIDE_EMACS_INT typedef long int EMACS_INT; typedef unsigned long EMACS_UINT; # define EMACS_INT_MAX LONG_MAX # define pI "l" +/* Check versus LLONG_MAX, not LLONG_MAX >> NONPOINTER_BITS. + In theory this is not safe, but in practice it seems to be OK. */ # elif INTPTR_MAX <= LLONG_MAX typedef long long int EMACS_INT; typedef unsigned long long int EMACS_UINT; @@ -119,7 +116,7 @@ enum { BOOL_VECTOR_BITS_PER_CHAR = }; /* An unsigned integer type representing a fixed-length bit sequence, - suitable for words in a Lisp bool vector. Normally it is size_t + suitable for bool vector words, GC mark bits, etc. Normally it is size_t for speed, but it is unsigned char on weird platforms. */ #if BOOL_VECTOR_BITS_PER_CHAR == CHAR_BIT typedef size_t bits_word; @@ -137,7 +134,6 @@ enum { BITS_PER_CHAR = CHAR_BIT, BITS_PER_SHORT = CHAR_BIT * sizeof (short), - BITS_PER_INT = CHAR_BIT * sizeof (int), BITS_PER_LONG = CHAR_BIT * sizeof (long int), BITS_PER_EMACS_INT = CHAR_BIT * sizeof (EMACS_INT) }; @@ -241,12 +237,6 @@ extern bool suppress_checking EXTERNALLY_VISIBLE; enum Lisp_Bits { - /* Number of bits in a Lisp_Object tag. This can be used in #if, - and for GDB's sake also as a regular symbol. */ - GCTYPEBITS = -#define GCTYPEBITS 3 - GCTYPEBITS, - /* 2**GCTYPEBITS. This must be a macro that expands to a literal integer constant, for MSVC. */ #define GCALIGNMENT 8 @@ -270,31 +260,19 @@ enum Lisp_Bits This can be used in #if, e.g., '#if VAL_MAX < UINTPTR_MAX' below. */ #define VAL_MAX (EMACS_INT_MAX >> (GCTYPEBITS - 1)) -/* Unless otherwise specified, use USE_LSB_TAG on systems where: */ -#ifndef USE_LSB_TAG -/* 1. We know malloc returns a multiple of 8. */ -# if (defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ \ - || defined DARWIN_OS || defined __sun) -/* 2. We can specify multiple-of-8 alignment on static variables. */ -# ifdef alignas -/* 3. Pointers-as-ints exceed VAL_MAX. +/* Whether the least-significant bits of an EMACS_INT contain the tag. On hosts where pointers-as-ints do not exceed VAL_MAX, USE_LSB_TAG is: a. unnecessary, because the top bits of an EMACS_INT are unused, and b. slower, because it typically requires extra masking. - So, default USE_LSB_TAG to true only on hosts where it might be useful. */ -# if VAL_MAX < UINTPTR_MAX -# define USE_LSB_TAG true -# endif -# endif -# endif -#endif -#ifdef USE_LSB_TAG -# undef USE_LSB_TAG -enum enum_USE_LSB_TAG { USE_LSB_TAG = true }; -# define USE_LSB_TAG true -#else -enum enum_USE_LSB_TAG { USE_LSB_TAG = false }; -# define USE_LSB_TAG false + So, USE_LSB_TAG is true only on hosts where it might be useful. */ +DEFINE_GDB_SYMBOL_BEGIN (bool, USE_LSB_TAG) +#define USE_LSB_TAG (EMACS_INT_MAX >> GCTYPEBITS < INTPTR_MAX) +DEFINE_GDB_SYMBOL_END (USE_LSB_TAG) + +#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 #ifndef alignas @@ -304,6 +282,15 @@ enum enum_USE_LSB_TAG { USE_LSB_TAG = false }; # endif #endif +#ifndef USE_STACK_LISP_OBJECTS +# define USE_STACK_LISP_OBJECTS false +#endif + +#if defined HAVE_STRUCT_ATTRIBUTE_ALIGNED && USE_STACK_LISP_OBJECTS +# define GCALIGNED __attribute__ ((aligned (GCALIGNMENT))) +#else +# define GCALIGNED /* empty */ +#endif /* Some operations are so commonly executed that they are implemented as macros, not functions, because otherwise runtime performance would @@ -348,8 +335,8 @@ enum enum_USE_LSB_TAG { USE_LSB_TAG = false }; #define lisp_h_CHECK_LIST_CONS(x, y) CHECK_TYPE (CONSP (x), Qlistp, y) #define lisp_h_CHECK_NUMBER(x) CHECK_TYPE (INTEGERP (x), Qintegerp, x) #define lisp_h_CHECK_SYMBOL(x) CHECK_TYPE (SYMBOLP (x), Qsymbolp, x) -#define lisp_h_CHECK_TYPE(ok, Qxxxp, x) \ - ((ok) ? (void) 0 : (void) wrong_type_argument (Qxxxp, x)) +#define lisp_h_CHECK_TYPE(ok, predicate, x) \ + ((ok) ? (void) 0 : (void) wrong_type_argument (predicate, x)) #define lisp_h_CONSP(x) (XTYPE (x) == Lisp_Cons) #define lisp_h_EQ(x, y) (XLI (x) == XLI (y)) #define lisp_h_FLOATP(x) (XTYPE (x) == Lisp_Float) @@ -369,15 +356,15 @@ enum enum_USE_LSB_TAG { USE_LSB_TAG = false }; #define lisp_h_XCONS(a) \ (eassert (CONSP (a)), (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons)) #define lisp_h_XHASH(a) XUINT (a) -#define lisp_h_XPNTR(a) \ - ((void *) (intptr_t) ((XLI (a) & VALMASK) | (DATA_SEG_BITS & ~VALMASK))) +#define lisp_h_XPNTR(a) ((void *) (intptr_t) (XLI (a) & VALMASK)) #define lisp_h_XSYMBOL(a) \ (eassert (SYMBOLP (a)), (struct Lisp_Symbol *) XUNTAG (a, Lisp_Symbol)) #ifndef GC_CHECK_CONS_LIST # define lisp_h_check_cons_list() ((void) 0) #endif #if USE_LSB_TAG -# define lisp_h_make_number(n) XIL ((EMACS_INT) (n) << INTTYPEBITS) +# define lisp_h_make_number(n) \ + XIL ((EMACS_INT) ((EMACS_UINT) (n) << INTTYPEBITS)) # define lisp_h_XFASTINT(a) XINT (a) # define lisp_h_XINT(a) (XLI (a) >> INTTYPEBITS) # define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK)) @@ -395,7 +382,7 @@ enum enum_USE_LSB_TAG { USE_LSB_TAG = false }; # define CHECK_LIST_CONS(x, y) lisp_h_CHECK_LIST_CONS (x, y) # define CHECK_NUMBER(x) lisp_h_CHECK_NUMBER (x) # define CHECK_SYMBOL(x) lisp_h_CHECK_SYMBOL (x) -# define CHECK_TYPE(ok, Qxxxp, x) lisp_h_CHECK_TYPE (ok, Qxxxp, x) +# define CHECK_TYPE(ok, predicate, x) lisp_h_CHECK_TYPE (ok, predicate, x) # define CONSP(x) lisp_h_CONSP (x) # define EQ(x, y) lisp_h_EQ (x, y) # define FLOATP(x) lisp_h_FLOATP (x) @@ -597,25 +584,15 @@ LISP_MACRO_DEFUN (XIL, Lisp_Object, (EMACS_INT i), (i)) /* In the size word of a vector, this bit means the vector has been marked. */ -#define ARRAY_MARK_FLAG_val PTRDIFF_MIN -#if ENUMABLE (ARRAY_MARK_FLAG_val) -DEFINE_GDB_SYMBOL_ENUM (ARRAY_MARK_FLAG) -#else DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, ARRAY_MARK_FLAG) -# define ARRAY_MARK_FLAG ARRAY_MARK_FLAG_val +# define ARRAY_MARK_FLAG PTRDIFF_MIN DEFINE_GDB_SYMBOL_END (ARRAY_MARK_FLAG) -#endif /* In the size word of a struct Lisp_Vector, this bit means it's really some other vector-like object. */ -#define PSEUDOVECTOR_FLAG_val (PTRDIFF_MAX - PTRDIFF_MAX / 2) -#if ENUMABLE (PSEUDOVECTOR_FLAG_val) -DEFINE_GDB_SYMBOL_ENUM (PSEUDOVECTOR_FLAG) -#else DEFINE_GDB_SYMBOL_BEGIN (ptrdiff_t, PSEUDOVECTOR_FLAG) -# define PSEUDOVECTOR_FLAG PSEUDOVECTOR_FLAG_val +# define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2) DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG) -#endif /* In a pseudovector, the size field actually contains a word with one PSEUDOVECTOR_FLAG bit set, and one of the following values extracted @@ -641,18 +618,8 @@ enum pvec_type PVEC_FONT /* Should be last because it's used for range checking. */ }; -/* DATA_SEG_BITS forces extra bits to be or'd in with any pointers - which were stored in a Lisp_Object. */ -#ifndef DATA_SEG_BITS -# define DATA_SEG_BITS 0 -#endif -enum { gdb_DATA_SEG_BITS = DATA_SEG_BITS }; -#undef DATA_SEG_BITS - enum More_Lisp_Bits { - DATA_SEG_BITS = gdb_DATA_SEG_BITS, - /* For convenience, we also store the number of elements in these bits. Note that this size is not necessarily the memory-footprint size, but only the number of Lisp_Object fields (that need to be traced by GC). @@ -678,14 +645,9 @@ enum More_Lisp_Bits that cons. */ /* Mask for the value (as opposed to the type bits) of a Lisp object. */ -#define VALMASK_val (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX) -#if ENUMABLE (VALMASK_val) -DEFINE_GDB_SYMBOL_ENUM (VALMASK) -#else DEFINE_GDB_SYMBOL_BEGIN (EMACS_INT, VALMASK) -# define VALMASK VALMASK_val +# define VALMASK (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX) DEFINE_GDB_SYMBOL_END (VALMASK) -#endif /* Largest and smallest representable fixnum values. These are the C values. They are macros for use in static initializers. */ @@ -714,7 +676,14 @@ LISP_MACRO_DEFUN (XUNTAG, void *, (Lisp_Object a, int type), (a, type)) INLINE Lisp_Object make_number (EMACS_INT n) { - return XIL (USE_LSB_TAG ? n << INTTYPEBITS : n & INTMASK); + if (USE_LSB_TAG) + { + EMACS_UINT u = n; + n = u << INTTYPEBITS; + } + else + n &= INTMASK; + return XIL (n); } /* Extract A's value as a signed integer. */ @@ -722,7 +691,12 @@ INLINE EMACS_INT XINT (Lisp_Object a) { EMACS_INT i = XLI (a); - return (USE_LSB_TAG ? i : i << INTTYPEBITS) >> INTTYPEBITS; + if (! USE_LSB_TAG) + { + EMACS_UINT u = i; + i = u << INTTYPEBITS; + } + return i >> INTTYPEBITS; } /* Like XINT (A), but may be faster. A must be nonnegative. @@ -828,7 +802,6 @@ INLINE struct Lisp_Save_Value *XSAVE_VALUE (Lisp_Object); /* Defined in chartab.c. */ extern Lisp_Object char_table_ref (Lisp_Object, int); extern void char_table_set (Lisp_Object, int, Lisp_Object); -extern int char_table_translate (Lisp_Object, int); /* Defined in data.c. */ extern Lisp_Object Qarrayp, Qbufferp, Qbuffer_or_string_p, Qchar_table_p; @@ -837,10 +810,13 @@ extern Lisp_Object Qnumberp, Qstringp, Qsymbolp, Qt, Qvectorp; extern Lisp_Object Qbool_vector_p; extern Lisp_Object Qvector_or_char_table_p, Qwholenump; extern Lisp_Object Qwindow; -extern Lisp_Object Ffboundp (Lisp_Object); extern _Noreturn Lisp_Object wrong_type_argument (Lisp_Object, Lisp_Object); +extern _Noreturn void wrong_choice (Lisp_Object, Lisp_Object); /* Defined in emacs.c. */ +extern bool might_dump; +/* True means Emacs has already been initialized. + Used during startup to detect startup of dumped Emacs. */ extern bool initialized; /* Defined in eval.c. */ @@ -1006,8 +982,9 @@ make_lisp_proc (struct Lisp_Process *p) /* Type checking. */ -LISP_MACRO_DEFUN_VOID (CHECK_TYPE, (int ok, Lisp_Object Qxxxp, Lisp_Object x), - (ok, Qxxxp, x)) +LISP_MACRO_DEFUN_VOID (CHECK_TYPE, + (int ok, Lisp_Object predicate, Lisp_Object x), + (ok, predicate, x)) /* Deprecated and will be removed soon. */ @@ -1017,7 +994,7 @@ LISP_MACRO_DEFUN_VOID (CHECK_TYPE, (int ok, Lisp_Object Qxxxp, Lisp_Object x), typedef struct interval *INTERVAL; -struct Lisp_Cons +struct GCALIGNED Lisp_Cons { /* Car of this cons cell. */ Lisp_Object car; @@ -1201,12 +1178,6 @@ STRING_SET_CHARS (Lisp_Object string, ptrdiff_t newsize) { XSTRING (string)->size = newsize; } -INLINE void -STRING_COPYIN (Lisp_Object string, ptrdiff_t index, char const *new, - ptrdiff_t count) -{ - memcpy (SDATA (string) + index, new, count); -} /* Header of vector-like objects. This documents the layout constraints on vectors and pseudovectors (objects of PVEC_xxx subtype). It also prevents @@ -1415,10 +1386,11 @@ gc_aset (Lisp_Object array, ptrdiff_t idx, Lisp_Object val) sense to handle a char-table with type struct Lisp_Vector. An element of a char table can be any Lisp objects, but if it is a sub char-table, we treat it a table that contains information of a - specific range of characters. A sub char-table has the same - structure as a vector. A sub char table appears only in an element - of a char-table, and there's no way to access it directly from - Emacs Lisp program. */ + specific range of characters. A sub char-table is like a vector but + with two integer fields between the header and Lisp data, which means + that it has to be marked with some precautions (see mark_char_table + in alloc.c). A sub char-table appears only in an element of a char-table, + and there's no way to access it directly from Emacs Lisp program. */ enum CHARTAB_SIZE_BITS { @@ -1473,10 +1445,10 @@ struct Lisp_Sub_Char_Table contains 32 elements, and each element covers 128 characters. A sub char-table of depth 3 contains 128 elements, and each element is for one character. */ - Lisp_Object depth; + int depth; /* Minimum character covered by the sub char-table. */ - Lisp_Object min_char; + int min_char; /* Use set_sub_char_table_contents to set this. */ Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER]; @@ -1547,12 +1519,16 @@ struct Lisp_Subr const char *doc; }; -/* This is the number of slots that every char table must have. This - counts the ordinary slots and the top, defalt, parent, and purpose - slots. */ -enum CHAR_TABLE_STANDARD_SLOTS +enum char_table_specials { - CHAR_TABLE_STANDARD_SLOTS = PSEUDOVECSIZE (struct Lisp_Char_Table, extras) + /* This is the number of slots that every char table must have. This + counts the ordinary slots and the top, defalt, parent, and purpose + slots. */ + CHAR_TABLE_STANDARD_SLOTS = PSEUDOVECSIZE (struct Lisp_Char_Table, extras), + + /* This is an index of first Lisp_Object field in Lisp_Sub_Char_Table + when the latter is treated as an ordinary Lisp_Vector. */ + SUB_CHAR_TABLE_OFFSET = PSEUDOVECSIZE (struct Lisp_Sub_Char_Table, contents) }; /* Return the number of "extra" slots in the char table CT. */ @@ -1564,7 +1540,11 @@ 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); + /*********************************************************************** Symbols ***********************************************************************/ @@ -1987,6 +1967,7 @@ enum Lisp_Save_Type SAVE_TYPE_OBJ_OBJ_OBJ_OBJ = SAVE_OBJECT + (SAVE_TYPE_OBJ_OBJ_OBJ << SAVE_SLOT_BITS), SAVE_TYPE_PTR_INT = SAVE_POINTER + (SAVE_INTEGER << SAVE_SLOT_BITS), + SAVE_TYPE_INT_OBJ = SAVE_INTEGER + (SAVE_OBJECT << SAVE_SLOT_BITS), SAVE_TYPE_PTR_OBJ = SAVE_POINTER + (SAVE_OBJECT << SAVE_SLOT_BITS), SAVE_TYPE_PTR_PTR = SAVE_POINTER + (SAVE_POINTER << SAVE_SLOT_BITS), SAVE_TYPE_FUNCPTR_PTR_OBJ @@ -2555,15 +2536,20 @@ CHECK_BOOL_VECTOR (Lisp_Object x) { CHECK_TYPE (BOOL_VECTOR_P (x), Qbool_vector_p, x); } -INLINE void +/* This is a bit special because we always need size afterwards. */ +INLINE ptrdiff_t CHECK_VECTOR_OR_STRING (Lisp_Object x) { - CHECK_TYPE (VECTORP (x) || STRINGP (x), Qarrayp, x); + if (VECTORP (x)) + return ASIZE (x); + if (STRINGP (x)) + return SCHARS (x); + wrong_type_argument (Qarrayp, x); } INLINE void -CHECK_ARRAY (Lisp_Object x, Lisp_Object Qxxxp) +CHECK_ARRAY (Lisp_Object x, Lisp_Object predicate) { - CHECK_TYPE (ARRAYP (x), Qxxxp, x); + CHECK_TYPE (ARRAYP (x), predicate, x); } INLINE void CHECK_BUFFER (Lisp_Object x) @@ -2690,16 +2676,10 @@ CHECK_NUMBER_CDR (Lisp_Object x) minargs, maxargs, lname, intspec, 0}; \ Lisp_Object fnname #else /* not _MSC_VER */ -# if __STDC_VERSION__ < 199901 -# define DEFUN_FUNCTION_INIT(fnname, maxargs) (Lisp_Object (*) (void)) fnname -# else -# define DEFUN_FUNCTION_INIT(fnname, maxargs) .a ## maxargs = fnname -# endif #define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ - Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \ static struct Lisp_Subr alignas (GCALIGNMENT) sname = \ { { PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, \ - { DEFUN_FUNCTION_INIT (fnname, maxargs) }, \ + { .a ## maxargs = fnname }, \ minargs, maxargs, lname, intspec, 0}; \ Lisp_Object fnname #endif @@ -3036,6 +3016,16 @@ struct gcpro ptrdiff_t nvars; #ifdef DEBUG_GCPRO + /* File name where this record is used. */ + const char *name; + + /* Line number in this file. */ + int lineno; + + /* Index in the local chain of records. */ + int idx; + + /* Nesting level. */ int level; #endif }; @@ -3091,122 +3081,150 @@ struct gcpro #ifndef DEBUG_GCPRO -#define GCPRO1(varname) \ - {gcpro1.next = gcprolist; gcpro1.var = &varname; gcpro1.nvars = 1; \ - gcprolist = &gcpro1; } +#define GCPRO1(a) \ + { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ + gcprolist = &gcpro1; } + +#define GCPRO2(a, b) \ + { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ + gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ + gcprolist = &gcpro2; } + +#define GCPRO3(a, b, c) \ + { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ + gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ + gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ + gcprolist = &gcpro3; } + +#define GCPRO4(a, b, c, d) \ + { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ + gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ + gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ + gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \ + gcprolist = &gcpro4; } + +#define GCPRO5(a, b, c, d, e) \ + { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ + gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ + gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ + gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \ + gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \ + gcprolist = &gcpro5; } + +#define GCPRO6(a, b, c, d, e, f) \ + { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ + gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ + gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ + gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \ + gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \ + gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1; \ + gcprolist = &gcpro6; } -#define GCPRO2(varname1, varname2) \ - {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ - gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ - gcprolist = &gcpro2; } - -#define GCPRO3(varname1, varname2, varname3) \ - {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ - gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ - gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \ - gcprolist = &gcpro3; } - -#define GCPRO4(varname1, varname2, varname3, varname4) \ - {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ - gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ - gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \ - gcpro4.next = &gcpro3; gcpro4.var = &varname4; gcpro4.nvars = 1; \ - gcprolist = &gcpro4; } - -#define GCPRO5(varname1, varname2, varname3, varname4, varname5) \ - {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ - gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ - gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \ - gcpro4.next = &gcpro3; gcpro4.var = &varname4; gcpro4.nvars = 1; \ - gcpro5.next = &gcpro4; gcpro5.var = &varname5; gcpro5.nvars = 1; \ - gcprolist = &gcpro5; } - -#define GCPRO6(varname1, varname2, varname3, varname4, varname5, varname6) \ - {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ - gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ - gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \ - gcpro4.next = &gcpro3; gcpro4.var = &varname4; gcpro4.nvars = 1; \ - gcpro5.next = &gcpro4; gcpro5.var = &varname5; gcpro5.nvars = 1; \ - gcpro6.next = &gcpro5; gcpro6.var = &varname6; gcpro6.nvars = 1; \ - gcprolist = &gcpro6; } - -#define GCPRO7(a, b, c, d, e, f, g) \ - {gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ - gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ - gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ - gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \ - gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \ - gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1; \ - gcpro7.next = &gcpro6; gcpro7.var = &(g); gcpro7.nvars = 1; \ - gcprolist = &gcpro7; } +#define GCPRO7(a, b, c, d, e, f, g) \ + { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ + gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ + gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ + gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \ + gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \ + gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1; \ + gcpro7.next = &gcpro6; gcpro7.var = &(g); gcpro7.nvars = 1; \ + gcprolist = &gcpro7; } #define UNGCPRO (gcprolist = gcpro1.next) -#else +#else /* !DEBUG_GCPRO */ extern int gcpro_level; -#define GCPRO1(varname) \ - {gcpro1.next = gcprolist; gcpro1.var = &varname; gcpro1.nvars = 1; \ - gcpro1.level = gcpro_level++; \ - gcprolist = &gcpro1; } - -#define GCPRO2(varname1, varname2) \ - {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ - gcpro1.level = gcpro_level; \ - gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ - gcpro2.level = gcpro_level++; \ - gcprolist = &gcpro2; } - -#define GCPRO3(varname1, varname2, varname3) \ - {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ - gcpro1.level = gcpro_level; \ - gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ - gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \ - gcpro3.level = gcpro_level++; \ - gcprolist = &gcpro3; } - -#define GCPRO4(varname1, varname2, varname3, varname4) \ - {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ - gcpro1.level = gcpro_level; \ - gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ - gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \ - gcpro4.next = &gcpro3; gcpro4.var = &varname4; gcpro4.nvars = 1; \ - gcpro4.level = gcpro_level++; \ - gcprolist = &gcpro4; } - -#define GCPRO5(varname1, varname2, varname3, varname4, varname5) \ - {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ - gcpro1.level = gcpro_level; \ - gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ - gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \ - gcpro4.next = &gcpro3; gcpro4.var = &varname4; gcpro4.nvars = 1; \ - gcpro5.next = &gcpro4; gcpro5.var = &varname5; gcpro5.nvars = 1; \ - gcpro5.level = gcpro_level++; \ - gcprolist = &gcpro5; } - -#define GCPRO6(varname1, varname2, varname3, varname4, varname5, varname6) \ - {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \ - gcpro1.level = gcpro_level; \ - gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \ - gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \ - gcpro4.next = &gcpro3; gcpro4.var = &varname4; gcpro4.nvars = 1; \ - gcpro5.next = &gcpro4; gcpro5.var = &varname5; gcpro5.nvars = 1; \ - gcpro6.next = &gcpro5; gcpro6.var = &varname6; gcpro6.nvars = 1; \ - gcpro6.level = gcpro_level++; \ - gcprolist = &gcpro6; } +#define GCPRO1(a) \ + { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ + gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1; \ + gcpro1.level = gcpro_level++; \ + gcprolist = &gcpro1; } + +#define GCPRO2(a, b) \ + { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ + gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1; \ + gcpro1.level = gcpro_level; \ + gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ + gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2; \ + gcpro2.level = gcpro_level++; \ + gcprolist = &gcpro2; } + +#define GCPRO3(a, b, c) \ + { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ + gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1; \ + gcpro1.level = gcpro_level; \ + gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ + gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2; \ + gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ + gcpro3.name = __FILE__; gcpro3.lineno = __LINE__; gcpro3.idx = 3; \ + gcpro3.level = gcpro_level++; \ + gcprolist = &gcpro3; } + +#define GCPRO4(a, b, c, d) \ + { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ + gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1; \ + gcpro1.level = gcpro_level; \ + gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ + gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2; \ + gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ + gcpro3.name = __FILE__; gcpro3.lineno = __LINE__; gcpro3.idx = 3; \ + gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \ + gcpro4.name = __FILE__; gcpro4.lineno = __LINE__; gcpro4.idx = 4; \ + gcpro4.level = gcpro_level++; \ + gcprolist = &gcpro4; } + +#define GCPRO5(a, b, c, d, e) \ + { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ + gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1; \ + gcpro1.level = gcpro_level; \ + gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ + gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2; \ + gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ + gcpro3.name = __FILE__; gcpro3.lineno = __LINE__; gcpro3.idx = 3; \ + gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \ + gcpro4.name = __FILE__; gcpro4.lineno = __LINE__; gcpro4.idx = 4; \ + gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \ + gcpro5.name = __FILE__; gcpro5.lineno = __LINE__; gcpro5.idx = 5; \ + gcpro5.level = gcpro_level++; \ + gcprolist = &gcpro5; } + +#define GCPRO6(a, b, c, d, e, f) \ + { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ + gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1; \ + gcpro1.level = gcpro_level; \ + gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ + gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2; \ + gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ + gcpro3.name = __FILE__; gcpro3.lineno = __LINE__; gcpro3.idx = 3; \ + gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \ + gcpro4.name = __FILE__; gcpro4.lineno = __LINE__; gcpro4.idx = 4; \ + gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \ + gcpro5.name = __FILE__; gcpro5.lineno = __LINE__; gcpro5.idx = 5; \ + gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1; \ + gcpro6.name = __FILE__; gcpro6.lineno = __LINE__; gcpro6.idx = 6; \ + gcpro6.level = gcpro_level++; \ + gcprolist = &gcpro6; } #define GCPRO7(a, b, c, d, e, f, g) \ - {gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ - gcpro1.level = gcpro_level; \ - gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ - gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ - gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \ - gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \ - gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1; \ - gcpro7.next = &gcpro6; gcpro7.var = &(g); gcpro7.nvars = 1; \ - gcpro7.level = gcpro_level++; \ - gcprolist = &gcpro7; } + { gcpro1.next = gcprolist; gcpro1.var = &(a); gcpro1.nvars = 1; \ + gcpro1.name = __FILE__; gcpro1.lineno = __LINE__; gcpro1.idx = 1; \ + gcpro1.level = gcpro_level; \ + gcpro2.next = &gcpro1; gcpro2.var = &(b); gcpro2.nvars = 1; \ + gcpro2.name = __FILE__; gcpro2.lineno = __LINE__; gcpro2.idx = 2; \ + gcpro3.next = &gcpro2; gcpro3.var = &(c); gcpro3.nvars = 1; \ + gcpro3.name = __FILE__; gcpro3.lineno = __LINE__; gcpro3.idx = 3; \ + gcpro4.next = &gcpro3; gcpro4.var = &(d); gcpro4.nvars = 1; \ + gcpro4.name = __FILE__; gcpro4.lineno = __LINE__; gcpro4.idx = 4; \ + gcpro5.next = &gcpro4; gcpro5.var = &(e); gcpro5.nvars = 1; \ + gcpro5.name = __FILE__; gcpro5.lineno = __LINE__; gcpro5.idx = 5; \ + gcpro6.next = &gcpro5; gcpro6.var = &(f); gcpro6.nvars = 1; \ + gcpro6.name = __FILE__; gcpro6.lineno = __LINE__; gcpro6.idx = 6; \ + gcpro7.next = &gcpro6; gcpro7.var = &(g); gcpro7.nvars = 1; \ + gcpro7.name = __FILE__; gcpro7.lineno = __LINE__; gcpro7.idx = 7; \ + gcpro7.level = gcpro_level++; \ + gcprolist = &gcpro7; } #define UNGCPRO \ (--gcpro_level != gcpro1.level \ @@ -3359,7 +3377,7 @@ set_sub_char_table_contents (Lisp_Object table, ptrdiff_t idx, Lisp_Object val) } /* Defined in data.c. */ -extern Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound; +extern Lisp_Object Qquote, Qunbound; extern Lisp_Object Qerror_conditions, Qerror_message, Qtop_level; extern Lisp_Object Qerror, Qquit, Qargs_out_of_range; extern Lisp_Object Qvoid_variable, Qvoid_function; @@ -3370,26 +3388,18 @@ extern Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only; extern Lisp_Object Qtext_read_only; extern Lisp_Object Qinteractive_form; extern Lisp_Object Qcircular_list; -extern Lisp_Object Qintegerp, Qwholenump, Qsymbolp, Qlistp, Qconsp; -extern Lisp_Object Qstringp, Qarrayp, Qsequencep, Qbufferp; -extern Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qvectorp; -extern Lisp_Object Qbuffer_or_string_p; +extern Lisp_Object Qsequencep; +extern Lisp_Object Qchar_or_string_p, Qinteger_or_marker_p; extern Lisp_Object Qfboundp; -extern Lisp_Object Qchar_table_p, Qvector_or_char_table_p; extern Lisp_Object Qcdr; extern Lisp_Object Qrange_error, Qoverflow_error; -extern Lisp_Object Qfloatp; -extern Lisp_Object Qnumberp, Qnumber_or_marker_p; +extern Lisp_Object Qnumber_or_marker_p; extern Lisp_Object Qbuffer, Qinteger, Qsymbol; -extern Lisp_Object Qfont_spec, Qfont_entity, Qfont_object; - -EXFUN (Fbyteorder, 0) ATTRIBUTE_CONST; - /* Defined in data.c. */ extern Lisp_Object indirect_function (Lisp_Object); extern Lisp_Object find_symbol_value (Lisp_Object); @@ -3436,7 +3446,6 @@ extern struct Lisp_Symbol *indirect_variable (struct Lisp_Symbol *); extern _Noreturn void args_out_of_range (Lisp_Object, Lisp_Object); extern _Noreturn void args_out_of_range_3 (Lisp_Object, Lisp_Object, Lisp_Object); -extern _Noreturn Lisp_Object wrong_type_argument (Lisp_Object, Lisp_Object); extern Lisp_Object do_symval_forwarding (union Lisp_Fwd *); extern void set_internal (Lisp_Object, Lisp_Object, Lisp_Object, bool); extern void syms_of_data (void); @@ -3455,11 +3464,8 @@ extern void init_coding_once (void); extern void syms_of_coding (void); /* Defined in character.c. */ -EXFUN (Fmax_char, 0) ATTRIBUTE_CONST; extern ptrdiff_t chars_in_text (const unsigned char *, ptrdiff_t); extern ptrdiff_t multibyte_chars_in_text (const unsigned char *, ptrdiff_t); -extern int multibyte_char_to_unibyte (int) ATTRIBUTE_CONST; -extern int multibyte_char_to_unibyte_safe (int) ATTRIBUTE_CONST; extern void syms_of_character (void); /* Defined in charset.c. */ @@ -3469,9 +3475,6 @@ extern void syms_of_charset (void); /* Structure forward declarations. */ struct charset; -/* Defined in composite.c. */ -extern void syms_of_composite (void); - /* Defined in syntax.c. */ extern void init_syntax_once (void); extern void syms_of_syntax (void); @@ -3479,7 +3482,6 @@ extern void syms_of_syntax (void); /* Defined in fns.c. */ extern Lisp_Object QCrehash_size, QCrehash_threshold; enum { NEXT_ALMOST_PRIME_LIMIT = 11 }; -EXFUN (Fidentity, 1) ATTRIBUTE_CONST; extern EMACS_INT next_almost_prime (EMACS_INT) ATTRIBUTE_CONST; extern Lisp_Object larger_vector (Lisp_Object, ptrdiff_t, ptrdiff_t); extern void sweep_weak_hash_tables (void); @@ -3494,7 +3496,8 @@ ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *); ptrdiff_t hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object, EMACS_UINT); extern struct hash_table_test hashtest_eql, hashtest_equal; - +extern void validate_subarray (Lisp_Object, Lisp_Object, Lisp_Object, + ptrdiff_t, ptrdiff_t *, ptrdiff_t *); extern Lisp_Object substring_both (Lisp_Object, ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t); extern Lisp_Object merge (Lisp_Object, Lisp_Object, Lisp_Object); @@ -3512,7 +3515,6 @@ extern Lisp_Object string_make_unibyte (Lisp_Object); extern void syms_of_fns (void); /* Defined in floatfns.c. */ -extern double extract_float (Lisp_Object); extern void syms_of_floatfns (void); extern Lisp_Object fmod_float (Lisp_Object x, Lisp_Object y); @@ -3533,6 +3535,7 @@ extern void syms_of_image (void); /* Defined in insdel.c. */ extern Lisp_Object Qinhibit_modification_hooks; +extern Lisp_Object Qregion_extract_function; extern void move_gap_both (ptrdiff_t, ptrdiff_t); extern _Noreturn void buffer_overflow (void); extern void make_gap (ptrdiff_t); @@ -3585,18 +3588,16 @@ _Noreturn void __executable_start (void); #endif extern Lisp_Object Vwindow_system; extern Lisp_Object sit_for (Lisp_Object, bool, int); -extern void init_display (void); -extern void syms_of_display (void); /* Defined in xdisp.c. */ extern Lisp_Object Qinhibit_point_motion_hooks; -extern Lisp_Object Qinhibit_redisplay, Qdisplay; +extern Lisp_Object Qinhibit_redisplay; extern Lisp_Object Qmenu_bar_update_hook; extern Lisp_Object Qwindow_scroll_functions; extern Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map; -extern Lisp_Object Qimage, Qtext, Qboth, Qboth_horiz, Qtext_image_horiz; +extern Lisp_Object Qtext, Qboth, Qboth_horiz, Qtext_image_horiz; extern Lisp_Object Qspace, Qcenter, QCalign_to; -extern Lisp_Object Qbar, Qhbar, Qbox, Qhollow; +extern Lisp_Object Qbar, Qhbar, Qhollow; extern Lisp_Object Qleft_margin, Qright_margin; extern Lisp_Object QCdata, QCfile; extern Lisp_Object QCmap; @@ -3623,7 +3624,6 @@ extern void message_log_maybe_newline (void); extern void update_echo_area (void); extern void truncate_echo_area (ptrdiff_t); extern void redisplay (void); -extern void redisplay_preserve_echo_area (int); void set_frame_cursor_types (struct frame *, Lisp_Object); extern void syms_of_xdisp (void); @@ -3638,6 +3638,10 @@ extern void syms_of_xsettings (void); /* Defined in vm-limit.c. */ extern void memory_warnings (void *, void (*warnfun) (const char *)); +/* Defined in character.c. */ +extern void parse_str_as_multibyte (const unsigned char *, ptrdiff_t, + ptrdiff_t *, ptrdiff_t *); + /* Defined in alloc.c. */ extern void check_pure_size (void); extern void free_misc (Lisp_Object); @@ -3647,7 +3651,7 @@ extern _Noreturn void memory_full (size_t); extern _Noreturn void buffer_memory_full (ptrdiff_t); extern bool survives_gc_p (Lisp_Object); extern void mark_object (Lisp_Object); -#if defined REL_ALLOC && !defined SYSTEM_MALLOC +#if defined REL_ALLOC && !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC extern void refill_memory_reserve (void); #endif extern const char *pending_malloc_warning; @@ -3690,6 +3694,8 @@ extern Lisp_Object make_uninit_bool_vector (EMACS_INT); extern Lisp_Object bool_vector_fill (Lisp_Object, Lisp_Object); extern _Noreturn void string_overflow (void); extern Lisp_Object make_string (const char *, ptrdiff_t); +extern Lisp_Object local_string_init (struct Lisp_String *, char const *, + ptrdiff_t); extern Lisp_Object make_formatted_string (char *, const char *, ...) ATTRIBUTE_FORMAT_PRINTF (2, 3); extern Lisp_Object make_unibyte_string (const char *, ptrdiff_t); @@ -3755,6 +3761,20 @@ make_uninit_vector (ptrdiff_t size) return v; } +/* Like above, but special for sub char-tables. */ + +INLINE Lisp_Object +make_uninit_sub_char_table (int depth, int min_char) +{ + int slots = SUB_CHAR_TABLE_OFFSET + chartab_size[depth]; + Lisp_Object v = make_uninit_vector (slots); + + XSETPVECTYPE (XVECTOR (v), PVEC_SUB_CHAR_TABLE); + XSUB_CHAR_TABLE (v)->depth = depth; + XSUB_CHAR_TABLE (v)->min_char = min_char; + return v; +} + extern struct Lisp_Vector *allocate_pseudovector (int, int, enum pvec_type); #define ALLOCATE_PSEUDOVECTOR(typ,field,tag) \ ((typ*) \ @@ -3764,6 +3784,8 @@ 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 Lisp_Object local_vector_init (struct Lisp_Vector *, ptrdiff_t, + Lisp_Object); extern struct terminal *allocate_terminal (void); extern bool gc_in_progress; extern bool abort_on_gc; @@ -3776,6 +3798,7 @@ extern Lisp_Object make_save_obj_obj_obj_obj (Lisp_Object, Lisp_Object, extern Lisp_Object make_save_ptr (void *); extern Lisp_Object make_save_ptr_int (void *, ptrdiff_t); extern Lisp_Object make_save_ptr_ptr (void *, void *); +extern Lisp_Object make_save_int_obj (ptrdiff_t, Lisp_Object); extern Lisp_Object make_save_funcptr_ptr_obj (void (*) (void), void *, Lisp_Object); extern Lisp_Object make_save_memory (Lisp_Object *, ptrdiff_t); @@ -3788,6 +3811,7 @@ extern void init_alloc (void); extern void syms_of_alloc (void); extern struct buffer * allocate_buffer (void); extern int valid_lisp_object_p (Lisp_Object); +extern int relocatable_string_data_p (const char *); #ifdef GC_CHECK_CONS_LIST extern void check_cons_list (void); #else @@ -3796,21 +3820,18 @@ INLINE void (check_cons_list) (void) { lisp_h_check_cons_list (); } #ifdef REL_ALLOC /* Defined in ralloc.c. */ -extern void *r_alloc (void **, size_t); +extern void *r_alloc (void **, size_t) ATTRIBUTE_ALLOC_SIZE ((2)); extern void r_alloc_free (void **); -extern void *r_re_alloc (void **, size_t); +extern void *r_re_alloc (void **, size_t) ATTRIBUTE_ALLOC_SIZE ((2)); extern void r_alloc_reset_variable (void **, void **); extern void r_alloc_inhibit_buffer_relocation (int); #endif /* Defined in chartab.c. */ extern Lisp_Object copy_char_table (Lisp_Object); -extern Lisp_Object char_table_ref (Lisp_Object, int); extern Lisp_Object char_table_ref_and_range (Lisp_Object, int, int *, int *); -extern void char_table_set (Lisp_Object, int, Lisp_Object); extern void char_table_set_range (Lisp_Object, int, int, Lisp_Object); -extern int char_table_translate (Lisp_Object, int); extern void map_char_table (void (*) (Lisp_Object, Lisp_Object, Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object); @@ -3888,7 +3909,8 @@ intern_c_string (const char *str) } /* Defined in eval.c. */ -extern Lisp_Object Qautoload, Qexit, Qinteractive, Qcommandp, Qmacro; +extern EMACS_INT lisp_eval_depth; +extern Lisp_Object Qexit, Qinteractive, Qcommandp, Qmacro; extern Lisp_Object Qinhibit_quit, Qinternal_interpreter_environment, Qclosure; extern Lisp_Object Qand_rest; extern Lisp_Object Vautoload_queue; @@ -3992,7 +4014,7 @@ extern bool overlay_touches_p (ptrdiff_t); extern Lisp_Object other_buffer_safely (Lisp_Object); extern Lisp_Object get_truename_buffer (Lisp_Object); extern void init_buffer_once (void); -extern void init_buffer (void); +extern void init_buffer (int); extern void syms_of_buffer (void); extern void keys_of_buffer (void); @@ -4023,7 +4045,6 @@ extern Lisp_Object expand_and_dir_to_file (Lisp_Object, Lisp_Object); extern Lisp_Object write_region (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, int); -EXFUN (Fread_file_name, 6); /* Not a normal DEFUN. */ extern void close_file_unwind (int); extern void fclose_unwind (void *); extern void restore_point_unwind (Lisp_Object); @@ -4032,7 +4053,7 @@ extern _Noreturn void report_file_error (const char *, Lisp_Object); extern bool internal_delete_file (Lisp_Object); extern Lisp_Object emacs_readlinkat (int, const char *); extern bool file_directory_p (const char *); -extern bool file_accessible_directory_p (const char *); +extern bool file_accessible_directory_p (Lisp_Object); extern void init_fileio (void); extern void syms_of_fileio (void); extern Lisp_Object make_temp_name (Lisp_Object, bool); @@ -4075,6 +4096,7 @@ extern void syms_of_minibuf (void); /* Defined in callint.c. */ extern Lisp_Object Qminus, Qplus; +extern Lisp_Object Qprogn; extern Lisp_Object Qwhen; extern Lisp_Object Qmouse_leave_buffer_hook; extern void syms_of_callint (void); @@ -4096,10 +4118,12 @@ extern Lisp_Object echo_message_buffer; extern struct kboard *echo_kboard; extern void cancel_echoing (void); extern Lisp_Object Qdisabled, QCfilter; -extern Lisp_Object Qup, Qdown, Qbottom; -extern Lisp_Object Qtop; +extern Lisp_Object Qup, Qdown; extern Lisp_Object last_undo_boundary; extern bool input_pending; +#ifdef HAVE_STACK_OVERFLOW_HANDLING +extern sigjmp_buf return_to_command_loop; +#endif extern Lisp_Object menu_bar_items (Lisp_Object); extern Lisp_Object tool_bar_items (Lisp_Object, int *); extern void discard_mouse_events (void); @@ -4129,14 +4153,10 @@ extern void syms_of_indent (void); /* Defined in frame.c. */ extern Lisp_Object Qonly, Qnone; -extern Lisp_Object Qvisible; -extern void set_frame_param (struct frame *, Lisp_Object, Lisp_Object); extern void store_frame_param (struct frame *, Lisp_Object, Lisp_Object); extern void store_in_alist (Lisp_Object *, Lisp_Object, Lisp_Object); extern Lisp_Object do_switch_frame (Lisp_Object, int, int, Lisp_Object); -#if HAVE_NS || HAVE_NTGUI extern Lisp_Object get_frame_param (struct frame *, Lisp_Object); -#endif extern void frames_discard_buffer (Lisp_Object); extern void syms_of_frame (void); @@ -4187,10 +4207,8 @@ extern bool running_asynch_code; /* Defined in process.c. */ extern Lisp_Object QCtype, Qlocal; extern void kill_buffer_processes (Lisp_Object); -extern bool wait_reading_process_output (intmax_t, int, int, bool, - Lisp_Object, - struct Lisp_Process *, - int); +extern int wait_reading_process_output (intmax_t, int, int, bool, Lisp_Object, + struct Lisp_Process *, int); /* Max value for the first argument of wait_reading_process_output. */ #if __GNUC__ == 3 || (__GNUC__ == 4 && __GNUC_MINOR__ <= 5) /* Work around a bug in GCC 3.4.2, known to be fixed in GCC 4.6.3. @@ -4199,6 +4217,9 @@ extern bool wait_reading_process_output (intmax_t, int, int, bool, #else # define WAIT_READING_MAX INTMAX_MAX #endif +#ifdef HAVE_TIMERFD +extern void add_timer_wait_descriptor (int); +#endif extern void add_keyboard_wait_descriptor (int); extern void delete_keyboard_wait_descriptor (int); #ifdef HAVE_GPM @@ -4253,9 +4274,8 @@ extern void record_property_change (ptrdiff_t, ptrdiff_t, Lisp_Object); extern void syms_of_undo (void); /* Defined in textprop.c. */ -extern Lisp_Object Qfont, Qmouse_face; +extern Lisp_Object Qmouse_face; extern Lisp_Object Qinsert_in_front_hooks, Qinsert_behind_hooks; -extern Lisp_Object Qfront_sticky, Qrear_nonsticky; extern Lisp_Object Qminibuffer_prompt; extern void report_interval_modification (Lisp_Object, Lisp_Object); @@ -4278,12 +4298,9 @@ extern char *get_current_dir_name (void); #endif extern void stuff_char (char c); extern void init_foreground_group (void); -extern void init_sigio (int); extern void sys_subshell (void); extern void sys_suspend (void); extern void discard_tty_input (void); -extern void block_tty_out_signal (void); -extern void unblock_tty_out_signal (void); extern void init_sys_modes (struct tty_display_info *); extern void reset_sys_modes (struct tty_display_info *); extern void init_all_sys_modes (void); @@ -4309,6 +4326,7 @@ extern void lock_file (Lisp_Object); extern void unlock_file (Lisp_Object); extern void unlock_buffer (struct buffer *); extern void syms_of_filelock (void); +extern int str_collate (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); /* Defined in sound.c. */ extern void syms_of_sound (void); @@ -4365,8 +4383,8 @@ extern void syms_of_w32notify (void); #endif /* Defined in xfaces.c. */ -extern Lisp_Object Qdefault, Qtool_bar, Qfringe; -extern Lisp_Object Qheader_line, Qscroll_bar, Qcursor; +extern Lisp_Object Qdefault, Qfringe; +extern Lisp_Object Qscroll_bar, Qcursor; extern Lisp_Object Qmode_line_inactive; extern Lisp_Object Qface; extern Lisp_Object Qnormal; @@ -4425,34 +4443,37 @@ extern void syms_of_profiler (void); /* Defined in msdos.c, w32.c. */ extern char *emacs_root_dir (void); #endif /* DOS_NT */ - -/* True means Emacs has already been initialized. - Used during startup to detect startup of dumped Emacs. */ -extern bool initialized; + +/* Defined in lastfile.c. */ +extern char my_edata[]; +extern char my_endbss[]; +extern char *my_endbss_static; /* True means ^G can quit instantly. */ extern bool immediate_quit; -extern void *xmalloc (size_t); -extern void *xzalloc (size_t); -extern void *xrealloc (void *, size_t); +extern void *xmalloc (size_t) ATTRIBUTE_MALLOC_SIZE ((1)); +extern void *xzalloc (size_t) ATTRIBUTE_MALLOC_SIZE ((1)); +extern void *xrealloc (void *, size_t) ATTRIBUTE_ALLOC_SIZE ((2)); extern void xfree (void *); -extern void *xnmalloc (ptrdiff_t, ptrdiff_t); -extern void *xnrealloc (void *, ptrdiff_t, ptrdiff_t); +extern void *xnmalloc (ptrdiff_t, ptrdiff_t) ATTRIBUTE_MALLOC_SIZE ((1,2)); +extern void *xnrealloc (void *, ptrdiff_t, ptrdiff_t) + ATTRIBUTE_ALLOC_SIZE ((2,3)); extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t); -extern char *xstrdup (const char *); -extern char *xlispstrdup (Lisp_Object); +extern char *xstrdup (const char *) ATTRIBUTE_MALLOC; +extern char *xlispstrdup (Lisp_Object) ATTRIBUTE_MALLOC; extern void dupstring (char **, char const *); extern void xputenv (const char *); -extern char *egetenv (const char *); - -/* Copy Lisp string to temporary (allocated on stack) C string. */ +extern char *egetenv_internal (const char *, ptrdiff_t); -#define xlispstrdupa(string) \ - memcpy (alloca (SBYTES (string) + 1), \ - SSDATA (string), SBYTES (string) + 1) +INLINE char * +egetenv (const char *var) +{ + /* When VAR is a string literal, strlen can be optimized away. */ + return egetenv_internal (var, strlen (var)); +} /* Set up the name of the machine we're running on. */ extern void init_system_name (void); @@ -4474,14 +4495,14 @@ extern void init_system_name (void); enum MAX_ALLOCA { MAX_ALLOCA = 16 * 1024 }; -extern void *record_xmalloc (size_t); +extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1)); #define USE_SAFE_ALLOCA \ ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = false /* SAFE_ALLOCA allocates a simple buffer. */ -#define SAFE_ALLOCA(size) ((size) < MAX_ALLOCA \ +#define SAFE_ALLOCA(size) ((size) <= MAX_ALLOCA \ ? alloca (size) \ : (sa_must_free = true, record_xmalloc (size))) @@ -4501,6 +4522,14 @@ extern void *record_xmalloc (size_t); } \ } while (false) +/* SAFE_ALLOCA_STRING allocates a C copy of a Lisp string. */ + +#define SAFE_ALLOCA_STRING(ptr, string) \ + do { \ + (ptr) = SAFE_ALLOCA (SBYTES (string) + 1); \ + memcpy (ptr, SDATA (string), SBYTES (string) + 1); \ + } while (false) + /* SAFE_FREE frees xmalloced memory and enables GC as needed. */ #define SAFE_FREE() \ @@ -4516,9 +4545,9 @@ extern void *record_xmalloc (size_t); #define SAFE_ALLOCA_LISP(buf, nelt) \ do { \ - if ((nelt) < MAX_ALLOCA / word_size) \ + if ((nelt) <= MAX_ALLOCA / word_size) \ (buf) = alloca ((nelt) * word_size); \ - else if ((nelt) < min (PTRDIFF_MAX, SIZE_MAX) / word_size) \ + else if ((nelt) <= min (PTRDIFF_MAX, SIZE_MAX) / word_size) \ { \ Lisp_Object arg_; \ (buf) = xmalloc ((nelt) * word_size); \ @@ -4530,6 +4559,102 @@ extern void *record_xmalloc (size_t); memory_full (SIZE_MAX); \ } while (false) + +/* If USE_STACK_LISP_OBJECTS, define macros that and functions that + allocate block-scoped conses and function-scoped vectors and + strings. These objects are not managed by the garbage collector, + so they are dangerous: passing them out of their scope (e.g., to + user code) results in undefined behavior. Conversely, they have + better performance because GC is not involved. + + This feature is experimental and requires careful debugging. + Brave users can compile with CPPFLAGS='-DUSE_STACK_LISP_OBJECTS' + to get into the game. */ + +/* A struct Lisp_Cons inside a union that is no larger and may be + better-aligned. */ + +union Aligned_Cons +{ + struct Lisp_Cons s; + double d; intmax_t i; void *p; +}; +verify (sizeof (struct Lisp_Cons) == sizeof (union Aligned_Cons)); + +/* Allocate a block-scoped cons. */ + +#define scoped_cons(car, cdr) \ + ((USE_STACK_LISP_OBJECTS \ + && alignof (union Aligned_Cons) % GCALIGNMENT == 0) \ + ? make_lisp_ptr (&((union Aligned_Cons) {{car, {cdr}}}).s, Lisp_Cons) \ + : Fcons (car, cdr)) + +/* Convenient utility macros similar to listX functions. */ + +#if USE_STACK_LISP_OBJECTS +# define scoped_list1(x) scoped_cons (x, Qnil) +# define scoped_list2(x, y) scoped_cons (x, scoped_list1 (y)) +# define scoped_list3(x, y, z) scoped_cons (x, scoped_list2 (y, z)) +#else +# define scoped_list1(x) list1 (x) +# define scoped_list2(x, y) list2 (x, y) +# define scoped_list3(x, y, z) list3 (x, y, z) +#endif + +#if USE_STACK_LISP_OBJECTS && HAVE_STATEMENT_EXPRESSIONS + +# define USE_LOCAL_ALLOCATORS + +/* Return a function-scoped vector of length SIZE, with each element + being INIT. */ + +# define make_local_vector(size, init) \ + ({ \ + ptrdiff_t size_ = size; \ + Lisp_Object init_ = init; \ + Lisp_Object vec_; \ + if (size_ <= (MAX_ALLOCA - header_size) / word_size) \ + { \ + void *ptr_ = alloca (size_ * word_size + header_size); \ + vec_ = local_vector_init (ptr_, size_, init_); \ + } \ + else \ + vec_ = Fmake_vector (make_number (size_), init_); \ + vec_; \ + }) + +/* Return a function-scoped string with contents DATA and length NBYTES. */ + +# define make_local_string(data, nbytes) \ + ({ \ + char const *data_ = data; \ + ptrdiff_t nbytes_ = nbytes; \ + Lisp_Object string_; \ + if (nbytes_ <= MAX_ALLOCA - sizeof (struct Lisp_String) - 1) \ + { \ + struct Lisp_String *ptr_ \ + = alloca (sizeof (struct Lisp_String) + 1 + nbytes_); \ + string_ = local_string_init (ptr_, data_, nbytes_); \ + } \ + else \ + string_ = make_string (data_, nbytes_); \ + string_; \ + }) + +/* Return a function-scoped string with contents DATA. */ + +# define build_local_string(data) \ + ({ char const *data_ = data; make_local_string (data_, strlen (data_)); }) + +#else + +/* Safer but slower implementations. */ +# define make_local_vector(size, init) Fmake_vector (make_number (size), init) +# define make_local_string(data, nbytes) make_string (data, nbytes) +# define build_local_string(data) build_string (data) +#endif + + /* Loop over all tails of a list, checking for cycles. FIXME: Make tortoise and n internal declarations. FIXME: Unroll the loop body so we don't need `n'. */ |