X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/5c0c0e8a1a3eeb60e58e9dc4b043a8db3e72ca3e..25e65510a3d35524ade205c3114970c43dc6ae05:/src/lisp.h diff --git a/src/lisp.h b/src/lisp.h index 55f8677f9a..3dbea6e0f7 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -28,6 +28,11 @@ along with GNU Emacs. If not, see . */ #include +INLINE_HEADER_BEGIN +#ifndef LISP_INLINE +# define LISP_INLINE INLINE +#endif + /* The ubiquitous max and min macros. */ #undef min #undef max @@ -295,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; @@ -326,11 +331,15 @@ enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = 0 }; /* In the size word of a vector, this bit means the vector has been marked. */ -static ptrdiff_t const ARRAY_MARK_FLAG = PTRDIFF_MIN; +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 = PTRDIFF_MAX - PTRDIFF_MAX / 2; +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 @@ -416,7 +425,9 @@ enum lsb_bits #else /* not USE_LSB_TAG */ -static EMACS_INT const VALMASK = VAL_MAX; +static EMACS_INT const VALMASK +#define VALMASK VAL_MAX + = VALMASK; #define XTYPE(a) ((enum Lisp_Type) ((EMACS_UINT) XLI (a) >> VALBITS)) @@ -480,7 +491,7 @@ static EMACS_INT const MOST_NEGATIVE_FIXNUM = #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; @@ -598,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. */ @@ -622,10 +633,7 @@ 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) -/* Lisp fields are usually hidden from most code and accessed - via special macros. Only select pieces of code, like the GC, - are allowed to use INTERNAL_FIELD directly. Objects which - aren't using this convention should be fixed. */ +/* Deprecated and will be removed soon. */ #define INTERNAL_FIELD(field) field ## _ @@ -637,17 +645,17 @@ 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. */ + /* 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; }; @@ -659,8 +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.) */ -#define XCAR_AS_LVALUE(c) (XCONS ((c))->car) -#define XCDR_AS_LVALUE(c) (XCONS ((c))->u.cdr) +#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)) @@ -744,12 +752,6 @@ static ptrdiff_t const STRING_BYTES_BOUND = (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. */ struct Lisp_String @@ -808,25 +810,49 @@ struct vectorlike_header } 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 @@ -962,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. @@ -1063,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. */ @@ -1089,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) @@ -1250,13 +1261,12 @@ enum DEFAULT_HASH_SIZE { DEFAULT_HASH_SIZE = 65 }; 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. */ @@ -1326,7 +1336,9 @@ struct Lisp_Overlay unsigned gcmarkbit : 1; int spacer : 15; struct Lisp_Overlay *next; - Lisp_Object start, end, plist; + Lisp_Object start; + Lisp_Object end; + Lisp_Object plist; }; /* Hold a C pointer for later use. @@ -1748,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) @@ -2319,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; @@ -2637,7 +2748,7 @@ extern Lisp_Object make_unibyte_string (const char *, ptrdiff_t); /* Make unibyte string from C string when the length isn't known. */ -static inline Lisp_Object +LISP_INLINE Lisp_Object build_unibyte_string (const char *str) { return make_unibyte_string (str, strlen (str)); @@ -2655,7 +2766,7 @@ extern Lisp_Object make_pure_c_string (const char *, ptrdiff_t); /* Make a string allocated in pure space, use STR as string data. */ -static inline Lisp_Object +LISP_INLINE Lisp_Object build_pure_c_string (const char *str) { return make_pure_c_string (str, strlen (str)); @@ -2664,7 +2775,7 @@ build_pure_c_string (const char *str) /* Make a string from the data at STR, treating it as multibyte if the data warrants. */ -static inline Lisp_Object +LISP_INLINE Lisp_Object build_string (const char *str) { return make_string (str, strlen (str)); @@ -2783,13 +2894,13 @@ extern void init_obarray (void); extern void init_lread (void); extern void syms_of_lread (void); -static inline Lisp_Object +LISP_INLINE Lisp_Object intern (const char *str) { return intern_1 (str, strlen (str)); } -static inline Lisp_Object +LISP_INLINE Lisp_Object intern_c_string (const char *str) { return intern_c_string_1 (str, strlen (str)); @@ -2841,7 +2952,9 @@ extern Lisp_Object internal_lisp_condition_case (Lisp_Object, Lisp_Object, Lisp_ 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); @@ -3015,7 +3128,7 @@ extern int indented_beyond_p (ptrdiff_t, ptrdiff_t, EMACS_INT); extern void syms_of_indent (void); /* Defined in frame.c. */ -extern Lisp_Object Qonly; +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); @@ -3305,23 +3418,6 @@ extern char *egetenv (const char *); /* Set up the name of the machine we're running on. */ extern void init_system_name (void); -static char const DIRECTORY_SEP = '/'; - -/* Use this to suppress gcc's warnings. */ -#ifdef lint - -/* Use CODE only if lint checking is in effect. */ -# define IF_LINT(Code) Code - -/* Assume that the expression COND is true. This differs in intent - from 'assert', as it is a message from the programmer to the compiler. */ -# define lint_assume(cond) ((cond) ? (void) 0 : abort ()) - -#else -# define IF_LINT(Code) /* empty */ -# define lint_assume(cond) ((void) (0 && (cond))) -#endif - /* 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. */ @@ -3367,24 +3463,16 @@ static char const DIRECTORY_SEP = '/'; 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 = 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 @@ -3416,21 +3504,21 @@ 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 = 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) @@ -3438,7 +3526,7 @@ extern Lisp_Object safe_alloca_unwind (Lisp_Object); /* Check whether it's time for GC, and run it if so. */ -static inline void +LISP_INLINE void maybe_gc (void) { if ((consing_since_gc > gc_cons_threshold @@ -3448,4 +3536,6 @@ maybe_gc (void) Fgarbage_collect (); } +INLINE_HEADER_END + #endif /* EMACS_LISP_H */