=== modified file 'ChangeLog' --- ChangeLog 2012-07-17 07:30:25 +0000 +++ ChangeLog 2012-07-24 02:00:33 +0000 @@ -1,3 +1,9 @@ +2012-07-24 Paul Eggert + + Use functions, not macros, for XINT etc. (Bug#11935). + * configure.ac (WARN_CFLAGS): Remove -Wbad-function-cast, + as it generates bogus warnings about reasonable casts of calls. + 2012-07-17 Dmitry Antipov Fix toolkit configuration report. === modified file 'configure.ac' --- configure.ac 2012-07-17 07:30:25 +0000 +++ configure.ac 2012-07-17 16:27:20 +0000 @@ -675,6 +675,7 @@ nw="$nw -Winline" # OK to ignore 'inline' nw="$nw -Wsync-nand" # irrelevant here, and provokes ObjC warning nw="$nw -Wunsafe-loop-optimizations" # OK to suppress unsafe optimizations + nw="$nw -Wbad-function-cast" # These casts are no worse than others. # Emacs doesn't care about shadowing; see # . === modified file 'src/ChangeLog' --- src/ChangeLog 2012-07-23 16:57:20 +0000 +++ src/ChangeLog 2012-07-24 02:00:33 +0000 @@ -1,3 +1,132 @@ +2012-07-24 Paul Eggert + + Use functions, not macros, for XINT etc. (Bug#11935). + In lisp.h, prefer functions to function-like macros, and + constants to object-like macros, when either will do. This: + . makes the code easier to debug, as the symbols are visible to GDB. + . simplifies use, as there's no more need to worry about + arguments' side effects being evaluated multiple times. + . shrinks the size of Emacs's text segment by 0.5% + on my platform (x86-64, GCC 4.7.1). + * buffer.c (Qoverlap): + * data.c (Qsubrp): + * fns.c (Qhash_table_p): + Now extern, so lisp.h can use these symbols. + * dispextern.h: Include character.h, for MAX_CHAR etc. + (GLYPH, GLYPH_CHAR, GLYPH_FACE, SET_GLYPH_CHAR, SET_GLYPH_FACE) + (SET_GLYPH, GLYPH_CODE_CHAR, GLYPH_CODE_FACE) + (SET_GLYPH_FROM_GLYPH_CODE, GLYPH_MODE_LINE_FACE, GLYPH_CHAR_VALID_P) + (GLYPH_CODE_P): Move here from lisp.h. + (GLYPH_CHAR, GLYPH_FACE, GLYPH_CODE_CHAR, GLYPH_CODE_FACE) + (GLYPH_CHAR_VALID_P, GLYPH_CODE_P): Now functions, not macros. + (GLYPH_MODE_LINE_FACE): Now enums, not macros. + * eval.c (Fautoload): Cast XUNTAG output to intptr_t, since + XUNTAG now returns void *. + * lisp.h (XLI, XIL, CHECK_TYPE, CHECK_LIST_CONS, CHECK_NUMBER) + (CHECK_SYMBOL, CONSP, EQ, FLOATP, INTEGERP, LISP_INT_TAG_P, MARKERP) + (MISCP, NILP, SET_SYMBOL_VAL, SYMBOL_CONSTANT_P, SYMBOL_VAL, SYMBOLP) + (VECTORLIKEP, XCAR, XCDR, XCONS, XHASH, XPNTR, XSYMBOL): + If compiling via GCC without optimization, inline these functions + manually, by defining macros in addition to inline functions. + To disable this, compile with -DINLINING=0. + (make_number, XFASTINT, XINT, XTYPE, XUNTAG): Likewise, but + hand-optimize only in the USE_LSB_TAG case, as GNUish hosts do that. + (CHECK_CONS_LIST, LISP_INT_TAG_P, XLI, XIL, XHASH, XTYPE) + (XINT, XFASTINT, XUINT, make_number, XPNTR, XUNTAG, EQ, XCONS, XVECTOR) + (XSTRING, XSYMBOL, XFLOAT, XPROCESS, XWINDOW, XTERMINAL, XSUBR) + (XBUFFER, XCHAR_TABLE, XSUB_CHAR_TABLE, XBOOL_VECTOR, CHECK_TYPE) + (CHECK_STRING_OR_BUFFER, XCAR, XCDR, XSETCAR, XSETCDR, CAR, CDR) + (CAR_SAFE, CDR_SAFE, STRING_MULTIBYTE, STRING_INTERVALS) + (STRING_SET_INTERVALS, SDATA, SSDATA, SREF, SSET, SCHARS) + (STRING_BYTES, SBYTES, STRING_SET_CHARS, ASIZE, ASET) + (CHAR_TABLE_EXTRA_SLOTS, CHAR_TABLE_REF_ASCII, CHAR_TABLE_REF) + (CHAR_TABLE_TRANSLATE, CHAR_TABLE_SET, SYMBOL_VAL, SYMBOL_ALIAS) + (SYMBOL_BLV, SYMBOL_FWD, SET_SYMBOL_VAL, SET_SYMBOL_ALIAS) + (SET_SYMBOL_BLV, SET_SYMBOL_FWD, SYMBOL_NAME, SYMBOL_INTERNED_P) + (SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P, SYMBOL_CONSTANT_P) + (XHASH_TABLE, HASH_TABLE_P, CHECK_HASH_TABLE, HASH_TABLE_SIZE) + (XMISC, XMISCANY, XMARKER, XOVERLAY, XSAVE_VALUE, XSETMISCTYPE) + (BLV_FOUND, SET_BLV_FOUND, BLV_VALUE, SET_BLV_VALUE, XFWDTYPE) + (XINTFWD, XBOOLFWD, XOBJFWD, XBUFFER_OBJFWD, XKBOARD_OBJFWD) + (XFLOAT_DATA, XFLOAT_INIT, NILP, NUMBERP, NATNUMP) + (RANGED_INTEGERP, CONSP, FLOATP, MISCP, STRINGP, SYMBOLP) + (INTEGERP, VECTORLIKEP, VECTORP, OVERLAYP) + (MARKERP, SAVE_VALUEP, INTFWDP, BOOLFWDP, OBJFWDP) + (BUFFER_OBJFWDP, KBOARD_OBJFWDP) + (PSEUDOVECTORP, WINDOW_CONFIGURATIONP, PROCESSP, WINDOWP) + (TERMINALP, SUBRP, COMPILEDP, BUFFERP, CHAR_TABLE_P) + (SUB_CHAR_TABLE_P, BOOL_VECTOR_P, FRAMEP, IMAGEP, ARRAYP) + (CHECK_LIST, CHECK_LIST_CONS, CHECK_LIST_END, CHECK_STRING) + (CHECK_STRING_CAR, CHECK_CONS, CHECK_SYMBOL, CHECK_CHAR_TABLE) + (CHECK_VECTOR, CHECK_VECTOR_OR_STRING, CHECK_ARRAY) + (CHECK_VECTOR_OR_CHAR_TABLE, CHECK_BUFFER, CHECK_WINDOW) + (CHECK_WINDOW_CONFIGURATION, CHECK_PROCESS, CHECK_SUBR) + (CHECK_NUMBER, CHECK_NATNUM, CHECK_MARKER, XFLOATINT) + (CHECK_FLOAT, CHECK_NUMBER_OR_FLOAT, CHECK_OVERLAY) + (CHECK_NUMBER_CAR, CHECK_NUMBER_CDR, CHECK_NATNUM_CAR) + (CHECK_NATNUM_CDR, FUNCTIONP, SPECPDL_INDEX, LOADHIST_ATTACH) + (IS_DIRECTORY_SEP, IS_DEVICE_SEP, IS_ANY_SEP): + Now static inline functions. + (PSEUDOVECTOR_SIZE_TYPEP) New static inline function, replacing ... + (PSEUDOVECTOR_TYPEP): Remove macro. All uses changed to the new API. + (check_cons_list) [!GC_CHECK_CONS_LIST]: New empty function. + (EMACS_INT, EMACS_UINT): Now typedefs, not macros. + (VALBITS, INTTYPEBITS, FIXNUM_BITS, LISP_INT_TAG) + (PSEUDOVECTOR_SIZE_BITS, PSEUDOVECTOR_SIZE_MASK, PVEC_TYPE_MASK) + (BOOL_VECTOR_BITS_PER_CHAR, CHAR_TABLE_STANDARD_SLOTS) + (CHARTAB_SIZE_BITS_0, CHARTAB_SIZE_BITS_1) + (CHARTAB_SIZE_BITS_2, CHARTAB_SIZE_BITS_3, DEFAULT_HASH_SIZE) + (COMPILED_ARGLIST, COMPILED_BYTECODE, COMPILED_CONSTANTS) + (COMPILED_STACK_DEPTH, COMPILED_DOC_STRING, COMPILED_INTERACTIVE) + (CHAR_ALT, CHAR_SUPER, CHAR_HYPER, CHAR_SHIFT, CHAR_CTL, CHAR_META) + (CHAR_MODIFIER_MASK, MANY, UNEVALLED, FLOAT_TO_STRING_BUFSIZE): + (DIRECTORY_SEP, MAX_ALLOCA): + Now constants, not macros. + (LISP_INT1_TAG, LISP_STRING_TAG, LISP_MAKE_RVALUE, TYPEMASK): + Remove; no longer needed. + (DATA_SEG_BITS): Default to 0, as this simplifies the rest of the code. + (VALMASK): Define in one place rather than in two, merging the + USE_LSB_TAG parts; this is simpler. + (MOST_POSITIVE_FIXNUM, MOST_NEGATIVE_FIXNUM, max, min) + (struct Lisp_String, UNSIGNED_CMP, ASCII_CHAR_P): + Move up, to avoid use before definition. + Also include "globals.h" earlier, for the same reason. + (make_natnum, xtag): New functions. + (XUNTAG): Now returns void *, not intptr_t, as this means fewer casts. + (union Lisp_Fwd, BOOLFWDP, BOOL_VECTOR_P, BUFFER_OBJFWDP, BUFFERP) + (CHAR_TABLE_P, CHAR_TABLE_REF_ASCII, CONSP, FLOATP, INTEGERP, INTFWDP) + (KBOARD_OBJFWDP, MARKERP, MISCP, NILP, OBJFWDP, OVERLAYP, PROCESSP) + (PSEUDOVECTORP, SAVE_VALUEP, STRINGP, SUB_CHAR_TABLE_P, SUBRP, SYMBOLP) + (VECTORLIKEP, WINDOWP, Qoverlayp, char_table_ref, char_table_set) + (char_table_translate, Qarrayp, Qbufferp, Qbuffer_or_string_p) + (Qchar_table_p, Qconsp, Qfloatp, Qintegerp, Qlambda, Qlistp, Qmarkerp) + (Qnil, Qnumberp, Qsubrp, Qstringp, Qsymbolp, Qvectorp) + (Qvector_or_char_table_p, Qwholenump, Ffboundp, wrong_type_argument) + (initialized, Qhash_table_p, extract_float, Qprocessp, Qwindowp) + (Qwindow_configuration_p, Qimage): New forward declarations. + (XSET): Simplify by rewriting in terms of xtag. + (XSETFASTINT): Simplify by rewriting in terms of make_natnum. + (STRING_COPYIN): Remove; unused. + (GLYPH, GLYPH_CHAR, GLYPH_FACE, SET_GLYPH_CHAR, SET_GLYPH_FACE) + (SET_GLYPH, GLYPH_CODE_CHAR, GLYPH_CODE_FACE) + (SET_GLYPH_FROM_GLYPH_CODE, GLYPH_MODE_LINE_FACE, GLYPH_CHAR_VALID_P) + (GLYPH_CODE_P): Move to dispextern.h, to avoid define-before-use. + (TYPE_RANGED_INTEGERP): Simplify. + (PSEUDOVECTOR_SIZE_TYPEP): Rename from PSEUDOVECTORP_TYPEP and + change the first arg to be a size rather than a pointer, + to make it usable as a function. All uses changed. + (Qsubrp, Qhash_table_p, Qoverlayp): New extern decls. + (setlocale, fixup_locale, synchronize_system_messages_locale) + (synchronize_system_time_locale) [!HAVE_SETLOCALE]: + Now empty functions, not macros. + * mem-limits.h (EXCEEDS_LISP_PTR) [!defined DATA_SEG_BITS]: + Remove, as DATA_SEG_BITS is always defined now, if only to zero. + * window.c (Qwindow_configuration_p): + Now extern, so window.h can use it. + * window.h (Qwindowp): Move decl back to lisp.h. + (CHECK_LIVE_WINDOW): Move here from lisp.h, so window.h internals + need not be moved to lisp.h. Now a function, not a macro. + 2012-07-23 Eli Zaretskii * print.c (print_object): Don't crash when a frame's name is nil === modified file 'src/alloc.c' --- src/alloc.c 2012-07-23 11:15:43 +0000 +++ src/alloc.c 2012-07-23 21:58:10 +0000 @@ -3074,12 +3074,12 @@ + VECTOR_BLOCK_BYTES - VBLOCK_BYTES_MIN) /* Number of bytes used by vector-block-allocated object. This is the only - place where we actually use the `nbytes' field of the vector-header. - I.e. we could get rid of the `nbytes' field by computing it based on the + place where we actually use the 'size' field of the vector-header. + I.e. we could get rid of the 'size' field by computing it based on the vector-type. */ #define PSEUDOVECTOR_NBYTES(vector) \ - (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE) \ + (PSEUDOVECTOR_SIZE_TYPEP (vector->header.size, PVEC_FREE) \ ? vector->header.size & PSEUDOVECTOR_SIZE_MASK \ : vector->header.next.nbytes) @@ -3171,7 +3171,8 @@ /* All non-bool pseudovectors are small enough to be allocated from vector blocks. This code should be redesigned if some pseudovector type grows beyond VBLOCK_BYTES_MAX. */ - eassert (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_BOOL_VECTOR)); + eassert (PSEUDOVECTOR_SIZE_TYPEP (vector->header.size, + PVEC_BOOL_VECTOR)); total_vector_slots += (bool_header_size @@ -4392,7 +4393,7 @@ while (VECTOR_IN_BLOCK (vector, block) && vector <= (struct Lisp_Vector *) p) { - if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FREE)) + if (PSEUDOVECTOR_SIZE_TYPEP (vector->header.size, PVEC_FREE)) vector = ADVANCE (vector, (vector->header.size & PSEUDOVECTOR_SIZE_MASK)); else if (vector == p) === modified file 'src/buffer.c' --- src/buffer.c 2012-07-23 11:15:43 +0000 +++ src/buffer.c 2012-07-23 21:50:36 +0000 @@ -139,7 +139,7 @@ static Lisp_Object Qget_file_buffer; -static Lisp_Object Qoverlayp; +Lisp_Object Qoverlayp; Lisp_Object Qpriority, Qbefore_string, Qafter_string; === modified file 'src/data.c' --- src/data.c 2012-07-19 22:35:58 +0000 +++ src/data.c 2012-07-23 21:50:36 +0000 @@ -91,7 +91,8 @@ static Lisp_Object Qcompiled_function, Qframe; Lisp_Object Qbuffer; static Lisp_Object Qchar_table, Qbool_vector, Qhash_table; -static Lisp_Object Qsubrp, Qmany, Qunevalled; +Lisp_Object Qsubrp; +static Lisp_Object Qmany, Qunevalled; Lisp_Object Qfont_spec, Qfont_entity, Qfont_object; static Lisp_Object Qdefun; === modified file 'src/dispextern.h' --- src/dispextern.h 2012-07-13 03:50:58 +0000 +++ src/dispextern.h 2012-07-13 03:52:53 +0000 @@ -22,6 +22,8 @@ #ifndef DISPEXTERN_H_INCLUDED #define DISPEXTERN_H_INCLUDED +#include "character.h" + #ifdef HAVE_X_WINDOWS #include @@ -265,6 +267,55 @@ Glyphs ***********************************************************************/ +/* The glyph datatype, used to represent characters on the display. + It consists of a char code and a face id. */ + +typedef struct { + int ch; + int face_id; +} GLYPH; + +/* Return a glyph's character code. */ +static inline int GLYPH_CHAR (GLYPH glyph) { return glyph.ch; } + +/* Return a glyph's face ID. */ +static inline int GLYPH_FACE (GLYPH glyph) { return glyph.face_id; } + +#define SET_GLYPH_CHAR(glyph, char) ((glyph).ch = (char)) +#define SET_GLYPH_FACE(glyph, face) ((glyph).face_id = (face)) +#define SET_GLYPH(glyph, char, face) \ + ((glyph).ch = (char), (glyph).face_id = (face)) + +/* The following are valid only if GLYPH_CODE_P (gc). */ + +static inline int +GLYPH_CODE_CHAR (Lisp_Object gc) +{ + return (CONSP (gc) + ? XINT (XCAR (gc)) + : XINT (gc) & MAX_CHAR); +} + +static inline int +GLYPH_CODE_FACE (Lisp_Object gc) +{ + return CONSP (gc) ? XINT (XCDR (gc)) : XINT (gc) >> CHARACTERBITS; +} + +#define SET_GLYPH_FROM_GLYPH_CODE(glyph, gc) \ + do \ + { \ + if (CONSP (gc)) \ + SET_GLYPH (glyph, XINT (XCAR (gc)), XINT (XCDR (gc))); \ + else \ + SET_GLYPH (glyph, (XINT (gc) & ((1 << CHARACTERBITS)-1)), \ + (XINT (gc) >> CHARACTERBITS)); \ + } \ + while (0) + +/* The ID of the mode line highlighting face. */ +enum { GLYPH_MODE_LINE_FACE = 1 }; + /* Enumeration of glyph types. Glyph structures contain a type field containing one of the enumerators defined here. */ @@ -1763,6 +1814,30 @@ #endif /* not HAVE_WINDOW_SYSTEM */ +/* Return 1 if G contains a valid character code. */ +static inline int +GLYPH_CHAR_VALID_P (GLYPH g) +{ + return CHAR_VALID_P (GLYPH_CHAR (g)); +} + +/* The glyph code from a display vector may either be an integer which + encodes a char code in the lower CHARACTERBITS bits and a (very small) + face-id in the upper bits, or it may be a cons (CHAR . FACE-ID). */ + +static inline int +GLYPH_CODE_P (Lisp_Object gc) +{ + return (CONSP (gc) + ? (CHARACTERP (XCAR (gc)) + && RANGED_INTEGERP (0, XCDR (gc), MAX_FACE_ID)) + : (RANGED_INTEGERP + (0, gc, + (MAX_FACE_ID < TYPE_MAXIMUM (EMACS_INT) >> CHARACTERBITS + ? ((EMACS_INT) MAX_FACE_ID << CHARACTERBITS) | MAX_CHAR + : TYPE_MAXIMUM (EMACS_INT))))); +} + /* Non-zero means face attributes have been changed since the last redisplay. Used in redisplay_internal. */ === modified file 'src/eval.c' --- src/eval.c 2012-07-20 05:28:00 +0000 +++ src/eval.c 2012-07-23 21:50:36 +0000 @@ -1919,7 +1919,7 @@ and assumed the docstring will be provided by Snarf-documentation, so it passed us 0 instead. But that leads to accidental sharing in purecopy's hash-consing, so we use a (hopefully) unique integer instead. */ - docstring = make_number (XUNTAG (function, Lisp_Symbol)); + docstring = make_number ((intptr_t) XUNTAG (function, Lisp_Symbol)); return Ffset (function, Fpurecopy (list5 (Qautoload, file, docstring, interactive, type))); === modified file 'src/fns.c' --- src/fns.c 2012-07-20 07:29:04 +0000 +++ src/fns.c 2012-07-23 21:50:36 +0000 @@ -3354,7 +3354,8 @@ /* Various symbols. */ -static Lisp_Object Qhash_table_p, Qkey, Qvalue; +Lisp_Object Qhash_table_p; +static Lisp_Object Qkey, Qvalue; Lisp_Object Qeq, Qeql, Qequal; Lisp_Object QCtest, QCsize, QCrehash_size, QCrehash_threshold, QCweakness; static Lisp_Object Qhash_table_test, Qkey_or_value, Qkey_and_value; === modified file 'src/lisp.h' --- src/lisp.h 2012-07-23 11:15:43 +0000 +++ src/lisp.h 2012-07-24 01:57:18 +0000 @@ -32,10 +32,10 @@ #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) +static inline void check_cons_list (void) { } #endif +static inline void CHECK_CONS_LIST (void) { check_cons_list (); } /* Temporarily disable wider-than-pointer integers until they're tested more. Build with CFLAGS='-DWIDE_EMACS_INT' to try them out. */ @@ -45,22 +45,24 @@ 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 @@ -153,8 +155,10 @@ variable VAR of type TYPE with the added requirement that it be TYPEBITS-aligned. */ +/* Number of bits in a Lisp_Obect tag. This can be used in #if. */ #define GCTYPEBITS 3 -#define VALBITS (BITS_PER_EMACS_INT - GCTYPEBITS) + +enum { VALBITS = BITS_PER_EMACS_INT - GCTYPEBITS }; /* 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. @@ -210,20 +214,72 @@ #endif +/* When compiling via GCC without optimization, inline a few functions + manually, as Emacs is too slow otherwise. There's no need to + inline everything, just the functions that would cause a serious + performance problem when debugging. To disable this hand-optimization, + compile with -DINLINING=0. + + Commentary for these macros can be found near their corresponding + functions, below. */ +#if (defined __NO_INLINE__ \ + && ! defined __OPTIMIZE__ && ! defined __OPTIMIZE_SIZE__ \ + && ! (defined INLINING && ! INLINING)) +# if CHECK_LISP_OBJECT_TYPE +# define XLI(o) (o).i +# define XIL(i) (Lisp_Object) { i } +# else +# define XLI(o) (o) +# define XIL(i) (i) +# endif +# define CHECK_TYPE(ok, Qxxxp, x) \ + ((void) ((ok) || wrong_type_argument (Qxxxp, x))) +# define CHECK_LIST_CONS(x, y) CHECK_TYPE (CONSP (x), Qlistp, y) +# define CHECK_NUMBER(x) CHECK_TYPE (INTEGERP (x), Qintegerp, x) +# define CHECK_SYMBOL(x) CHECK_TYPE (SYMBOLP (x), Qsymbolp, x) +# define CONSP(x) (XTYPE (x) == Lisp_Cons) +# define EQ(a, b) (XHASH (a) == XHASH (b)) +# define FLOATP(x) (XTYPE (x) == Lisp_Float) +# define INTEGERP(x) LISP_INT_TAG_P (XTYPE (x)) +# define LISP_INT_TAG_P(x) (((x) & ~Lisp_Int1) == 0) +# define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker) +# define MISCP(x) (XTYPE (x) == Lisp_Misc) +# define NILP(x) EQ (x, Qnil) +# define SET_SYMBOL_VAL(sym, v) \ + (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value = (v)) +# define SYMBOL_CONSTANT_P(sym) (XSYMBOL (sym)->constant) +# define SYMBOL_VAL(sym) \ + (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value) +# define SYMBOLP(x) (XTYPE (x) == Lisp_Symbol) +# define VECTORLIKEP(x) (XTYPE (x) == Lisp_Vectorlike) +# define XCAR(c) XCAR_AS_LVALUE (c) +# define XCDR(c) XCDR_AS_LVALUE (c) +# define XCONS(a) \ + (eassert (CONSP (a)), (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons)) +# define XHASH(o) XLI (o) +# define XPNTR(a) ((void *) (intptr_t) ((XLI (a) & VALMASK) | DATA_SEG_BITS)) +# define XSYMBOL(a) \ + (eassert (SYMBOLP (a)), (struct Lisp_Symbol *) XUNTAG (a, Lisp_Symbol)) +# if USE_LSB_TAG +# define make_number(n) XIL ((EMACS_INT) (n) << INTTYPEBITS) +# define XFASTINT(a) XINT (a) +# define XINT(a) (XLI (a) >> INTTYPEBITS) +# define XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK)) +# define XUNTAG(a, type) ((void *) (XLI (a) - (type))) +# endif +#endif + + /* Define the fundamental Lisp data structures. */ /* This is the set of Lisp data types. */ /* 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) +enum { INTTYPEBITS = GCTYPEBITS - 1 }; +enum { FIXNUM_BITS = VALBITS + 1 }; #define INTMASK (EMACS_INT_MAX >> (INTTYPEBITS - 1)) -#define LISP_INT_TAG Lisp_Int0 #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) /* Stolen from GDB. The only known compiler that doesn't support enums in bitfields is MSVC. */ @@ -238,7 +294,7 @@ { /* Integer. XINT (obj) is the integer value. */ Lisp_Int0 = 0, - Lisp_Int1 = LISP_INT1_TAG, + Lisp_Int1 = USE_LSB_TAG ? 4 : 1, /* Symbol. XSYMBOL (object) points to a struct Lisp_Symbol. */ Lisp_Symbol = 2, @@ -249,7 +305,7 @@ /* 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 : 4, /* Vector of Lisp objects, or something resembling it. XVECTOR (object) points to a struct Lisp_Vector, which contains @@ -263,6 +319,11 @@ Lisp_Float = 7, }; +/* An older name for Lisp_Int0. */ +enum { LISP_INT_TAG = Lisp_Int0 }; + +static inline int (LISP_INT_TAG_P) (int x) { return (x & ~Lisp_Int1) == 0; } + /* This is the set of data types that share a common structure. The first member of the structure is a type code from this set. The enum values are arbitrary, but we'll use large numbers to make it @@ -297,20 +358,15 @@ typedef struct { EMACS_INT i; } Lisp_Object; -#define XLI(o) (o).i +static inline EMACS_INT (XLI) (Lisp_Object o) { return o.i; } + static inline Lisp_Object -XIL (EMACS_INT i) +(XIL) (EMACS_INT i) { Lisp_Object o = { i }; return o; } -static inline Lisp_Object -LISP_MAKE_RVALUE (Lisp_Object o) -{ - return o; -} - #define LISP_INITIALLY_ZERO {0} #else /* CHECK_LISP_OBJECT_TYPE */ @@ -318,9 +374,8 @@ /* If a struct type is not wanted, define Lisp_Object as just a number. */ typedef EMACS_INT Lisp_Object; -#define XLI(o) (o) -#define XIL(i) (i) -#define LISP_MAKE_RVALUE(o) (0+(o)) +static inline EMACS_INT (XLI) (Lisp_Object o) { return o; } +static inline Lisp_Object (XIL) (EMACS_INT i) { return i; } #define LISP_INITIALLY_ZERO 0 #endif /* CHECK_LISP_OBJECT_TYPE */ @@ -368,89 +423,119 @@ 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_BITS 16 -#define PSEUDOVECTOR_SIZE_MASK ((1 << PSEUDOVECTOR_SIZE_BITS) - 1) -#define PVEC_TYPE_MASK (0x0fff << PSEUDOVECTOR_SIZE_BITS) +enum + { + PSEUDOVECTOR_SIZE_BITS = 16, + PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1, + PVEC_TYPE_MASK = 0xfff << PSEUDOVECTOR_SIZE_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 - -/* These macros extract various sorts of values from a Lisp_Object. +enum { BOOL_VECTOR_BITS_PER_CHAR = 8 }; + +/* 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 + +/* These functions extract various sorts of values from a Lisp_Object. For example, if tem is a Lisp_Object whose type is Lisp_Cons, XCONS (tem) is the struct Lisp_Cons * pointing to the memory for that cons. */ /* Return a perfect hash of the Lisp_Object representation. */ -#define XHASH(a) XLI (a) - -#if USE_LSB_TAG - -#define TYPEMASK ((1 << GCTYPEBITS) - 1) -#define XTYPE(a) ((enum Lisp_Type) (XLI (a) & TYPEMASK)) -#define XINT(a) (XLI (a) >> INTTYPEBITS) -#define XUINT(a) ((EMACS_UINT) XLI (a) >> INTTYPEBITS) -#define make_number(N) XIL ((EMACS_INT) (N) << INTTYPEBITS) -#define XSET(var, type, ptr) \ - (eassert (XTYPE (XIL ((intptr_t) (ptr))) == 0), /* Check alignment. */ \ - (var) = XIL ((type) | (intptr_t) (ptr))) - -#define XPNTR(a) ((intptr_t) (XLI (a) & ~TYPEMASK)) -#define XUNTAG(a, type) ((intptr_t) (XLI (a) - (type))) - -#else /* not USE_LSB_TAG */ - -#define VALMASK VAL_MAX - -#define XTYPE(a) ((enum Lisp_Type) ((EMACS_UINT) XLI (a) >> VALBITS)) - -/* For integers known to be positive, XFASTINT provides fast retrieval - and XSETFASTINT provides fast storage. This takes advantage of the - fact that Lisp integers have zero-bits in their tags. */ -#define XFASTINT(a) (XLI (a) + 0) -#define XSETFASTINT(a, b) ((a) = XIL (b)) - -/* Extract the value of a Lisp_Object as a (un)signed integer. */ - -#define XINT(a) (XLI (a) << INTTYPEBITS >> INTTYPEBITS) -#define XUINT(a) ((EMACS_UINT) (XLI (a) & INTMASK)) -#define make_number(N) XIL ((EMACS_INT) (N) & INTMASK) - -#define XSET(var, type, ptr) \ - ((var) = XIL ((EMACS_INT) ((EMACS_UINT) (type) << VALBITS) \ - + ((intptr_t) (ptr) & VALMASK))) - -#ifdef 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)) -#else -#define XPNTR(a) ((uintptr_t) (XLI (a) & VALMASK)) -#endif - -#endif /* not USE_LSB_TAG */ - -/* For integers known to be positive, XFASTINT sometimes provides - faster retrieval and XSETFASTINT provides faster storage. - If not, fallback on the non-accelerated path. */ -#ifndef XFASTINT -# define XFASTINT(a) (XINT (a)) -# define XSETFASTINT(a, b) (XSETINT (a, b)) -#endif - -/* Extract the pointer value of the Lisp object A, under the - assumption that A's type is TYPE. This is a fallback - implementation if nothing faster is available. */ -#ifndef XUNTAG -# define XUNTAG(a, type) XPNTR (a) -#endif - -#define EQ(x, y) (XHASH (x) == XHASH (y)) +static inline EMACS_INT (XHASH) (Lisp_Object o) { return XLI (o); } + +#define VALMASK (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX) /* Largest and smallest representable fixnum values. These are the C values. */ #define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS) #define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM) +static inline enum Lisp_Type +(XTYPE) (Lisp_Object a) +{ + EMACS_UINT i = XLI (a); + return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS; +} + +/* Extract the value of a Lisp_Object as a signed integer. */ +static inline EMACS_INT +(XINT) (Lisp_Object a) +{ + EMACS_INT i = XLI (a); + return (USE_LSB_TAG ? i : i << INTTYPEBITS) >> INTTYPEBITS; +} + +/* Like XINT (A), but may be faster. A must be nonnegative. This takes + advantage of the fact that Lisp integers have zero-bits in their tags. */ +static inline EMACS_INT +(XFASTINT) (Lisp_Object a) +{ + EMACS_INT n = USE_LSB_TAG ? XINT (a) : XLI (a) >> INTTYPEBITS; + eassert (0 <= n); + return n; +} + +/* Extract the value of a Lisp_Object as an unsigned integer. */ +static inline EMACS_UINT +XUINT (Lisp_Object a) +{ + EMACS_UINT i = XLI (a); + return USE_LSB_TAG ? i >> INTTYPEBITS : i & INTMASK; +} + +static inline Lisp_Object +(make_number) (EMACS_INT n) +{ + return XIL (USE_LSB_TAG ? n << INTTYPEBITS : n & INTMASK); +} + +/* Like make_number (N), but may be faster. N must be in nonnegative range. */ +static inline Lisp_Object +make_natnum (EMACS_INT n) +{ + eassert (0 <= n && n <= MOST_POSITIVE_FIXNUM); + return USE_LSB_TAG ? make_number (n) : XIL (n); +} + +static inline void * +(XPNTR) (Lisp_Object a) +{ + intptr_t i = (XLI (a) & VALMASK) | DATA_SEG_BITS; + return (void *) i; +} + +/* Extract the pointer value of the Lisp object A, under the + assumption that A's type is TYPE. */ +static inline void * +(XUNTAG) (Lisp_Object a, int type) +{ + if (USE_LSB_TAG) + { + intptr_t i = XLI (a) - type; + return (void *) i; + } + return XPNTR (a); +} + +static inline int +(EQ) (Lisp_Object a, Lisp_Object b) +{ + return XHASH (a) == XHASH (b); +} + +/* 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)) + /* 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 type or if I is a NaN. */ @@ -463,64 +548,181 @@ { return num < lower ? lower : num <= upper ? num : upper; } + +/* Forward declarations. */ + +/* Defined in this file. */ +union Lisp_Fwd; +static int BOOLFWDP (union Lisp_Fwd *); +static int BOOL_VECTOR_P (Lisp_Object); +static int BUFFER_OBJFWDP (union Lisp_Fwd *); +static int BUFFERP (Lisp_Object); +static int CHAR_TABLE_P (Lisp_Object); +static Lisp_Object CHAR_TABLE_REF_ASCII (Lisp_Object, ptrdiff_t); +static int (CONSP) (Lisp_Object); +static int (FLOATP) (Lisp_Object); +static int (INTEGERP) (Lisp_Object); +static int INTFWDP (union Lisp_Fwd *); +static int KBOARD_OBJFWDP (union Lisp_Fwd *); +static int (MARKERP) (Lisp_Object); +static int (MISCP) (Lisp_Object); +static int (NILP) (Lisp_Object); +static int OBJFWDP (union Lisp_Fwd *); +static int OVERLAYP (Lisp_Object); +static int PROCESSP (Lisp_Object); +static int PSEUDOVECTORP (Lisp_Object, int); +static int SAVE_VALUEP (Lisp_Object); +static int STRINGP (Lisp_Object); +static int SUB_CHAR_TABLE_P (Lisp_Object); +static int SUBRP (Lisp_Object); +static int (SYMBOLP) (Lisp_Object); +static int (VECTORLIKEP) (Lisp_Object); +static int WINDOWP (Lisp_Object); + +/* Defined in buffer.c. */ +extern Lisp_Object Qoverlayp; + +/* Defined in chartab.c. */ +extern Lisp_Object char_table_ref (Lisp_Object, int); +extern Lisp_Object 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; +extern Lisp_Object Qconsp, Qfloatp, Qintegerp, Qlambda, Qlistp, Qmarkerp, Qnil; +extern Lisp_Object Qnumberp, Qsubrp, Qstringp, Qsymbolp, Qvectorp; +extern Lisp_Object Qvector_or_char_table_p, Qwholenump; +extern Lisp_Object Ffboundp (Lisp_Object); +extern _Noreturn Lisp_Object wrong_type_argument (Lisp_Object, Lisp_Object); + +/* Defined in emacs.c. */ +extern int initialized; + +/* Defined in fns.c */ +extern Lisp_Object Qhash_table_p; + +/* Defined in floatfns.c. */ +extern double extract_float (Lisp_Object); + +/* Defined in process.c. */ +extern Lisp_Object Qprocessp; + +/* Defined in window.c. */ +extern Lisp_Object Qwindowp, Qwindow_configuration_p; + +/* Defined in xdisp.c. */ +extern Lisp_Object Qimage; + /* Extract a value or address from a Lisp_Object. */ -#define XCONS(a) (eassert (CONSP (a)), \ - (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons)) -#define XVECTOR(a) (eassert (VECTORLIKEP (a)), \ - (struct Lisp_Vector *) XUNTAG (a, Lisp_Vectorlike)) -#define XSTRING(a) (eassert (STRINGP (a)), \ - (struct Lisp_String *) XUNTAG (a, Lisp_String)) -#define XSYMBOL(a) (eassert (SYMBOLP (a)), \ - (struct Lisp_Symbol *) XUNTAG (a, Lisp_Symbol)) -#define XFLOAT(a) (eassert (FLOATP (a)), \ - (struct Lisp_Float *) XUNTAG (a, Lisp_Float)) - -/* Misc types. */ - -#define XMISC(a) ((union Lisp_Misc *) XUNTAG (a, Lisp_Misc)) -#define XMISCANY(a) (eassert (MISCP (a)), &(XMISC (a)->u_any)) -#define XMISCTYPE(a) (XMISCANY (a)->type) -#define XMARKER(a) (eassert (MARKERP (a)), &(XMISC (a)->u_marker)) -#define XOVERLAY(a) (eassert (OVERLAYP (a)), &(XMISC (a)->u_overlay)) -#define XSAVE_VALUE(a) (eassert (SAVE_VALUEP (a)), &(XMISC (a)->u_save_value)) - -/* Forwarding object types. */ - -#define XFWDTYPE(a) (a->u_intfwd.type) -#define XINTFWD(a) (eassert (INTFWDP (a)), &((a)->u_intfwd)) -#define XBOOLFWD(a) (eassert (BOOLFWDP (a)), &((a)->u_boolfwd)) -#define XOBJFWD(a) (eassert (OBJFWDP (a)), &((a)->u_objfwd)) -#define XBUFFER_OBJFWD(a) \ - (eassert (BUFFER_OBJFWDP (a)), &((a)->u_buffer_objfwd)) -#define XKBOARD_OBJFWD(a) \ - (eassert (KBOARD_OBJFWDP (a)), &((a)->u_kboard_objfwd)) +static inline struct Lisp_Cons * +(XCONS) (Lisp_Object a) +{ + eassert (CONSP (a)); + return XUNTAG (a, Lisp_Cons); +} + +static inline struct Lisp_Vector * +XVECTOR (Lisp_Object a) +{ + eassert (VECTORLIKEP (a)); + return XUNTAG (a, Lisp_Vectorlike); +} + +static inline struct Lisp_String * +XSTRING (Lisp_Object a) +{ + eassert (STRINGP (a)); + return XUNTAG (a, Lisp_String); +} + +static inline struct Lisp_Symbol * +(XSYMBOL) (Lisp_Object a) +{ + eassert (SYMBOLP (a)); + return XUNTAG (a, Lisp_Symbol); +} + +static inline struct Lisp_Float * +XFLOAT (Lisp_Object a) +{ + eassert (FLOATP (a)); + return XUNTAG (a, Lisp_Float); +} /* Pseudovector types. */ -#define XPROCESS(a) (eassert (PROCESSP (a)), \ - (struct Lisp_Process *) XUNTAG (a, Lisp_Vectorlike)) -#define XWINDOW(a) (eassert (WINDOWP (a)), \ - (struct window *) XUNTAG (a, Lisp_Vectorlike)) -#define XTERMINAL(a) (eassert (TERMINALP (a)), \ - (struct terminal *) XUNTAG (a, Lisp_Vectorlike)) -#define XSUBR(a) (eassert (SUBRP (a)), \ - (struct Lisp_Subr *) XUNTAG (a, Lisp_Vectorlike)) -#define XBUFFER(a) (eassert (BUFFERP (a)), \ - (struct buffer *) XUNTAG (a, Lisp_Vectorlike)) -#define XCHAR_TABLE(a) (eassert (CHAR_TABLE_P (a)), \ - (struct Lisp_Char_Table *) XUNTAG (a, Lisp_Vectorlike)) -#define XSUB_CHAR_TABLE(a) (eassert (SUB_CHAR_TABLE_P (a)), \ - ((struct Lisp_Sub_Char_Table *) \ - XUNTAG (a, Lisp_Vectorlike))) -#define XBOOL_VECTOR(a) (eassert (BOOL_VECTOR_P (a)), \ - ((struct Lisp_Bool_Vector *) \ - XUNTAG (a, Lisp_Vectorlike))) +static inline struct Lisp_Process * +XPROCESS (Lisp_Object a) +{ + eassert (PROCESSP (a)); + return XUNTAG (a, Lisp_Vectorlike); +} + +static inline struct window * +XWINDOW (Lisp_Object a) +{ + eassert (WINDOWP (a)); + return XUNTAG (a, Lisp_Vectorlike); +} + +static inline struct terminal * +XTERMINAL (Lisp_Object a) +{ + return XUNTAG (a, Lisp_Vectorlike); +} + +static inline struct Lisp_Subr * +XSUBR (Lisp_Object a) +{ + eassert (SUBRP (a)); + return XUNTAG (a, Lisp_Vectorlike); +} + +static inline struct buffer * +XBUFFER (Lisp_Object a) +{ + eassert (BUFFERP (a)); + return XUNTAG (a, Lisp_Vectorlike); +} + +static inline struct Lisp_Char_Table * +XCHAR_TABLE (Lisp_Object a) +{ + eassert (CHAR_TABLE_P (a)); + return XUNTAG (a, Lisp_Vectorlike); +} + +static inline struct Lisp_Sub_Char_Table * +XSUB_CHAR_TABLE (Lisp_Object a) +{ + eassert (SUB_CHAR_TABLE_P (a)); + return XUNTAG (a, Lisp_Vectorlike); +} + +static inline struct Lisp_Bool_Vector * +XBOOL_VECTOR (Lisp_Object a) +{ + eassert (BOOL_VECTOR_P (a)); + return XUNTAG (a, Lisp_Vectorlike); +} /* Construct a Lisp_Object from a value or address. */ +static inline Lisp_Object +xtag (enum Lisp_Type type, void *ptr) +{ + EMACS_UINT utype = type; + EMACS_INT typebits = USE_LSB_TAG ? type : utype << VALBITS; + Lisp_Object a = XIL (typebits | (intptr_t) ptr); + eassert (XUNTAG (a, type) == ptr); /* Check alignment. */ + return a; +} + +#define XSET(var, type, ptr) ((var) = xtag (type, ptr)) #define XSETINT(a, b) (a) = make_number (b) +#define XSETFASTINT(a, b) ((a) = make_natnum (b)) #define XSETCONS(a, b) XSET (a, Lisp_Cons, b) #define XSETVECTOR(a, b) XSET (a, Lisp_Vectorlike, b) #define XSETSTRING(a, b) XSET (a, Lisp_String, b) @@ -568,48 +770,25 @@ #define XSETBOOL_VECTOR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR)) #define XSETSUB_CHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_SUB_CHAR_TABLE)) -/* Convenience macros for dealing with Lisp arrays. */ - -#define AREF(ARRAY, IDX) XVECTOR ((ARRAY))->contents[IDX] -#define ASIZE(ARRAY) XVECTOR ((ARRAY))->header.size -/* The IDX==IDX tries to detect when the macro argument is side-effecting. */ -#define ASET(ARRAY, IDX, VAL) \ - (eassert ((IDX) == (IDX)), \ - eassert ((IDX) >= 0 && (IDX) < ASIZE (ARRAY)), \ - AREF ((ARRAY), (IDX)) = (VAL)) - -/* Convenience macros for dealing with Lisp strings. */ - -#define SDATA(string) (XSTRING (string)->data + 0) -#define SREF(string, index) (SDATA (string)[index] + 0) -#define SSET(string, index, new) (SDATA (string)[index] = (new)) -#define SCHARS(string) (XSTRING (string)->size + 0) -#define SBYTES(string) (STRING_BYTES (XSTRING (string)) + 0) - -/* Avoid "differ in sign" warnings. */ -#define SSDATA(x) ((char *) SDATA (x)) - -#define STRING_SET_CHARS(string, newsize) \ - (XSTRING (string)->size = (newsize)) - -#define STRING_COPYIN(string, index, new, count) \ - memcpy (SDATA (string) + index, new, count) - /* Type checking. */ -#define CHECK_TYPE(ok, Qxxxp, x) \ - do { if (!(ok)) wrong_type_argument (Qxxxp, (x)); } while (0) - - +static inline void +(CHECK_TYPE) (int ok, Lisp_Object Qxxxp, Lisp_Object x) +{ + if (!ok) + wrong_type_argument (Qxxxp, x); +} /* See the macros in intervals.h. */ typedef struct interval *INTERVAL; /* Complain if object is not string or buffer type */ -#define CHECK_STRING_OR_BUFFER(x) \ - CHECK_TYPE (STRINGP (x) || BUFFERP (x), Qbuffer_or_string_p, x) - +static inline void +CHECK_STRING_OR_BUFFER (Lisp_Object 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 */ @@ -650,54 +829,68 @@ #endif /* Use these from normal code. */ -#define XCAR(c) LISP_MAKE_RVALUE (XCAR_AS_LVALUE (c)) -#define XCDR(c) LISP_MAKE_RVALUE (XCDR_AS_LVALUE (c)) +static inline Lisp_Object (XCAR) (Lisp_Object c) { return XCAR_AS_LVALUE (c); } +static inline Lisp_Object (XCDR) (Lisp_Object c) { return XCDR_AS_LVALUE (c); } /* Use these to set the fields of a cons cell. Note that both arguments may refer to the same object, so 'n' - should not be read after 'c' is first modified. Also, neither - argument should be evaluated more than once; side effects are - especially common in the second argument. */ -#define XSETCAR(c,n) (XCAR_AS_LVALUE (c) = (n)) -#define XSETCDR(c,n) (XCDR_AS_LVALUE (c) = (n)) - -/* Take the car or cdr of something whose type is not known. */ -#define CAR(c) \ - (CONSP ((c)) ? XCAR ((c)) \ - : NILP ((c)) ? Qnil \ - : wrong_type_argument (Qlistp, (c))) - -#define CDR(c) \ - (CONSP ((c)) ? XCDR ((c)) \ - : NILP ((c)) ? Qnil \ - : wrong_type_argument (Qlistp, (c))) - -/* Take the car or cdr of something whose type is not known. */ -#define CAR_SAFE(c) \ - (CONSP ((c)) ? XCAR ((c)) : Qnil) - -#define CDR_SAFE(c) \ - (CONSP ((c)) ? XCDR ((c)) : Qnil) + should not be read after 'c' is first modified. */ +static inline void +XSETCAR (Lisp_Object c, Lisp_Object n) +{ + XCAR_AS_LVALUE (c) = n; +} +static inline void +XSETCDR (Lisp_Object c, Lisp_Object n) +{ + XCDR_AS_LVALUE (c) = n; +} + +/* Take the car or cdr of something whose type is not known. */ +static inline Lisp_Object +CAR (Lisp_Object c) +{ + return (CONSP (c) ? XCAR (c) + : NILP (c) ? Qnil + : wrong_type_argument (Qlistp, c)); +} +static inline Lisp_Object +CDR (Lisp_Object c) +{ + return (CONSP (c) ? XCDR (c) + : NILP (c) ? Qnil + : wrong_type_argument (Qlistp, c)); +} + +/* Take the car or cdr of something whose type is not known. */ +static inline Lisp_Object +CAR_SAFE (Lisp_Object c) +{ + return CONSP (c) ? XCAR (c) : Qnil; +} +static inline Lisp_Object +CDR_SAFE (Lisp_Object c) +{ + return CONSP (c) ? XCDR (c) : Qnil; +} + +/* 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. */ + unsigned char *data; + }; /* Nonzero if STR is a multibyte string. */ -#define STRING_MULTIBYTE(STR) \ - (XSTRING (STR)->size_byte >= 0) - -/* Return the length in bytes of STR. */ - -#ifdef GC_CHECK_STRING_BYTES - -struct Lisp_String; -extern ptrdiff_t string_bytes (struct Lisp_String *); -#define STRING_BYTES(S) string_bytes ((S)) - -#else /* not GC_CHECK_STRING_BYTES */ - -#define STRING_BYTES(STR) \ - ((STR)->size_byte < 0 ? (STR)->size : (STR)->size_byte) - -#endif /* not GC_CHECK_STRING_BYTES */ +static inline int +STRING_MULTIBYTE (Lisp_Object str) +{ + return 0 <= XSTRING (str)->size_byte; +} /* An upper bound on the number of bytes in a Lisp string, not counting the terminating null. This a tight enough bound to @@ -727,25 +920,72 @@ else XSTRING (STR)->size_byte = XSTRING (STR)->size; } while (0) /* Get text properties. */ -#define STRING_INTERVALS(STR) (XSTRING (STR)->intervals + 0) +static inline INTERVAL +STRING_INTERVALS (Lisp_Object str) +{ + return XSTRING (str)->intervals; +} /* 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. */ - -struct Lisp_String - { - ptrdiff_t size; - ptrdiff_t size_byte; - INTERVAL intervals; /* Text properties in this string. */ - unsigned char *data; - }; +static inline void +STRING_SET_INTERVALS (Lisp_Object str, INTERVAL intervals) +{ + XSTRING (str)->intervals = intervals; +} + +/* Convenience functions for dealing with Lisp strings. */ + +static inline unsigned char * +SDATA (Lisp_Object string) +{ + return XSTRING (string)->data; +} +static inline char * +SSDATA (Lisp_Object string) +{ + /* Avoid "differ in sign" warnings. */ + return (char *) SDATA (string); +} +static inline unsigned char +SREF (Lisp_Object string, ptrdiff_t index) +{ + return SDATA (string)[index]; +} +static inline void +SSET (Lisp_Object string, ptrdiff_t index, unsigned char new) +{ + SDATA (string)[index] = new; +} +static inline ptrdiff_t +SCHARS (Lisp_Object string) +{ + return XSTRING (string)->size; +} +static inline ptrdiff_t +STRING_BYTES (struct Lisp_String *s) +{ +#ifdef GC_CHECK_STRING_BYTES + extern ptrdiff_t string_bytes (struct Lisp_String *); + return string_bytes (s); +#else + return s->size_byte < 0 ? s->size : s->size_byte; +#endif +} +static inline ptrdiff_t +SBYTES (Lisp_Object string) +{ + return STRING_BYTES (XSTRING (string)); +} +static inline void +STRING_SET_CHARS (Lisp_Object string, ptrdiff_t newsize) +{ + XSTRING (string)->size = newsize; +} /* Header of vector-like objects. This documents the layout constraints on vectors and pseudovectors other than struct Lisp_Subr. It also prevents - compilers from being fooled by Emacs's type punning: the XSETPSEUDOVECTOR - and PSEUDOVECTORP macros cast their pointers to struct vectorlike_header *, + compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR + and PSEUDOVECTORP cast their pointers to struct vectorlike_header *, because when two such pointers potentially alias, a compiler won't incorrectly reorder loads and stores to their size fields. See . */ @@ -796,6 +1036,23 @@ Lisp_Object contents[1]; }; +/* Conveniences for dealing with Lisp arrays. */ + +/* A macro because it is also used as an lvalue. FIXME: Use ASET instead. */ +#define AREF(ARRAY, IDX) XVECTOR ((ARRAY))->contents[IDX] + +static inline ptrdiff_t +ASIZE (Lisp_Object array) +{ + return XVECTOR (array)->header.size; +} + +static inline void +ASET (Lisp_Object array, ptrdiff_t idx, Lisp_Object val) +{ + XVECTOR (array)->contents[idx] = val; +} + /* 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) \ @@ -810,53 +1067,6 @@ ((offsetof (type, nonlispfield) - offsetof (struct Lisp_Vector, contents[0])) \ / sizeof (Lisp_Object)) -/* 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 - 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. */ - -/* 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) \ - ({struct Lisp_Char_Table *_tbl = NULL; \ - Lisp_Object _val; \ - do { \ - _tbl = _tbl ? XCHAR_TABLE (_tbl->parent) : XCHAR_TABLE (CT); \ - _val = (! SUB_CHAR_TABLE_P (_tbl->ascii) ? _tbl->ascii \ - : XSUB_CHAR_TABLE (_tbl->ascii)->contents[IDX]); \ - if (NILP (_val)) \ - _val = _tbl->defalt; \ - } while (NILP (_val) && ! NILP (_tbl->parent)); \ - _val; }) - -#else /* not __GNUC__ */ - -#define CHAR_TABLE_REF_ASCII(CT, IDX) \ - (! NILP (XCHAR_TABLE (CT)->ascii) \ - ? (! SUB_CHAR_TABLE_P (XCHAR_TABLE (CT)->ascii) \ - ? XCHAR_TABLE (CT)->ascii \ - : ! NILP (XSUB_CHAR_TABLE (XCHAR_TABLE (CT)->ascii)->contents[IDX]) \ - ? XSUB_CHAR_TABLE (XCHAR_TABLE (CT)->ascii)->contents[IDX] \ - : char_table_ref ((CT), (IDX))) \ - : char_table_ref ((CT), (IDX))) - -#endif /* not __GNUC__ */ - /* Compute A OP B, using the unsigned comparison operator OP. A and B should be integer expressions. This is not the same as mathematical comparison; for example, UNSIGNED_CMP (0, <, -1) @@ -870,31 +1080,23 @@ /* Nonzero iff C is an ASCII character. */ #define ASCII_CHAR_P(c) UNSIGNED_CMP (c, <, 0x80) -/* Almost equivalent to Faref (CT, IDX) with optimization for ASCII - characters. Do not check validity of CT. */ -#define CHAR_TABLE_REF(CT, IDX) \ - (ASCII_CHAR_P (IDX) ? CHAR_TABLE_REF_ASCII ((CT), (IDX)) \ - : char_table_ref ((CT), (IDX))) - -/* Almost equivalent to Faref (CT, IDX). However, if the result is - not a character, return IDX. - - For these characters, do not check validity of CT - and do not follow parent. */ -#define CHAR_TABLE_TRANSLATE(CT, IDX) \ - char_table_translate (CT, IDX) - -/* Equivalent to Faset (CT, IDX, VAL) with optimization for ASCII and - 8-bit European characters. Do not check validity of CT. */ -#define CHAR_TABLE_SET(CT, IDX, VAL) \ - (ASCII_CHAR_P (IDX) && SUB_CHAR_TABLE_P (XCHAR_TABLE (CT)->ascii) \ - ? 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 +/* 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 + 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. */ + +enum + { + 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]; @@ -951,6 +1153,70 @@ Lisp_Object contents[1]; }; +/* 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 = VECSIZE (struct Lisp_Char_Table) - 1 }; + +/* Return the number of "extra" slots in the char table CT. */ + +static inline int +CHAR_TABLE_EXTRA_SLOTS (struct Lisp_Char_Table *ct) +{ + return ((ct->header.size & PSEUDOVECTOR_SIZE_MASK) + - CHAR_TABLE_STANDARD_SLOTS); +} + +static inline Lisp_Object +CHAR_TABLE_REF_ASCII (Lisp_Object ct, ptrdiff_t idx) +{ + struct Lisp_Char_Table *tbl = NULL; + Lisp_Object val; + do + { + tbl = tbl ? XCHAR_TABLE (tbl->parent) : XCHAR_TABLE (ct); + val = (! SUB_CHAR_TABLE_P (tbl->ascii) ? tbl->ascii + : XSUB_CHAR_TABLE (tbl->ascii)->contents[idx]); + if (NILP (val)) + val = tbl->defalt; + } + while (NILP (val) && ! NILP (tbl->parent)); + + return val; +} + +/* Almost equivalent to Faref (CT, IDX) with optimization for ASCII + characters. Do not check validity of CT. */ +static inline Lisp_Object +CHAR_TABLE_REF (Lisp_Object ct, int idx) +{ + return (ASCII_CHAR_P (idx) + ? CHAR_TABLE_REF_ASCII (ct, idx) + : char_table_ref (ct, idx)); +} + +/* Almost equivalent to Faref (CT, IDX). However, if the result is + not a character, return IDX. + + For these characters, do not check validity of CT + and do not follow parent. */ +static inline int +CHAR_TABLE_TRANSLATE (Lisp_Object ct, int idx) +{ + return char_table_translate (ct, idx); +} + +/* Equivalent to Faset (CT, IDX, VAL) with optimization for ASCII and + 8-bit European characters. Do not check validity of CT. */ +static inline void +CHAR_TABLE_SET (Lisp_Object ct, int idx, Lisp_Object val) +{ + if (ASCII_CHAR_P (idx) && SUB_CHAR_TABLE_P (XCHAR_TABLE (ct)->ascii)) + XSUB_CHAR_TABLE (XCHAR_TABLE (ct)->ascii)->contents[idx] = val; + else + char_table_set (ct, idx, val); +} + /* A boolvector is a kind of vectorlike, with contents are like a string. */ struct Lisp_Bool_Vector { @@ -1065,41 +1331,86 @@ /* Value is name of symbol. */ -#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) \ - (eassert ((sym)->redirect == SYMBOL_LOCALIZED), (sym)->val.blv) -#define SYMBOL_FWD(sym) \ - (eassert ((sym)->redirect == SYMBOL_FORWARDED), (sym)->val.fwd) -#define SET_SYMBOL_VAL(sym, v) \ - (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value = (v)) -#define SET_SYMBOL_ALIAS(sym, v) \ - (eassert ((sym)->redirect == SYMBOL_VARALIAS), (sym)->val.alias = (v)) -#define SET_SYMBOL_BLV(sym, v) \ - (eassert ((sym)->redirect == SYMBOL_LOCALIZED), (sym)->val.blv = (v)) -#define SET_SYMBOL_FWD(sym, v) \ - (eassert ((sym)->redirect == SYMBOL_FORWARDED), (sym)->val.fwd = (v)) +static inline Lisp_Object +(SYMBOL_VAL) (struct Lisp_Symbol *sym) +{ + eassert (sym->redirect == SYMBOL_PLAINVAL); + return sym->val.value; +} +static inline struct Lisp_Symbol * +SYMBOL_ALIAS (struct Lisp_Symbol *sym) +{ + eassert (sym->redirect == SYMBOL_VARALIAS); + return sym->val.alias; +} +static inline struct Lisp_Buffer_Local_Value * +SYMBOL_BLV (struct Lisp_Symbol *sym) +{ + eassert (sym->redirect == SYMBOL_LOCALIZED); + return sym->val.blv; +} +static inline union Lisp_Fwd * +SYMBOL_FWD (struct Lisp_Symbol *sym) +{ + eassert (sym->redirect == SYMBOL_FORWARDED); + return sym->val.fwd; +} +static inline void +(SET_SYMBOL_VAL) (struct Lisp_Symbol *sym, Lisp_Object v) +{ + eassert (sym->redirect == SYMBOL_PLAINVAL); + sym->val.value = v; +} +static inline void +SET_SYMBOL_ALIAS (struct Lisp_Symbol *sym, struct Lisp_Symbol *v) +{ + eassert (sym->redirect == SYMBOL_VARALIAS); + sym->val.alias = v; +} +static inline void +SET_SYMBOL_BLV (struct Lisp_Symbol *sym, struct Lisp_Buffer_Local_Value *v) +{ + eassert (sym->redirect == SYMBOL_LOCALIZED); + sym->val.blv = v; +} +static inline void +SET_SYMBOL_FWD (struct Lisp_Symbol *sym, union Lisp_Fwd *v) +{ + eassert (sym->redirect == SYMBOL_FORWARDED); + sym->val.fwd = v; +} -#define SYMBOL_NAME(sym) \ - LISP_MAKE_RVALUE (XSYMBOL (sym)->xname) +static inline Lisp_Object +SYMBOL_NAME (Lisp_Object sym) +{ + return XSYMBOL (sym)->xname; +} /* Value is non-zero if SYM is an interned symbol. */ -#define SYMBOL_INTERNED_P(sym) \ - (XSYMBOL (sym)->interned != SYMBOL_UNINTERNED) +static inline int +SYMBOL_INTERNED_P (Lisp_Object sym) +{ + return 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) +static inline int +SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (Lisp_Object sym) +{ + return 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 +static inline int +(SYMBOL_CONSTANT_P) (Lisp_Object sym) +{ + return XSYMBOL (sym)->constant; +} #define DEFSYM(sym, name) \ do { (sym) = intern_c_string ((name)); staticpro (&(sym)); } while (0) @@ -1181,16 +1492,25 @@ }; -#define XHASH_TABLE(OBJ) \ - ((struct Lisp_Hash_Table *) XUNTAG (OBJ, Lisp_Vectorlike)) +static inline struct Lisp_Hash_Table * +XHASH_TABLE (Lisp_Object a) +{ + return XUNTAG (a, Lisp_Vectorlike); +} #define XSET_HASH_TABLE(VAR, PTR) \ (XSETPSEUDOVECTOR (VAR, PTR, PVEC_HASH_TABLE)) -#define HASH_TABLE_P(OBJ) PSEUDOVECTORP (OBJ, PVEC_HASH_TABLE) - -#define CHECK_HASH_TABLE(x) \ - CHECK_TYPE (HASH_TABLE_P (x), Qhash_table_p, x) +static inline int +HASH_TABLE_P (Lisp_Object a) +{ + return PSEUDOVECTORP (a, PVEC_HASH_TABLE); +} +static inline void +CHECK_HASH_TABLE (Lisp_Object x) +{ + return CHECK_TYPE (HASH_TABLE_P (x), Qhash_table_p, x); +} /* Value is the key part of entry IDX in hash table H. */ @@ -1215,12 +1535,14 @@ #define HASH_INDEX(H, IDX) AREF ((H)->index, (IDX)) /* Value is the size of hash table H. */ - -#define HASH_TABLE_SIZE(H) ASIZE ((H)->next) +static inline ptrdiff_t +HASH_TABLE_SIZE (struct Lisp_Hash_Table *h) +{ + return ASIZE (h->next); +} /* Default size for hash tables if not specified. */ - -#define DEFAULT_HASH_SIZE 65 +enum { 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 @@ -1330,6 +1652,43 @@ struct Lisp_Save_Value u_save_value; }; +static inline union Lisp_Misc * +XMISC (Lisp_Object a) +{ + return XUNTAG (a, Lisp_Misc); +} + +static inline struct Lisp_Misc_Any * +XMISCANY (Lisp_Object a) +{ + eassert (MISCP (a)); + return & XMISC (a)->u_any; +} + +/* A macro because it is also used as an lvalue. FIXME: clean this up. */ +#define XMISCTYPE(a) (XMISCANY (a)->type) + +static inline struct Lisp_Marker * +XMARKER (Lisp_Object a) +{ + eassert (MARKERP (a)); + return & XMISC (a)->u_marker; +} + +static inline struct Lisp_Overlay * +XOVERLAY (Lisp_Object a) +{ + eassert (OVERLAYP (a)); + return & XMISC (a)->u_overlay; +} + +static inline struct Lisp_Save_Value * +XSAVE_VALUE (Lisp_Object a) +{ + eassert (SAVE_VALUEP (a)); + return & XMISC (a)->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 @@ -1419,13 +1778,29 @@ Lisp_Object valcell; }; -#define BLV_FOUND(blv) \ - (eassert ((blv)->found == !EQ ((blv)->defcell, (blv)->valcell)), (blv)->found) -#define SET_BLV_FOUND(blv, v) \ - (eassert ((v) == !EQ ((blv)->defcell, (blv)->valcell)), (blv)->found = (v)) +static inline int +BLV_FOUND (struct Lisp_Buffer_Local_Value *blv) +{ + eassert (blv->found == !EQ (blv->defcell, blv->valcell)); + return blv->found; +} +static inline void +SET_BLV_FOUND (struct Lisp_Buffer_Local_Value *blv, int v) +{ + eassert (v == !EQ (blv->defcell, blv->valcell)); + blv->found = v; +} -#define BLV_VALUE(blv) (XCDR ((blv)->valcell)) -#define SET_BLV_VALUE(blv, v) (XSETCDR ((blv)->valcell, v)) +static inline Lisp_Object +BLV_VALUE (struct Lisp_Buffer_Local_Value *blv) +{ + return XCDR (blv->valcell); +} +static inline void +SET_BLV_VALUE (struct Lisp_Buffer_Local_Value *blv, Lisp_Object v) +{ + XSETCDR (blv->valcell, v); +} /* Like Lisp_Objfwd except that value lives in a slot in the current kboard. */ @@ -1443,6 +1818,47 @@ struct Lisp_Buffer_Objfwd u_buffer_objfwd; struct Lisp_Kboard_Objfwd u_kboard_objfwd; }; + +static inline enum Lisp_Fwd_Type +XFWDTYPE (union Lisp_Fwd *a) +{ + return a->u_intfwd.type; +} + +static inline struct Lisp_Intfwd * +XINTFWD (union Lisp_Fwd *a) +{ + eassert (INTFWDP (a)); + return &a->u_intfwd; +} + +static inline struct Lisp_Boolfwd * +XBOOLFWD (union Lisp_Fwd *a) +{ + eassert (BOOLFWDP (a)); + return &a->u_boolfwd; +} + +static inline struct Lisp_Objfwd * +XOBJFWD (union Lisp_Fwd *a) +{ + eassert (OBJFWDP (a)); + return &a->u_objfwd; +} + +static inline struct Lisp_Buffer_Objfwd * +XBUFFER_OBJFWD (union Lisp_Fwd *a) +{ + eassert (BUFFER_OBJFWDP (a)); + return &a->u_buffer_objfwd; +} + +static inline struct Lisp_Kboard_Objfwd * +XKBOARD_OBJFWD (union Lisp_Fwd *a) +{ + eassert (KBOARD_OBJFWDP (a)); + return &a->u_kboard_objfwd; +} /* Lisp floating point type. */ struct Lisp_Float @@ -1458,13 +1874,24 @@ } u; }; +static inline double +XFLOAT_DATA (Lisp_Object f) +{ #ifdef HIDE_LISP_IMPLEMENTATION -#define XFLOAT_DATA(f) (0 ? XFLOAT (f)->u.data_ : XFLOAT (f)->u.data_) + return XFLOAT (f)->u.data_; #else -#define XFLOAT_DATA(f) (0 ? XFLOAT (f)->u.data : XFLOAT (f)->u.data) + return XFLOAT (f)->u.data; +#endif +} + +#ifndef HIDE_LISP_IMPLEMENTATION /* This should be used only in alloc.c, which always disables HIDE_LISP_IMPLEMENTATION. */ -#define XFLOAT_INIT(f,n) (XFLOAT (f)->u.data = (n)) +static inline void +XFLOAT_INIT (Lisp_Object f, double n) +{ + XFLOAT (f)->u.data = n; +} #endif /* A character, declared with the following typedef, is a member @@ -1475,91 +1902,36 @@ #endif /* 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 + { + COMPILED_ARGLIST, + COMPILED_BYTECODE, + COMPILED_CONSTANTS, + COMPILED_STACK_DEPTH, + COMPILED_DOC_STRING, + COMPILED_INTERACTIVE + }; /* 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_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. */ -#define CHARACTERBITS 22 - - -/* The glyph datatype, used to represent characters on the display. - It consists of a char code and a face id. */ - -typedef struct { - int ch; - int face_id; -} GLYPH; - -/* Return a glyph's character code. */ -#define GLYPH_CHAR(glyph) ((glyph).ch) - -/* Return a glyph's face ID. */ -#define GLYPH_FACE(glyph) ((glyph).face_id) - -#define SET_GLYPH_CHAR(glyph, char) ((glyph).ch = (char)) -#define SET_GLYPH_FACE(glyph, face) ((glyph).face_id = (face)) -#define SET_GLYPH(glyph, char, face) ((glyph).ch = (char), (glyph).face_id = (face)) - -/* Return 1 if GLYPH contains valid character code. */ -#define GLYPH_CHAR_VALID_P(glyph) CHAR_VALID_P (GLYPH_CHAR (glyph)) - - -/* Glyph Code from a display vector may either be an integer which - encodes a char code in the lower CHARACTERBITS bits and a (very small) - face-id in the upper bits, or it may be a cons (CHAR . FACE-ID). */ - -#define GLYPH_CODE_P(gc) \ - (CONSP (gc) \ - ? (CHARACTERP (XCAR (gc)) \ - && RANGED_INTEGERP (0, XCDR (gc), MAX_FACE_ID)) \ - : (RANGED_INTEGERP \ - (0, gc, \ - (MAX_FACE_ID < TYPE_MAXIMUM (EMACS_INT) >> CHARACTERBITS \ - ? ((EMACS_INT) MAX_FACE_ID << CHARACTERBITS) | MAX_CHAR \ - : TYPE_MAXIMUM (EMACS_INT))))) - -/* The following are valid only if GLYPH_CODE_P (gc). */ - -#define GLYPH_CODE_CHAR(gc) \ - (CONSP (gc) ? XINT (XCAR (gc)) : XINT (gc) & ((1 << CHARACTERBITS) - 1)) - -#define GLYPH_CODE_FACE(gc) \ - (CONSP (gc) ? XINT (XCDR (gc)) : XINT (gc) >> CHARACTERBITS) - -#define SET_GLYPH_FROM_GLYPH_CODE(glyph, gc) \ - do \ - { \ - if (CONSP (gc)) \ - SET_GLYPH (glyph, XINT (XCAR (gc)), XINT (XCDR (gc))); \ - else \ - SET_GLYPH (glyph, (XINT (gc) & ((1 << CHARACTERBITS)-1)), \ - (XINT (gc) >> CHARACTERBITS)); \ - } \ - while (0) - -/* The ID of the mode line highlighting face. */ -#define GLYPH_MODE_LINE_FACE 1 +enum { CHARACTERBITS = 22 }; + /* Structure to hold mouse highlight data. This is here because other header files need it for defining struct x_output etc. */ @@ -1598,140 +1970,308 @@ /* Data type checking */ -#define NILP(x) EQ (x, Qnil) - -#define NUMBERP(x) (INTEGERP (x) || FLOATP (x)) -#define NATNUMP(x) (INTEGERP (x) && XINT (x) >= 0) - -#define RANGED_INTEGERP(lo, x, hi) \ - (INTEGERP (x) && (lo) <= XINT (x) && XINT (x) <= (hi)) +static inline int +(NILP) (Lisp_Object x) +{ + return EQ (x, Qnil); +} + +static inline int +NUMBERP (Lisp_Object x) +{ + return INTEGERP (x) || FLOATP (x); +} +static inline int +NATNUMP (Lisp_Object x) +{ + return INTEGERP (x) && 0 <= XINT (x); +} + +static inline int +RANGED_INTEGERP (intmax_t lo, Lisp_Object x, intmax_t hi) +{ + return INTEGERP (x) && lo <= XINT (x) && XINT (x) <= hi; +} + #define TYPE_RANGED_INTEGERP(type, x) \ - (TYPE_SIGNED (type) \ - ? RANGED_INTEGERP (TYPE_MINIMUM (type), x, TYPE_MAXIMUM (type)) \ - : RANGED_INTEGERP (0, x, TYPE_MAXIMUM (type))) - -#define INTEGERP(x) (LISP_INT_TAG_P (XTYPE ((x)))) -#define SYMBOLP(x) (XTYPE ((x)) == Lisp_Symbol) -#define MISCP(x) (XTYPE ((x)) == Lisp_Misc) -#define VECTORLIKEP(x) (XTYPE ((x)) == Lisp_Vectorlike) -#define STRINGP(x) (XTYPE ((x)) == Lisp_String) -#define CONSP(x) (XTYPE ((x)) == Lisp_Cons) - -#define FLOATP(x) (XTYPE ((x)) == Lisp_Float) -#define VECTORP(x) (VECTORLIKEP (x) && !(ASIZE (x) & PSEUDOVECTOR_FLAG)) -#define OVERLAYP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay) -#define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker) -#define SAVE_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value) - -#define INTFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Int) -#define BOOLFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Bool) -#define OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Obj) -#define BUFFER_OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Buffer_Obj) -#define KBOARD_OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Kboard_Obj) - -/* 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) - -#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) \ - && PSEUDOVECTOR_TYPEP ((struct t *) XUNTAG (x, Lisp_Vectorlike), code)) + (INTEGERP (x) \ + && (TYPE_SIGNED (type) ? TYPE_MINIMUM (type) <= XINT (x) : 0 <= XINT (x)) \ + && XINT (x) <= TYPE_MAXIMUM (type)) + +static inline int (CONSP) (Lisp_Object x) { return XTYPE (x) == Lisp_Cons; } +static inline int (FLOATP) (Lisp_Object x) { return XTYPE (x) == Lisp_Float; } +static inline int (MISCP) (Lisp_Object x) { return XTYPE (x) == Lisp_Misc; } +static inline int STRINGP (Lisp_Object x) { return XTYPE (x) == Lisp_String; } +static inline int +(SYMBOLP) (Lisp_Object x) +{ + return XTYPE (x) == Lisp_Symbol; +} +static inline int +(INTEGERP) (Lisp_Object x) +{ + return LISP_INT_TAG_P (XTYPE (x)); +} +static inline int +(VECTORLIKEP) (Lisp_Object x) +{ + return XTYPE (x) == Lisp_Vectorlike; +} +static inline int +VECTORP (Lisp_Object x) +{ + return VECTORLIKEP (x) && ! (ASIZE (x) & PSEUDOVECTOR_FLAG); +} +static inline int +OVERLAYP (Lisp_Object x) +{ + return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay; +} +static inline int +(MARKERP) (Lisp_Object x) +{ + return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker; +} +static inline int +SAVE_VALUEP (Lisp_Object x) +{ + return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value; +} + +static inline int +INTFWDP (union Lisp_Fwd *a) +{ + return XFWDTYPE (a) == Lisp_Fwd_Int; +} +static inline int +BOOLFWDP (union Lisp_Fwd *a) +{ + return XFWDTYPE (a) == Lisp_Fwd_Bool; +} +static inline int +OBJFWDP (union Lisp_Fwd *a) +{ + return XFWDTYPE (a) == Lisp_Fwd_Obj; +} +static inline int +BUFFER_OBJFWDP (union Lisp_Fwd *a) +{ + return XFWDTYPE (a) == Lisp_Fwd_Buffer_Obj; +} +static inline int +KBOARD_OBJFWDP (union Lisp_Fwd *a) +{ + return XFWDTYPE (a) == Lisp_Fwd_Kboard_Obj; +} + +/* True if the size field SIZE of a pseudovector is that of a + pseudovector whose code is CODE. */ +static inline int +PSEUDOVECTOR_SIZE_TYPEP (ptrdiff_t size, int code) +{ + return ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) + == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_SIZE_BITS))); +} + +/* True if A is a pseudovector whose code is CODE. */ +static inline int +PSEUDOVECTORP (Lisp_Object a, int code) +{ + if (! VECTORLIKEP (a)) + return 0; + else + { + /* Converting to struct vectorlike_header * avoids aliasing issues. */ + struct vectorlike_header *h = XUNTAG (a, Lisp_Vectorlike); + return PSEUDOVECTOR_SIZE_TYPEP (h->size, code); + } +} + /* Test for specific pseudovector types. */ -#define WINDOW_CONFIGURATIONP(x) PSEUDOVECTORP (x, PVEC_WINDOW_CONFIGURATION) -#define PROCESSP(x) PSEUDOVECTORP (x, PVEC_PROCESS) -#define WINDOWP(x) PSEUDOVECTORP (x, PVEC_WINDOW) -#define TERMINALP(x) PSEUDOVECTORP (x, PVEC_TERMINAL) + +static inline int +WINDOW_CONFIGURATIONP (Lisp_Object a) +{ + return PSEUDOVECTORP (a, PVEC_WINDOW_CONFIGURATION); +} + +static inline int +PROCESSP (Lisp_Object a) +{ + return PSEUDOVECTORP (a, PVEC_PROCESS); +} + +static inline int +WINDOWP (Lisp_Object a) +{ + return PSEUDOVECTORP (a, PVEC_WINDOW); +} + +static inline int +TERMINALP (Lisp_Object a) +{ + return PSEUDOVECTORP (a, PVEC_TERMINAL); +} + /* SUBRP is special since Lisp_Subr lacks struct vectorlike_header. */ -#define SUBRP(x) TYPED_PSEUDOVECTORP (x, Lisp_Subr, PVEC_SUBR) -#define COMPILEDP(x) PSEUDOVECTORP (x, PVEC_COMPILED) -#define BUFFERP(x) PSEUDOVECTORP (x, PVEC_BUFFER) -#define CHAR_TABLE_P(x) PSEUDOVECTORP (x, PVEC_CHAR_TABLE) -#define SUB_CHAR_TABLE_P(x) PSEUDOVECTORP (x, PVEC_SUB_CHAR_TABLE) -#define BOOL_VECTOR_P(x) PSEUDOVECTORP (x, PVEC_BOOL_VECTOR) -#define FRAMEP(x) PSEUDOVECTORP (x, PVEC_FRAME) +static inline int +SUBRP (Lisp_Object a) +{ + if (! VECTORLIKEP (a)) + return 0; + else + { + struct Lisp_Subr *h = XUNTAG (a, Lisp_Vectorlike); + return PSEUDOVECTOR_SIZE_TYPEP (h->size, PVEC_SUBR); + } +} + +static inline int +COMPILEDP (Lisp_Object a) +{ + return PSEUDOVECTORP (a, PVEC_COMPILED); +} + +static inline int +BUFFERP (Lisp_Object a) +{ + return PSEUDOVECTORP (a, PVEC_BUFFER); +} + +static inline int +CHAR_TABLE_P (Lisp_Object a) +{ + return PSEUDOVECTORP (a, PVEC_CHAR_TABLE); +} + +static inline int +SUB_CHAR_TABLE_P (Lisp_Object a) +{ + return PSEUDOVECTORP (a, PVEC_SUB_CHAR_TABLE); +} + +static inline int +BOOL_VECTOR_P (Lisp_Object a) +{ + return PSEUDOVECTORP (a, PVEC_BOOL_VECTOR); +} + +static inline int +FRAMEP (Lisp_Object a) +{ + return PSEUDOVECTORP (a, PVEC_FRAME); +} /* Test for image (image . spec) */ -#define IMAGEP(x) (CONSP (x) && EQ (XCAR (x), Qimage)) +static inline int +IMAGEP (Lisp_Object x) +{ + return CONSP (x) && EQ (XCAR (x), Qimage); +} /* Array types. */ - -#define ARRAYP(x) \ - (VECTORP (x) || STRINGP (x) || CHAR_TABLE_P (x) || BOOL_VECTOR_P (x)) +static inline int +ARRAYP (Lisp_Object x) +{ + return VECTORP (x) || STRINGP (x) || CHAR_TABLE_P (x) || BOOL_VECTOR_P (x); +} -#define CHECK_LIST(x) \ - CHECK_TYPE (CONSP (x) || NILP (x), Qlistp, x) - -#define CHECK_LIST_CONS(x, y) \ - CHECK_TYPE (CONSP (x), Qlistp, y) - -#define CHECK_LIST_END(x, y) \ - CHECK_TYPE (NILP (x), Qlistp, y) - -#define CHECK_STRING(x) \ - CHECK_TYPE (STRINGP (x), Qstringp, x) - -#define CHECK_STRING_CAR(x) \ - CHECK_TYPE (STRINGP (XCAR (x)), Qstringp, XCAR (x)) - -#define CHECK_CONS(x) \ - CHECK_TYPE (CONSP (x), Qconsp, x) - -#define CHECK_SYMBOL(x) \ - CHECK_TYPE (SYMBOLP (x), Qsymbolp, x) - -#define CHECK_CHAR_TABLE(x) \ - CHECK_TYPE (CHAR_TABLE_P (x), Qchar_table_p, x) - -#define CHECK_VECTOR(x) \ - CHECK_TYPE (VECTORP (x), Qvectorp, x) - -#define CHECK_VECTOR_OR_STRING(x) \ - CHECK_TYPE (VECTORP (x) || STRINGP (x), Qarrayp, x) - -#define CHECK_ARRAY(x, Qxxxp) \ - CHECK_TYPE (ARRAYP (x), Qxxxp, x) - -#define CHECK_VECTOR_OR_CHAR_TABLE(x) \ - CHECK_TYPE (VECTORP (x) || CHAR_TABLE_P (x), Qvector_or_char_table_p, x) - -#define CHECK_BUFFER(x) \ - CHECK_TYPE (BUFFERP (x), Qbufferp, x) - -#define CHECK_WINDOW(x) \ - CHECK_TYPE (WINDOWP (x), Qwindowp, x) - -#define CHECK_WINDOW_CONFIGURATION(x) \ - CHECK_TYPE (WINDOW_CONFIGURATIONP (x), Qwindow_configuration_p, x) - -/* This macro rejects windows on the interior of the window tree as - "dead", which is what we want; this is an argument-checking macro, and - the user should never get access to interior windows. - - A window of any sort, leaf or interior, is dead if the buffer, - vchild, and hchild members are all nil. */ - -#define CHECK_LIVE_WINDOW(x) \ - CHECK_TYPE (WINDOWP (x) && !NILP (XWINDOW (x)->buffer), Qwindow_live_p, x) - -#define CHECK_PROCESS(x) \ - CHECK_TYPE (PROCESSP (x), Qprocessp, x) - -#define CHECK_SUBR(x) \ - CHECK_TYPE (SUBRP (x), Qsubrp, x) - -#define CHECK_NUMBER(x) \ - CHECK_TYPE (INTEGERP (x), Qintegerp, x) - -#define CHECK_NATNUM(x) \ - CHECK_TYPE (NATNUMP (x), Qwholenump, x) +static inline void +CHECK_LIST (Lisp_Object x) +{ + CHECK_TYPE (CONSP (x) || NILP (x), Qlistp, x); +} +static inline void +(CHECK_LIST_CONS) (Lisp_Object x, Lisp_Object y) +{ + CHECK_TYPE (CONSP (x), Qlistp, y); +} +static inline void +CHECK_LIST_END (Lisp_Object x, Lisp_Object y) +{ + CHECK_TYPE (NILP (x), Qlistp, y); +} +static inline void +CHECK_STRING (Lisp_Object x) +{ + CHECK_TYPE (STRINGP (x), Qstringp, x); +} +static inline void +CHECK_STRING_CAR (Lisp_Object x) +{ + CHECK_TYPE (STRINGP (XCAR (x)), Qstringp, XCAR (x)); +} +static inline void +CHECK_CONS (Lisp_Object x) +{ + CHECK_TYPE (CONSP (x), Qconsp, x); +} +static inline void +(CHECK_SYMBOL) (Lisp_Object x) +{ + CHECK_TYPE (SYMBOLP (x), Qsymbolp, x); +} +static inline void +CHECK_CHAR_TABLE (Lisp_Object x) +{ + CHECK_TYPE (CHAR_TABLE_P (x), Qchar_table_p, x); +} +static inline void +CHECK_VECTOR (Lisp_Object x) +{ + CHECK_TYPE (VECTORP (x), Qvectorp, x); +} +static inline void +CHECK_VECTOR_OR_STRING (Lisp_Object x) +{ + CHECK_TYPE (VECTORP (x) || STRINGP (x), Qarrayp, x); +} +static inline void +CHECK_ARRAY (Lisp_Object x, Lisp_Object Qxxxp) +{ + CHECK_TYPE (ARRAYP (x), Qxxxp, x); +} +static inline void +CHECK_VECTOR_OR_CHAR_TABLE (Lisp_Object x) +{ + CHECK_TYPE (VECTORP (x) || CHAR_TABLE_P (x), Qvector_or_char_table_p, x); +} +static inline void +CHECK_BUFFER (Lisp_Object x) +{ + CHECK_TYPE (BUFFERP (x), Qbufferp, x); +} +static inline void +CHECK_WINDOW (Lisp_Object x) +{ + CHECK_TYPE (WINDOWP (x), Qwindowp, x); +} +static inline void +CHECK_WINDOW_CONFIGURATION (Lisp_Object x) +{ + CHECK_TYPE (WINDOW_CONFIGURATIONP (x), Qwindow_configuration_p, x); +} +static inline void +CHECK_PROCESS (Lisp_Object x) +{ + CHECK_TYPE (PROCESSP (x), Qprocessp, x); +} +static inline void +CHECK_SUBR (Lisp_Object x) +{ + CHECK_TYPE (SUBRP (x), Qsubrp, x); +} +static inline void +(CHECK_NUMBER) (Lisp_Object x) +{ + CHECK_TYPE (INTEGERP (x), Qintegerp, x); +} +static inline void +CHECK_NATNUM (Lisp_Object x) +{ + CHECK_TYPE (NATNUMP (x), Qwholenump, x); +} #define CHECK_RANGED_INTEGER(x, lo, hi) \ do { \ @@ -1752,57 +2292,76 @@ CHECK_RANGED_INTEGER (x, 0, TYPE_MAXIMUM (type)); \ } while (0) -#define CHECK_MARKER(x) \ - CHECK_TYPE (MARKERP (x), Qmarkerp, x) +static inline void +CHECK_MARKER (Lisp_Object x) +{ + CHECK_TYPE (MARKERP (x), Qmarkerp, x); +} #define CHECK_NUMBER_COERCE_MARKER(x) \ do { if (MARKERP ((x))) XSETFASTINT (x, marker_position (x)); \ else CHECK_TYPE (INTEGERP (x), Qinteger_or_marker_p, x); } while (0) -#define XFLOATINT(n) extract_float((n)) - -#define CHECK_FLOAT(x) \ - CHECK_TYPE (FLOATP (x), Qfloatp, x) - -#define CHECK_NUMBER_OR_FLOAT(x) \ - CHECK_TYPE (FLOATP (x) || INTEGERP (x), Qnumberp, x) +static inline double +XFLOATINT (Lisp_Object n) +{ + return extract_float (n); +} + +static inline void +CHECK_FLOAT (Lisp_Object x) +{ + CHECK_TYPE (FLOATP (x), Qfloatp, x); +} +static inline void +CHECK_NUMBER_OR_FLOAT (Lisp_Object x) +{ + CHECK_TYPE (FLOATP (x) || INTEGERP (x), Qnumberp, x); +} #define CHECK_NUMBER_OR_FLOAT_COERCE_MARKER(x) \ do { if (MARKERP (x)) XSETFASTINT (x, marker_position (x)); \ else CHECK_TYPE (INTEGERP (x) || FLOATP (x), Qnumber_or_marker_p, x); } while (0) -#define CHECK_OVERLAY(x) \ - CHECK_TYPE (OVERLAYP (x), Qoverlayp, x) +static inline void +CHECK_OVERLAY (Lisp_Object x) +{ + CHECK_TYPE (OVERLAYP (x), Qoverlayp, x); +} /* Since we can't assign directly to the CAR or CDR fields of a cons cell, use these when checking that those fields contain numbers. */ -#define CHECK_NUMBER_CAR(x) \ - do { \ - Lisp_Object tmp = XCAR (x); \ - CHECK_NUMBER (tmp); \ - XSETCAR ((x), tmp); \ - } while (0) - -#define CHECK_NUMBER_CDR(x) \ - do { \ - Lisp_Object tmp = XCDR (x); \ - CHECK_NUMBER (tmp); \ - XSETCDR ((x), tmp); \ - } while (0) - -#define CHECK_NATNUM_CAR(x) \ - do { \ - Lisp_Object tmp = XCAR (x); \ - CHECK_NATNUM (tmp); \ - XSETCAR ((x), tmp); \ - } while (0) - -#define CHECK_NATNUM_CDR(x) \ - do { \ - Lisp_Object tmp = XCDR (x); \ - CHECK_NATNUM (tmp); \ - XSETCDR ((x), tmp); \ - } while (0) +static inline void +CHECK_NUMBER_CAR (Lisp_Object x) +{ + Lisp_Object tmp = XCAR (x); + CHECK_NUMBER (tmp); + XSETCAR (x, tmp); +} + +static inline void +CHECK_NUMBER_CDR (Lisp_Object x) +{ + Lisp_Object tmp = XCDR (x); + CHECK_NUMBER (tmp); + XSETCDR (x, tmp); +} + +static inline void +CHECK_NATNUM_CAR (Lisp_Object x) +{ + Lisp_Object tmp = XCAR (x); + CHECK_NATNUM (tmp); + XSETCAR (x, tmp); +} + +static inline void +CHECK_NATNUM_CDR (Lisp_Object x) +{ + Lisp_Object tmp = XCDR (x); + CHECK_NATNUM (tmp); + XSETCDR (x, tmp); +} /* Define a built-in function for calling from Lisp. `lname' should be the name to give the function in Lisp, @@ -1869,18 +2428,20 @@ Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object) /* Non-zero if OBJ is a Lisp function. */ -#define FUNCTIONP(OBJ) \ - ((CONSP (OBJ) && EQ (XCAR (OBJ), Qlambda)) \ - || (SYMBOLP (OBJ) && !NILP (Ffboundp (OBJ))) \ - || COMPILEDP (OBJ) \ - || SUBRP (OBJ)) +static inline int +FUNCTIONP (Lisp_Object obj) +{ + return ((CONSP (obj) && EQ (XCAR (obj), Qlambda)) + || (SYMBOLP (obj) && !NILP (Ffboundp (obj))) + || COMPILEDP (obj) + || SUBRP (obj)); +} /* defsubr (Sname); 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 { 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 *); @@ -1973,7 +2534,11 @@ extern struct specbinding *specpdl_ptr; extern ptrdiff_t specpdl_size; -#define SPECPDL_INDEX() (specpdl_ptr - specpdl) +static inline ptrdiff_t +SPECPDL_INDEX (void) +{ + return specpdl_ptr - specpdl; +} /* Everything needed to describe an active condition case. */ struct handler @@ -2283,6 +2848,8 @@ #define EXFUN(fnname, maxargs) \ extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs +#include "globals.h" + /* Forward declarations for prototypes. */ struct window; struct frame; @@ -2317,6 +2884,7 @@ extern Lisp_Object Qinteger, Qinterval, Qsymbol, Qstring; extern Lisp_Object Qmisc, Qvector, Qfloat, Qcons, Qbuffer; +extern Lisp_Object Qsubrp; extern Lisp_Object Qfont_spec, Qfont_entity, Qfont_object; EXFUN (Fbyteorder, 0) ATTRIBUTE_CONST; @@ -2411,6 +2979,7 @@ extern Lisp_Object Qcursor_in_echo_area; extern Lisp_Object Qstring_lessp; extern Lisp_Object QCsize, QCtest, QCweakness, Qequal, Qeq, Qeql; +extern Lisp_Object Qhash_table_p; EMACS_UINT hash_string (char const *, ptrdiff_t); EMACS_UINT sxhash (Lisp_Object, int); Lisp_Object make_hash_table (Lisp_Object, Lisp_Object, Lisp_Object, @@ -2706,7 +3275,7 @@ 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 +enum { FLOAT_TO_STRING_BUFSIZE = 350 }; extern int float_to_string (char *, double); extern void syms_of_print (void); @@ -2729,10 +3298,12 @@ 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 { \ - if (initialized) Vcurrent_load_list = Fcons (x, Vcurrent_load_list); \ - } while (0) +static inline void +LOADHIST_ATTACH (Lisp_Object x) +{ + if (initialized) + Vcurrent_load_list = Fcons (x, Vcurrent_load_list); +} extern int openp (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object *, Lisp_Object); Lisp_Object string_to_number (char const *, int, int); @@ -2850,6 +3421,7 @@ extern Lisp_Object Vbuffer_alist; extern Lisp_Object set_buffer_if_live (Lisp_Object); extern Lisp_Object other_buffer_safely (Lisp_Object); +extern Lisp_Object Qoverlayp; extern Lisp_Object Qpriority, Qwindow, Qbefore_string, Qafter_string; extern Lisp_Object get_truename_buffer (Lisp_Object); extern void init_buffer_once (void); @@ -3007,10 +3579,10 @@ void synchronize_system_messages_locale (void); void synchronize_system_time_locale (void); #else -#define setlocale(category, locale) -#define fixup_locale() -#define synchronize_system_messages_locale() -#define synchronize_system_time_locale() +static inline char *setlocale (int cat, char const *locale) { return 0; } +static inline void fixup_locale (void) {} +static inline void synchronize_system_messages_locale (void) {} +static inline void synchronize_system_time_locale (void) {} #endif void shut_down_emacs (int, int, Lisp_Object); /* Nonzero means don't do interactive redisplay and don't change tty modes. */ @@ -3271,19 +3843,19 @@ 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 '/' +enum { DIRECTORY_SEP = '/' }; #ifndef IS_DIRECTORY_SEP -#define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP) +static inline int IS_DIRECTORY_SEP (int c) { return c == DIRECTORY_SEP; } #endif #ifndef IS_DEVICE_SEP #ifndef DEVICE_SEP -#define IS_DEVICE_SEP(_c_) 0 +static inline int IS_DEVICE_SEP (int c) { return 0; } #else -#define IS_DEVICE_SEP(_c_) ((_c_) == DEVICE_SEP) +static inline int IS_DEVICE_SEP (int c) { return c == DEVICE_SEP; } #endif #endif #ifndef IS_ANY_SEP -#define IS_ANY_SEP(_c_) (IS_DIRECTORY_SEP (_c_)) +static inline int IS_ANY_SEP (int c) { return IS_DIRECTORY_SEP (c); } #endif #define SWITCH_ENUM_CAST(x) (x) @@ -3303,15 +3875,6 @@ # 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. */ @@ -3354,7 +3917,7 @@ /* 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 = 16*1024 }; extern Lisp_Object safe_alloca_unwind (Lisp_Object); @@ -3424,8 +3987,6 @@ } while (0) -#include "globals.h" - /* Check whether it's time for GC, and run it if so. */ static inline void === modified file 'src/mem-limits.h' --- src/mem-limits.h 2012-07-09 16:38:45 +0000 +++ src/mem-limits.h 2012-07-13 03:37:42 +0000 @@ -36,9 +36,7 @@ extern char *start_of_data (void) ATTRIBUTE_CONST; #if USE_LSB_TAG || UINTPTR_MAX <= VAL_MAX #define EXCEEDS_LISP_PTR(ptr) 0 -#elif defined DATA_SEG_BITS +#else #define EXCEEDS_LISP_PTR(ptr) \ (((uintptr_t) (ptr) & ~DATA_SEG_BITS) >> VALBITS) -#else -#define EXCEEDS_LISP_PTR(ptr) ((uintptr_t) (ptr) >> VALBITS) #endif === modified file 'src/window.c' --- src/window.c 2012-07-23 16:57:20 +0000 +++ src/window.c 2012-07-23 21:50:36 +0000 @@ -51,8 +51,8 @@ #include "nsterm.h" #endif -Lisp_Object Qwindowp, Qwindow_live_p; -static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer; +Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configuration_p; +static Lisp_Object Qrecord_window_buffer; static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer; static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window; static Lisp_Object Qwindow_resize_root_window, Qwindow_resize_root_window_vertically; === modified file 'src/window.h' --- src/window.h 2012-07-05 15:20:12 +0000 +++ src/window.h 2012-07-13 03:37:42 +0000 @@ -885,7 +885,7 @@ /* These used to be in lisp.h. */ -extern Lisp_Object Qwindowp, Qwindow_live_p; +extern Lisp_Object Qwindow_live_p; extern Lisp_Object Vwindow_list; extern int compare_window_configurations (Lisp_Object, Lisp_Object, int); @@ -900,4 +900,17 @@ extern void syms_of_window (void); extern void keys_of_window (void); +/* CHECK_LIVE_WINDOW rejects windows on the interior of the window tree as + "dead", which is what we want; this is an argument-checking function, and + the user should never get access to interior windows. + + A window of any sort, leaf or interior, is dead if the buffer, + vchild, and hchild members are all nil. */ +static inline void +CHECK_LIVE_WINDOW (Lisp_Object x) +{ + CHECK_TYPE (WINDOWP (x) && !NILP (XWINDOW (x)->buffer), Qwindow_live_p, x); +} + + #endif /* not WINDOW_H_INCLUDED */