X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/41b7f8bc6c4511ab6fcf7f6b1f9e7fdcd8592821..9fb0c957319ac71aca7b668bd3ee781590f59b19:/src/lisp.h diff --git a/src/lisp.h b/src/lisp.h index 8093682f0f..e23093f56c 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -1,6 +1,6 @@ /* Fundamental definitions for GNU Emacs Lisp interpreter. - Copyright (C) 1985-1987, 1993-1995, 1997-2012 - Free Software Foundation, Inc. + +Copyright (C) 1985-1987, 1993-1995, 1997-2012 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -20,6 +20,7 @@ along with GNU Emacs. If not, see . */ #ifndef EMACS_LISP_H #define EMACS_LISP_H +#include #include #include #include @@ -27,40 +28,39 @@ along with GNU Emacs. If not, see . */ #include -/* Use the configure flag --enable-checking[=LIST] to enable various - types of run time checks for Lisp objects. */ - -#ifdef GC_CHECK_CONS_LIST -extern void check_cons_list (void); -#define CHECK_CONS_LIST() check_cons_list () -#else -#define CHECK_CONS_LIST() ((void) 0) +INLINE_HEADER_BEGIN +#ifndef LISP_INLINE +# define LISP_INLINE INLINE #endif -/* Temporarily disable wider-than-pointer integers until they're tested more. - Build with CFLAGS='-DWIDE_EMACS_INT' to try them out. */ -/* #undef WIDE_EMACS_INT */ +/* The ubiquitous max and min macros. */ +#undef min +#undef max +#define max(a, b) ((a) > (b) ? (a) : (b)) +#define min(a, b) ((a) < (b) ? (a) : (b)) /* 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 EMACS_UINT - unsigned variant of EMACS_INT */ -#ifndef EMACS_INT +#ifndef EMACS_INT_MAX # if LONG_MAX < LLONG_MAX && defined WIDE_EMACS_INT -# define EMACS_INT long long +typedef long long int EMACS_INT; +typedef unsigned long long int EMACS_UINT; # define EMACS_INT_MAX LLONG_MAX # define pI "ll" # elif INT_MAX < LONG_MAX -# define EMACS_INT long +typedef long int EMACS_INT; +typedef unsigned long int EMACS_UINT; # define EMACS_INT_MAX LONG_MAX # define pI "l" # else -# define EMACS_INT int +typedef int EMACS_INT; +typedef unsigned int EMACS_UINT; # define EMACS_INT_MAX INT_MAX # define pI "" # endif #endif -#define EMACS_UINT unsigned EMACS_INT /* Number of bits in some machine integer types. */ enum @@ -106,47 +106,29 @@ typedef EMACS_UINT uprintmax_t; /* Extra internal type checking? */ -#ifdef ENABLE_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. */ +#ifndef ENABLE_CHECKING +# define eassert(X) ((void) (0 && (X))) /* Check that X compiles. */ +#else /* ENABLE_CHECKING */ -extern void die (const char *, const char *, int) NO_RETURN; +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. - Testing suppress_checking after the supplied condition ensures that - the side effects produced by CHECK will be consistent, independent - of whether ENABLE_CHECKING is defined, or whether the checks are - suppressed at run time. - In some cases, a good compiler may be able to optimize away the - CHECK macro altogether, e.g., if XSTRING (x) uses CHECK to test + 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 int suppress_checking EXTERNALLY_VISIBLE; -#define CHECK(check,msg) (((check) || suppress_checking \ - ? (void) 0 \ - : die ((msg), __FILE__, __LINE__)), \ - 0) -#else - -/* Produce same side effects and result, but don't complain. */ -#define CHECK(check,msg) ((check),0) - -#endif - -/* Define an Emacs version of "assert", since some system ones are - flaky. */ -#ifndef ENABLE_CHECKING -#define eassert(X) ((void) (0 && (X))) /* Check that X compiles. */ -#else /* ENABLE_CHECKING */ -#if defined (__GNUC__) && __GNUC__ >= 2 && defined (__STDC__) -#define eassert(cond) CHECK (cond, "assertion failed: " #cond) -#else -#define eassert(cond) CHECK (cond, "assertion failed") -#endif +# define eassert(cond) \ + ((cond) || suppress_checking \ + ? (void) 0 \ + : die ("assertion failed: " # cond, __FILE__, __LINE__)) #endif /* ENABLE_CHECKING */ /* Use the configure flag --enable-check-lisp-object-type to make @@ -167,43 +149,46 @@ extern int suppress_checking EXTERNALLY_VISIBLE; on the few static Lisp_Objects used: all the defsubr as well as the two special buffers buffer_defaults and buffer_local_symbols. */ -/* First, try and define DECL_ALIGN(type,var) which declares a static - variable VAR of type TYPE with the added requirement that it be - TYPEBITS-aligned. */ - +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 -#define VALBITS (BITS_PER_EMACS_INT - GCTYPEBITS) + GCTYPEBITS, + + /* 2**GCTYPEBITS. This must also be a macro that expands to a + literal integer constant, for MSVC. */ + GCALIGNMENT = +#define GCALIGNMENT 8 + GCALIGNMENT, + + /* Number of bits in a Lisp_Object value, not counting the tag. */ + VALBITS = BITS_PER_EMACS_INT - GCTYPEBITS, + + /* Number of bits in a Lisp fixnum tag. */ + INTTYPEBITS = GCTYPEBITS - 1, + + /* Number of bits in a Lisp fixnum value, not counting the tag. */ + FIXNUM_BITS = VALBITS + 1 + }; + +#if GCALIGNMENT != 1 << GCTYPEBITS +# error "GCALIGNMENT and GCTYPEBITS are inconsistent" +#endif /* The maximum value that can be stored in a EMACS_INT, assuming all bits other than the type bits contribute to a nonnegative signed value. This can be used in #if, e.g., '#if VAL_MAX < UINTPTR_MAX' below. */ #define VAL_MAX (EMACS_INT_MAX >> (GCTYPEBITS - 1)) -#ifndef NO_DECL_ALIGN -# ifndef DECL_ALIGN -# if HAVE_ATTRIBUTE_ALIGNED -# define DECL_ALIGN(type, var) \ - type __attribute__ ((__aligned__ (1 << GCTYPEBITS))) var -# elif defined(_MSC_VER) -# define ALIGN_GCTYPEBITS 8 -# if (1 << GCTYPEBITS) != ALIGN_GCTYPEBITS -# error ALIGN_GCTYPEBITS is wrong! -# endif -# define DECL_ALIGN(type, var) \ - type __declspec(align(ALIGN_GCTYPEBITS)) var -# else - /* What directives do other compilers use? */ -# endif -# endif -#endif - /* 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 DECL_ALIGN +# ifdef alignas /* 3. Pointers-as-ints exceed VAL_MAX. 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 @@ -215,16 +200,20 @@ extern int suppress_checking EXTERNALLY_VISIBLE; # endif # endif #endif -#ifndef USE_LSB_TAG +#ifdef USE_LSB_TAG +# undef USE_LSB_TAG +enum enum_USE_LSB_TAG { USE_LSB_TAG = 1 }; +# define USE_LSB_TAG 1 +#else +enum enum_USE_LSB_TAG { USE_LSB_TAG = 0 }; # define USE_LSB_TAG 0 #endif -/* If we cannot use 8-byte alignment, make DECL_ALIGN a no-op. */ -#ifndef DECL_ALIGN +#ifndef alignas +# define alignas(alignment) /* empty */ # if USE_LSB_TAG -# error "USE_LSB_TAG used without defining DECL_ALIGN" +# error "USE_LSB_TAG requires alignas" # endif -# define DECL_ALIGN(type, var) type var #endif @@ -234,14 +223,9 @@ extern int suppress_checking EXTERNALLY_VISIBLE; /* Lisp integers use 2 tags, to give them one extra bit, thus extending their range from, e.g., -2^28..2^28-1 to -2^29..2^29-1. */ -#define INTTYPEBITS (GCTYPEBITS - 1) -#define FIXNUM_BITS (VALBITS + 1) -#define INTMASK (EMACS_INT_MAX >> (INTTYPEBITS - 1)) -#define LISP_INT_TAG Lisp_Int0 +static EMACS_INT const INTMASK = EMACS_INT_MAX >> (INTTYPEBITS - 1); #define case_Lisp_Int case Lisp_Int0: case Lisp_Int1 -#define LISP_INT1_TAG (USE_LSB_TAG ? 1 << INTTYPEBITS : 1) -#define LISP_STRING_TAG (5 - LISP_INT1_TAG) -#define LISP_INT_TAG_P(x) (((x) & ~LISP_INT1_TAG) == 0) +#define LISP_INT_TAG_P(x) (((x) & ~Lisp_Int1) == 0) /* Stolen from GDB. The only known compiler that doesn't support enums in bitfields is MSVC. */ @@ -256,7 +240,7 @@ enum Lisp_Type { /* Integer. XINT (obj) is the integer value. */ Lisp_Int0 = 0, - Lisp_Int1 = LISP_INT1_TAG, + Lisp_Int1 = USE_LSB_TAG ? 1 << INTTYPEBITS : 1, /* Symbol. XSYMBOL (object) points to a struct Lisp_Symbol. */ Lisp_Symbol = 2, @@ -267,7 +251,7 @@ enum Lisp_Type /* String. XSTRING (object) points to a struct Lisp_String. The length of the string, and its contents, are stored therein. */ - Lisp_String = LISP_STRING_TAG, + Lisp_String = USE_LSB_TAG ? 1 : 1 << INTTYPEBITS, /* Vector of Lisp objects, or something resembling it. XVECTOR (object) points to a struct Lisp_Vector, which contains @@ -316,14 +300,14 @@ enum Lisp_Fwd_Type typedef struct { EMACS_INT i; } Lisp_Object; #define XLI(o) (o).i -static inline Lisp_Object +LISP_INLINE Lisp_Object XIL (EMACS_INT i) { Lisp_Object o = { i }; return o; } -static inline Lisp_Object +LISP_INLINE Lisp_Object LISP_MAKE_RVALUE (Lisp_Object o) { return o; @@ -331,6 +315,8 @@ LISP_MAKE_RVALUE (Lisp_Object o) #define LISP_INITIALLY_ZERO {0} +#undef CHECK_LISP_OBJECT_TYPE +enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = 1 }; #else /* CHECK_LISP_OBJECT_TYPE */ /* If a struct type is not wanted, define Lisp_Object as just a number. */ @@ -340,15 +326,20 @@ typedef EMACS_INT Lisp_Object; #define XIL(i) (i) #define LISP_MAKE_RVALUE(o) (0+(o)) #define LISP_INITIALLY_ZERO 0 +enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = 0 }; #endif /* CHECK_LISP_OBJECT_TYPE */ /* In the size word of a vector, this bit means the vector has been marked. */ +static ptrdiff_t const ARRAY_MARK_FLAG #define ARRAY_MARK_FLAG PTRDIFF_MIN + = ARRAY_MARK_FLAG; /* In the size word of a struct Lisp_Vector, this bit means it's really some other vector-like object. */ +static ptrdiff_t const PSEUDOVECTOR_FLAG #define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2) + = PSEUDOVECTOR_FLAG; /* In a pseudovector, the size field actually contains a word with one PSEUDOVECTOR_FLAG bit set, and exactly one of the following bits to @@ -359,40 +350,53 @@ typedef EMACS_INT Lisp_Object; It is not crucial, but there are plenty of bits here, so why not do it? */ enum pvec_type { - PVEC_NORMAL_VECTOR = 0, - PVEC_PROCESS = 0x200, - PVEC_FRAME = 0x400, - PVEC_COMPILED = 0x800, - PVEC_WINDOW = 0x1000, - PVEC_WINDOW_CONFIGURATION = 0x2000, - PVEC_SUBR = 0x4000, - PVEC_CHAR_TABLE = 0x8000, - PVEC_BOOL_VECTOR = 0x10000, - PVEC_BUFFER = 0x20000, - PVEC_HASH_TABLE = 0x40000, - PVEC_TERMINAL = 0x80000, - PVEC_SUB_CHAR_TABLE = 0x100000, - PVEC_FONT = 0x200000, - PVEC_OTHER = 0x400000, - PVEC_TYPE_MASK = 0x7ffe00 - -#if 0 /* This is used to make the value of PSEUDOVECTOR_FLAG available to - GDB. It doesn't work on OS Alpha. Moved to a variable in - emacs.c. */ - PVEC_FLAG = PSEUDOVECTOR_FLAG -#endif + PVEC_NORMAL_VECTOR = 0, /* Unused! */ + PVEC_FREE, + PVEC_PROCESS, + PVEC_FRAME, + PVEC_WINDOW, + PVEC_BOOL_VECTOR, + PVEC_BUFFER, + PVEC_HASH_TABLE, + PVEC_TERMINAL, + PVEC_WINDOW_CONFIGURATION, + PVEC_SUBR, + PVEC_OTHER, + /* These last 4 are special because we OR them in fns.c:internal_equal, + so they have to use a disjoint bit pattern: + if (!(size & (PVEC_COMPILED | PVEC_CHAR_TABLE + | PVEC_SUB_CHAR_TABLE | PVEC_FONT))) */ + PVEC_COMPILED = 0x10, + PVEC_CHAR_TABLE = 0x20, + PVEC_SUB_CHAR_TABLE = 0x30, + PVEC_FONT = 0x40 }; -/* 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 the GC). - The distinction is used e.g. by Lisp_Process which places extra - non-Lisp_Object fields at the end of the structure. */ -#define PSEUDOVECTOR_SIZE_MASK 0x1ff +/* 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 -/* Number of bits to put in each character in the internal representation - of bool vectors. This should not vary across implementations. */ -#define BOOL_VECTOR_BITS_PER_CHAR 8 +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). + The distinction is used, e.g., by Lisp_Process, which places extra + non-Lisp_Object fields at the end of the structure. */ + PSEUDOVECTOR_SIZE_BITS = 16, + PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1, + PVEC_TYPE_MASK = 0x0fff << PSEUDOVECTOR_SIZE_BITS, + + /* Number of bits to put in each character in the internal representation + of bool vectors. This should not vary across implementations. */ + BOOL_VECTOR_BITS_PER_CHAR = 8 + }; /* These macros extract various sorts of values from a Lisp_Object. For example, if tem is a Lisp_Object whose type is Lisp_Cons, @@ -403,7 +407,11 @@ enum pvec_type #if USE_LSB_TAG -#define TYPEMASK ((1 << GCTYPEBITS) - 1) +enum lsb_bits + { + TYPEMASK = (1 << GCTYPEBITS) - 1, + VALMASK = ~ TYPEMASK + }; #define XTYPE(a) ((enum Lisp_Type) (XLI (a) & TYPEMASK)) #define XINT(a) (XLI (a) >> INTTYPEBITS) #define XUINT(a) ((EMACS_UINT) XLI (a) >> INTTYPEBITS) @@ -417,7 +425,9 @@ enum pvec_type #else /* not USE_LSB_TAG */ +static EMACS_INT const VALMASK #define VALMASK VAL_MAX + = VALMASK; #define XTYPE(a) ((enum Lisp_Type) ((EMACS_UINT) XLI (a) >> VALBITS)) @@ -437,7 +447,7 @@ enum pvec_type ((var) = XIL ((EMACS_INT) ((EMACS_UINT) (type) << VALBITS) \ + ((intptr_t) (ptr) & VALMASK))) -#ifdef DATA_SEG_BITS +#if DATA_SEG_BITS /* DATA_SEG_BITS forces extra bits to be or'd in with any pointers which were stored in a Lisp_Object */ #define XPNTR(a) ((uintptr_t) ((XLI (a) & VALMASK)) | DATA_SEG_BITS)) @@ -465,9 +475,14 @@ enum pvec_type #define EQ(x, y) (XHASH (x) == XHASH (y)) /* Largest and smallest representable fixnum values. These are the C - values. */ + values. They are macros for use in static initializers, and + constants for visibility to GDB. */ +static EMACS_INT const MOST_POSITIVE_FIXNUM = #define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS) + MOST_POSITIVE_FIXNUM; +static EMACS_INT const MOST_NEGATIVE_FIXNUM = #define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM) + MOST_NEGATIVE_FIXNUM; /* Value is non-zero if I doesn't fit into a Lisp fixnum. It is written this way so that it also works if I is of unsigned @@ -476,7 +491,7 @@ enum pvec_type #define FIXNUM_OVERFLOW_P(i) \ (! ((0 <= (i) || MOST_NEGATIVE_FIXNUM <= (i)) && (i) <= MOST_POSITIVE_FIXNUM)) -static inline ptrdiff_t +LISP_INLINE ptrdiff_t clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper) { return num < lower ? lower : num <= upper ? num : upper; @@ -554,21 +569,23 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper) #define XSETPVECTYPE(v, code) XSETTYPED_PVECTYPE (v, header.size, code) #define XSETTYPED_PVECTYPE(v, size_member, code) \ - ((v)->size_member |= PSEUDOVECTOR_FLAG | (code)) + ((v)->size_member |= PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_SIZE_BITS)) #define XSETPVECTYPESIZE(v, code, sizeval) \ - ((v)->header.size = PSEUDOVECTOR_FLAG | (code) | (sizeval)) + ((v)->header.size = (PSEUDOVECTOR_FLAG \ + | ((code) << PSEUDOVECTOR_SIZE_BITS) \ + | (sizeval))) /* The cast to struct vectorlike_header * avoids aliasing issues. */ #define XSETPSEUDOVECTOR(a, b, code) \ - XSETTYPED_PSEUDOVECTOR(a, b, \ - (((struct vectorlike_header *) \ - XUNTAG (a, Lisp_Vectorlike)) \ - ->size), \ - code) + XSETTYPED_PSEUDOVECTOR (a, b, \ + (((struct vectorlike_header *) \ + XUNTAG (a, Lisp_Vectorlike)) \ + ->size), \ + code) #define XSETTYPED_PSEUDOVECTOR(a, b, size, code) \ (XSETVECTOR (a, b), \ eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \ - == (PSEUDOVECTOR_FLAG | (code)))) + == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_SIZE_BITS)))) #define XSETWINDOW_CONFIGURATION(a, b) \ (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION)) @@ -592,7 +609,7 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper) #define ASET(ARRAY, IDX, VAL) \ (eassert ((IDX) == (IDX)), \ eassert ((IDX) >= 0 && (IDX) < ASIZE (ARRAY)), \ - AREF ((ARRAY), (IDX)) = (VAL)) + XVECTOR (ARRAY)->contents[IDX] = (VAL)) /* Convenience macros for dealing with Lisp strings. */ @@ -616,8 +633,10 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper) #define CHECK_TYPE(ok, Qxxxp, x) \ do { if (!(ok)) wrong_type_argument (Qxxxp, (x)); } while (0) +/* Deprecated and will be removed soon. */ + +#define INTERNAL_FIELD(field) field ## _ - /* See the macros in intervals.h. */ typedef struct interval *INTERVAL; @@ -626,28 +645,19 @@ typedef struct interval *INTERVAL; #define CHECK_STRING_OR_BUFFER(x) \ CHECK_TYPE (STRINGP (x) || BUFFERP (x), Qbuffer_or_string_p, x) - -/* In a cons, the markbit of the car is the gc mark bit */ - struct Lisp_Cons { - /* Please do not use the names of these elements in code other - than the core lisp implementation. Use XCAR and XCDR below. */ -#ifdef HIDE_LISP_IMPLEMENTATION - Lisp_Object car_; - union - { - Lisp_Object cdr_; - struct Lisp_Cons *chain; - } u; -#else + /* Car of this cons cell. */ Lisp_Object car; + union { + /* Cdr of this cons cell. */ Lisp_Object cdr; + + /* Used to chain conses on a free list. */ struct Lisp_Cons *chain; } u; -#endif }; /* Take the car or cdr of something known to be a cons cell. */ @@ -657,13 +667,8 @@ struct Lisp_Cons fields are not accessible as lvalues. (What if we want to switch to a copying collector someday? Cached cons cell field addresses may be invalidated at arbitrary points.) */ -#ifdef HIDE_LISP_IMPLEMENTATION -#define XCAR_AS_LVALUE(c) (XCONS ((c))->car_) -#define XCDR_AS_LVALUE(c) (XCONS ((c))->u.cdr_) -#else -#define XCAR_AS_LVALUE(c) (XCONS ((c))->car) -#define XCDR_AS_LVALUE(c) (XCONS ((c))->u.cdr) -#endif +#define XCAR_AS_LVALUE(c) (XCONS (c)->car) +#define XCDR_AS_LVALUE(c) (XCONS (c)->u.cdr) /* Use these from normal code. */ #define XCAR(c) LISP_MAKE_RVALUE (XCAR_AS_LVALUE (c)) @@ -724,10 +729,15 @@ extern ptrdiff_t string_bytes (struct Lisp_String *); Although the actual size limit (see STRING_BYTES_MAX in alloc.c) may be a bit smaller than STRING_BYTES_BOUND, calculating it here would expose alloc.c internal details that we'd rather keep - private. The cast to ptrdiff_t ensures that STRING_BYTES_BOUND is - signed. */ + private. + + This is a macro for use in static initializers, and a constant for + visibility to GDB. The cast to ptrdiff_t ensures that + the macro is signed. */ +static ptrdiff_t const STRING_BYTES_BOUND = #define STRING_BYTES_BOUND \ - min (MOST_POSITIVE_FIXNUM, (ptrdiff_t) min (SIZE_MAX, PTRDIFF_MAX) - 1) + ((ptrdiff_t) min (MOST_POSITIVE_FIXNUM, min (SIZE_MAX, PTRDIFF_MAX) - 1)) + STRING_BYTES_BOUND; /* Mark STR as a unibyte string. */ #define STRING_SET_UNIBYTE(STR) \ @@ -742,19 +752,13 @@ extern ptrdiff_t string_bytes (struct Lisp_String *); (STR) = empty_multibyte_string; \ else XSTRING (STR)->size_byte = XSTRING (STR)->size; } while (0) -/* Get text properties. */ -#define STRING_INTERVALS(STR) (XSTRING (STR)->intervals + 0) - -/* Set text properties. */ -#define STRING_SET_INTERVALS(STR, INT) (XSTRING (STR)->intervals = (INT)) - -/* In a string or vector, the sign bit of the `size' is the gc mark bit */ +/* In a string or vector, the sign bit of the `size' is the gc mark bit. */ struct Lisp_String { ptrdiff_t size; ptrdiff_t size_byte; - INTERVAL intervals; /* text properties in this string */ + INTERVAL intervals; /* Text properties in this string. */ unsigned char *data; }; @@ -767,6 +771,20 @@ struct Lisp_String . */ struct vectorlike_header { + /* This field contains various pieces of information: + - The MSB (ARRAY_MARK_FLAG) holds the gcmarkbit. + - The next bit (PSEUDOVECTOR_FLAG) indicates whether this is a plain + vector (0) or a pseudovector (1). + - If PSEUDOVECTOR_FLAG is 0, the rest holds the size (number + of slots) of the vector. + - If PSEUDOVECTOR_FLAG is 1, the rest is subdivided into + a "pvec type" tag held in PVEC_TYPE_MASK and a size held in the lowest + PSEUDOVECTOR_SIZE_BITS. That size normally indicates the number of + Lisp_Object slots at the beginning of the object that need to be + traced by the GC, tho some types use it slightly differently. + - E.g. if the pvec type is PVEC_FREE it means this is an unallocated + vector on a free-list and PSEUDOVECTOR_SIZE_BITS indicates its size + in bytes. */ ptrdiff_t size; /* When the vector is allocated from a vector block, NBYTES is used @@ -777,31 +795,64 @@ struct vectorlike_header pointer: this way, one can write P->next.vector instead of ((struct Lisp_Vector *) P->next). */ union { + /* This is only needed for small vectors that are not free because the + `size' field only gives us the number of Lisp_Object slots, whereas we + need to know the total size, including non-Lisp_Object data. + FIXME: figure out a way to store this info elsewhere so we can + finally get rid of this extra word of overhead. */ ptrdiff_t nbytes; struct buffer *buffer; + /* FIXME: This can be removed: For large vectors, this field could be + placed *before* the vector itself. And for small vectors on a free + list, this field could be stored in the vector's bytes, since the + empty vector is handled specially anyway. */ struct Lisp_Vector *vector; } next; }; +/* Regular vector is just a header plus array of Lisp_Objects. */ + struct Lisp_Vector { struct vectorlike_header header; Lisp_Object contents[1]; }; +/* A boolvector is a kind of vectorlike, with contents are like a string. */ + +struct Lisp_Bool_Vector + { + /* HEADER.SIZE is the vector's size field. It doesn't have the real size, + just the subtype information. */ + struct vectorlike_header header; + /* This is the size in bits. */ + EMACS_INT size; + /* This contains the actual bits, packed into bytes. */ + unsigned char data[1]; + }; + +/* 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) + }; + /* If a struct is made to look like a vector, this macro returns the length of the shortest vector that would hold that struct. */ -#define VECSIZE(type) ((sizeof (type) \ - - offsetof (struct Lisp_Vector, contents[0]) \ - + sizeof (Lisp_Object) - 1) /* round up */ \ - / sizeof (Lisp_Object)) + +#define VECSIZE(type) \ + ((sizeof (type) - header_size + word_size - 1) / word_size) /* Like VECSIZE, but used when the pseudo-vector has non-Lisp_Object fields at the end and we need to compute the number of Lisp_Object fields (the ones that the GC needs to trace). */ -#define PSEUDOVECSIZE(type, nonlispfield) \ - ((offsetof (type, nonlispfield) - offsetof (struct Lisp_Vector, contents[0])) \ - / sizeof (Lisp_Object)) + +#define PSEUDOVECSIZE(type, nonlispfield) \ + ((offsetof (type, nonlispfield) - header_size) / word_size) /* 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 @@ -813,16 +864,6 @@ struct Lisp_Vector of a char-table, and there's no way to access it directly from Emacs Lisp program. */ -/* 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. */ -#define CHAR_TABLE_STANDARD_SLOTS (VECSIZE (struct Lisp_Char_Table) - 1) - -/* Return the number of "extra" slots in the char table CT. */ - -#define CHAR_TABLE_EXTRA_SLOTS(CT) \ - (((CT)->header.size & PSEUDOVECTOR_SIZE_MASK) - CHAR_TABLE_STANDARD_SLOTS) - #ifdef __GNUC__ #define CHAR_TABLE_REF_ASCII(CT, IDX) \ @@ -884,10 +925,13 @@ struct Lisp_Vector ? XSUB_CHAR_TABLE (XCHAR_TABLE (CT)->ascii)->contents[IDX] = VAL \ : char_table_set (CT, IDX, VAL)) -#define CHARTAB_SIZE_BITS_0 6 -#define CHARTAB_SIZE_BITS_1 4 -#define CHARTAB_SIZE_BITS_2 5 -#define CHARTAB_SIZE_BITS_3 7 +enum CHARTAB_SIZE_BITS + { + CHARTAB_SIZE_BITS_0 = 6, + CHARTAB_SIZE_BITS_1 = 4, + CHARTAB_SIZE_BITS_2 = 5, + CHARTAB_SIZE_BITS_3 = 7 + }; extern const int chartab_size[4]; @@ -944,18 +988,6 @@ struct Lisp_Sub_Char_Table Lisp_Object contents[1]; }; -/* A boolvector is a kind of vectorlike, with contents are like a string. */ -struct Lisp_Bool_Vector - { - /* HEADER.SIZE is the vector's size field. It doesn't have the real size, - just the subtype information. */ - struct vectorlike_header header; - /* This is the size in bits. */ - EMACS_INT size; - /* This contains the actual bits, packed into bytes. */ - unsigned char data[1]; - }; - /* This structure describes a built-in function. It is generated by the DEFUN macro only. defsubr makes it into a Lisp object. @@ -986,6 +1018,19 @@ 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 + { + CHAR_TABLE_STANDARD_SLOTS = VECSIZE (struct Lisp_Char_Table) - 1 + }; + +/* Return the number of "extra" slots in the char table CT. */ + +#define CHAR_TABLE_EXTRA_SLOTS(CT) \ + (((CT)->header.size & PSEUDOVECTOR_SIZE_MASK) - CHAR_TABLE_STANDARD_SLOTS) + /*********************************************************************** Symbols @@ -1032,10 +1077,8 @@ struct Lisp_Symbol special (with `defvar' etc), and shouldn't be lexically bound. */ unsigned declared_special : 1; - /* The symbol's name, as a Lisp string. - The name "xname" is used to intentionally break code referring to - the old field "name" of type pointer to struct Lisp_String. */ - Lisp_Object xname; + /* The symbol's name, as a Lisp string. */ + Lisp_Object name; /* Value of the symbol or Qunbound if unbound. Which alternative of the union is used depends on the `redirect' field above. */ @@ -1058,43 +1101,42 @@ struct Lisp_Symbol /* Value is name of symbol. */ -#define SYMBOL_VAL(sym) \ - (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value) -#define SYMBOL_ALIAS(sym) \ +#define SYMBOL_VAL(sym) \ + (eassert ((sym)->redirect == SYMBOL_PLAINVAL), sym->val.value) +#define SYMBOL_ALIAS(sym) \ (eassert ((sym)->redirect == SYMBOL_VARALIAS), (sym)->val.alias) -#define SYMBOL_BLV(sym) \ +#define SYMBOL_BLV(sym) \ (eassert ((sym)->redirect == SYMBOL_LOCALIZED), (sym)->val.blv) -#define SYMBOL_FWD(sym) \ +#define SYMBOL_FWD(sym) \ (eassert ((sym)->redirect == SYMBOL_FORWARDED), (sym)->val.fwd) -#define SET_SYMBOL_VAL(sym, v) \ +#define SET_SYMBOL_VAL(sym, v) \ (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value = (v)) -#define SET_SYMBOL_ALIAS(sym, v) \ +#define SET_SYMBOL_ALIAS(sym, v) \ (eassert ((sym)->redirect == SYMBOL_VARALIAS), (sym)->val.alias = (v)) -#define SET_SYMBOL_BLV(sym, v) \ +#define SET_SYMBOL_BLV(sym, v) \ (eassert ((sym)->redirect == SYMBOL_LOCALIZED), (sym)->val.blv = (v)) -#define SET_SYMBOL_FWD(sym, v) \ +#define SET_SYMBOL_FWD(sym, v) \ (eassert ((sym)->redirect == SYMBOL_FORWARDED), (sym)->val.fwd = (v)) -#define SYMBOL_NAME(sym) \ - LISP_MAKE_RVALUE (XSYMBOL (sym)->xname) +#define SYMBOL_NAME(sym) XSYMBOL (sym)->name /* Value is non-zero if SYM is an interned symbol. */ -#define SYMBOL_INTERNED_P(sym) \ - (XSYMBOL (sym)->interned != SYMBOL_UNINTERNED) +#define SYMBOL_INTERNED_P(sym) \ + (XSYMBOL (sym)->interned != SYMBOL_UNINTERNED) /* Value is non-zero if SYM is interned in initial_obarray. */ -#define SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P(sym) \ - (XSYMBOL (sym)->interned == SYMBOL_INTERNED_IN_INITIAL_OBARRAY) +#define SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P(sym) \ + (XSYMBOL (sym)->interned == SYMBOL_INTERNED_IN_INITIAL_OBARRAY) /* Value is non-zero if symbol is considered a constant, i.e. its value cannot be changed (there is an exception for keyword symbols, whose value can be set to the keyword symbol itself). */ -#define SYMBOL_CONSTANT_P(sym) XSYMBOL (sym)->constant +#define SYMBOL_CONSTANT_P(sym) XSYMBOL (sym)->constant -#define DEFSYM(sym, name) \ +#define DEFSYM(sym, name) \ do { (sym) = intern_c_string ((name)); staticpro (&(sym)); } while (0) @@ -1213,19 +1255,18 @@ struct Lisp_Hash_Table /* Default size for hash tables if not specified. */ -#define DEFAULT_HASH_SIZE 65 +enum DEFAULT_HASH_SIZE { DEFAULT_HASH_SIZE = 65 }; /* Default threshold specifying when to resize a hash table. The value gives the ratio of current entries in the hash table and the size of the hash table. */ -#define DEFAULT_REHASH_THRESHOLD 0.8 +static double const DEFAULT_REHASH_THRESHOLD = 0.8; /* Default factor by which to increase the size of a hash table. */ -#define DEFAULT_REHASH_SIZE 1.5 +static double const DEFAULT_REHASH_SIZE = 1.5; - /* These structures are used for various misc types. */ struct Lisp_Misc_Any /* Supertype of all Misc types. */ @@ -1276,6 +1317,66 @@ struct Lisp_Marker ptrdiff_t bytepos; }; +/* START and END are markers in the overlay's buffer, and + PLIST is the overlay's property list. */ +struct Lisp_Overlay +/* An overlay's real data content is: + - plist + - buffer (really there are two buffer pointers, one per marker, + and both points to the same buffer) + - insertion type of both ends (per-marker fields) + - start & start byte (of start marker) + - end & end byte (of end marker) + - next (singly linked list of overlays) + - next fields of start and end markers (singly linked list of markers). + I.e. 9words plus 2 bits, 3words of which are for external linked lists. +*/ + { + ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Overlay */ + unsigned gcmarkbit : 1; + int spacer : 15; + struct Lisp_Overlay *next; + Lisp_Object start; + Lisp_Object end; + Lisp_Object plist; + }; + +/* Hold a C pointer for later use. + This type of object is used in the arg to record_unwind_protect. */ +struct Lisp_Save_Value + { + ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Save_Value */ + unsigned gcmarkbit : 1; + int spacer : 14; + /* If DOGC is set, POINTER is the address of a memory + area containing INTEGER potential Lisp_Objects. */ + unsigned int dogc : 1; + void *pointer; + ptrdiff_t integer; + }; + + +/* A miscellaneous object, when it's on the free list. */ +struct Lisp_Free + { + ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Free */ + unsigned gcmarkbit : 1; + int spacer : 15; + union Lisp_Misc *chain; + }; + +/* To get the type field of a union Lisp_Misc, use XMISCTYPE. + It uses one of these struct subtypes to get the type field. */ + +union Lisp_Misc + { + struct Lisp_Misc_Any u_any; /* Supertype of all Misc types. */ + struct Lisp_Free u_free; + struct Lisp_Marker u_marker; + struct Lisp_Overlay u_overlay; + struct Lisp_Save_Value u_save_value; + }; + /* Forwarding pointer to an int variable. This is allowed only in the value cell of a symbol, and it means that the symbol's value really lives in the @@ -1342,13 +1443,13 @@ struct Lisp_Buffer_Objfwd struct Lisp_Buffer_Local_Value { /* 1 means that merely setting the variable creates a local - binding for the current buffer */ + binding for the current buffer. */ unsigned int local_if_set : 1; /* 1 means this variable can have frame-local bindings, otherwise, it is can have buffer-local bindings. The two cannot be combined. */ unsigned int frame_local : 1; /* 1 means that the binding now loaded was found. - Presumably equivalent to (defcell!=valcell) */ + Presumably equivalent to (defcell!=valcell). */ unsigned int found : 1; /* If non-NULL, a forwarding to the C var where it should also be set. */ union Lisp_Fwd *fwd; /* Should never be (Buffer|Kboard)_Objfwd. */ @@ -1373,27 +1474,6 @@ struct Lisp_Buffer_Local_Value #define BLV_VALUE(blv) (XCDR ((blv)->valcell)) #define SET_BLV_VALUE(blv, v) (XSETCDR ((blv)->valcell, v)) -/* START and END are markers in the overlay's buffer, and - PLIST is the overlay's property list. */ -struct Lisp_Overlay -/* An overlay's real data content is: - - plist - - buffer - - insertion type of both ends - - start & start_byte - - end & end_byte - - next (singly linked list of overlays). - - start_next and end_next (singly linked list of markers). - I.e. 9words plus 2 bits, 3words of which are for external linked lists. -*/ - { - ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Overlay */ - unsigned gcmarkbit : 1; - int spacer : 15; - struct Lisp_Overlay *next; - Lisp_Object start, end, plist; - }; - /* Like Lisp_Objfwd except that value lives in a slot in the current kboard. */ struct Lisp_Kboard_Objfwd @@ -1402,42 +1482,6 @@ struct Lisp_Kboard_Objfwd int offset; }; -/* Hold a C pointer for later use. - This type of object is used in the arg to record_unwind_protect. */ -struct Lisp_Save_Value - { - ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Save_Value */ - unsigned gcmarkbit : 1; - int spacer : 14; - /* If DOGC is set, POINTER is the address of a memory - area containing INTEGER potential Lisp_Objects. */ - unsigned int dogc : 1; - void *pointer; - ptrdiff_t integer; - }; - - -/* A miscellaneous object, when it's on the free list. */ -struct Lisp_Free - { - ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Free */ - unsigned gcmarkbit : 1; - int spacer : 15; - union Lisp_Misc *chain; - }; - -/* To get the type field of a union Lisp_Misc, use XMISCTYPE. - It uses one of these struct subtypes to get the type field. */ - -union Lisp_Misc - { - struct Lisp_Misc_Any u_any; /* Supertype of all Misc types. */ - struct Lisp_Free u_free; - struct Lisp_Marker u_marker; - struct Lisp_Overlay u_overlay; - struct Lisp_Save_Value u_save_value; - }; - union Lisp_Fwd { struct Lisp_Intfwd u_intfwd; @@ -1447,28 +1491,18 @@ union Lisp_Fwd struct Lisp_Kboard_Objfwd u_kboard_objfwd; }; -/* Lisp floating point type */ +/* Lisp floating point type. */ struct Lisp_Float { union { -#ifdef HIDE_LISP_IMPLEMENTATION - double data_; -#else double data; -#endif struct Lisp_Float *chain; } u; }; -#ifdef HIDE_LISP_IMPLEMENTATION -#define XFLOAT_DATA(f) (0 ? XFLOAT (f)->u.data_ : XFLOAT (f)->u.data_) -#else -#define XFLOAT_DATA(f) (0 ? XFLOAT (f)->u.data : XFLOAT (f)->u.data) -/* This should be used only in alloc.c, which always disables - HIDE_LISP_IMPLEMENTATION. */ -#define XFLOAT_INIT(f,n) (XFLOAT (f)->u.data = (n)) -#endif +#define XFLOAT_DATA(f) (0 ? XFLOAT (f)->u.data : XFLOAT (f)->u.data) +#define XFLOAT_INIT(f, n) (XFLOAT (f)->u.data = (n)) /* A character, declared with the following typedef, is a member of some character set associated with the current buffer. */ @@ -1479,31 +1513,38 @@ typedef unsigned char UCHAR; /* Meanings of slots in a Lisp_Compiled: */ -#define COMPILED_ARGLIST 0 -#define COMPILED_BYTECODE 1 -#define COMPILED_CONSTANTS 2 -#define COMPILED_STACK_DEPTH 3 -#define COMPILED_DOC_STRING 4 -#define COMPILED_INTERACTIVE 5 +enum Lisp_Compiled + { + COMPILED_ARGLIST = 0, + COMPILED_BYTECODE = 1, + COMPILED_CONSTANTS = 2, + COMPILED_STACK_DEPTH = 3, + COMPILED_DOC_STRING = 4, + COMPILED_INTERACTIVE = 5 + }; /* Flag bits in a character. These also get used in termhooks.h. Richard Stallman thinks that MULE (MUlti-Lingual Emacs) might need 22 bits for the character value itself, so we probably shouldn't use any bits lower than 0x0400000. */ -#define CHAR_ALT (0x0400000) -#define CHAR_SUPER (0x0800000) -#define CHAR_HYPER (0x1000000) -#define CHAR_SHIFT (0x2000000) -#define CHAR_CTL (0x4000000) -#define CHAR_META (0x8000000) - -#define CHAR_MODIFIER_MASK \ - (CHAR_ALT | CHAR_SUPER | CHAR_HYPER | CHAR_SHIFT | CHAR_CTL | CHAR_META) +enum char_bits + { + CHAR_ALT = 0x0400000, + CHAR_SUPER = 0x0800000, + CHAR_HYPER = 0x1000000, + CHAR_SHIFT = 0x2000000, + CHAR_CTL = 0x4000000, + CHAR_META = 0x8000000, + + CHAR_MODIFIER_MASK = + CHAR_ALT | CHAR_SUPER | CHAR_HYPER | CHAR_SHIFT | CHAR_CTL | CHAR_META, + + /* Actually, the current Emacs uses 22 bits for the character value + itself. */ + CHARACTERBITS = 22 + }; -/* Actually, the current Emacs uses 22 bits for the character value - itself. */ -#define CHARACTERBITS 22 /* The glyph datatype, used to represent characters on the display. @@ -1560,9 +1601,6 @@ typedef struct { (XINT (gc) >> CHARACTERBITS)); \ } \ while (0) - -/* The ID of the mode line highlighting face. */ -#define GLYPH_MODE_LINE_FACE 1 /* Structure to hold mouse highlight data. This is here because other header files need it for defining struct x_output etc. */ @@ -1635,15 +1673,17 @@ typedef struct { /* True if object X is a pseudovector whose code is CODE. The cast to struct vectorlike_header * avoids aliasing issues. */ #define PSEUDOVECTORP(x, code) \ - TYPED_PSEUDOVECTORP(x, vectorlike_header, code) + TYPED_PSEUDOVECTORP (x, vectorlike_header, code) + +#define PSEUDOVECTOR_TYPEP(v, code) \ + (((v)->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \ + == (PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_SIZE_BITS))) /* True if object X, with internal type struct T *, is a pseudovector whose code is CODE. */ #define TYPED_PSEUDOVECTORP(x, t, code) \ (VECTORLIKEP (x) \ - && (((((struct t *) XUNTAG (x, Lisp_Vectorlike))->size \ - & (PSEUDOVECTOR_FLAG | (code)))) \ - == (PSEUDOVECTOR_FLAG | (code)))) + && PSEUDOVECTOR_TYPEP ((struct t *) XUNTAG (x, Lisp_Vectorlike), code)) /* Test for specific pseudovector types. */ #define WINDOW_CONFIGURATIONP(x) PSEUDOVECTORP (x, PVEC_WINDOW_CONFIGURATION) @@ -1720,7 +1760,8 @@ typedef struct { vchild, and hchild members are all nil. */ #define CHECK_LIVE_WINDOW(x) \ - CHECK_TYPE (WINDOWP (x) && !NILP (XWINDOW (x)->buffer), Qwindow_live_p, x) + CHECK_TYPE (WINDOWP (x) && !NILP (XWINDOW (x)->buffer), \ + Qwindow_live_p, x) #define CHECK_PROCESS(x) \ CHECK_TYPE (PROCESSP (x), Qprocessp, x) @@ -1734,7 +1775,7 @@ typedef struct { #define CHECK_NATNUM(x) \ CHECK_TYPE (NATNUMP (x), Qwholenump, x) -#define CHECK_RANGED_INTEGER(lo, x, hi) \ +#define CHECK_RANGED_INTEGER(x, lo, hi) \ do { \ CHECK_NUMBER (x); \ if (! ((lo) <= XINT (x) && XINT (x) <= (hi))) \ @@ -1748,9 +1789,9 @@ typedef struct { #define CHECK_TYPE_RANGED_INTEGER(type, x) \ do { \ if (TYPE_SIGNED (type)) \ - CHECK_RANGED_INTEGER (TYPE_MINIMUM (type), x, TYPE_MAXIMUM (type)); \ + CHECK_RANGED_INTEGER (x, TYPE_MINIMUM (type), TYPE_MAXIMUM (type)); \ else \ - CHECK_RANGED_INTEGER (0, x, TYPE_MAXIMUM (type)); \ + CHECK_RANGED_INTEGER (x, 0, TYPE_MAXIMUM (type)); \ } while (0) #define CHECK_MARKER(x) \ @@ -1835,16 +1876,17 @@ typedef struct { #ifdef _MSC_VER #define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \ - static DECL_ALIGN (struct Lisp_Subr, sname) = \ - { PVEC_SUBR | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)), \ + static struct Lisp_Subr alignas (GCALIGNMENT) sname = \ + { (PVEC_SUBR << PSEUDOVECTOR_SIZE_BITS) \ + | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)), \ { (Lisp_Object (__cdecl *)(void))fnname }, \ minargs, maxargs, lname, intspec, 0}; \ Lisp_Object fnname #else /* not _MSC_VER */ #define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \ - static DECL_ALIGN (struct Lisp_Subr, sname) = \ - { PVEC_SUBR, \ + static struct Lisp_Subr alignas (GCALIGNMENT) sname = \ + { PVEC_SUBR << PSEUDOVECTOR_SIZE_BITS, \ { .a ## maxargs = fnname }, \ minargs, maxargs, lname, intspec, 0}; \ Lisp_Object fnname @@ -1879,8 +1921,11 @@ typedef struct { is how we define the symbol for function `name' at start-up time. */ extern void defsubr (struct Lisp_Subr *); -#define MANY -2 -#define UNEVALLED -1 +enum maxargs + { + MANY = -2, + UNEVALLED = -1 + }; extern void defvar_lisp (struct Lisp_Objfwd *, const char *, Lisp_Object *); extern void defvar_lisp_nopro (struct Lisp_Objfwd *, const char *, Lisp_Object *); @@ -2081,14 +2126,6 @@ extern void process_quit_flag (void); extern Lisp_Object Vascii_downcase_table; extern Lisp_Object Vascii_canon_table; -/* Number of bytes of structure consed since last GC. */ - -extern EMACS_INT consing_since_gc; - -extern EMACS_INT gc_relative_threshold; - -extern EMACS_INT memory_full_cons_threshold; - /* Structure for recording stack slots that need marking. */ /* This is a chain of structures, each of which points at a Lisp_Object @@ -2295,6 +2332,104 @@ void staticpro (Lisp_Object *); struct window; struct frame; +/* Simple access functions. */ + +LISP_INLINE Lisp_Object * +aref_addr (Lisp_Object array, ptrdiff_t idx) +{ + return & XVECTOR (array)->contents[idx]; +} + +LISP_INLINE void +gc_aset (Lisp_Object array, ptrdiff_t idx, Lisp_Object val) +{ + /* Like ASET, but also can be used in the garbage collector: + sweep_weak_table calls set_hash_key etc. while the table is marked. */ + eassert (0 <= idx && idx < (ASIZE (array) & ~ARRAY_MARK_FLAG)); + XVECTOR (array)->contents[idx] = val; +} + +LISP_INLINE void +set_hash_key (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val) +{ + gc_aset (h->key_and_value, 2 * idx, val); +} + +LISP_INLINE void +set_hash_value (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val) +{ + gc_aset (h->key_and_value, 2 * idx + 1, val); +} + +LISP_INLINE void +set_hash_next (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val) +{ + gc_aset (h->next, idx, val); +} + +LISP_INLINE void +set_hash_hash (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val) +{ + gc_aset (h->hash, idx, val); +} + +LISP_INLINE void +set_hash_index (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val) +{ + gc_aset (h->index, idx, val); +} + +/* Use these functions to set Lisp_Object + or pointer slots of struct Lisp_Symbol. */ + +LISP_INLINE void +set_symbol_name (Lisp_Object sym, Lisp_Object name) +{ + XSYMBOL (sym)->name = name; +} + +LISP_INLINE void +set_symbol_function (Lisp_Object sym, Lisp_Object function) +{ + XSYMBOL (sym)->function = function; +} + +LISP_INLINE void +set_symbol_plist (Lisp_Object sym, Lisp_Object plist) +{ + XSYMBOL (sym)->plist = plist; +} + +LISP_INLINE void +set_symbol_next (Lisp_Object sym, struct Lisp_Symbol *next) +{ + XSYMBOL (sym)->next = next; +} + +/* Set overlay's property list. */ + +LISP_INLINE void +set_overlay_plist (Lisp_Object overlay, Lisp_Object plist) +{ + XOVERLAY (overlay)->plist = plist; +} + +/* Get text properties of S. */ + +LISP_INLINE INTERVAL +string_get_intervals (Lisp_Object s) +{ + return XSTRING (s)->intervals; +} + +/* Set text properties of S to I. */ + +LISP_INLINE void +string_set_intervals (Lisp_Object s, INTERVAL i) +{ + XSTRING (s)->intervals = i; +} + /* Defined in data.c. */ extern Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound; extern Lisp_Object Qerror_conditions, Qerror_message, Qtop_level; @@ -2322,60 +2457,19 @@ extern Lisp_Object Qoverflow_error, Qunderflow_error; extern Lisp_Object Qfloatp; extern Lisp_Object Qnumberp, Qnumber_or_marker_p; -extern Lisp_Object Qinteger; +extern Lisp_Object Qinteger, Qinterval, Qsymbol, Qstring; +extern Lisp_Object Qmisc, Qvector, Qfloat, Qcons, Qbuffer; extern Lisp_Object Qfont_spec, Qfont_entity, Qfont_object; -EXFUN (Finteractive_form, 1); -EXFUN (Fbyteorder, 0); +EXFUN (Fbyteorder, 0) ATTRIBUTE_CONST; /* Defined in frame.c */ extern Lisp_Object Qframep; /* Defined in data.c */ -EXFUN (Fcar, 1); -EXFUN (Fcar_safe, 1); -EXFUN (Fcdr, 1); -EXFUN (Fcdr_safe, 1); -EXFUN (Fsetcar, 2); -EXFUN (Fsetcdr, 2); -EXFUN (Fboundp, 1); -EXFUN (Ffboundp, 1); -EXFUN (Fsymbol_function, 1); -EXFUN (Fsymbol_name, 1); extern Lisp_Object indirect_function (Lisp_Object); -EXFUN (Findirect_function, 2); -EXFUN (Ffset, 2); -EXFUN (Fsymbol_value, 1); extern Lisp_Object find_symbol_value (Lisp_Object); -EXFUN (Fset, 2); -EXFUN (Fdefault_value, 1); -EXFUN (Fset_default, 2); -EXFUN (Fdefault_boundp, 1); -EXFUN (Fmake_local_variable, 1); -EXFUN (Flocal_variable_p, 2); - -EXFUN (Faref, 2); -EXFUN (Faset, 3); - -EXFUN (Fstring_to_number, 2); -EXFUN (Fnumber_to_string, 1); -EXFUN (Fgtr, 2); -EXFUN (Flss, 2); -EXFUN (Fgeq, 2); -EXFUN (Fleq, 2); -EXFUN (Fzerop, 1); -EXFUN (Fplus, MANY); -EXFUN (Fminus, MANY); -EXFUN (Ftimes, MANY); -EXFUN (Fquo, MANY); -EXFUN (Frem, 2); -EXFUN (Fmax, MANY); -EXFUN (Fmin, MANY); - -EXFUN (Fadd1, 1); -EXFUN (Fsub1, 1); -EXFUN (Fmake_variable_buffer_local, 1); /* Convert the integer I to an Emacs representation, either the integer itself, or a cons of two or three integers, or if all else fails a float. @@ -2406,10 +2500,10 @@ extern intmax_t cons_to_signed (Lisp_Object, intmax_t, intmax_t); extern uintmax_t cons_to_unsigned (Lisp_Object, uintmax_t); extern struct Lisp_Symbol *indirect_variable (struct Lisp_Symbol *); -extern void args_out_of_range (Lisp_Object, Lisp_Object) NO_RETURN; -extern void args_out_of_range_3 (Lisp_Object, Lisp_Object, - Lisp_Object) NO_RETURN; -extern Lisp_Object wrong_type_argument (Lisp_Object, Lisp_Object) NO_RETURN; +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, int); extern void syms_of_data (void); @@ -2417,22 +2511,11 @@ extern void init_data (void); extern void swap_in_global_binding (struct Lisp_Symbol *); /* Defined in cmds.c */ -EXFUN (Fend_of_line, 1); -EXFUN (Fforward_char, 1); -EXFUN (Fforward_line, 1); extern void syms_of_cmds (void); extern void keys_of_cmds (void); /* Defined in coding.c */ extern Lisp_Object Qcharset; -EXFUN (Fcoding_system_p, 1); -EXFUN (Fcoding_system_base, 1); -EXFUN (Fcoding_system_eol_type, 1); -EXFUN (Fcheck_coding_system, 1); -EXFUN (Fread_coding_system, 2); -EXFUN (Fread_non_nil_coding_system, 1); -EXFUN (Ffind_operation_coding_system, MANY); -EXFUN (Fdecode_coding_string, 4); extern Lisp_Object detect_coding_system (const unsigned char *, ptrdiff_t, ptrdiff_t, int, int, Lisp_Object); extern void init_coding (void); @@ -2440,13 +2523,11 @@ extern void init_coding_once (void); extern void syms_of_coding (void); /* Defined in character.c */ -EXFUN (Fchar_width, 1); -EXFUN (Fstring, MANY); +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); -extern int multibyte_char_to_unibyte_safe (int); -extern void init_character_once (void); +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 */ @@ -2460,16 +2541,14 @@ struct charset; extern void syms_of_composite (void); /* Defined in syntax.c */ -EXFUN (Fforward_word, 1); -EXFUN (Fskip_chars_forward, 2); -EXFUN (Fskip_chars_backward, 2); extern void init_syntax_once (void); extern void syms_of_syntax (void); /* Defined in fns.c */ extern Lisp_Object QCrehash_size, QCrehash_threshold; enum { NEXT_ALMOST_PRIME_LIMIT = 11 }; -extern EMACS_INT next_almost_prime (EMACS_INT); +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); extern Lisp_Object Qcursor_in_echo_area; @@ -2483,48 +2562,10 @@ Lisp_Object make_hash_table (Lisp_Object, Lisp_Object, Lisp_Object, 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); -void init_weak_hash_tables (void); -extern void init_fns (void); -EXFUN (Fmake_hash_table, MANY); -EXFUN (Fgethash, 3); -EXFUN (Fputhash, 3); -EXFUN (Fremhash, 2); - -EXFUN (Fidentity, 1); -EXFUN (Flength, 1); -EXFUN (Fappend, MANY); -EXFUN (Fconcat, MANY); -EXFUN (Fvconcat, MANY); -EXFUN (Fcopy_sequence, 1); -EXFUN (Fstring_make_multibyte, 1); -EXFUN (Fstring_make_unibyte, 1); -EXFUN (Fstring_as_multibyte, 1); -EXFUN (Fstring_as_unibyte, 1); -EXFUN (Fstring_to_multibyte, 1); -EXFUN (Fsubstring, 3); + extern Lisp_Object substring_both (Lisp_Object, ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t); -EXFUN (Fnth, 2); -EXFUN (Fnthcdr, 2); -EXFUN (Fmemq, 2); -EXFUN (Fassq, 2); -EXFUN (Fassoc, 2); -EXFUN (Felt, 2); -EXFUN (Fmember, 2); -EXFUN (Frassq, 2); -EXFUN (Fdelq, 2); -EXFUN (Fdelete, 2); -EXFUN (Fsort, 2); -EXFUN (Freverse, 1); -EXFUN (Fnreverse, 1); -EXFUN (Fget, 2); -EXFUN (Fput, 3); -EXFUN (Fequal, 2); -EXFUN (Fnconc, MANY); -EXFUN (Fmapcar, 2); -EXFUN (Fmapconcat, 3); extern Lisp_Object do_yes_or_no_p (Lisp_Object); -EXFUN (Fprovide, 2); extern Lisp_Object concat2 (Lisp_Object, Lisp_Object); extern Lisp_Object concat3 (Lisp_Object, Lisp_Object, Lisp_Object); extern Lisp_Object nconc2 (Lisp_Object, Lisp_Object); @@ -2535,20 +2576,10 @@ extern ptrdiff_t string_char_to_byte (Lisp_Object, ptrdiff_t); extern ptrdiff_t string_byte_to_char (Lisp_Object, ptrdiff_t); extern Lisp_Object string_to_multibyte (Lisp_Object); extern Lisp_Object string_make_unibyte (Lisp_Object); -EXFUN (Fcopy_alist, 1); -EXFUN (Fplist_get, 2); -EXFUN (Fplist_put, 3); -EXFUN (Fplist_member, 2); -EXFUN (Frassoc, 2); -EXFUN (Fstring_equal, 2); -EXFUN (Fcompare_strings, 7); -EXFUN (Fstring_lessp, 2); extern void syms_of_fns (void); /* Defined in floatfns.c */ extern double extract_float (Lisp_Object); -EXFUN (Ffloat, 1); -EXFUN (Ftruncate, 2); extern void init_floatfns (void); extern void syms_of_floatfns (void); extern Lisp_Object fmod_float (Lisp_Object x, Lisp_Object y); @@ -2566,13 +2597,12 @@ extern Lisp_Object QCascent, QCmargin, QCrelief; extern Lisp_Object QCconversion; extern int x_bitmap_mask (struct frame *, ptrdiff_t); extern void syms_of_image (void); -extern void init_image (void); /* Defined in insdel.c */ extern Lisp_Object Qinhibit_modification_hooks; extern void move_gap (ptrdiff_t); extern void move_gap_both (ptrdiff_t, ptrdiff_t); -extern void buffer_overflow (void) NO_RETURN; +extern _Noreturn void buffer_overflow (void); extern void make_gap (ptrdiff_t); extern ptrdiff_t copy_text (const unsigned char *, unsigned char *, ptrdiff_t, int, int); @@ -2617,15 +2647,11 @@ extern void syms_of_insdel (void); /* Defined in dispnew.c */ #if (defined PROFILING \ && (defined __FreeBSD__ || defined GNU_LINUX || defined __MINGW32__)) -void __executable_start (void) NO_RETURN; +_Noreturn void __executable_start (void); #endif extern Lisp_Object selected_frame; extern Lisp_Object Vwindow_system; -EXFUN (Fding, 1); -EXFUN (Fredraw_frame, 1); void duration_to_sec_usec (double, int *, int *); -EXFUN (Fsleep_for, 2); -EXFUN (Fredisplay, 1); extern Lisp_Object sit_for (Lisp_Object, int, int); extern void init_display (void); extern void syms_of_display (void); @@ -2693,34 +2719,41 @@ extern void allocate_string_data (struct Lisp_String *, EMACS_INT, EMACS_INT); extern void reset_malloc_hooks (void); extern void uninterrupt_malloc (void); extern void malloc_warning (const char *); -extern void memory_full (size_t) NO_RETURN; -extern void buffer_memory_full (ptrdiff_t) NO_RETURN; +extern _Noreturn void memory_full (size_t); +extern _Noreturn void buffer_memory_full (ptrdiff_t); extern int survives_gc_p (Lisp_Object); extern void mark_object (Lisp_Object); #if defined REL_ALLOC && !defined SYSTEM_MALLOC extern void refill_memory_reserve (void); #endif extern const char *pending_malloc_warning; +extern Lisp_Object zero_vector; extern Lisp_Object *stack_base; -EXFUN (Fcons, 2); +extern EMACS_INT consing_since_gc; +extern EMACS_INT gc_relative_threshold; +extern EMACS_INT memory_full_cons_threshold; extern Lisp_Object list1 (Lisp_Object); extern Lisp_Object list2 (Lisp_Object, Lisp_Object); extern Lisp_Object list3 (Lisp_Object, Lisp_Object, Lisp_Object); extern Lisp_Object list4 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); extern Lisp_Object list5 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); -EXFUN (Flist, MANY); -EXFUN (Fmake_list, 2); -extern Lisp_Object allocate_misc (void); -EXFUN (Fmake_vector, 2); -EXFUN (Fvector, MANY); -EXFUN (Fmake_symbol, 1); -EXFUN (Fmake_marker, 0); -extern void string_overflow (void) NO_RETURN; -EXFUN (Fmake_string, 2); -extern Lisp_Object build_string (const char *); +enum constype {CONSTYPE_HEAP, CONSTYPE_PURE}; +extern Lisp_Object listn (enum constype, ptrdiff_t, Lisp_Object, ...); +extern _Noreturn void string_overflow (void); extern Lisp_Object make_string (const char *, 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); + +/* Make unibyte string from C string when the length isn't known. */ + +LISP_INLINE Lisp_Object +build_unibyte_string (const char *str) +{ + return make_unibyte_string (str, strlen (str)); +} + extern Lisp_Object make_multibyte_string (const char *, ptrdiff_t, ptrdiff_t); extern Lisp_Object make_event_array (int, Lisp_Object *); extern Lisp_Object make_uninit_string (EMACS_INT); @@ -2728,14 +2761,28 @@ extern Lisp_Object make_uninit_multibyte_string (EMACS_INT, EMACS_INT); extern Lisp_Object make_string_from_bytes (const char *, ptrdiff_t, ptrdiff_t); extern Lisp_Object make_specified_string (const char *, ptrdiff_t, ptrdiff_t, int); -EXFUN (Fpurecopy, 1); extern Lisp_Object make_pure_string (const char *, ptrdiff_t, ptrdiff_t, int); -extern Lisp_Object make_pure_c_string (const char *data); +extern Lisp_Object make_pure_c_string (const char *, ptrdiff_t); + +/* Make a string allocated in pure space, use STR as string data. */ + +LISP_INLINE Lisp_Object +build_pure_c_string (const char *str) +{ + return make_pure_c_string (str, strlen (str)); +} + +/* Make a string from the data at STR, treating it as multibyte if the + data warrants. */ + +LISP_INLINE Lisp_Object +build_string (const char *str) +{ + return make_string (str, strlen (str)); +} + extern Lisp_Object pure_cons (Lisp_Object, Lisp_Object); -EXFUN (Fgarbage_collect, 0); extern void make_byte_code (struct Lisp_Vector *); -EXFUN (Fmake_byte_code, MANY); -EXFUN (Fmake_bool_vector, 2); extern Lisp_Object Qchar_table_extra_slots; extern struct Lisp_Vector *allocate_vector (EMACS_INT); extern struct Lisp_Vector *allocate_pseudovector (int memlen, int lisplen, int tag); @@ -2754,6 +2801,7 @@ extern Lisp_Object make_float (double); extern void display_malloc_warning (void); extern ptrdiff_t inhibit_garbage_collection (void); extern Lisp_Object make_save_value (void *, ptrdiff_t); +extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); extern void free_marker (Lisp_Object); extern void free_cons (struct Lisp_Cons *); extern void init_alloc_once (void); @@ -2761,6 +2809,11 @@ 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); +#ifdef GC_CHECK_CONS_LIST +extern void check_cons_list (void); +#else +#define check_cons_list() ((void) 0) +#endif #ifdef REL_ALLOC /* Defined in ralloc.c */ @@ -2772,12 +2825,6 @@ extern void r_alloc_inhibit_buffer_relocation (int); #endif /* Defined in chartab.c */ -EXFUN (Fmake_char_table, 2); -EXFUN (Fset_char_table_parent, 2); -EXFUN (Fchar_table_extra_slot, 2); -EXFUN (Fset_char_table_extra_slot, 3); -EXFUN (Fset_char_table_range, 3); -EXFUN (Foptimize_char_table, 2); 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, @@ -2799,11 +2846,6 @@ extern void syms_of_chartab (void); /* Defined in print.c */ extern Lisp_Object Vprin1_to_string_buffer; extern void debug_print (Lisp_Object) EXTERNALLY_VISIBLE; -EXFUN (Fprin1, 2); -EXFUN (Fprin1_to_string, 2); -EXFUN (Fterpri, 1); -EXFUN (Fprint, 2); -EXFUN (Ferror_message_string, 1); extern Lisp_Object Qstandard_output; extern Lisp_Object Qexternal_debugging_output; extern void temp_output_buffer_setup (const char *); @@ -2814,8 +2856,8 @@ extern void print_error_message (Lisp_Object, Lisp_Object, const char *, Lisp_Object); extern Lisp_Object internal_with_output_to_temp_buffer (const char *, Lisp_Object (*) (Lisp_Object), Lisp_Object); -#define FLOAT_TO_STRING_BUFSIZE 350 -extern void float_to_string (char *, double); +enum FLOAT_TO_STRING_BUFSIZE { FLOAT_TO_STRING_BUFSIZE = 350 }; +extern int float_to_string (char *, double); extern void syms_of_print (void); /* Defined in doprnt.c */ @@ -2833,18 +2875,9 @@ extern ptrdiff_t evxprintf (char **, ptrdiff_t *, char const *, ptrdiff_t, /* Defined in lread.c. */ extern Lisp_Object Qvariable_documentation, Qstandard_input; extern Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction; -EXFUN (Fread, 1); -EXFUN (Fread_from_string, 3); -EXFUN (Fintern, 2); -EXFUN (Fintern_soft, 2); -EXFUN (Funintern, 2); -EXFUN (Fload, 5); -EXFUN (Fget_load_suffixes, 0); -EXFUN (Fread_char, 3); -EXFUN (Fread_event, 3); extern Lisp_Object check_obarray (Lisp_Object); -extern Lisp_Object intern (const char *); -extern Lisp_Object intern_c_string (const char *); +extern Lisp_Object intern_1 (const char *, ptrdiff_t); +extern Lisp_Object intern_c_string_1 (const char *, ptrdiff_t); extern Lisp_Object oblookup (Lisp_Object, const char *, ptrdiff_t, ptrdiff_t); #define LOADHIST_ATTACH(x) \ do { \ @@ -2861,6 +2894,18 @@ extern void init_obarray (void); extern void init_lread (void); extern void syms_of_lread (void); +LISP_INLINE Lisp_Object +intern (const char *str) +{ + return intern_1 (str, strlen (str)); +} + +LISP_INLINE Lisp_Object +intern_c_string (const char *str) +{ + return intern_c_string_1 (str, strlen (str)); +} + /* Defined in eval.c. */ extern Lisp_Object Qautoload, Qexit, Qinteractive, Qcommandp, Qmacro; extern Lisp_Object Qinhibit_quit, Qclosure; @@ -2881,29 +2926,18 @@ extern struct handler *handlerlist; should no longer be used. */ extern Lisp_Object Vrun_hooks; -EXFUN (Frun_hooks, MANY); -EXFUN (Frun_hook_with_args, MANY); -EXFUN (Frun_hook_with_args_until_failure, MANY); extern void run_hook_with_args_2 (Lisp_Object, Lisp_Object, Lisp_Object); extern Lisp_Object run_hook_with_args (ptrdiff_t nargs, Lisp_Object *args, Lisp_Object (*funcall) (ptrdiff_t nargs, Lisp_Object *args)); -EXFUN (Fprogn, UNEVALLED); -EXFUN (Finteractive_p, 0); -EXFUN (Fthrow, 2) NO_RETURN; -EXFUN (Fsignal, 2); -extern void xsignal (Lisp_Object, Lisp_Object) NO_RETURN; -extern void xsignal0 (Lisp_Object) NO_RETURN; -extern void xsignal1 (Lisp_Object, Lisp_Object) NO_RETURN; -extern void xsignal2 (Lisp_Object, Lisp_Object, Lisp_Object) NO_RETURN; -extern void xsignal3 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object) NO_RETURN; -extern void signal_error (const char *, Lisp_Object) NO_RETURN; -EXFUN (Fcommandp, 2); -EXFUN (Ffunctionp, 1); -EXFUN (Feval, 2); +extern _Noreturn void xsignal (Lisp_Object, Lisp_Object); +extern _Noreturn void xsignal0 (Lisp_Object); +extern _Noreturn void xsignal1 (Lisp_Object, Lisp_Object); +extern _Noreturn void xsignal2 (Lisp_Object, Lisp_Object, Lisp_Object); +extern _Noreturn void xsignal3 (Lisp_Object, Lisp_Object, Lisp_Object, + Lisp_Object); +extern _Noreturn void signal_error (const char *, Lisp_Object); extern Lisp_Object eval_sub (Lisp_Object form); -EXFUN (Fapply, MANY); -EXFUN (Ffuncall, MANY); extern Lisp_Object apply1 (Lisp_Object, Lisp_Object); extern Lisp_Object call0 (Lisp_Object); extern Lisp_Object call1 (Lisp_Object, Lisp_Object); @@ -2913,23 +2947,23 @@ extern Lisp_Object call4 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Li extern Lisp_Object call5 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); extern Lisp_Object call6 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); extern Lisp_Object call7 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); -EXFUN (Fdo_auto_save, 2); extern Lisp_Object internal_catch (Lisp_Object, Lisp_Object (*) (Lisp_Object), Lisp_Object); extern Lisp_Object internal_lisp_condition_case (Lisp_Object, Lisp_Object, Lisp_Object); extern Lisp_Object internal_condition_case (Lisp_Object (*) (void), Lisp_Object, Lisp_Object (*) (Lisp_Object)); extern Lisp_Object internal_condition_case_1 (Lisp_Object (*) (Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object (*) (Lisp_Object)); extern Lisp_Object internal_condition_case_2 (Lisp_Object (*) (Lisp_Object, Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object (*) (Lisp_Object)); -extern Lisp_Object internal_condition_case_n (Lisp_Object (*) (ptrdiff_t, Lisp_Object *), ptrdiff_t, Lisp_Object *, Lisp_Object, Lisp_Object (*) (Lisp_Object)); +extern Lisp_Object internal_condition_case_n + (Lisp_Object (*) (ptrdiff_t, Lisp_Object *), ptrdiff_t, Lisp_Object *, + Lisp_Object, Lisp_Object (*) (Lisp_Object, ptrdiff_t, Lisp_Object *)); extern void specbind (Lisp_Object, Lisp_Object); extern void record_unwind_protect (Lisp_Object (*) (Lisp_Object), Lisp_Object); extern Lisp_Object unbind_to (ptrdiff_t, Lisp_Object); -extern void error (const char *, ...) NO_RETURN ATTRIBUTE_FORMAT_PRINTF (1, 2); -extern void verror (const char *, va_list) - NO_RETURN ATTRIBUTE_FORMAT_PRINTF (1, 0); -extern void do_autoload (Lisp_Object, Lisp_Object); +extern _Noreturn void error (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2); +extern _Noreturn void verror (const char *, va_list) + ATTRIBUTE_FORMAT_PRINTF (1, 0); extern Lisp_Object un_autoload (Lisp_Object); extern void init_eval_once (void); -extern Lisp_Object safe_call (ptrdiff_t, Lisp_Object *); +extern Lisp_Object safe_call (ptrdiff_t, Lisp_Object, ...); extern Lisp_Object safe_call1 (Lisp_Object, Lisp_Object); extern Lisp_Object safe_call2 (Lisp_Object, Lisp_Object, Lisp_Object); extern void init_eval (void); @@ -2938,58 +2972,26 @@ extern void mark_backtrace (void); #endif extern void syms_of_eval (void); -/* Defined in editfns.c */ +/* Defined in editfns.c. */ extern Lisp_Object Qfield; -EXFUN (Fcurrent_message, 0); -EXFUN (Fgoto_char, 1); -EXFUN (Fpoint_max_marker, 0); -EXFUN (Fpoint, 0); -EXFUN (Fpoint_marker, 0); -EXFUN (Fline_beginning_position, 1); -EXFUN (Fline_end_position, 1); -EXFUN (Ffollowing_char, 0); -EXFUN (Fprevious_char, 0); -EXFUN (Fchar_after, 1); -EXFUN (Finsert, MANY); -EXFUN (Finsert_char, 3); extern void insert1 (Lisp_Object); -EXFUN (Feolp, 0); -EXFUN (Feobp, 0); -EXFUN (Fbolp, 0); -EXFUN (Fbobp, 0); -EXFUN (Fformat, MANY); -EXFUN (Fmessage, MANY); extern Lisp_Object format2 (const char *, Lisp_Object, Lisp_Object); -EXFUN (Fbuffer_substring, 2); -EXFUN (Fbuffer_string, 0); extern Lisp_Object save_excursion_save (void); extern Lisp_Object save_restriction_save (void); extern Lisp_Object save_excursion_restore (Lisp_Object); extern Lisp_Object save_restriction_restore (Lisp_Object); -EXFUN (Fchar_to_string, 1); -EXFUN (Fdelete_region, 2); -EXFUN (Fnarrow_to_region, 2); -EXFUN (Fwiden, 0); -EXFUN (Fuser_login_name, 1); -EXFUN (Fsystem_name, 0); -EXFUN (Fcurrent_time, 0); -EXFUN (Fget_internal_run_time, 0); +extern _Noreturn void time_overflow (void); extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, int); extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, int); extern void init_editfns (void); const char *get_system_name (void); extern void syms_of_editfns (void); -EXFUN (Fconstrain_to_field, 5); -EXFUN (Ffield_end, 3); extern void set_time_zone_rule (const char *); -/* Defined in buffer.c */ +/* Defined in buffer.c. */ extern int mouse_face_overlay_overlaps (Lisp_Object); -extern void nsberror (Lisp_Object) NO_RETURN; -EXFUN (Fset_buffer_multibyte, 1); -EXFUN (Foverlay_start, 1); -EXFUN (Foverlay_end, 1); +extern _Noreturn void nsberror (Lisp_Object); extern void adjust_overlays_for_insert (ptrdiff_t, ptrdiff_t); extern void adjust_overlays_for_delete (ptrdiff_t, ptrdiff_t); extern void fix_start_end_in_overlays (ptrdiff_t, ptrdiff_t); @@ -2997,38 +2999,17 @@ extern void report_overlay_modification (Lisp_Object, Lisp_Object, int, Lisp_Object, Lisp_Object, Lisp_Object); extern int overlay_touches_p (ptrdiff_t); extern Lisp_Object Vbuffer_alist; -EXFUN (Fget_buffer, 1); -EXFUN (Fget_buffer_create, 1); -EXFUN (Fgenerate_new_buffer_name, 2); -EXFUN (Fset_buffer, 1); extern Lisp_Object set_buffer_if_live (Lisp_Object); -EXFUN (Fbarf_if_buffer_read_only, 0); -EXFUN (Fcurrent_buffer, 0); -EXFUN (Fother_buffer, 3); extern Lisp_Object other_buffer_safely (Lisp_Object); -EXFUN (Foverlay_get, 2); -EXFUN (Fbuffer_modified_p, 1); -EXFUN (Fset_buffer_modified_p, 1); -EXFUN (Fkill_buffer, 1); -EXFUN (Fkill_all_local_variables, 0); -EXFUN (Fbuffer_enable_undo, 1); -EXFUN (Ferase_buffer, 0); extern Lisp_Object Qpriority, Qwindow, Qbefore_string, Qafter_string; extern Lisp_Object get_truename_buffer (Lisp_Object); -extern struct buffer *all_buffers; -EXFUN (Fprevious_overlay_change, 1); -EXFUN (Fbuffer_file_name, 1); extern void init_buffer_once (void); extern void init_buffer (void); extern void syms_of_buffer (void); extern void keys_of_buffer (void); -/* Defined in marker.c */ +/* Defined in marker.c. */ -EXFUN (Fmarker_position, 1); -EXFUN (Fmarker_buffer, 1); -EXFUN (Fcopy_marker, 2); -EXFUN (Fset_marker, 3); extern ptrdiff_t marker_position (Lisp_Object); extern ptrdiff_t marker_byte_position (Lisp_Object); extern void clear_charpos_cache (struct buffer *); @@ -3040,6 +3021,7 @@ extern Lisp_Object set_marker_restricted (Lisp_Object, Lisp_Object, Lisp_Object) extern Lisp_Object set_marker_both (Lisp_Object, Lisp_Object, ptrdiff_t, ptrdiff_t); extern Lisp_Object set_marker_restricted_both (Lisp_Object, Lisp_Object, ptrdiff_t, ptrdiff_t); +extern Lisp_Object build_marker (struct buffer *, ptrdiff_t, ptrdiff_t); extern void syms_of_marker (void); /* Defined in fileio.c */ @@ -3049,27 +3031,11 @@ extern Lisp_Object Qfile_exists_p; extern Lisp_Object Qfile_directory_p; extern Lisp_Object Qinsert_file_contents; extern Lisp_Object Qfile_name_history; -EXFUN (Ffind_file_name_handler, 2); -EXFUN (Ffile_name_as_directory, 1); -EXFUN (Fexpand_file_name, 2); -EXFUN (Ffile_name_nondirectory, 1); -EXFUN (Fsubstitute_in_file_name, 1); -EXFUN (Ffile_symlink_p, 1); -EXFUN (Fverify_visited_file_modtime, 1); -EXFUN (Ffile_exists_p, 1); -EXFUN (Ffile_name_absolute_p, 1); -EXFUN (Fdirectory_file_name, 1); -EXFUN (Ffile_name_directory, 1); extern Lisp_Object expand_and_dir_to_file (Lisp_Object, Lisp_Object); -EXFUN (Ffile_accessible_directory_p, 1); -EXFUN (Funhandled_file_name_directory, 1); -EXFUN (Ffile_directory_p, 1); -EXFUN (Fwrite_region, 7); -EXFUN (Ffile_readable_p, 1); -EXFUN (Fread_file_name, 6); +EXFUN (Fread_file_name, 6); /* not a normal DEFUN */ extern Lisp_Object close_file_unwind (Lisp_Object); extern Lisp_Object restore_point_unwind (Lisp_Object); -extern void report_file_error (const char *, Lisp_Object) NO_RETURN; +extern _Noreturn void report_file_error (const char *, Lisp_Object); extern int internal_delete_file (Lisp_Object); extern void syms_of_fileio (void); extern Lisp_Object make_temp_name (Lisp_Object, int); @@ -3077,19 +3043,15 @@ extern Lisp_Object Qdelete_file; /* Defined in search.c */ extern void shrink_regexp_cache (void); -EXFUN (Fstring_match, 3); extern void restore_search_regs (void); -EXFUN (Fmatch_data, 3); -EXFUN (Fset_match_data, 2); -EXFUN (Fmatch_beginning, 1); -EXFUN (Fmatch_end, 1); extern void record_unwind_save_match_data (void); struct re_registers; extern struct re_pattern_buffer *compile_pattern (Lisp_Object, struct re_registers *, Lisp_Object, int, int); extern ptrdiff_t fast_string_match (Lisp_Object, Lisp_Object); -extern ptrdiff_t fast_c_string_match_ignore_case (Lisp_Object, const char *); +extern ptrdiff_t fast_c_string_match_ignore_case (Lisp_Object, const char *, + ptrdiff_t); extern ptrdiff_t fast_string_match_ignore_case (Lisp_Object, Lisp_Object); extern ptrdiff_t fast_looking_at (Lisp_Object, ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, Lisp_Object); @@ -3103,50 +3065,34 @@ extern ptrdiff_t find_before_next_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t); extern void syms_of_search (void); extern void clear_regexp_cache (void); -/* Defined in minibuf.c */ +/* Defined in minibuf.c. */ extern Lisp_Object Qcompletion_ignore_case; extern Lisp_Object Vminibuffer_list; extern Lisp_Object last_minibuf_string; -EXFUN (Fcompleting_read, 8); -EXFUN (Fread_from_minibuffer, 7); -EXFUN (Fread_variable, 2); -EXFUN (Fread_buffer, 3); -EXFUN (Fread_minibuffer, 2); -EXFUN (Feval_minibuffer, 2); -EXFUN (Fread_string, 5); -EXFUN (Fassoc_string, 3); extern Lisp_Object get_minibuffer (EMACS_INT); extern void init_minibuf_once (void); extern void syms_of_minibuf (void); -/* Defined in callint.c */ +/* Defined in callint.c. */ extern Lisp_Object Qminus, Qplus; extern Lisp_Object Qwhen; extern Lisp_Object Qcall_interactively, Qmouse_leave_buffer_hook; -EXFUN (Fprefix_numeric_value, 1); extern void syms_of_callint (void); -/* Defined in casefiddle.c */ +/* Defined in casefiddle.c. */ extern Lisp_Object Qidentity; -EXFUN (Fdowncase, 1); -EXFUN (Fupcase, 1); -EXFUN (Fupcase_region, 2); -EXFUN (Fupcase_initials, 1); -EXFUN (Fupcase_initials_region, 2); extern void syms_of_casefiddle (void); extern void keys_of_casefiddle (void); -/* Defined in casetab.c */ +/* Defined in casetab.c. */ -EXFUN (Fset_case_table, 1); -EXFUN (Fset_standard_case_table, 1); extern void init_casetab_once (void); extern void syms_of_casetab (void); -/* Defined in keyboard.c */ +/* Defined in keyboard.c. */ extern Lisp_Object echo_message_buffer; extern struct kboard *echo_kboard; @@ -3154,17 +3100,11 @@ extern void cancel_echoing (void); extern Lisp_Object Qdisabled, QCfilter; extern Lisp_Object Qup, Qdown, Qbottom; extern Lisp_Object Qtop; +extern Lisp_Object last_undo_boundary; extern int input_pending; -EXFUN (Fdiscard_input, 0); -EXFUN (Frecursive_edit, 0); -EXFUN (Ftop_level, 0) NO_RETURN; extern Lisp_Object menu_bar_items (Lisp_Object); extern Lisp_Object tool_bar_items (Lisp_Object, int *); extern void discard_mouse_events (void); -EXFUN (Fevent_convert_list, 1); -EXFUN (Fread_key_sequence, 5); -EXFUN (Fset_input_interrupt_mode, 1); -EXFUN (Fset_input_mode, 4); extern Lisp_Object pending_funcalls; extern int detect_input_pending (void); extern int detect_input_pending_ignore_squeezables (void); @@ -3181,19 +3121,14 @@ extern void init_keyboard (void); extern void syms_of_keyboard (void); extern void keys_of_keyboard (void); -/* Defined in indent.c */ -EXFUN (Fvertical_motion, 2); -EXFUN (Findent_to, 2); -EXFUN (Fmove_to_column, 2); +/* Defined in indent.c. */ extern ptrdiff_t current_column (void); extern void invalidate_current_column (void); extern int indented_beyond_p (ptrdiff_t, ptrdiff_t, EMACS_INT); extern void syms_of_indent (void); -/* Defined in frame.c */ -#ifdef HAVE_WINDOW_SYSTEM -#endif /* HAVE_WINDOW_SYSTEM */ -extern Lisp_Object Qonly; +/* Defined in frame.c. */ +extern Lisp_Object Qonly, Qnone; extern Lisp_Object Qvisible; extern void store_frame_param (struct frame *, Lisp_Object, Lisp_Object); extern void store_in_alist (Lisp_Object *, Lisp_Object, Lisp_Object); @@ -3202,18 +3137,10 @@ extern Lisp_Object do_switch_frame (Lisp_Object, int, int, Lisp_Object); extern Lisp_Object get_frame_param (struct frame *, Lisp_Object); #endif extern Lisp_Object frame_buffer_predicate (Lisp_Object); -EXFUN (Fselect_frame, 2); -EXFUN (Fselected_frame, 0); -EXFUN (Fmake_frame_visible, 1); -EXFUN (Ficonify_frame, 1); -EXFUN (Fframe_parameter, 2); -EXFUN (Fmodify_frame_parameters, 2); -EXFUN (Fraise_frame, 1); -EXFUN (Fredirect_frame_focus, 2); extern void frames_discard_buffer (Lisp_Object); extern void syms_of_frame (void); -/* Defined in emacs.c */ +/* Defined in emacs.c. */ extern char **initial_argv; extern int initial_argc; #if defined (HAVE_X_WINDOWS) || defined (HAVE_NS) @@ -3226,7 +3153,6 @@ extern Lisp_Object Qfile_name_handler_alist; extern void fatal_error_signal (int); #endif extern Lisp_Object Qkill_emacs; -EXFUN (Fkill_emacs, 1) NO_RETURN; #if HAVE_SETLOCALE void fixup_locale (void); void synchronize_system_messages_locale (void); @@ -3256,16 +3182,20 @@ extern int running_asynch_code; /* Defined in process.c. */ extern Lisp_Object QCtype, Qlocal; -EXFUN (Fget_buffer_process, 1); -EXFUN (Fprocess_status, 1); -EXFUN (Fkill_process, 2); -EXFUN (Fwaiting_for_user_input_p, 0); extern Lisp_Object Qprocessp; extern void kill_buffer_processes (Lisp_Object); -extern int wait_reading_process_output (int, int, int, int, +extern int wait_reading_process_output (intmax_t, int, int, int, 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. + The bug merely causes a bogus warning, but the warning is annoying. */ +# define WAIT_READING_MAX min (TYPE_MAXIMUM (time_t), INTMAX_MAX) +#else +# define WAIT_READING_MAX INTMAX_MAX +#endif extern void add_keyboard_wait_descriptor (int); extern void delete_keyboard_wait_descriptor (int); #ifdef HAVE_GPM @@ -3273,16 +3203,14 @@ extern void add_gpm_wait_descriptor (int); extern void delete_gpm_wait_descriptor (int); #endif extern void close_process_descs (void); -extern void init_process (void); +extern void init_process_emacs (void); extern void syms_of_process (void); extern void setup_process_coding_systems (Lisp_Object); -EXFUN (Fcall_process, MANY); -extern int child_setup (int, int, int, char **, int, Lisp_Object) #ifndef DOS_NT - NO_RETURN + _Noreturn #endif - ; +extern int child_setup (int, int, int, char **, int, Lisp_Object); extern void init_callproc_1 (void); extern void init_callproc (void); extern void set_initial_environment (void); @@ -3290,7 +3218,6 @@ extern void syms_of_callproc (void); /* Defined in doc.c */ extern Lisp_Object Qfunction_documentation; -EXFUN (Fsubstitute_command_keys, 1); extern Lisp_Object read_doc_string (Lisp_Object); extern Lisp_Object get_doc_string (Lisp_Object, int, int); extern void syms_of_doc (void); @@ -3309,15 +3236,12 @@ extern Lisp_Object exec_byte_code (Lisp_Object, Lisp_Object, Lisp_Object, /* Defined in macros.c */ extern Lisp_Object Qexecute_kbd_macro; -EXFUN (Fexecute_kbd_macro, 3); -EXFUN (Fcancel_kbd_macro_events, 0); extern void init_macros (void); extern void syms_of_macros (void); /* Defined in undo.c */ extern Lisp_Object Qapply; extern Lisp_Object Qinhibit_read_only; -EXFUN (Fundo_boundary, 0); extern void truncate_undo_list (struct buffer *); extern void record_marker_adjustment (Lisp_Object, ptrdiff_t); extern void record_insert (ptrdiff_t, ptrdiff_t); @@ -3334,21 +3258,12 @@ extern Lisp_Object Qinsert_in_front_hooks, Qinsert_behind_hooks; extern Lisp_Object Qfront_sticky, Qrear_nonsticky; extern Lisp_Object Qminibuffer_prompt; -EXFUN (Fnext_single_property_change, 4); -EXFUN (Fnext_single_char_property_change, 4); -EXFUN (Fprevious_single_property_change, 4); -EXFUN (Fget_text_property, 3); -EXFUN (Fput_text_property, 5); -EXFUN (Fprevious_char_property_change, 2); -EXFUN (Fnext_char_property_change, 2); extern void report_interval_modification (Lisp_Object, Lisp_Object); /* Defined in menu.c */ extern void syms_of_menu (void); /* Defined in xmenu.c */ -EXFUN (Fx_popup_menu, 2); -EXFUN (Fx_popup_dialog, 3); extern void syms_of_xmenu (void); /* Defined in termchar.h */ @@ -3372,7 +3287,7 @@ extern void init_all_sys_modes (void); extern void reset_all_sys_modes (void); extern void wait_for_termination (pid_t); extern void interruptible_wait_for_termination (pid_t); -extern void flush_pending_output (int); +extern void flush_pending_output (int) ATTRIBUTE_CONST; extern void child_setup_tty (int); extern void setup_pty (int); extern int set_window_size (int, int, int); @@ -3385,17 +3300,14 @@ extern ptrdiff_t emacs_write (int, const char *, ptrdiff_t); enum { READLINK_BUFSIZE = 1024 }; extern char *emacs_readlink (const char *, char [READLINK_BUFSIZE]); -EXFUN (Funlock_buffer, 0); extern void unlock_all_files (void); 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 void init_filelock (void); /* Defined in sound.c */ extern void syms_of_sound (void); -extern void init_sound (void); /* Defined in category.c */ extern void init_category_once (void); @@ -3415,12 +3327,10 @@ extern Lisp_Object directory_files_internal (Lisp_Object, Lisp_Object, extern int *char_ins_del_vector; extern void mark_ttys (void); extern void syms_of_term (void); -extern void fatal (const char *msgid, ...) - NO_RETURN ATTRIBUTE_FORMAT_PRINTF (1, 2); +extern _Noreturn void fatal (const char *msgid, ...) + ATTRIBUTE_FORMAT_PRINTF (1, 2); /* Defined in terminal.c */ -EXFUN (Fframe_terminal, 1); -EXFUN (Fdelete_terminal, 2); extern void syms_of_terminal (void); /* Defined in font.c */ @@ -3433,8 +3343,6 @@ extern void syms_of_fontset (void); /* Defined in xfns.c, w32fns.c, or macfns.c */ extern Lisp_Object Qfont_param; -EXFUN (Fxw_display_color_p, 1); -EXFUN (Fx_focus_frame, 1); #endif /* Defined in xfaces.c */ @@ -3447,8 +3355,6 @@ extern Lisp_Object QCfamily, QCweight, QCslant; extern Lisp_Object QCheight, QCname, QCwidth, QCforeground, QCbackground; extern Lisp_Object Vface_alternative_font_family_alist; extern Lisp_Object Vface_alternative_font_registry_alist; -EXFUN (Fclear_face_cache, 1); -EXFUN (Fx_load_color_file, 1); extern void syms_of_xfaces (void); #ifdef HAVE_X_WINDOWS @@ -3470,11 +3376,6 @@ extern void syms_of_xterm (void); extern char *x_get_keysym_name (int); #endif /* HAVE_WINDOW_SYSTEM */ -#ifdef MSDOS -/* Defined in msdos.c */ -EXFUN (Fmsdos_downcase_filename, 1); -#endif - #ifdef HAVE_LIBXML2 /* Defined in xml.c */ extern void syms_of_xml (void); @@ -3503,6 +3404,7 @@ extern int initialized; extern int immediate_quit; /* Nonzero means ^G can quit instantly */ extern void *xmalloc (size_t); +extern void *xzalloc (size_t); extern void *xrealloc (void *, size_t); extern void xfree (void *); extern void *xnmalloc (ptrdiff_t, ptrdiff_t); @@ -3516,27 +3418,6 @@ extern char *egetenv (const char *); /* Set up the name of the machine we're running on. */ extern void init_system_name (void); -/* Some systems (e.g., NT) use a different path separator than Unix, - in addition to a device separator. Set the path separator - to '/', and don't test for a device separator in IS_ANY_SEP. */ - -#define DIRECTORY_SEP '/' -#ifndef IS_DIRECTORY_SEP -#define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP) -#endif -#ifndef IS_DEVICE_SEP -#ifndef DEVICE_SEP -#define IS_DEVICE_SEP(_c_) 0 -#else -#define IS_DEVICE_SEP(_c_) ((_c_) == DEVICE_SEP) -#endif -#endif -#ifndef IS_ANY_SEP -#define IS_ANY_SEP(_c_) (IS_DIRECTORY_SEP (_c_)) -#endif - -#define SWITCH_ENUM_CAST(x) (x) - /* Use this to suppress gcc's warnings. */ #ifdef lint @@ -3552,15 +3433,6 @@ extern void init_system_name (void); # define lint_assume(cond) ((void) (0 && (cond))) #endif -/* The ubiquitous min and max macros. */ - -#ifdef max -#undef max -#undef min -#endif -#define min(a, b) ((a) < (b) ? (a) : (b)) -#define max(a, b) ((a) > (b) ? (a) : (b)) - /* We used to use `abs', but that clashes with system headers on some platforms, and using a name reserved by Standard C is a bad idea anyway. */ @@ -3603,27 +3475,19 @@ extern void init_system_name (void); /* SAFE_ALLOCA normally allocates memory on the stack, but if size is larger than MAX_ALLOCA, use xmalloc to avoid overflowing the stack. */ -#define MAX_ALLOCA 16*1024 +enum MAX_ALLOCA { MAX_ALLOCA = 16*1024 }; extern Lisp_Object safe_alloca_unwind (Lisp_Object); +extern void *record_xmalloc (size_t); #define USE_SAFE_ALLOCA \ ptrdiff_t sa_count = SPECPDL_INDEX (); int sa_must_free = 0 /* SAFE_ALLOCA allocates a simple buffer. */ -#define SAFE_ALLOCA(buf, type, size) \ - do { \ - if ((size) < MAX_ALLOCA) \ - buf = (type) alloca (size); \ - else \ - { \ - buf = (type) xmalloc (size); \ - sa_must_free = 1; \ - record_unwind_protect (safe_alloca_unwind, \ - make_save_value (buf, 0)); \ - } \ - } while (0) +#define SAFE_ALLOCA(size) ((size) < MAX_ALLOCA \ + ? alloca (size) \ + : (sa_must_free = 1, record_xmalloc (size))) /* SAFE_NALLOCA sets BUF to a newly allocated array of MULTIPLIER * NITEMS items, each of the same type as *BUF. MULTIPLIER must @@ -3655,24 +3519,38 @@ extern Lisp_Object safe_alloca_unwind (Lisp_Object); /* SAFE_ALLOCA_LISP allocates an array of Lisp_Objects. */ -#define SAFE_ALLOCA_LISP(buf, nelt) \ - do { \ - if ((nelt) < MAX_ALLOCA / sizeof (Lisp_Object)) \ - buf = (Lisp_Object *) alloca ((nelt) * sizeof (Lisp_Object)); \ - else if ((nelt) < min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Lisp_Object)) \ - { \ - Lisp_Object arg_; \ - buf = (Lisp_Object *) xmalloc ((nelt) * sizeof (Lisp_Object)); \ - arg_ = make_save_value (buf, nelt); \ - XSAVE_VALUE (arg_)->dogc = 1; \ - sa_must_free = 1; \ - record_unwind_protect (safe_alloca_unwind, arg_); \ - } \ - else \ - memory_full (SIZE_MAX); \ +#define SAFE_ALLOCA_LISP(buf, nelt) \ + do { \ + if ((nelt) < MAX_ALLOCA / word_size) \ + buf = alloca ((nelt) * word_size); \ + else if ((nelt) < min (PTRDIFF_MAX, SIZE_MAX) / word_size) \ + { \ + Lisp_Object arg_; \ + buf = xmalloc ((nelt) * word_size); \ + arg_ = make_save_value (buf, nelt); \ + XSAVE_VALUE (arg_)->dogc = 1; \ + sa_must_free = 1; \ + record_unwind_protect (safe_alloca_unwind, arg_); \ + } \ + else \ + memory_full (SIZE_MAX); \ } while (0) #include "globals.h" +/* Check whether it's time for GC, and run it if so. */ + +LISP_INLINE void +maybe_gc (void) +{ + if ((consing_since_gc > gc_cons_threshold + && consing_since_gc > gc_relative_threshold) + || (!NILP (Vmemory_full) + && consing_since_gc > memory_full_cons_threshold)) + Fgarbage_collect (); +} + +INLINE_HEADER_END + #endif /* EMACS_LISP_H */