diff options
| author | Joakim Verona | 2013-07-02 22:46:17 +0200 |
|---|---|---|
| committer | Joakim Verona | 2013-07-02 22:46:17 +0200 |
| commit | 3718127221fbbc31f8ebd027ab7c95403dbe9118 (patch) | |
| tree | ef422898f3344c8f94f6ecf63eb583122bbf2bd8 /src/lisp.h | |
| parent | 1ce45b902c67b8a0dda8d71bd2812de29a9988a6 (diff) | |
| parent | a3b49114c186d84404226af75ae7905bd1cd018f (diff) | |
| download | emacs-3718127221fbbc31f8ebd027ab7c95403dbe9118.tar.gz emacs-3718127221fbbc31f8ebd027ab7c95403dbe9118.zip | |
Merge branch 'trunk' into xwidget
Conflicts:
src/window.c
Diffstat (limited to 'src/lisp.h')
| -rw-r--r-- | src/lisp.h | 1816 |
1 files changed, 1083 insertions, 733 deletions
diff --git a/src/lisp.h b/src/lisp.h index 15eb0306251..6bea1ec67ed 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -73,7 +73,6 @@ enum | |||
| 73 | BITS_PER_SHORT = CHAR_BIT * sizeof (short), | 73 | BITS_PER_SHORT = CHAR_BIT * sizeof (short), |
| 74 | BITS_PER_INT = CHAR_BIT * sizeof (int), | 74 | BITS_PER_INT = CHAR_BIT * sizeof (int), |
| 75 | BITS_PER_LONG = CHAR_BIT * sizeof (long int), | 75 | BITS_PER_LONG = CHAR_BIT * sizeof (long int), |
| 76 | BITS_PER_PTRDIFF_T = CHAR_BIT * sizeof (ptrdiff_t), | ||
| 77 | BITS_PER_EMACS_INT = CHAR_BIT * sizeof (EMACS_INT) | 76 | BITS_PER_EMACS_INT = CHAR_BIT * sizeof (EMACS_INT) |
| 78 | }; | 77 | }; |
| 79 | 78 | ||
| @@ -131,9 +130,9 @@ extern _Noreturn void die (const char *, const char *, int); | |||
| 131 | extern bool suppress_checking EXTERNALLY_VISIBLE; | 130 | extern bool suppress_checking EXTERNALLY_VISIBLE; |
| 132 | 131 | ||
| 133 | # define eassert(cond) \ | 132 | # define eassert(cond) \ |
| 134 | ((cond) || suppress_checking \ | 133 | (suppress_checking || (cond) \ |
| 135 | ? (void) 0 \ | 134 | ? (void) 0 \ |
| 136 | : die ("assertion failed: " # cond, __FILE__, __LINE__)) | 135 | : die (# cond, __FILE__, __LINE__)) |
| 137 | #endif /* ENABLE_CHECKING */ | 136 | #endif /* ENABLE_CHECKING */ |
| 138 | 137 | ||
| 139 | /* Use the configure flag --enable-check-lisp-object-type to make | 138 | /* Use the configure flag --enable-check-lisp-object-type to make |
| @@ -220,6 +219,139 @@ enum enum_USE_LSB_TAG { USE_LSB_TAG = 0 }; | |||
| 220 | #endif | 219 | #endif |
| 221 | 220 | ||
| 222 | 221 | ||
| 222 | /* Some operations are so commonly executed that they are implemented | ||
| 223 | as macros, not functions, because otherwise runtime performance would | ||
| 224 | suffer too much when compiling with GCC without optimization. | ||
| 225 | There's no need to inline everything, just the operations that | ||
| 226 | would otherwise cause a serious performance problem. | ||
| 227 | |||
| 228 | For each such operation OP, define a macro lisp_h_OP that contains | ||
| 229 | the operation's implementation. That way, OP can be implemented | ||
| 230 | via a macro definition like this: | ||
| 231 | |||
| 232 | #define OP(x) lisp_h_OP (x) | ||
| 233 | |||
| 234 | and/or via a function definition like this: | ||
| 235 | |||
| 236 | LISP_MACRO_DEFUN (OP, Lisp_Object, (Lisp_Object x), (x)) | ||
| 237 | |||
| 238 | which macro-expands to this: | ||
| 239 | |||
| 240 | Lisp_Object (OP) (Lisp_Object x) { return lisp_h_OP (x); } | ||
| 241 | |||
| 242 | without worrying about the implementations diverging, since | ||
| 243 | lisp_h_OP defines the actual implementation. The lisp_h_OP macros | ||
| 244 | are intended to be private to this include file, and should not be | ||
| 245 | used elsewhere. | ||
| 246 | |||
| 247 | FIXME: Remove the lisp_h_OP macros, and define just the inline OP | ||
| 248 | functions, once most developers have access to GCC 4.8 or later and | ||
| 249 | can use "gcc -Og" to debug. Maybe in the year 2016. See | ||
| 250 | Bug#11935. | ||
| 251 | |||
| 252 | Commentary for these macros can be found near their corresponding | ||
| 253 | functions, below. */ | ||
| 254 | |||
| 255 | #if CHECK_LISP_OBJECT_TYPE | ||
| 256 | # define lisp_h_XLI(o) ((o).i) | ||
| 257 | # define lisp_h_XIL(i) ((Lisp_Object) { i }) | ||
| 258 | #else | ||
| 259 | # define lisp_h_XLI(o) (o) | ||
| 260 | # define lisp_h_XIL(i) (i) | ||
| 261 | #endif | ||
| 262 | #define lisp_h_CHECK_LIST_CONS(x, y) CHECK_TYPE (CONSP (x), Qlistp, y) | ||
| 263 | #define lisp_h_CHECK_NUMBER(x) CHECK_TYPE (INTEGERP (x), Qintegerp, x) | ||
| 264 | #define lisp_h_CHECK_SYMBOL(x) CHECK_TYPE (SYMBOLP (x), Qsymbolp, x) | ||
| 265 | #define lisp_h_CHECK_TYPE(ok, Qxxxp, x) \ | ||
| 266 | ((ok) ? (void) 0 : (void) wrong_type_argument (Qxxxp, x)) | ||
| 267 | #define lisp_h_CONSP(x) (XTYPE (x) == Lisp_Cons) | ||
| 268 | #define lisp_h_EQ(x, y) (XLI (x) == XLI (y)) | ||
| 269 | #define lisp_h_FLOATP(x) (XTYPE (x) == Lisp_Float) | ||
| 270 | #define lisp_h_INTEGERP(x) ((XTYPE (x) & ~Lisp_Int1) == 0) | ||
| 271 | #define lisp_h_MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker) | ||
| 272 | #define lisp_h_MISCP(x) (XTYPE (x) == Lisp_Misc) | ||
| 273 | #define lisp_h_NILP(x) EQ (x, Qnil) | ||
| 274 | #define lisp_h_SET_SYMBOL_VAL(sym, v) \ | ||
| 275 | (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value = (v)) | ||
| 276 | #define lisp_h_SYMBOL_CONSTANT_P(sym) (XSYMBOL (sym)->constant) | ||
| 277 | #define lisp_h_SYMBOL_VAL(sym) \ | ||
| 278 | (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value) | ||
| 279 | #define lisp_h_SYMBOLP(x) (XTYPE (x) == Lisp_Symbol) | ||
| 280 | #define lisp_h_VECTORLIKEP(x) (XTYPE (x) == Lisp_Vectorlike) | ||
| 281 | #define lisp_h_XCAR(c) XCONS (c)->car | ||
| 282 | #define lisp_h_XCDR(c) XCONS (c)->u.cdr | ||
| 283 | #define lisp_h_XCONS(a) \ | ||
| 284 | (eassert (CONSP (a)), (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons)) | ||
| 285 | #define lisp_h_XHASH(a) XUINT (a) | ||
| 286 | #define lisp_h_XPNTR(a) \ | ||
| 287 | ((void *) (intptr_t) ((XLI (a) & VALMASK) | DATA_SEG_BITS)) | ||
| 288 | #define lisp_h_XSYMBOL(a) \ | ||
| 289 | (eassert (SYMBOLP (a)), (struct Lisp_Symbol *) XUNTAG (a, Lisp_Symbol)) | ||
| 290 | #ifndef GC_CHECK_CONS_LIST | ||
| 291 | # define lisp_h_check_cons_list() ((void) 0) | ||
| 292 | #endif | ||
| 293 | #if USE_LSB_TAG | ||
| 294 | # define lisp_h_make_number(n) XIL ((EMACS_INT) (n) << INTTYPEBITS) | ||
| 295 | # define lisp_h_XFASTINT(a) XINT (a) | ||
| 296 | # define lisp_h_XINT(a) (XLI (a) >> INTTYPEBITS) | ||
| 297 | # define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK)) | ||
| 298 | # define lisp_h_XUNTAG(a, type) ((void *) (XLI (a) - (type))) | ||
| 299 | #endif | ||
| 300 | |||
| 301 | /* When compiling via gcc -O0, define the key operations as macros, as | ||
| 302 | Emacs is too slow otherwise. To disable this optimization, compile | ||
| 303 | with -DINLINING=0. */ | ||
| 304 | #if (defined __NO_INLINE__ \ | ||
| 305 | && ! defined __OPTIMIZE__ && ! defined __OPTIMIZE_SIZE__ \ | ||
| 306 | && ! (defined INLINING && ! INLINING)) | ||
| 307 | # define XLI(o) lisp_h_XLI (o) | ||
| 308 | # define XIL(i) lisp_h_XIL (i) | ||
| 309 | # define CHECK_LIST_CONS(x, y) lisp_h_CHECK_LIST_CONS (x, y) | ||
| 310 | # define CHECK_NUMBER(x) lisp_h_CHECK_NUMBER (x) | ||
| 311 | # define CHECK_SYMBOL(x) lisp_h_CHECK_SYMBOL (x) | ||
| 312 | # define CHECK_TYPE(ok, Qxxxp, x) lisp_h_CHECK_TYPE (ok, Qxxxp, x) | ||
| 313 | # define CONSP(x) lisp_h_CONSP (x) | ||
| 314 | # define EQ(x, y) lisp_h_EQ (x, y) | ||
| 315 | # define FLOATP(x) lisp_h_FLOATP (x) | ||
| 316 | # define INTEGERP(x) lisp_h_INTEGERP (x) | ||
| 317 | # define MARKERP(x) lisp_h_MARKERP (x) | ||
| 318 | # define MISCP(x) lisp_h_MISCP (x) | ||
| 319 | # define NILP(x) lisp_h_NILP (x) | ||
| 320 | # define SET_SYMBOL_VAL(sym, v) lisp_h_SET_SYMBOL_VAL (sym, v) | ||
| 321 | # define SYMBOL_CONSTANT_P(sym) lisp_h_SYMBOL_CONSTANT_P (sym) | ||
| 322 | # define SYMBOL_VAL(sym) lisp_h_SYMBOL_VAL (sym) | ||
| 323 | # define SYMBOLP(x) lisp_h_SYMBOLP (x) | ||
| 324 | # define VECTORLIKEP(x) lisp_h_VECTORLIKEP (x) | ||
| 325 | # define XCAR(c) lisp_h_XCAR (c) | ||
| 326 | # define XCDR(c) lisp_h_XCDR (c) | ||
| 327 | # define XCONS(a) lisp_h_XCONS (a) | ||
| 328 | # define XHASH(a) lisp_h_XHASH (a) | ||
| 329 | # define XPNTR(a) lisp_h_XPNTR (a) | ||
| 330 | # define XSYMBOL(a) lisp_h_XSYMBOL (a) | ||
| 331 | # ifndef GC_CHECK_CONS_LIST | ||
| 332 | # define check_cons_list() lisp_h_check_cons_list () | ||
| 333 | # endif | ||
| 334 | # if USE_LSB_TAG | ||
| 335 | # define make_number(n) lisp_h_make_number (n) | ||
| 336 | # define XFASTINT(a) lisp_h_XFASTINT (a) | ||
| 337 | # define XINT(a) lisp_h_XINT (a) | ||
| 338 | # define XTYPE(a) lisp_h_XTYPE (a) | ||
| 339 | # define XUNTAG(a, type) lisp_h_XUNTAG (a, type) | ||
| 340 | # endif | ||
| 341 | #endif | ||
| 342 | |||
| 343 | /* Define NAME as a lisp.h inline function that returns TYPE and has | ||
| 344 | arguments declared as ARGDECLS and passed as ARGS. ARGDECLS and | ||
| 345 | ARGS should be parenthesized. Implement the function by calling | ||
| 346 | lisp_h_NAME ARGS. */ | ||
| 347 | #define LISP_MACRO_DEFUN(name, type, argdecls, args) \ | ||
| 348 | LISP_INLINE type (name) argdecls { return lisp_h_##name args; } | ||
| 349 | |||
| 350 | /* like LISP_MACRO_DEFUN, except NAME returns void. */ | ||
| 351 | #define LISP_MACRO_DEFUN_VOID(name, argdecls, args) \ | ||
| 352 | LISP_INLINE void (name) argdecls { lisp_h_##name args; } | ||
| 353 | |||
| 354 | |||
| 223 | /* Define the fundamental Lisp data structures. */ | 355 | /* Define the fundamental Lisp data structures. */ |
| 224 | 356 | ||
| 225 | /* This is the set of Lisp data types. If you want to define a new | 357 | /* This is the set of Lisp data types. If you want to define a new |
| @@ -230,7 +362,6 @@ enum enum_USE_LSB_TAG { USE_LSB_TAG = 0 }; | |||
| 230 | extending their range from, e.g., -2^28..2^28-1 to -2^29..2^29-1. */ | 362 | extending their range from, e.g., -2^28..2^28-1 to -2^29..2^29-1. */ |
| 231 | #define INTMASK (EMACS_INT_MAX >> (INTTYPEBITS - 1)) | 363 | #define INTMASK (EMACS_INT_MAX >> (INTTYPEBITS - 1)) |
| 232 | #define case_Lisp_Int case Lisp_Int0: case Lisp_Int1 | 364 | #define case_Lisp_Int case Lisp_Int0: case Lisp_Int1 |
| 233 | #define LISP_INT_TAG_P(x) (((x) & ~Lisp_Int1) == 0) | ||
| 234 | 365 | ||
| 235 | /* Idea stolen from GDB. MSVC doesn't support enums in bitfields, | 366 | /* Idea stolen from GDB. MSVC doesn't support enums in bitfields, |
| 236 | and xlc complains vociferously about them. */ | 367 | and xlc complains vociferously about them. */ |
| @@ -359,20 +490,6 @@ enum Lisp_Fwd_Type | |||
| 359 | 490 | ||
| 360 | typedef struct { EMACS_INT i; } Lisp_Object; | 491 | typedef struct { EMACS_INT i; } Lisp_Object; |
| 361 | 492 | ||
| 362 | #define XLI(o) (o).i | ||
| 363 | LISP_INLINE Lisp_Object | ||
| 364 | XIL (EMACS_INT i) | ||
| 365 | { | ||
| 366 | Lisp_Object o = { i }; | ||
| 367 | return o; | ||
| 368 | } | ||
| 369 | |||
| 370 | LISP_INLINE Lisp_Object | ||
| 371 | LISP_MAKE_RVALUE (Lisp_Object o) | ||
| 372 | { | ||
| 373 | return o; | ||
| 374 | } | ||
| 375 | |||
| 376 | #define LISP_INITIALLY_ZERO {0} | 493 | #define LISP_INITIALLY_ZERO {0} |
| 377 | 494 | ||
| 378 | #undef CHECK_LISP_OBJECT_TYPE | 495 | #undef CHECK_LISP_OBJECT_TYPE |
| @@ -382,13 +499,15 @@ enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = 1 }; | |||
| 382 | /* If a struct type is not wanted, define Lisp_Object as just a number. */ | 499 | /* If a struct type is not wanted, define Lisp_Object as just a number. */ |
| 383 | 500 | ||
| 384 | typedef EMACS_INT Lisp_Object; | 501 | typedef EMACS_INT Lisp_Object; |
| 385 | #define XLI(o) (o) | ||
| 386 | #define XIL(i) (i) | ||
| 387 | #define LISP_MAKE_RVALUE(o) (0 + (o)) | ||
| 388 | #define LISP_INITIALLY_ZERO 0 | 502 | #define LISP_INITIALLY_ZERO 0 |
| 389 | enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = 0 }; | 503 | enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = 0 }; |
| 390 | #endif /* CHECK_LISP_OBJECT_TYPE */ | 504 | #endif /* CHECK_LISP_OBJECT_TYPE */ |
| 391 | 505 | ||
| 506 | /* Convert a Lisp_Object to the corresponding EMACS_INT and vice versa. | ||
| 507 | At the machine level, these operations are no-ops. */ | ||
| 508 | LISP_MACRO_DEFUN (XLI, EMACS_INT, (Lisp_Object o), (o)) | ||
| 509 | LISP_MACRO_DEFUN (XIL, Lisp_Object, (EMACS_INT i), (i)) | ||
| 510 | |||
| 392 | /* In the size word of a vector, this bit means the vector has been marked. */ | 511 | /* In the size word of a vector, this bit means the vector has been marked. */ |
| 393 | 512 | ||
| 394 | static ptrdiff_t const ARRAY_MARK_FLAG | 513 | static ptrdiff_t const ARRAY_MARK_FLAG |
| @@ -465,84 +584,108 @@ enum More_Lisp_Bits | |||
| 465 | BOOL_VECTOR_BITS_PER_CHAR = 8 | 584 | BOOL_VECTOR_BITS_PER_CHAR = 8 |
| 466 | }; | 585 | }; |
| 467 | 586 | ||
| 468 | /* These macros extract various sorts of values from a Lisp_Object. | 587 | /* These functions extract various sorts of values from a Lisp_Object. |
| 469 | For example, if tem is a Lisp_Object whose type is Lisp_Cons, | 588 | For example, if tem is a Lisp_Object whose type is Lisp_Cons, |
| 470 | XCONS (tem) is the struct Lisp_Cons * pointing to the memory for that cons. */ | 589 | XCONS (tem) is the struct Lisp_Cons * pointing to the memory for that cons. */ |
| 471 | 590 | ||
| 472 | #if USE_LSB_TAG | 591 | static EMACS_INT const VALMASK |
| 592 | #define VALMASK (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX) | ||
| 593 | = VALMASK; | ||
| 473 | 594 | ||
| 474 | enum lsb_bits | 595 | /* Largest and smallest representable fixnum values. These are the C |
| 475 | { | 596 | values. They are macros for use in static initializers. */ |
| 476 | TYPEMASK = (1 << GCTYPEBITS) - 1, | 597 | #define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS) |
| 477 | VALMASK = ~ TYPEMASK | 598 | #define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM) |
| 478 | }; | ||
| 479 | #define XTYPE(a) ((enum Lisp_Type) (XLI (a) & TYPEMASK)) | ||
| 480 | #define XINT(a) (XLI (a) >> INTTYPEBITS) | ||
| 481 | #define XUINT(a) ((EMACS_UINT) XLI (a) >> INTTYPEBITS) | ||
| 482 | #define make_number(N) XIL ((EMACS_INT) (N) << INTTYPEBITS) | ||
| 483 | #define make_lisp_ptr(ptr, type) \ | ||
| 484 | (eassert (XTYPE (XIL ((intptr_t) (ptr))) == 0), /* Check alignment. */ \ | ||
| 485 | XIL ((type) | (intptr_t) (ptr))) | ||
| 486 | 599 | ||
| 487 | #define XPNTR(a) ((intptr_t) (XLI (a) & ~TYPEMASK)) | 600 | /* Extract the pointer hidden within A. */ |
| 488 | #define XUNTAG(a, type) ((intptr_t) (XLI (a) - (type))) | 601 | LISP_MACRO_DEFUN (XPNTR, void *, (Lisp_Object a), (a)) |
| 489 | 602 | ||
| 490 | #else /* not USE_LSB_TAG */ | 603 | #if USE_LSB_TAG |
| 491 | 604 | ||
| 492 | static EMACS_INT const VALMASK | 605 | LISP_MACRO_DEFUN (make_number, Lisp_Object, (EMACS_INT n), (n)) |
| 493 | #define VALMASK VAL_MAX | 606 | LISP_MACRO_DEFUN (XINT, EMACS_INT, (Lisp_Object a), (a)) |
| 494 | = VALMASK; | 607 | LISP_MACRO_DEFUN (XFASTINT, EMACS_INT, (Lisp_Object a), (a)) |
| 608 | LISP_MACRO_DEFUN (XTYPE, enum Lisp_Type, (Lisp_Object a), (a)) | ||
| 609 | LISP_MACRO_DEFUN (XUNTAG, void *, (Lisp_Object a, int type), (a, type)) | ||
| 495 | 610 | ||
| 496 | #define XTYPE(a) ((enum Lisp_Type) ((EMACS_UINT) XLI (a) >> VALBITS)) | 611 | #else /* ! USE_LSB_TAG */ |
| 497 | 612 | ||
| 498 | /* For integers known to be positive, XFASTINT provides fast retrieval | 613 | /* Although compiled only if ! USE_LSB_TAG, the following functions |
| 499 | and XSETFASTINT provides fast storage. This takes advantage of the | 614 | also work when USE_LSB_TAG; this is to aid future maintenance when |
| 500 | fact that Lisp integers have zero-bits in their tags. */ | 615 | the lisp_h_* macros are eventually removed. */ |
| 501 | #define XFASTINT(a) (XLI (a) + 0) | ||
| 502 | #define XSETFASTINT(a, b) ((a) = XIL (b)) | ||
| 503 | 616 | ||
| 504 | /* Extract the value of a Lisp_Object as a (un)signed integer. */ | 617 | /* Make a Lisp integer representing the value of the low order |
| 618 | bits of N. */ | ||
| 619 | LISP_INLINE Lisp_Object | ||
| 620 | make_number (EMACS_INT n) | ||
| 621 | { | ||
| 622 | return XIL (USE_LSB_TAG ? n << INTTYPEBITS : n & INTMASK); | ||
| 623 | } | ||
| 505 | 624 | ||
| 506 | #define XINT(a) (XLI (a) << INTTYPEBITS >> INTTYPEBITS) | 625 | /* Extract A's value as a signed integer. */ |
| 507 | #define XUINT(a) ((EMACS_UINT) (XLI (a) & INTMASK)) | 626 | LISP_INLINE EMACS_INT |
| 508 | #define make_number(N) XIL ((EMACS_INT) (N) & INTMASK) | 627 | XINT (Lisp_Object a) |
| 628 | { | ||
| 629 | EMACS_INT i = XLI (a); | ||
| 630 | return (USE_LSB_TAG ? i : i << INTTYPEBITS) >> INTTYPEBITS; | ||
| 631 | } | ||
| 509 | 632 | ||
| 510 | #define make_lisp_ptr(ptr, type) \ | 633 | /* Like XINT (A), but may be faster. A must be nonnegative. |
| 511 | (XIL ((EMACS_INT) ((EMACS_UINT) (type) << VALBITS) \ | 634 | If ! USE_LSB_TAG, this takes advantage of the fact that Lisp |
| 512 | + ((intptr_t) (ptr) & VALMASK))) | 635 | integers have zero-bits in their tags. */ |
| 636 | LISP_INLINE EMACS_INT | ||
| 637 | XFASTINT (Lisp_Object a) | ||
| 638 | { | ||
| 639 | EMACS_INT n = USE_LSB_TAG ? XINT (a) : XLI (a); | ||
| 640 | eassert (0 <= n); | ||
| 641 | return n; | ||
| 642 | } | ||
| 513 | 643 | ||
| 514 | /* DATA_SEG_BITS forces extra bits to be or'd in with any pointers | 644 | /* Extract A's type. */ |
| 515 | which were stored in a Lisp_Object. */ | 645 | LISP_INLINE enum Lisp_Type |
| 516 | #define XPNTR(a) ((uintptr_t) ((XLI (a) & VALMASK) | DATA_SEG_BITS)) | 646 | XTYPE (Lisp_Object a) |
| 647 | { | ||
| 648 | EMACS_UINT i = XLI (a); | ||
| 649 | return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS; | ||
| 650 | } | ||
| 517 | 651 | ||
| 518 | #endif /* not USE_LSB_TAG */ | 652 | /* Extract A's pointer value, assuming A's type is TYPE. */ |
| 653 | LISP_INLINE void * | ||
| 654 | XUNTAG (Lisp_Object a, int type) | ||
| 655 | { | ||
| 656 | if (USE_LSB_TAG) | ||
| 657 | { | ||
| 658 | intptr_t i = XLI (a) - type; | ||
| 659 | return (void *) i; | ||
| 660 | } | ||
| 661 | return XPNTR (a); | ||
| 662 | } | ||
| 519 | 663 | ||
| 520 | /* Return a (Lisp-integer sized) hash of the Lisp_Object value. Happens to be | 664 | #endif /* ! USE_LSB_TAG */ |
| 521 | like XUINT right now, but XUINT should only be applied to objects we know | ||
| 522 | are integers. */ | ||
| 523 | #define XHASH(a) XUINT (a) | ||
| 524 | 665 | ||
| 525 | /* For integers known to be positive, XFASTINT sometimes provides | 666 | /* Extract A's value as an unsigned integer. */ |
| 526 | faster retrieval and XSETFASTINT provides faster storage. | 667 | LISP_INLINE EMACS_UINT |
| 527 | If not, fallback on the non-accelerated path. */ | 668 | XUINT (Lisp_Object a) |
| 528 | #ifndef XFASTINT | 669 | { |
| 529 | # define XFASTINT(a) (XINT (a)) | 670 | EMACS_UINT i = XLI (a); |
| 530 | # define XSETFASTINT(a, b) (XSETINT (a, b)) | 671 | return USE_LSB_TAG ? i >> INTTYPEBITS : i & INTMASK; |
| 531 | #endif | 672 | } |
| 532 | 673 | ||
| 533 | /* Extract the pointer value of the Lisp object A, under the | 674 | /* Return A's (Lisp-integer sized) hash. Happens to be like XUINT |
| 534 | assumption that A's type is TYPE. This is a fallback | 675 | right now, but XUINT should only be applied to objects we know are |
| 535 | implementation if nothing faster is available. */ | 676 | integers. */ |
| 536 | #ifndef XUNTAG | 677 | LISP_MACRO_DEFUN (XHASH, EMACS_INT, (Lisp_Object a), (a)) |
| 537 | # define XUNTAG(a, type) XPNTR (a) | ||
| 538 | #endif | ||
| 539 | 678 | ||
| 540 | #define EQ(x, y) (XLI (x) == XLI (y)) | 679 | /* Like make_number (N), but may be faster. N must be in nonnegative range. */ |
| 680 | LISP_INLINE Lisp_Object | ||
| 681 | make_natnum (EMACS_INT n) | ||
| 682 | { | ||
| 683 | eassert (0 <= n && n <= MOST_POSITIVE_FIXNUM); | ||
| 684 | return USE_LSB_TAG ? make_number (n) : XIL (n); | ||
| 685 | } | ||
| 541 | 686 | ||
| 542 | /* Largest and smallest representable fixnum values. These are the C | 687 | /* Return true if X and Y are the same object. */ |
| 543 | values. They are macros for use in static initializers. */ | 688 | LISP_MACRO_DEFUN (EQ, bool, (Lisp_Object x, Lisp_Object y), (x, y)) |
| 544 | #define MOST_POSITIVE_FIXNUM (EMACS_INT_MAX >> INTTYPEBITS) | ||
| 545 | #define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM) | ||
| 546 | 689 | ||
| 547 | /* Value is non-zero if I doesn't fit into a Lisp fixnum. It is | 690 | /* Value is non-zero if I doesn't fit into a Lisp fixnum. It is |
| 548 | written this way so that it also works if I is of unsigned | 691 | written this way so that it also works if I is of unsigned |
| @@ -556,66 +699,173 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper) | |||
| 556 | { | 699 | { |
| 557 | return num < lower ? lower : num <= upper ? num : upper; | 700 | return num < lower ? lower : num <= upper ? num : upper; |
| 558 | } | 701 | } |
| 702 | |||
| 703 | /* Forward declarations. */ | ||
| 704 | |||
| 705 | /* Defined in this file. */ | ||
| 706 | union Lisp_Fwd; | ||
| 707 | LISP_INLINE bool BOOL_VECTOR_P (Lisp_Object); | ||
| 708 | LISP_INLINE bool BUFFER_OBJFWDP (union Lisp_Fwd *); | ||
| 709 | LISP_INLINE bool BUFFERP (Lisp_Object); | ||
| 710 | LISP_INLINE bool CHAR_TABLE_P (Lisp_Object); | ||
| 711 | LISP_INLINE Lisp_Object CHAR_TABLE_REF_ASCII (Lisp_Object, ptrdiff_t); | ||
| 712 | LISP_INLINE bool (CONSP) (Lisp_Object); | ||
| 713 | LISP_INLINE bool (FLOATP) (Lisp_Object); | ||
| 714 | LISP_INLINE bool functionp (Lisp_Object); | ||
| 715 | LISP_INLINE bool (INTEGERP) (Lisp_Object); | ||
| 716 | LISP_INLINE bool (MARKERP) (Lisp_Object); | ||
| 717 | LISP_INLINE bool (MISCP) (Lisp_Object); | ||
| 718 | LISP_INLINE bool (NILP) (Lisp_Object); | ||
| 719 | LISP_INLINE bool OVERLAYP (Lisp_Object); | ||
| 720 | LISP_INLINE bool PROCESSP (Lisp_Object); | ||
| 721 | LISP_INLINE bool PSEUDOVECTORP (Lisp_Object, int); | ||
| 722 | LISP_INLINE bool SAVE_VALUEP (Lisp_Object); | ||
| 723 | LISP_INLINE void set_sub_char_table_contents (Lisp_Object, ptrdiff_t, | ||
| 724 | Lisp_Object); | ||
| 725 | LISP_INLINE bool STRINGP (Lisp_Object); | ||
| 726 | LISP_INLINE bool SUB_CHAR_TABLE_P (Lisp_Object); | ||
| 727 | LISP_INLINE bool SUBRP (Lisp_Object); | ||
| 728 | LISP_INLINE bool (SYMBOLP) (Lisp_Object); | ||
| 729 | LISP_INLINE bool (VECTORLIKEP) (Lisp_Object); | ||
| 730 | LISP_INLINE bool WINDOWP (Lisp_Object); | ||
| 731 | LISP_INLINE struct Lisp_Save_Value *XSAVE_VALUE (Lisp_Object); | ||
| 732 | |||
| 733 | /* Defined in chartab.c. */ | ||
| 734 | extern Lisp_Object char_table_ref (Lisp_Object, int); | ||
| 735 | extern void char_table_set (Lisp_Object, int, Lisp_Object); | ||
| 736 | extern int char_table_translate (Lisp_Object, int); | ||
| 737 | |||
| 738 | /* Defined in data.c. */ | ||
| 739 | extern Lisp_Object Qarrayp, Qbufferp, Qbuffer_or_string_p, Qchar_table_p; | ||
| 740 | extern Lisp_Object Qconsp, Qfloatp, Qintegerp, Qlambda, Qlistp, Qmarkerp, Qnil; | ||
| 741 | extern Lisp_Object Qnumberp, Qstringp, Qsymbolp, Qvectorp; | ||
| 742 | extern Lisp_Object Qvector_or_char_table_p, Qwholenump; | ||
| 743 | extern Lisp_Object Ffboundp (Lisp_Object); | ||
| 744 | extern _Noreturn Lisp_Object wrong_type_argument (Lisp_Object, Lisp_Object); | ||
| 745 | |||
| 746 | /* Defined in emacs.c. */ | ||
| 747 | extern bool initialized; | ||
| 748 | |||
| 749 | /* Defined in eval.c. */ | ||
| 750 | extern Lisp_Object Qautoload; | ||
| 751 | |||
| 752 | /* Defined in floatfns.c. */ | ||
| 753 | extern double extract_float (Lisp_Object); | ||
| 754 | |||
| 755 | /* Defined in process.c. */ | ||
| 756 | extern Lisp_Object Qprocessp; | ||
| 757 | |||
| 758 | /* Defined in window.c. */ | ||
| 759 | extern Lisp_Object Qwindowp; | ||
| 559 | 760 | ||
| 761 | /* Defined in xdisp.c. */ | ||
| 762 | extern Lisp_Object Qimage; | ||
| 560 | 763 | ||
| 764 | |||
| 561 | /* Extract a value or address from a Lisp_Object. */ | 765 | /* Extract a value or address from a Lisp_Object. */ |
| 562 | 766 | ||
| 563 | #define XCONS(a) (eassert (CONSP (a)), \ | 767 | LISP_MACRO_DEFUN (XCONS, struct Lisp_Cons *, (Lisp_Object a), (a)) |
| 564 | (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons)) | ||
| 565 | #define XVECTOR(a) (eassert (VECTORLIKEP (a)), \ | ||
| 566 | (struct Lisp_Vector *) XUNTAG (a, Lisp_Vectorlike)) | ||
| 567 | #define XSTRING(a) (eassert (STRINGP (a)), \ | ||
| 568 | (struct Lisp_String *) XUNTAG (a, Lisp_String)) | ||
| 569 | #define XSYMBOL(a) (eassert (SYMBOLP (a)), \ | ||
| 570 | (struct Lisp_Symbol *) XUNTAG (a, Lisp_Symbol)) | ||
| 571 | #define XFLOAT(a) (eassert (FLOATP (a)), \ | ||
| 572 | (struct Lisp_Float *) XUNTAG (a, Lisp_Float)) | ||
| 573 | 768 | ||
| 574 | /* Misc types. */ | 769 | LISP_INLINE struct Lisp_Vector * |
| 770 | XVECTOR (Lisp_Object a) | ||
| 771 | { | ||
| 772 | eassert (VECTORLIKEP (a)); | ||
| 773 | return XUNTAG (a, Lisp_Vectorlike); | ||
| 774 | } | ||
| 575 | 775 | ||
| 576 | #define XMISC(a) ((union Lisp_Misc *) XUNTAG (a, Lisp_Misc)) | 776 | LISP_INLINE struct Lisp_String * |
| 577 | #define XMISCANY(a) (eassert (MISCP (a)), &(XMISC (a)->u_any)) | 777 | XSTRING (Lisp_Object a) |
| 578 | #define XMISCTYPE(a) (XMISCANY (a)->type) | 778 | { |
| 579 | #define XMARKER(a) (eassert (MARKERP (a)), &(XMISC (a)->u_marker)) | 779 | eassert (STRINGP (a)); |
| 580 | #define XOVERLAY(a) (eassert (OVERLAYP (a)), &(XMISC (a)->u_overlay)) | 780 | return XUNTAG (a, Lisp_String); |
| 781 | } | ||
| 581 | 782 | ||
| 582 | /* Forwarding object types. */ | 783 | LISP_MACRO_DEFUN (XSYMBOL, struct Lisp_Symbol *, (Lisp_Object a), (a)) |
| 583 | 784 | ||
| 584 | #define XFWDTYPE(a) (a->u_intfwd.type) | 785 | LISP_INLINE struct Lisp_Float * |
| 585 | #define XINTFWD(a) (eassert (INTFWDP (a)), &((a)->u_intfwd)) | 786 | XFLOAT (Lisp_Object a) |
| 586 | #define XBOOLFWD(a) (eassert (BOOLFWDP (a)), &((a)->u_boolfwd)) | 787 | { |
| 587 | #define XOBJFWD(a) (eassert (OBJFWDP (a)), &((a)->u_objfwd)) | 788 | eassert (FLOATP (a)); |
| 588 | #define XBUFFER_OBJFWD(a) \ | 789 | return XUNTAG (a, Lisp_Float); |
| 589 | (eassert (BUFFER_OBJFWDP (a)), &((a)->u_buffer_objfwd)) | 790 | } |
| 590 | #define XKBOARD_OBJFWD(a) \ | ||
| 591 | (eassert (KBOARD_OBJFWDP (a)), &((a)->u_kboard_objfwd)) | ||
| 592 | 791 | ||
| 593 | /* Pseudovector types. */ | 792 | /* Pseudovector types. */ |
| 594 | struct Lisp_Process; | 793 | |
| 595 | LISP_INLINE Lisp_Object make_lisp_proc (struct Lisp_Process *p) | 794 | LISP_INLINE struct Lisp_Process * |
| 596 | { return make_lisp_ptr (p, Lisp_Vectorlike); } | 795 | XPROCESS (Lisp_Object a) |
| 597 | #define XPROCESS(a) (eassert (PROCESSP (a)), \ | 796 | { |
| 598 | (struct Lisp_Process *) XUNTAG (a, Lisp_Vectorlike)) | 797 | eassert (PROCESSP (a)); |
| 599 | #define XWINDOW(a) (eassert (WINDOWP (a)), \ | 798 | return XUNTAG (a, Lisp_Vectorlike); |
| 600 | (struct window *) XUNTAG (a, Lisp_Vectorlike)) | 799 | } |
| 601 | #define XTERMINAL(a) (eassert (TERMINALP (a)), \ | 800 | |
| 602 | (struct terminal *) XUNTAG (a, Lisp_Vectorlike)) | 801 | LISP_INLINE struct window * |
| 603 | #define XSUBR(a) (eassert (SUBRP (a)), \ | 802 | XWINDOW (Lisp_Object a) |
| 604 | (struct Lisp_Subr *) XUNTAG (a, Lisp_Vectorlike)) | 803 | { |
| 605 | #define XBUFFER(a) (eassert (BUFFERP (a)), \ | 804 | eassert (WINDOWP (a)); |
| 606 | (struct buffer *) XUNTAG (a, Lisp_Vectorlike)) | 805 | return XUNTAG (a, Lisp_Vectorlike); |
| 607 | #define XCHAR_TABLE(a) (eassert (CHAR_TABLE_P (a)), \ | 806 | } |
| 608 | (struct Lisp_Char_Table *) XUNTAG (a, Lisp_Vectorlike)) | 807 | |
| 609 | #define XSUB_CHAR_TABLE(a) (eassert (SUB_CHAR_TABLE_P (a)), \ | 808 | LISP_INLINE struct terminal * |
| 610 | ((struct Lisp_Sub_Char_Table *) \ | 809 | XTERMINAL (Lisp_Object a) |
| 611 | XUNTAG (a, Lisp_Vectorlike))) | 810 | { |
| 612 | #define XBOOL_VECTOR(a) (eassert (BOOL_VECTOR_P (a)), \ | 811 | return XUNTAG (a, Lisp_Vectorlike); |
| 613 | ((struct Lisp_Bool_Vector *) \ | 812 | } |
| 614 | XUNTAG (a, Lisp_Vectorlike))) | 813 | |
| 814 | LISP_INLINE struct Lisp_Subr * | ||
| 815 | XSUBR (Lisp_Object a) | ||
| 816 | { | ||
| 817 | eassert (SUBRP (a)); | ||
| 818 | return XUNTAG (a, Lisp_Vectorlike); | ||
| 819 | } | ||
| 820 | |||
| 821 | LISP_INLINE struct buffer * | ||
| 822 | XBUFFER (Lisp_Object a) | ||
| 823 | { | ||
| 824 | eassert (BUFFERP (a)); | ||
| 825 | return XUNTAG (a, Lisp_Vectorlike); | ||
| 826 | } | ||
| 827 | |||
| 828 | LISP_INLINE struct Lisp_Char_Table * | ||
| 829 | XCHAR_TABLE (Lisp_Object a) | ||
| 830 | { | ||
| 831 | eassert (CHAR_TABLE_P (a)); | ||
| 832 | return XUNTAG (a, Lisp_Vectorlike); | ||
| 833 | } | ||
| 834 | |||
| 835 | LISP_INLINE struct Lisp_Sub_Char_Table * | ||
| 836 | XSUB_CHAR_TABLE (Lisp_Object a) | ||
| 837 | { | ||
| 838 | eassert (SUB_CHAR_TABLE_P (a)); | ||
| 839 | return XUNTAG (a, Lisp_Vectorlike); | ||
| 840 | } | ||
| 841 | |||
| 842 | LISP_INLINE struct Lisp_Bool_Vector * | ||
| 843 | XBOOL_VECTOR (Lisp_Object a) | ||
| 844 | { | ||
| 845 | eassert (BOOL_VECTOR_P (a)); | ||
| 846 | return XUNTAG (a, Lisp_Vectorlike); | ||
| 847 | } | ||
| 615 | 848 | ||
| 616 | /* Construct a Lisp_Object from a value or address. */ | 849 | /* Construct a Lisp_Object from a value or address. */ |
| 617 | 850 | ||
| 851 | LISP_INLINE Lisp_Object | ||
| 852 | make_lisp_ptr (void *ptr, enum Lisp_Type type) | ||
| 853 | { | ||
| 854 | EMACS_UINT utype = type; | ||
| 855 | EMACS_UINT typebits = USE_LSB_TAG ? type : utype << VALBITS; | ||
| 856 | Lisp_Object a = XIL (typebits | (uintptr_t) ptr); | ||
| 857 | eassert (XTYPE (a) == type && XUNTAG (a, type) == ptr); | ||
| 858 | return a; | ||
| 859 | } | ||
| 860 | |||
| 861 | LISP_INLINE Lisp_Object | ||
| 862 | make_lisp_proc (struct Lisp_Process *p) | ||
| 863 | { | ||
| 864 | return make_lisp_ptr (p, Lisp_Vectorlike); | ||
| 865 | } | ||
| 866 | |||
| 618 | #define XSETINT(a, b) ((a) = make_number (b)) | 867 | #define XSETINT(a, b) ((a) = make_number (b)) |
| 868 | #define XSETFASTINT(a, b) ((a) = make_natnum (b)) | ||
| 619 | #define XSETCONS(a, b) ((a) = make_lisp_ptr (b, Lisp_Cons)) | 869 | #define XSETCONS(a, b) ((a) = make_lisp_ptr (b, Lisp_Cons)) |
| 620 | #define XSETVECTOR(a, b) ((a) = make_lisp_ptr (b, Lisp_Vectorlike)) | 870 | #define XSETVECTOR(a, b) ((a) = make_lisp_ptr (b, Lisp_Vectorlike)) |
| 621 | #define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String)) | 871 | #define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String)) |
| @@ -661,35 +911,10 @@ LISP_INLINE Lisp_Object make_lisp_proc (struct Lisp_Process *p) | |||
| 661 | #define XSETBOOL_VECTOR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR)) | 911 | #define XSETBOOL_VECTOR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR)) |
| 662 | #define XSETSUB_CHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_SUB_CHAR_TABLE)) | 912 | #define XSETSUB_CHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_SUB_CHAR_TABLE)) |
| 663 | 913 | ||
| 664 | /* Convenience macros for dealing with Lisp arrays. */ | ||
| 665 | |||
| 666 | #define AREF(ARRAY, IDX) XVECTOR ((ARRAY))->contents[IDX] | ||
| 667 | #define ASIZE(ARRAY) XVECTOR ((ARRAY))->header.size | ||
| 668 | #define ASET(ARRAY, IDX, VAL) \ | ||
| 669 | (eassert (0 <= (IDX) && (IDX) < ASIZE (ARRAY)), \ | ||
| 670 | XVECTOR (ARRAY)->contents[IDX] = (VAL)) | ||
| 671 | |||
| 672 | /* Convenience macros for dealing with Lisp strings. */ | ||
| 673 | |||
| 674 | #define SDATA(string) (XSTRING (string)->data + 0) | ||
| 675 | #define SREF(string, index) (SDATA (string)[index] + 0) | ||
| 676 | #define SSET(string, index, new) (SDATA (string)[index] = (new)) | ||
| 677 | #define SCHARS(string) (XSTRING (string)->size + 0) | ||
| 678 | #define SBYTES(string) (STRING_BYTES (XSTRING (string)) + 0) | ||
| 679 | |||
| 680 | /* Avoid "differ in sign" warnings. */ | ||
| 681 | #define SSDATA(x) ((char *) SDATA (x)) | ||
| 682 | |||
| 683 | #define STRING_SET_CHARS(string, newsize) \ | ||
| 684 | (XSTRING (string)->size = (newsize)) | ||
| 685 | |||
| 686 | #define STRING_COPYIN(string, index, new, count) \ | ||
| 687 | memcpy (SDATA (string) + index, new, count) | ||
| 688 | |||
| 689 | /* Type checking. */ | 914 | /* Type checking. */ |
| 690 | 915 | ||
| 691 | #define CHECK_TYPE(ok, Qxxxp, x) \ | 916 | LISP_MACRO_DEFUN_VOID (CHECK_TYPE, (int ok, Lisp_Object Qxxxp, Lisp_Object x), |
| 692 | do { if (!(ok)) wrong_type_argument (Qxxxp, (x)); } while (0) | 917 | (ok, Qxxxp, x)) |
| 693 | 918 | ||
| 694 | /* Deprecated and will be removed soon. */ | 919 | /* Deprecated and will be removed soon. */ |
| 695 | 920 | ||
| @@ -699,10 +924,6 @@ LISP_INLINE Lisp_Object make_lisp_proc (struct Lisp_Process *p) | |||
| 699 | 924 | ||
| 700 | typedef struct interval *INTERVAL; | 925 | typedef struct interval *INTERVAL; |
| 701 | 926 | ||
| 702 | /* Complain if object is not string or buffer type. */ | ||
| 703 | #define CHECK_STRING_OR_BUFFER(x) \ | ||
| 704 | CHECK_TYPE (STRINGP (x) || BUFFERP (x), Qbuffer_or_string_p, x) | ||
| 705 | |||
| 706 | struct Lisp_Cons | 927 | struct Lisp_Cons |
| 707 | { | 928 | { |
| 708 | /* Car of this cons cell. */ | 929 | /* Car of this cons cell. */ |
| @@ -719,64 +940,86 @@ struct Lisp_Cons | |||
| 719 | }; | 940 | }; |
| 720 | 941 | ||
| 721 | /* Take the car or cdr of something known to be a cons cell. */ | 942 | /* Take the car or cdr of something known to be a cons cell. */ |
| 722 | /* The _AS_LVALUE macros shouldn't be used outside of the minimal set | 943 | /* The _addr functions shouldn't be used outside of the minimal set |
| 723 | of code that has to know what a cons cell looks like. Other code not | 944 | of code that has to know what a cons cell looks like. Other code not |
| 724 | part of the basic lisp implementation should assume that the car and cdr | 945 | part of the basic lisp implementation should assume that the car and cdr |
| 725 | fields are not accessible as lvalues. (What if we want to switch to | 946 | fields are not accessible. (What if we want to switch to |
| 726 | a copying collector someday? Cached cons cell field addresses may be | 947 | a copying collector someday? Cached cons cell field addresses may be |
| 727 | invalidated at arbitrary points.) */ | 948 | invalidated at arbitrary points.) */ |
| 728 | #define XCAR_AS_LVALUE(c) (XCONS (c)->car) | 949 | LISP_INLINE Lisp_Object * |
| 729 | #define XCDR_AS_LVALUE(c) (XCONS (c)->u.cdr) | 950 | xcar_addr (Lisp_Object c) |
| 951 | { | ||
| 952 | return &XCONS (c)->car; | ||
| 953 | } | ||
| 954 | LISP_INLINE Lisp_Object * | ||
| 955 | xcdr_addr (Lisp_Object c) | ||
| 956 | { | ||
| 957 | return &XCONS (c)->u.cdr; | ||
| 958 | } | ||
| 730 | 959 | ||
| 731 | /* Use these from normal code. */ | 960 | /* Use these from normal code. */ |
| 732 | #define XCAR(c) LISP_MAKE_RVALUE (XCAR_AS_LVALUE (c)) | 961 | LISP_MACRO_DEFUN (XCAR, Lisp_Object, (Lisp_Object c), (c)) |
| 733 | #define XCDR(c) LISP_MAKE_RVALUE (XCDR_AS_LVALUE (c)) | 962 | LISP_MACRO_DEFUN (XCDR, Lisp_Object, (Lisp_Object c), (c)) |
| 734 | 963 | ||
| 735 | /* Use these to set the fields of a cons cell. | 964 | /* Use these to set the fields of a cons cell. |
| 736 | 965 | ||
| 737 | Note that both arguments may refer to the same object, so 'n' | 966 | Note that both arguments may refer to the same object, so 'n' |
| 738 | should not be read after 'c' is first modified. Also, neither | 967 | should not be read after 'c' is first modified. */ |
| 739 | argument should be evaluated more than once; side effects are | 968 | LISP_INLINE void |
| 740 | especially common in the second argument. */ | 969 | XSETCAR (Lisp_Object c, Lisp_Object n) |
| 741 | #define XSETCAR(c,n) (XCAR_AS_LVALUE (c) = (n)) | 970 | { |
| 742 | #define XSETCDR(c,n) (XCDR_AS_LVALUE (c) = (n)) | 971 | *xcar_addr (c) = n; |
| 972 | } | ||
| 973 | LISP_INLINE void | ||
| 974 | XSETCDR (Lisp_Object c, Lisp_Object n) | ||
| 975 | { | ||
| 976 | *xcdr_addr (c) = n; | ||
| 977 | } | ||
| 743 | 978 | ||
| 744 | /* Take the car or cdr of something whose type is not known. */ | 979 | /* Take the car or cdr of something whose type is not known. */ |
| 745 | #define CAR(c) \ | 980 | LISP_INLINE Lisp_Object |
| 746 | (CONSP ((c)) ? XCAR ((c)) \ | 981 | CAR (Lisp_Object c) |
| 747 | : NILP ((c)) ? Qnil \ | 982 | { |
| 748 | : wrong_type_argument (Qlistp, (c))) | 983 | return (CONSP (c) ? XCAR (c) |
| 749 | 984 | : NILP (c) ? Qnil | |
| 750 | #define CDR(c) \ | 985 | : wrong_type_argument (Qlistp, c)); |
| 751 | (CONSP ((c)) ? XCDR ((c)) \ | 986 | } |
| 752 | : NILP ((c)) ? Qnil \ | 987 | LISP_INLINE Lisp_Object |
| 753 | : wrong_type_argument (Qlistp, (c))) | 988 | CDR (Lisp_Object c) |
| 989 | { | ||
| 990 | return (CONSP (c) ? XCDR (c) | ||
| 991 | : NILP (c) ? Qnil | ||
| 992 | : wrong_type_argument (Qlistp, c)); | ||
| 993 | } | ||
| 754 | 994 | ||
| 755 | /* Take the car or cdr of something whose type is not known. */ | 995 | /* Take the car or cdr of something whose type is not known. */ |
| 756 | #define CAR_SAFE(c) \ | 996 | LISP_INLINE Lisp_Object |
| 757 | (CONSP ((c)) ? XCAR ((c)) : Qnil) | 997 | CAR_SAFE (Lisp_Object c) |
| 758 | 998 | { | |
| 759 | #define CDR_SAFE(c) \ | 999 | return CONSP (c) ? XCAR (c) : Qnil; |
| 760 | (CONSP ((c)) ? XCDR ((c)) : Qnil) | 1000 | } |
| 761 | 1001 | LISP_INLINE Lisp_Object | |
| 762 | /* True if STR is a multibyte string. */ | 1002 | CDR_SAFE (Lisp_Object c) |
| 763 | #define STRING_MULTIBYTE(STR) \ | 1003 | { |
| 764 | (XSTRING (STR)->size_byte >= 0) | 1004 | return CONSP (c) ? XCDR (c) : Qnil; |
| 765 | 1005 | } | |
| 766 | /* Return the length in bytes of STR. */ | ||
| 767 | |||
| 768 | #ifdef GC_CHECK_STRING_BYTES | ||
| 769 | |||
| 770 | struct Lisp_String; | ||
| 771 | extern ptrdiff_t string_bytes (struct Lisp_String *); | ||
| 772 | #define STRING_BYTES(S) string_bytes ((S)) | ||
| 773 | 1006 | ||
| 774 | #else /* not GC_CHECK_STRING_BYTES */ | 1007 | /* In a string or vector, the sign bit of the `size' is the gc mark bit. */ |
| 775 | 1008 | ||
| 776 | #define STRING_BYTES(STR) \ | 1009 | struct Lisp_String |
| 777 | ((STR)->size_byte < 0 ? (STR)->size : (STR)->size_byte) | 1010 | { |
| 1011 | ptrdiff_t size; | ||
| 1012 | ptrdiff_t size_byte; | ||
| 1013 | INTERVAL intervals; /* Text properties in this string. */ | ||
| 1014 | unsigned char *data; | ||
| 1015 | }; | ||
| 778 | 1016 | ||
| 779 | #endif /* not GC_CHECK_STRING_BYTES */ | 1017 | /* True if STR is a multibyte string. */ |
| 1018 | LISP_INLINE bool | ||
| 1019 | STRING_MULTIBYTE (Lisp_Object str) | ||
| 1020 | { | ||
| 1021 | return 0 <= XSTRING (str)->size_byte; | ||
| 1022 | } | ||
| 780 | 1023 | ||
| 781 | /* An upper bound on the number of bytes in a Lisp string, not | 1024 | /* An upper bound on the number of bytes in a Lisp string, not |
| 782 | counting the terminating null. This a tight enough bound to | 1025 | counting the terminating null. This a tight enough bound to |
| @@ -807,20 +1050,69 @@ extern ptrdiff_t string_bytes (struct Lisp_String *); | |||
| 807 | (STR) = empty_multibyte_string; \ | 1050 | (STR) = empty_multibyte_string; \ |
| 808 | else XSTRING (STR)->size_byte = XSTRING (STR)->size; } while (0) | 1051 | else XSTRING (STR)->size_byte = XSTRING (STR)->size; } while (0) |
| 809 | 1052 | ||
| 810 | /* In a string or vector, the sign bit of the `size' is the gc mark bit. */ | 1053 | /* Convenience functions for dealing with Lisp strings. */ |
| 811 | 1054 | ||
| 812 | struct Lisp_String | 1055 | LISP_INLINE unsigned char * |
| 813 | { | 1056 | SDATA (Lisp_Object string) |
| 814 | ptrdiff_t size; | 1057 | { |
| 815 | ptrdiff_t size_byte; | 1058 | return XSTRING (string)->data; |
| 816 | INTERVAL intervals; /* Text properties in this string. */ | 1059 | } |
| 817 | unsigned char *data; | 1060 | LISP_INLINE char * |
| 818 | }; | 1061 | SSDATA (Lisp_Object string) |
| 1062 | { | ||
| 1063 | /* Avoid "differ in sign" warnings. */ | ||
| 1064 | return (char *) SDATA (string); | ||
| 1065 | } | ||
| 1066 | LISP_INLINE unsigned char | ||
| 1067 | SREF (Lisp_Object string, ptrdiff_t index) | ||
| 1068 | { | ||
| 1069 | return SDATA (string)[index]; | ||
| 1070 | } | ||
| 1071 | LISP_INLINE void | ||
| 1072 | SSET (Lisp_Object string, ptrdiff_t index, unsigned char new) | ||
| 1073 | { | ||
| 1074 | SDATA (string)[index] = new; | ||
| 1075 | } | ||
| 1076 | LISP_INLINE ptrdiff_t | ||
| 1077 | SCHARS (Lisp_Object string) | ||
| 1078 | { | ||
| 1079 | return XSTRING (string)->size; | ||
| 1080 | } | ||
| 1081 | |||
| 1082 | #ifdef GC_CHECK_STRING_BYTES | ||
| 1083 | extern ptrdiff_t string_bytes (struct Lisp_String *); | ||
| 1084 | #endif | ||
| 1085 | LISP_INLINE ptrdiff_t | ||
| 1086 | STRING_BYTES (struct Lisp_String *s) | ||
| 1087 | { | ||
| 1088 | #ifdef GC_CHECK_STRING_BYTES | ||
| 1089 | return string_bytes (s); | ||
| 1090 | #else | ||
| 1091 | return s->size_byte < 0 ? s->size : s->size_byte; | ||
| 1092 | #endif | ||
| 1093 | } | ||
| 1094 | |||
| 1095 | LISP_INLINE ptrdiff_t | ||
| 1096 | SBYTES (Lisp_Object string) | ||
| 1097 | { | ||
| 1098 | return STRING_BYTES (XSTRING (string)); | ||
| 1099 | } | ||
| 1100 | LISP_INLINE void | ||
| 1101 | STRING_SET_CHARS (Lisp_Object string, ptrdiff_t newsize) | ||
| 1102 | { | ||
| 1103 | XSTRING (string)->size = newsize; | ||
| 1104 | } | ||
| 1105 | LISP_INLINE void | ||
| 1106 | STRING_COPYIN (Lisp_Object string, ptrdiff_t index, char const *new, | ||
| 1107 | ptrdiff_t count) | ||
| 1108 | { | ||
| 1109 | memcpy (SDATA (string) + index, new, count); | ||
| 1110 | } | ||
| 819 | 1111 | ||
| 820 | /* Header of vector-like objects. This documents the layout constraints on | 1112 | /* Header of vector-like objects. This documents the layout constraints on |
| 821 | vectors and pseudovectors (objects of PVEC_xxx subtype). It also prevents | 1113 | vectors and pseudovectors (objects of PVEC_xxx subtype). It also prevents |
| 822 | compilers from being fooled by Emacs's type punning: the XSETPSEUDOVECTOR | 1114 | compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR |
| 823 | and PSEUDOVECTORP macros cast their pointers to struct vectorlike_header *, | 1115 | and PSEUDOVECTORP cast their pointers to struct vectorlike_header *, |
| 824 | because when two such pointers potentially alias, a compiler won't | 1116 | because when two such pointers potentially alias, a compiler won't |
| 825 | incorrectly reorder loads and stores to their size fields. See | 1117 | incorrectly reorder loads and stores to their size fields. See |
| 826 | <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8546>. */ | 1118 | <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8546>. */ |
| @@ -853,7 +1145,7 @@ struct vectorlike_header | |||
| 853 | struct Lisp_Vector | 1145 | struct Lisp_Vector |
| 854 | { | 1146 | { |
| 855 | struct vectorlike_header header; | 1147 | struct vectorlike_header header; |
| 856 | Lisp_Object contents[1]; | 1148 | Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER]; |
| 857 | }; | 1149 | }; |
| 858 | 1150 | ||
| 859 | /* A boolvector is a kind of vectorlike, with contents are like a string. */ | 1151 | /* A boolvector is a kind of vectorlike, with contents are like a string. */ |
| @@ -866,7 +1158,7 @@ struct Lisp_Bool_Vector | |||
| 866 | /* This is the size in bits. */ | 1158 | /* This is the size in bits. */ |
| 867 | EMACS_INT size; | 1159 | EMACS_INT size; |
| 868 | /* This contains the actual bits, packed into bytes. */ | 1160 | /* This contains the actual bits, packed into bytes. */ |
| 869 | unsigned char data[1]; | 1161 | unsigned char data[FLEXIBLE_ARRAY_MEMBER]; |
| 870 | }; | 1162 | }; |
| 871 | 1163 | ||
| 872 | /* Some handy constants for calculating sizes | 1164 | /* Some handy constants for calculating sizes |
| @@ -879,6 +1171,42 @@ enum | |||
| 879 | word_size = sizeof (Lisp_Object) | 1171 | word_size = sizeof (Lisp_Object) |
| 880 | }; | 1172 | }; |
| 881 | 1173 | ||
| 1174 | /* Conveniences for dealing with Lisp arrays. */ | ||
| 1175 | |||
| 1176 | LISP_INLINE Lisp_Object | ||
| 1177 | AREF (Lisp_Object array, ptrdiff_t idx) | ||
| 1178 | { | ||
| 1179 | return XVECTOR (array)->contents[idx]; | ||
| 1180 | } | ||
| 1181 | |||
| 1182 | LISP_INLINE Lisp_Object * | ||
| 1183 | aref_addr (Lisp_Object array, ptrdiff_t idx) | ||
| 1184 | { | ||
| 1185 | return & XVECTOR (array)->contents[idx]; | ||
| 1186 | } | ||
| 1187 | |||
| 1188 | LISP_INLINE ptrdiff_t | ||
| 1189 | ASIZE (Lisp_Object array) | ||
| 1190 | { | ||
| 1191 | return XVECTOR (array)->header.size; | ||
| 1192 | } | ||
| 1193 | |||
| 1194 | LISP_INLINE void | ||
| 1195 | ASET (Lisp_Object array, ptrdiff_t idx, Lisp_Object val) | ||
| 1196 | { | ||
| 1197 | eassert (0 <= idx && idx < ASIZE (array)); | ||
| 1198 | XVECTOR (array)->contents[idx] = val; | ||
| 1199 | } | ||
| 1200 | |||
| 1201 | LISP_INLINE void | ||
| 1202 | gc_aset (Lisp_Object array, ptrdiff_t idx, Lisp_Object val) | ||
| 1203 | { | ||
| 1204 | /* Like ASET, but also can be used in the garbage collector: | ||
| 1205 | sweep_weak_table calls set_hash_key etc. while the table is marked. */ | ||
| 1206 | eassert (0 <= idx && idx < (ASIZE (array) & ~ARRAY_MARK_FLAG)); | ||
| 1207 | XVECTOR (array)->contents[idx] = val; | ||
| 1208 | } | ||
| 1209 | |||
| 882 | /* If a struct is made to look like a vector, this macro returns the length | 1210 | /* If a struct is made to look like a vector, this macro returns the length |
| 883 | of the shortest vector that would hold that struct. */ | 1211 | of the shortest vector that would hold that struct. */ |
| 884 | 1212 | ||
| @@ -892,43 +1220,6 @@ enum | |||
| 892 | #define PSEUDOVECSIZE(type, nonlispfield) \ | 1220 | #define PSEUDOVECSIZE(type, nonlispfield) \ |
| 893 | ((offsetof (type, nonlispfield) - header_size) / word_size) | 1221 | ((offsetof (type, nonlispfield) - header_size) / word_size) |
| 894 | 1222 | ||
| 895 | /* A char-table is a kind of vectorlike, with contents are like a | ||
| 896 | vector but with a few other slots. For some purposes, it makes | ||
| 897 | sense to handle a char-table with type struct Lisp_Vector. An | ||
| 898 | element of a char table can be any Lisp objects, but if it is a sub | ||
| 899 | char-table, we treat it a table that contains information of a | ||
| 900 | specific range of characters. A sub char-table has the same | ||
| 901 | structure as a vector. A sub char table appears only in an element | ||
| 902 | of a char-table, and there's no way to access it directly from | ||
| 903 | Emacs Lisp program. */ | ||
| 904 | |||
| 905 | #ifdef __GNUC__ | ||
| 906 | |||
| 907 | #define CHAR_TABLE_REF_ASCII(CT, IDX) \ | ||
| 908 | ({struct Lisp_Char_Table *_tbl = NULL; \ | ||
| 909 | Lisp_Object _val; \ | ||
| 910 | do { \ | ||
| 911 | _tbl = _tbl ? XCHAR_TABLE (_tbl->parent) : XCHAR_TABLE (CT); \ | ||
| 912 | _val = (! SUB_CHAR_TABLE_P (_tbl->ascii) ? _tbl->ascii \ | ||
| 913 | : XSUB_CHAR_TABLE (_tbl->ascii)->contents[IDX]); \ | ||
| 914 | if (NILP (_val)) \ | ||
| 915 | _val = _tbl->defalt; \ | ||
| 916 | } while (NILP (_val) && ! NILP (_tbl->parent)); \ | ||
| 917 | _val; }) | ||
| 918 | |||
| 919 | #else /* not __GNUC__ */ | ||
| 920 | |||
| 921 | #define CHAR_TABLE_REF_ASCII(CT, IDX) \ | ||
| 922 | (! NILP (XCHAR_TABLE (CT)->ascii) \ | ||
| 923 | ? (! SUB_CHAR_TABLE_P (XCHAR_TABLE (CT)->ascii) \ | ||
| 924 | ? XCHAR_TABLE (CT)->ascii \ | ||
| 925 | : ! NILP (XSUB_CHAR_TABLE (XCHAR_TABLE (CT)->ascii)->contents[IDX]) \ | ||
| 926 | ? XSUB_CHAR_TABLE (XCHAR_TABLE (CT)->ascii)->contents[IDX] \ | ||
| 927 | : char_table_ref ((CT), (IDX))) \ | ||
| 928 | : char_table_ref ((CT), (IDX))) | ||
| 929 | |||
| 930 | #endif /* not __GNUC__ */ | ||
| 931 | |||
| 932 | /* Compute A OP B, using the unsigned comparison operator OP. A and B | 1223 | /* Compute A OP B, using the unsigned comparison operator OP. A and B |
| 933 | should be integer expressions. This is not the same as | 1224 | should be integer expressions. This is not the same as |
| 934 | mathematical comparison; for example, UNSIGNED_CMP (0, <, -1) | 1225 | mathematical comparison; for example, UNSIGNED_CMP (0, <, -1) |
| @@ -942,18 +1233,15 @@ enum | |||
| 942 | /* Nonzero iff C is an ASCII character. */ | 1233 | /* Nonzero iff C is an ASCII character. */ |
| 943 | #define ASCII_CHAR_P(c) UNSIGNED_CMP (c, <, 0x80) | 1234 | #define ASCII_CHAR_P(c) UNSIGNED_CMP (c, <, 0x80) |
| 944 | 1235 | ||
| 945 | /* Almost equivalent to Faref (CT, IDX) with optimization for ASCII | 1236 | /* A char-table is a kind of vectorlike, with contents are like a |
| 946 | characters. Do not check validity of CT. */ | 1237 | vector but with a few other slots. For some purposes, it makes |
| 947 | #define CHAR_TABLE_REF(CT, IDX) \ | 1238 | sense to handle a char-table with type struct Lisp_Vector. An |
| 948 | (ASCII_CHAR_P (IDX) ? CHAR_TABLE_REF_ASCII ((CT), (IDX)) \ | 1239 | element of a char table can be any Lisp objects, but if it is a sub |
| 949 | : char_table_ref ((CT), (IDX))) | 1240 | char-table, we treat it a table that contains information of a |
| 950 | 1241 | specific range of characters. A sub char-table has the same | |
| 951 | /* Equivalent to Faset (CT, IDX, VAL) with optimization for ASCII and | 1242 | structure as a vector. A sub char table appears only in an element |
| 952 | 8-bit European characters. Do not check validity of CT. */ | 1243 | of a char-table, and there's no way to access it directly from |
| 953 | #define CHAR_TABLE_SET(CT, IDX, VAL) \ | 1244 | Emacs Lisp program. */ |
| 954 | (ASCII_CHAR_P (IDX) && SUB_CHAR_TABLE_P (XCHAR_TABLE (CT)->ascii) \ | ||
| 955 | ? set_sub_char_table_contents (XCHAR_TABLE (CT)->ascii, IDX, VAL) \ | ||
| 956 | : char_table_set (CT, IDX, VAL)) | ||
| 957 | 1245 | ||
| 958 | enum CHARTAB_SIZE_BITS | 1246 | enum CHARTAB_SIZE_BITS |
| 959 | { | 1247 | { |
| @@ -993,7 +1281,7 @@ struct Lisp_Char_Table | |||
| 993 | Lisp_Object contents[(1 << CHARTAB_SIZE_BITS_0)]; | 1281 | Lisp_Object contents[(1 << CHARTAB_SIZE_BITS_0)]; |
| 994 | 1282 | ||
| 995 | /* These hold additional data. It is a vector. */ | 1283 | /* These hold additional data. It is a vector. */ |
| 996 | Lisp_Object extras[1]; | 1284 | Lisp_Object extras[FLEXIBLE_ARRAY_MEMBER]; |
| 997 | }; | 1285 | }; |
| 998 | 1286 | ||
| 999 | struct Lisp_Sub_Char_Table | 1287 | struct Lisp_Sub_Char_Table |
| @@ -1014,9 +1302,48 @@ struct Lisp_Sub_Char_Table | |||
| 1014 | Lisp_Object min_char; | 1302 | Lisp_Object min_char; |
| 1015 | 1303 | ||
| 1016 | /* Use set_sub_char_table_contents to set this. */ | 1304 | /* Use set_sub_char_table_contents to set this. */ |
| 1017 | Lisp_Object contents[1]; | 1305 | Lisp_Object contents[FLEXIBLE_ARRAY_MEMBER]; |
| 1018 | }; | 1306 | }; |
| 1019 | 1307 | ||
| 1308 | LISP_INLINE Lisp_Object | ||
| 1309 | CHAR_TABLE_REF_ASCII (Lisp_Object ct, ptrdiff_t idx) | ||
| 1310 | { | ||
| 1311 | struct Lisp_Char_Table *tbl = NULL; | ||
| 1312 | Lisp_Object val; | ||
| 1313 | do | ||
| 1314 | { | ||
| 1315 | tbl = tbl ? XCHAR_TABLE (tbl->parent) : XCHAR_TABLE (ct); | ||
| 1316 | val = (! SUB_CHAR_TABLE_P (tbl->ascii) ? tbl->ascii | ||
| 1317 | : XSUB_CHAR_TABLE (tbl->ascii)->contents[idx]); | ||
| 1318 | if (NILP (val)) | ||
| 1319 | val = tbl->defalt; | ||
| 1320 | } | ||
| 1321 | while (NILP (val) && ! NILP (tbl->parent)); | ||
| 1322 | |||
| 1323 | return val; | ||
| 1324 | } | ||
| 1325 | |||
| 1326 | /* Almost equivalent to Faref (CT, IDX) with optimization for ASCII | ||
| 1327 | characters. Do not check validity of CT. */ | ||
| 1328 | LISP_INLINE Lisp_Object | ||
| 1329 | CHAR_TABLE_REF (Lisp_Object ct, int idx) | ||
| 1330 | { | ||
| 1331 | return (ASCII_CHAR_P (idx) | ||
| 1332 | ? CHAR_TABLE_REF_ASCII (ct, idx) | ||
| 1333 | : char_table_ref (ct, idx)); | ||
| 1334 | } | ||
| 1335 | |||
| 1336 | /* Equivalent to Faset (CT, IDX, VAL) with optimization for ASCII and | ||
| 1337 | 8-bit European characters. Do not check validity of CT. */ | ||
| 1338 | LISP_INLINE void | ||
| 1339 | CHAR_TABLE_SET (Lisp_Object ct, int idx, Lisp_Object val) | ||
| 1340 | { | ||
| 1341 | if (ASCII_CHAR_P (idx) && SUB_CHAR_TABLE_P (XCHAR_TABLE (ct)->ascii)) | ||
| 1342 | set_sub_char_table_contents (XCHAR_TABLE (ct)->ascii, idx, val); | ||
| 1343 | else | ||
| 1344 | char_table_set (ct, idx, val); | ||
| 1345 | } | ||
| 1346 | |||
| 1020 | /* This structure describes a built-in function. | 1347 | /* This structure describes a built-in function. |
| 1021 | It is generated by the DEFUN macro only. | 1348 | It is generated by the DEFUN macro only. |
| 1022 | defsubr makes it into a Lisp object. */ | 1349 | defsubr makes it into a Lisp object. */ |
| @@ -1048,13 +1375,17 @@ struct Lisp_Subr | |||
| 1048 | slots. */ | 1375 | slots. */ |
| 1049 | enum CHAR_TABLE_STANDARD_SLOTS | 1376 | enum CHAR_TABLE_STANDARD_SLOTS |
| 1050 | { | 1377 | { |
| 1051 | CHAR_TABLE_STANDARD_SLOTS = VECSIZE (struct Lisp_Char_Table) - 1 | 1378 | CHAR_TABLE_STANDARD_SLOTS = PSEUDOVECSIZE (struct Lisp_Char_Table, extras) |
| 1052 | }; | 1379 | }; |
| 1053 | 1380 | ||
| 1054 | /* Return the number of "extra" slots in the char table CT. */ | 1381 | /* Return the number of "extra" slots in the char table CT. */ |
| 1055 | 1382 | ||
| 1056 | #define CHAR_TABLE_EXTRA_SLOTS(CT) \ | 1383 | LISP_INLINE int |
| 1057 | (((CT)->header.size & PSEUDOVECTOR_SIZE_MASK) - CHAR_TABLE_STANDARD_SLOTS) | 1384 | CHAR_TABLE_EXTRA_SLOTS (struct Lisp_Char_Table *ct) |
| 1385 | { | ||
| 1386 | return ((ct->header.size & PSEUDOVECTOR_SIZE_MASK) | ||
| 1387 | - CHAR_TABLE_STANDARD_SLOTS); | ||
| 1388 | } | ||
| 1058 | 1389 | ||
| 1059 | 1390 | ||
| 1060 | /*********************************************************************** | 1391 | /*********************************************************************** |
| @@ -1126,40 +1457,76 @@ struct Lisp_Symbol | |||
| 1126 | 1457 | ||
| 1127 | /* Value is name of symbol. */ | 1458 | /* Value is name of symbol. */ |
| 1128 | 1459 | ||
| 1129 | #define SYMBOL_VAL(sym) \ | 1460 | LISP_MACRO_DEFUN (SYMBOL_VAL, Lisp_Object, (struct Lisp_Symbol *sym), (sym)) |
| 1130 | (eassert ((sym)->redirect == SYMBOL_PLAINVAL), sym->val.value) | ||
| 1131 | #define SYMBOL_ALIAS(sym) \ | ||
| 1132 | (eassert ((sym)->redirect == SYMBOL_VARALIAS), (sym)->val.alias) | ||
| 1133 | #define SYMBOL_BLV(sym) \ | ||
| 1134 | (eassert ((sym)->redirect == SYMBOL_LOCALIZED), (sym)->val.blv) | ||
| 1135 | #define SYMBOL_FWD(sym) \ | ||
| 1136 | (eassert ((sym)->redirect == SYMBOL_FORWARDED), (sym)->val.fwd) | ||
| 1137 | #define SET_SYMBOL_VAL(sym, v) \ | ||
| 1138 | (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value = (v)) | ||
| 1139 | #define SET_SYMBOL_ALIAS(sym, v) \ | ||
| 1140 | (eassert ((sym)->redirect == SYMBOL_VARALIAS), (sym)->val.alias = (v)) | ||
| 1141 | #define SET_SYMBOL_BLV(sym, v) \ | ||
| 1142 | (eassert ((sym)->redirect == SYMBOL_LOCALIZED), (sym)->val.blv = (v)) | ||
| 1143 | #define SET_SYMBOL_FWD(sym, v) \ | ||
| 1144 | (eassert ((sym)->redirect == SYMBOL_FORWARDED), (sym)->val.fwd = (v)) | ||
| 1145 | 1461 | ||
| 1146 | #define SYMBOL_NAME(sym) XSYMBOL (sym)->name | 1462 | LISP_INLINE struct Lisp_Symbol * |
| 1463 | SYMBOL_ALIAS (struct Lisp_Symbol *sym) | ||
| 1464 | { | ||
| 1465 | eassert (sym->redirect == SYMBOL_VARALIAS); | ||
| 1466 | return sym->val.alias; | ||
| 1467 | } | ||
| 1468 | LISP_INLINE struct Lisp_Buffer_Local_Value * | ||
| 1469 | SYMBOL_BLV (struct Lisp_Symbol *sym) | ||
| 1470 | { | ||
| 1471 | eassert (sym->redirect == SYMBOL_LOCALIZED); | ||
| 1472 | return sym->val.blv; | ||
| 1473 | } | ||
| 1474 | LISP_INLINE union Lisp_Fwd * | ||
| 1475 | SYMBOL_FWD (struct Lisp_Symbol *sym) | ||
| 1476 | { | ||
| 1477 | eassert (sym->redirect == SYMBOL_FORWARDED); | ||
| 1478 | return sym->val.fwd; | ||
| 1479 | } | ||
| 1147 | 1480 | ||
| 1148 | /* Value is non-zero if SYM is an interned symbol. */ | 1481 | LISP_MACRO_DEFUN_VOID (SET_SYMBOL_VAL, |
| 1482 | (struct Lisp_Symbol *sym, Lisp_Object v), (sym, v)) | ||
| 1149 | 1483 | ||
| 1150 | #define SYMBOL_INTERNED_P(sym) \ | 1484 | LISP_INLINE void |
| 1151 | (XSYMBOL (sym)->interned != SYMBOL_UNINTERNED) | 1485 | SET_SYMBOL_ALIAS (struct Lisp_Symbol *sym, struct Lisp_Symbol *v) |
| 1486 | { | ||
| 1487 | eassert (sym->redirect == SYMBOL_VARALIAS); | ||
| 1488 | sym->val.alias = v; | ||
| 1489 | } | ||
| 1490 | LISP_INLINE void | ||
| 1491 | SET_SYMBOL_BLV (struct Lisp_Symbol *sym, struct Lisp_Buffer_Local_Value *v) | ||
| 1492 | { | ||
| 1493 | eassert (sym->redirect == SYMBOL_LOCALIZED); | ||
| 1494 | sym->val.blv = v; | ||
| 1495 | } | ||
| 1496 | LISP_INLINE void | ||
| 1497 | SET_SYMBOL_FWD (struct Lisp_Symbol *sym, union Lisp_Fwd *v) | ||
| 1498 | { | ||
| 1499 | eassert (sym->redirect == SYMBOL_FORWARDED); | ||
| 1500 | sym->val.fwd = v; | ||
| 1501 | } | ||
| 1502 | |||
| 1503 | LISP_INLINE Lisp_Object | ||
| 1504 | SYMBOL_NAME (Lisp_Object sym) | ||
| 1505 | { | ||
| 1506 | return XSYMBOL (sym)->name; | ||
| 1507 | } | ||
| 1508 | |||
| 1509 | /* Value is true if SYM is an interned symbol. */ | ||
| 1152 | 1510 | ||
| 1153 | /* Value is non-zero if SYM is interned in initial_obarray. */ | 1511 | LISP_INLINE bool |
| 1512 | SYMBOL_INTERNED_P (Lisp_Object sym) | ||
| 1513 | { | ||
| 1514 | return XSYMBOL (sym)->interned != SYMBOL_UNINTERNED; | ||
| 1515 | } | ||
| 1154 | 1516 | ||
| 1155 | #define SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P(sym) \ | 1517 | /* Value is true if SYM is interned in initial_obarray. */ |
| 1156 | (XSYMBOL (sym)->interned == SYMBOL_INTERNED_IN_INITIAL_OBARRAY) | 1518 | |
| 1519 | LISP_INLINE bool | ||
| 1520 | SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (Lisp_Object sym) | ||
| 1521 | { | ||
| 1522 | return XSYMBOL (sym)->interned == SYMBOL_INTERNED_IN_INITIAL_OBARRAY; | ||
| 1523 | } | ||
| 1157 | 1524 | ||
| 1158 | /* Value is non-zero if symbol is considered a constant, i.e. its | 1525 | /* Value is non-zero if symbol is considered a constant, i.e. its |
| 1159 | value cannot be changed (there is an exception for keyword symbols, | 1526 | value cannot be changed (there is an exception for keyword symbols, |
| 1160 | whose value can be set to the keyword symbol itself). */ | 1527 | whose value can be set to the keyword symbol itself). */ |
| 1161 | 1528 | ||
| 1162 | #define SYMBOL_CONSTANT_P(sym) XSYMBOL (sym)->constant | 1529 | LISP_MACRO_DEFUN (SYMBOL_CONSTANT_P, int, (Lisp_Object sym), (sym)) |
| 1163 | 1530 | ||
| 1164 | #define DEFSYM(sym, name) \ | 1531 | #define DEFSYM(sym, name) \ |
| 1165 | do { (sym) = intern_c_string ((name)); staticpro (&(sym)); } while (0) | 1532 | do { (sym) = intern_c_string ((name)); staticpro (&(sym)); } while (0) |
| @@ -1245,42 +1612,64 @@ struct Lisp_Hash_Table | |||
| 1245 | }; | 1612 | }; |
| 1246 | 1613 | ||
| 1247 | 1614 | ||
| 1248 | #define XHASH_TABLE(OBJ) \ | 1615 | LISP_INLINE struct Lisp_Hash_Table * |
| 1249 | ((struct Lisp_Hash_Table *) XUNTAG (OBJ, Lisp_Vectorlike)) | 1616 | XHASH_TABLE (Lisp_Object a) |
| 1617 | { | ||
| 1618 | return XUNTAG (a, Lisp_Vectorlike); | ||
| 1619 | } | ||
| 1250 | 1620 | ||
| 1251 | #define XSET_HASH_TABLE(VAR, PTR) \ | 1621 | #define XSET_HASH_TABLE(VAR, PTR) \ |
| 1252 | (XSETPSEUDOVECTOR (VAR, PTR, PVEC_HASH_TABLE)) | 1622 | (XSETPSEUDOVECTOR (VAR, PTR, PVEC_HASH_TABLE)) |
| 1253 | 1623 | ||
| 1254 | #define HASH_TABLE_P(OBJ) PSEUDOVECTORP (OBJ, PVEC_HASH_TABLE) | 1624 | LISP_INLINE bool |
| 1255 | 1625 | HASH_TABLE_P (Lisp_Object a) | |
| 1256 | #define CHECK_HASH_TABLE(x) \ | 1626 | { |
| 1257 | CHECK_TYPE (HASH_TABLE_P (x), Qhash_table_p, x) | 1627 | return PSEUDOVECTORP (a, PVEC_HASH_TABLE); |
| 1628 | } | ||
| 1258 | 1629 | ||
| 1259 | /* Value is the key part of entry IDX in hash table H. */ | 1630 | /* Value is the key part of entry IDX in hash table H. */ |
| 1260 | 1631 | LISP_INLINE Lisp_Object | |
| 1261 | #define HASH_KEY(H, IDX) AREF ((H)->key_and_value, 2 * (IDX)) | 1632 | HASH_KEY (struct Lisp_Hash_Table *h, ptrdiff_t idx) |
| 1633 | { | ||
| 1634 | return AREF (h->key_and_value, 2 * idx); | ||
| 1635 | } | ||
| 1262 | 1636 | ||
| 1263 | /* Value is the value part of entry IDX in hash table H. */ | 1637 | /* Value is the value part of entry IDX in hash table H. */ |
| 1264 | 1638 | LISP_INLINE Lisp_Object | |
| 1265 | #define HASH_VALUE(H, IDX) AREF ((H)->key_and_value, 2 * (IDX) + 1) | 1639 | HASH_VALUE (struct Lisp_Hash_Table *h, ptrdiff_t idx) |
| 1640 | { | ||
| 1641 | return AREF (h->key_and_value, 2 * idx + 1); | ||
| 1642 | } | ||
| 1266 | 1643 | ||
| 1267 | /* Value is the index of the next entry following the one at IDX | 1644 | /* Value is the index of the next entry following the one at IDX |
| 1268 | in hash table H. */ | 1645 | in hash table H. */ |
| 1269 | 1646 | LISP_INLINE Lisp_Object | |
| 1270 | #define HASH_NEXT(H, IDX) AREF ((H)->next, (IDX)) | 1647 | HASH_NEXT (struct Lisp_Hash_Table *h, ptrdiff_t idx) |
| 1648 | { | ||
| 1649 | return AREF (h->next, idx); | ||
| 1650 | } | ||
| 1271 | 1651 | ||
| 1272 | /* Value is the hash code computed for entry IDX in hash table H. */ | 1652 | /* Value is the hash code computed for entry IDX in hash table H. */ |
| 1273 | 1653 | LISP_INLINE Lisp_Object | |
| 1274 | #define HASH_HASH(H, IDX) AREF ((H)->hash, (IDX)) | 1654 | HASH_HASH (struct Lisp_Hash_Table *h, ptrdiff_t idx) |
| 1655 | { | ||
| 1656 | return AREF (h->hash, idx); | ||
| 1657 | } | ||
| 1275 | 1658 | ||
| 1276 | /* Value is the index of the element in hash table H that is the | 1659 | /* Value is the index of the element in hash table H that is the |
| 1277 | start of the collision list at index IDX in the index vector of H. */ | 1660 | start of the collision list at index IDX in the index vector of H. */ |
| 1278 | 1661 | LISP_INLINE Lisp_Object | |
| 1279 | #define HASH_INDEX(H, IDX) AREF ((H)->index, (IDX)) | 1662 | HASH_INDEX (struct Lisp_Hash_Table *h, ptrdiff_t idx) |
| 1663 | { | ||
| 1664 | return AREF (h->index, idx); | ||
| 1665 | } | ||
| 1280 | 1666 | ||
| 1281 | /* Value is the size of hash table H. */ | 1667 | /* Value is the size of hash table H. */ |
| 1282 | 1668 | LISP_INLINE ptrdiff_t | |
| 1283 | #define HASH_TABLE_SIZE(H) ASIZE ((H)->next) | 1669 | HASH_TABLE_SIZE (struct Lisp_Hash_Table *h) |
| 1670 | { | ||
| 1671 | return ASIZE (h->next); | ||
| 1672 | } | ||
| 1284 | 1673 | ||
| 1285 | /* Default size for hash tables if not specified. */ | 1674 | /* Default size for hash tables if not specified. */ |
| 1286 | 1675 | ||
| @@ -1393,12 +1782,13 @@ enum | |||
| 1393 | { | 1782 | { |
| 1394 | SAVE_UNUSED, | 1783 | SAVE_UNUSED, |
| 1395 | SAVE_INTEGER, | 1784 | SAVE_INTEGER, |
| 1785 | SAVE_FUNCPOINTER, | ||
| 1396 | SAVE_POINTER, | 1786 | SAVE_POINTER, |
| 1397 | SAVE_OBJECT | 1787 | SAVE_OBJECT |
| 1398 | }; | 1788 | }; |
| 1399 | 1789 | ||
| 1400 | /* Number of bits needed to store one of the above values. */ | 1790 | /* Number of bits needed to store one of the above values. */ |
| 1401 | enum { SAVE_SLOT_BITS = 2 }; | 1791 | enum { SAVE_SLOT_BITS = 3 }; |
| 1402 | 1792 | ||
| 1403 | /* Number of slots in a save value where save_type is nonzero. */ | 1793 | /* Number of slots in a save value where save_type is nonzero. */ |
| 1404 | enum { SAVE_VALUE_SLOTS = 4 }; | 1794 | enum { SAVE_VALUE_SLOTS = 4 }; |
| @@ -1419,8 +1809,8 @@ enum Lisp_Save_Type | |||
| 1419 | SAVE_TYPE_PTR_INT = SAVE_POINTER + (SAVE_INTEGER << SAVE_SLOT_BITS), | 1809 | SAVE_TYPE_PTR_INT = SAVE_POINTER + (SAVE_INTEGER << SAVE_SLOT_BITS), |
| 1420 | SAVE_TYPE_PTR_OBJ = SAVE_POINTER + (SAVE_OBJECT << SAVE_SLOT_BITS), | 1810 | SAVE_TYPE_PTR_OBJ = SAVE_POINTER + (SAVE_OBJECT << SAVE_SLOT_BITS), |
| 1421 | SAVE_TYPE_PTR_PTR = SAVE_POINTER + (SAVE_POINTER << SAVE_SLOT_BITS), | 1811 | SAVE_TYPE_PTR_PTR = SAVE_POINTER + (SAVE_POINTER << SAVE_SLOT_BITS), |
| 1422 | SAVE_TYPE_PTR_PTR_OBJ | 1812 | SAVE_TYPE_FUNCPTR_PTR_OBJ |
| 1423 | = SAVE_POINTER + (SAVE_TYPE_PTR_OBJ << SAVE_SLOT_BITS), | 1813 | = SAVE_FUNCPOINTER + (SAVE_TYPE_PTR_OBJ << SAVE_SLOT_BITS), |
| 1424 | 1814 | ||
| 1425 | /* This has an extra bit indicating it's raw memory. */ | 1815 | /* This has an extra bit indicating it's raw memory. */ |
| 1426 | SAVE_TYPE_MEMORY = SAVE_TYPE_PTR_INT + (1 << (SAVE_TYPE_BITS - 1)) | 1816 | SAVE_TYPE_MEMORY = SAVE_TYPE_PTR_INT + (1 << (SAVE_TYPE_BITS - 1)) |
| @@ -1429,9 +1819,9 @@ enum Lisp_Save_Type | |||
| 1429 | /* Special object used to hold a different values for later use. | 1819 | /* Special object used to hold a different values for later use. |
| 1430 | 1820 | ||
| 1431 | This is mostly used to package C integers and pointers to call | 1821 | This is mostly used to package C integers and pointers to call |
| 1432 | record_unwind_protect. Typical task is to pass just one C pointer | 1822 | record_unwind_protect. A typical task is to pass just one C object |
| 1433 | to unwind function. You should pack pointer with make_save_pointer | 1823 | pointer to the unwind function. You should pack an object pointer with |
| 1434 | and then get it back with XSAVE_POINTER, e.g.: | 1824 | make_save_pointer and then get it back with XSAVE_POINTER, e.g.: |
| 1435 | 1825 | ||
| 1436 | ... | 1826 | ... |
| 1437 | struct my_data *md = get_my_data (); | 1827 | struct my_data *md = get_my_data (); |
| @@ -1444,10 +1834,10 @@ enum Lisp_Save_Type | |||
| 1444 | ... | 1834 | ... |
| 1445 | } | 1835 | } |
| 1446 | 1836 | ||
| 1447 | If yon need to pass more than just one C pointer, you should | 1837 | If you need to pass something else you can use make_save_value, |
| 1448 | use make_save_value. This function allows you to pack up to | 1838 | which allows you to pack up to SAVE_VALUE_SLOTS integers, pointers, |
| 1449 | SAVE_VALUE_SLOTS integers, pointers or Lisp_Objects and | 1839 | function pointers or Lisp_Objects and conveniently get them back |
| 1450 | conveniently get them back with XSAVE_POINTER, XSAVE_INTEGER and | 1840 | with XSAVE_INTEGER, XSAVE_POINTER, XSAVE_FUNCPOINTER, and |
| 1451 | XSAVE_OBJECT macros: | 1841 | XSAVE_OBJECT macros: |
| 1452 | 1842 | ||
| 1453 | ... | 1843 | ... |
| @@ -1470,6 +1860,8 @@ enum Lisp_Save_Type | |||
| 1470 | or XSAVE_OBJECT (arg, 0) are wrong because nothing was saved in slot 2 and | 1860 | or XSAVE_OBJECT (arg, 0) are wrong because nothing was saved in slot 2 and |
| 1471 | Lisp_Object was saved in slot 1 of ARG. */ | 1861 | Lisp_Object was saved in slot 1 of ARG. */ |
| 1472 | 1862 | ||
| 1863 | typedef void (*voidfuncptr) (void); | ||
| 1864 | |||
| 1473 | struct Lisp_Save_Value | 1865 | struct Lisp_Save_Value |
| 1474 | { | 1866 | { |
| 1475 | ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Save_Value */ | 1867 | ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Save_Value */ |
| @@ -1485,11 +1877,65 @@ struct Lisp_Save_Value | |||
| 1485 | ENUM_BF (Lisp_Save_Type) save_type : SAVE_TYPE_BITS; | 1877 | ENUM_BF (Lisp_Save_Type) save_type : SAVE_TYPE_BITS; |
| 1486 | union { | 1878 | union { |
| 1487 | void *pointer; | 1879 | void *pointer; |
| 1880 | voidfuncptr funcpointer; | ||
| 1488 | ptrdiff_t integer; | 1881 | ptrdiff_t integer; |
| 1489 | Lisp_Object object; | 1882 | Lisp_Object object; |
| 1490 | } data[SAVE_VALUE_SLOTS]; | 1883 | } data[SAVE_VALUE_SLOTS]; |
| 1491 | }; | 1884 | }; |
| 1492 | 1885 | ||
| 1886 | /* Return the type of V's Nth saved value. */ | ||
| 1887 | LISP_INLINE int | ||
| 1888 | save_type (struct Lisp_Save_Value *v, int n) | ||
| 1889 | { | ||
| 1890 | eassert (0 <= n && n < SAVE_VALUE_SLOTS); | ||
| 1891 | return (v->save_type >> (SAVE_SLOT_BITS * n) & ((1 << SAVE_SLOT_BITS) - 1)); | ||
| 1892 | } | ||
| 1893 | |||
| 1894 | /* Get and set the Nth saved pointer. */ | ||
| 1895 | |||
| 1896 | LISP_INLINE void * | ||
| 1897 | XSAVE_POINTER (Lisp_Object obj, int n) | ||
| 1898 | { | ||
| 1899 | eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_POINTER); | ||
| 1900 | return XSAVE_VALUE (obj)->data[n].pointer; | ||
| 1901 | } | ||
| 1902 | LISP_INLINE void | ||
| 1903 | set_save_pointer (Lisp_Object obj, int n, void *val) | ||
| 1904 | { | ||
| 1905 | eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_POINTER); | ||
| 1906 | XSAVE_VALUE (obj)->data[n].pointer = val; | ||
| 1907 | } | ||
| 1908 | LISP_INLINE voidfuncptr | ||
| 1909 | XSAVE_FUNCPOINTER (Lisp_Object obj, int n) | ||
| 1910 | { | ||
| 1911 | eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_FUNCPOINTER); | ||
| 1912 | return XSAVE_VALUE (obj)->data[n].funcpointer; | ||
| 1913 | } | ||
| 1914 | |||
| 1915 | /* Likewise for the saved integer. */ | ||
| 1916 | |||
| 1917 | LISP_INLINE ptrdiff_t | ||
| 1918 | XSAVE_INTEGER (Lisp_Object obj, int n) | ||
| 1919 | { | ||
| 1920 | eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_INTEGER); | ||
| 1921 | return XSAVE_VALUE (obj)->data[n].integer; | ||
| 1922 | } | ||
| 1923 | LISP_INLINE void | ||
| 1924 | set_save_integer (Lisp_Object obj, int n, ptrdiff_t val) | ||
| 1925 | { | ||
| 1926 | eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_INTEGER); | ||
| 1927 | XSAVE_VALUE (obj)->data[n].integer = val; | ||
| 1928 | } | ||
| 1929 | |||
| 1930 | /* Extract Nth saved object. */ | ||
| 1931 | |||
| 1932 | LISP_INLINE Lisp_Object | ||
| 1933 | XSAVE_OBJECT (Lisp_Object obj, int n) | ||
| 1934 | { | ||
| 1935 | eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_OBJECT); | ||
| 1936 | return XSAVE_VALUE (obj)->data[n].object; | ||
| 1937 | } | ||
| 1938 | |||
| 1493 | /* A miscellaneous object, when it's on the free list. */ | 1939 | /* A miscellaneous object, when it's on the free list. */ |
| 1494 | struct Lisp_Free | 1940 | struct Lisp_Free |
| 1495 | { | 1941 | { |
| @@ -1511,6 +1957,46 @@ union Lisp_Misc | |||
| 1511 | struct Lisp_Save_Value u_save_value; | 1957 | struct Lisp_Save_Value u_save_value; |
| 1512 | }; | 1958 | }; |
| 1513 | 1959 | ||
| 1960 | LISP_INLINE union Lisp_Misc * | ||
| 1961 | XMISC (Lisp_Object a) | ||
| 1962 | { | ||
| 1963 | return XUNTAG (a, Lisp_Misc); | ||
| 1964 | } | ||
| 1965 | |||
| 1966 | LISP_INLINE struct Lisp_Misc_Any * | ||
| 1967 | XMISCANY (Lisp_Object a) | ||
| 1968 | { | ||
| 1969 | eassert (MISCP (a)); | ||
| 1970 | return & XMISC (a)->u_any; | ||
| 1971 | } | ||
| 1972 | |||
| 1973 | LISP_INLINE enum Lisp_Misc_Type | ||
| 1974 | XMISCTYPE (Lisp_Object a) | ||
| 1975 | { | ||
| 1976 | return XMISCANY (a)->type; | ||
| 1977 | } | ||
| 1978 | |||
| 1979 | LISP_INLINE struct Lisp_Marker * | ||
| 1980 | XMARKER (Lisp_Object a) | ||
| 1981 | { | ||
| 1982 | eassert (MARKERP (a)); | ||
| 1983 | return & XMISC (a)->u_marker; | ||
| 1984 | } | ||
| 1985 | |||
| 1986 | LISP_INLINE struct Lisp_Overlay * | ||
| 1987 | XOVERLAY (Lisp_Object a) | ||
| 1988 | { | ||
| 1989 | eassert (OVERLAYP (a)); | ||
| 1990 | return & XMISC (a)->u_overlay; | ||
| 1991 | } | ||
| 1992 | |||
| 1993 | LISP_INLINE struct Lisp_Save_Value * | ||
| 1994 | XSAVE_VALUE (Lisp_Object a) | ||
| 1995 | { | ||
| 1996 | eassert (SAVE_VALUEP (a)); | ||
| 1997 | return & XMISC (a)->u_save_value; | ||
| 1998 | } | ||
| 1999 | |||
| 1514 | /* Forwarding pointer to an int variable. | 2000 | /* Forwarding pointer to an int variable. |
| 1515 | This is allowed only in the value cell of a symbol, | 2001 | This is allowed only in the value cell of a symbol, |
| 1516 | and it means that the symbol's value really lives in the | 2002 | and it means that the symbol's value really lives in the |
| @@ -1617,6 +2103,19 @@ union Lisp_Fwd | |||
| 1617 | struct Lisp_Buffer_Objfwd u_buffer_objfwd; | 2103 | struct Lisp_Buffer_Objfwd u_buffer_objfwd; |
| 1618 | struct Lisp_Kboard_Objfwd u_kboard_objfwd; | 2104 | struct Lisp_Kboard_Objfwd u_kboard_objfwd; |
| 1619 | }; | 2105 | }; |
| 2106 | |||
| 2107 | LISP_INLINE enum Lisp_Fwd_Type | ||
| 2108 | XFWDTYPE (union Lisp_Fwd *a) | ||
| 2109 | { | ||
| 2110 | return a->u_intfwd.type; | ||
| 2111 | } | ||
| 2112 | |||
| 2113 | LISP_INLINE struct Lisp_Buffer_Objfwd * | ||
| 2114 | XBUFFER_OBJFWD (union Lisp_Fwd *a) | ||
| 2115 | { | ||
| 2116 | eassert (BUFFER_OBJFWDP (a)); | ||
| 2117 | return &a->u_buffer_objfwd; | ||
| 2118 | } | ||
| 1620 | 2119 | ||
| 1621 | /* Lisp floating point type. */ | 2120 | /* Lisp floating point type. */ |
| 1622 | struct Lisp_Float | 2121 | struct Lisp_Float |
| @@ -1628,8 +2127,11 @@ struct Lisp_Float | |||
| 1628 | } u; | 2127 | } u; |
| 1629 | }; | 2128 | }; |
| 1630 | 2129 | ||
| 1631 | #define XFLOAT_DATA(f) (0 ? XFLOAT (f)->u.data : XFLOAT (f)->u.data) | 2130 | LISP_INLINE double |
| 1632 | #define XFLOAT_INIT(f, n) (XFLOAT (f)->u.data = (n)) | 2131 | XFLOAT_DATA (Lisp_Object f) |
| 2132 | { | ||
| 2133 | return XFLOAT (f)->u.data; | ||
| 2134 | } | ||
| 1633 | 2135 | ||
| 1634 | /* Most hosts nowadays use IEEE floating point, so they use IEC 60559 | 2136 | /* Most hosts nowadays use IEEE floating point, so they use IEC 60559 |
| 1635 | representations, have infinities and NaNs, and do not trap on | 2137 | representations, have infinities and NaNs, and do not trap on |
| @@ -1638,8 +2140,12 @@ struct Lisp_Float | |||
| 1638 | wanted here, but is not quite right because Emacs does not require | 2140 | wanted here, but is not quite right because Emacs does not require |
| 1639 | all the features of C11 Annex F (and does not require C11 at all, | 2141 | all the features of C11 Annex F (and does not require C11 at all, |
| 1640 | for that matter). */ | 2142 | for that matter). */ |
| 1641 | #define IEEE_FLOATING_POINT (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \ | 2143 | enum |
| 1642 | && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128) | 2144 | { |
| 2145 | IEEE_FLOATING_POINT | ||
| 2146 | = (FLT_RADIX == 2 && FLT_MANT_DIG == 24 | ||
| 2147 | && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128) | ||
| 2148 | }; | ||
| 1643 | 2149 | ||
| 1644 | /* A character, declared with the following typedef, is a member | 2150 | /* A character, declared with the following typedef, is a member |
| 1645 | of some character set associated with the current buffer. */ | 2151 | of some character set associated with the current buffer. */ |
| @@ -1680,64 +2186,6 @@ enum char_bits | |||
| 1680 | itself. */ | 2186 | itself. */ |
| 1681 | CHARACTERBITS = 22 | 2187 | CHARACTERBITS = 22 |
| 1682 | }; | 2188 | }; |
| 1683 | |||
| 1684 | |||
| 1685 | |||
| 1686 | |||
| 1687 | /* The glyph datatype, used to represent characters on the display. | ||
| 1688 | It consists of a char code and a face id. */ | ||
| 1689 | |||
| 1690 | typedef struct { | ||
| 1691 | int ch; | ||
| 1692 | int face_id; | ||
| 1693 | } GLYPH; | ||
| 1694 | |||
| 1695 | /* Return a glyph's character code. */ | ||
| 1696 | #define GLYPH_CHAR(glyph) ((glyph).ch) | ||
| 1697 | |||
| 1698 | /* Return a glyph's face ID. */ | ||
| 1699 | #define GLYPH_FACE(glyph) ((glyph).face_id) | ||
| 1700 | |||
| 1701 | #define SET_GLYPH_CHAR(glyph, char) ((glyph).ch = (char)) | ||
| 1702 | #define SET_GLYPH_FACE(glyph, face) ((glyph).face_id = (face)) | ||
| 1703 | #define SET_GLYPH(glyph, char, face) ((glyph).ch = (char), (glyph).face_id = (face)) | ||
| 1704 | |||
| 1705 | /* Return 1 if GLYPH contains valid character code. */ | ||
| 1706 | #define GLYPH_CHAR_VALID_P(glyph) CHAR_VALID_P (GLYPH_CHAR (glyph)) | ||
| 1707 | |||
| 1708 | |||
| 1709 | /* Glyph Code from a display vector may either be an integer which | ||
| 1710 | encodes a char code in the lower CHARACTERBITS bits and a (very small) | ||
| 1711 | face-id in the upper bits, or it may be a cons (CHAR . FACE-ID). */ | ||
| 1712 | |||
| 1713 | #define GLYPH_CODE_P(gc) \ | ||
| 1714 | (CONSP (gc) \ | ||
| 1715 | ? (CHARACTERP (XCAR (gc)) \ | ||
| 1716 | && RANGED_INTEGERP (0, XCDR (gc), MAX_FACE_ID)) \ | ||
| 1717 | : (RANGED_INTEGERP \ | ||
| 1718 | (0, gc, \ | ||
| 1719 | (MAX_FACE_ID < TYPE_MAXIMUM (EMACS_INT) >> CHARACTERBITS \ | ||
| 1720 | ? ((EMACS_INT) MAX_FACE_ID << CHARACTERBITS) | MAX_CHAR \ | ||
| 1721 | : TYPE_MAXIMUM (EMACS_INT))))) | ||
| 1722 | |||
| 1723 | /* The following are valid only if GLYPH_CODE_P (gc). */ | ||
| 1724 | |||
| 1725 | #define GLYPH_CODE_CHAR(gc) \ | ||
| 1726 | (CONSP (gc) ? XINT (XCAR (gc)) : XINT (gc) & ((1 << CHARACTERBITS) - 1)) | ||
| 1727 | |||
| 1728 | #define GLYPH_CODE_FACE(gc) \ | ||
| 1729 | (CONSP (gc) ? XINT (XCDR (gc)) : XINT (gc) >> CHARACTERBITS) | ||
| 1730 | |||
| 1731 | #define SET_GLYPH_FROM_GLYPH_CODE(glyph, gc) \ | ||
| 1732 | do \ | ||
| 1733 | { \ | ||
| 1734 | if (CONSP (gc)) \ | ||
| 1735 | SET_GLYPH (glyph, XINT (XCAR (gc)), XINT (XCDR (gc))); \ | ||
| 1736 | else \ | ||
| 1737 | SET_GLYPH (glyph, (XINT (gc) & ((1 << CHARACTERBITS)-1)), \ | ||
| 1738 | (XINT (gc) >> CHARACTERBITS)); \ | ||
| 1739 | } \ | ||
| 1740 | while (0) | ||
| 1741 | 2189 | ||
| 1742 | /* Structure to hold mouse highlight data. This is here because other | 2190 | /* Structure to hold mouse highlight data. This is here because other |
| 1743 | header files need it for defining struct x_output etc. */ | 2191 | header files need it for defining struct x_output etc. */ |
| @@ -1773,190 +2221,235 @@ typedef struct { | |||
| 1773 | 2221 | ||
| 1774 | /* Data type checking. */ | 2222 | /* Data type checking. */ |
| 1775 | 2223 | ||
| 1776 | #define NILP(x) EQ (x, Qnil) | 2224 | LISP_MACRO_DEFUN (NILP, bool, (Lisp_Object x), (x)) |
| 1777 | |||
| 1778 | #define NUMBERP(x) (INTEGERP (x) || FLOATP (x)) | ||
| 1779 | #define NATNUMP(x) (INTEGERP (x) && XINT (x) >= 0) | ||
| 1780 | |||
| 1781 | #define RANGED_INTEGERP(lo, x, hi) \ | ||
| 1782 | (INTEGERP (x) && (lo) <= XINT (x) && XINT (x) <= (hi)) | ||
| 1783 | #define TYPE_RANGED_INTEGERP(type, x) \ | ||
| 1784 | (TYPE_SIGNED (type) \ | ||
| 1785 | ? RANGED_INTEGERP (TYPE_MINIMUM (type), x, TYPE_MAXIMUM (type)) \ | ||
| 1786 | : RANGED_INTEGERP (0, x, TYPE_MAXIMUM (type))) | ||
| 1787 | |||
| 1788 | #define INTEGERP(x) (LISP_INT_TAG_P (XTYPE ((x)))) | ||
| 1789 | #define SYMBOLP(x) (XTYPE ((x)) == Lisp_Symbol) | ||
| 1790 | #define MISCP(x) (XTYPE ((x)) == Lisp_Misc) | ||
| 1791 | #define VECTORLIKEP(x) (XTYPE ((x)) == Lisp_Vectorlike) | ||
| 1792 | #define STRINGP(x) (XTYPE ((x)) == Lisp_String) | ||
| 1793 | #define CONSP(x) (XTYPE ((x)) == Lisp_Cons) | ||
| 1794 | |||
| 1795 | #define FLOATP(x) (XTYPE ((x)) == Lisp_Float) | ||
| 1796 | #define VECTORP(x) (VECTORLIKEP (x) && !(ASIZE (x) & PSEUDOVECTOR_FLAG)) | ||
| 1797 | #define OVERLAYP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay) | ||
| 1798 | #define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker) | ||
| 1799 | 2225 | ||
| 1800 | LISP_INLINE bool | 2226 | LISP_INLINE bool |
| 1801 | SAVE_VALUEP (Lisp_Object x) | 2227 | NUMBERP (Lisp_Object x) |
| 1802 | { | 2228 | { |
| 1803 | return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value; | 2229 | return INTEGERP (x) || FLOATP (x); |
| 1804 | } | 2230 | } |
| 1805 | 2231 | LISP_INLINE bool | |
| 1806 | LISP_INLINE struct Lisp_Save_Value * | 2232 | NATNUMP (Lisp_Object x) |
| 1807 | XSAVE_VALUE (Lisp_Object a) | ||
| 1808 | { | 2233 | { |
| 1809 | eassert (SAVE_VALUEP (a)); | 2234 | return INTEGERP (x) && 0 <= XINT (x); |
| 1810 | return & XMISC (a)->u_save_value; | ||
| 1811 | } | 2235 | } |
| 1812 | 2236 | ||
| 1813 | /* Return the type of V's Nth saved value. */ | 2237 | LISP_INLINE bool |
| 1814 | LISP_INLINE int | 2238 | RANGED_INTEGERP (intmax_t lo, Lisp_Object x, intmax_t hi) |
| 1815 | save_type (struct Lisp_Save_Value *v, int n) | ||
| 1816 | { | 2239 | { |
| 1817 | eassert (0 <= n && n < SAVE_VALUE_SLOTS); | 2240 | return INTEGERP (x) && lo <= XINT (x) && XINT (x) <= hi; |
| 1818 | return (v->save_type >> (SAVE_SLOT_BITS * n) & ((1 << SAVE_SLOT_BITS) - 1)); | ||
| 1819 | } | 2241 | } |
| 1820 | 2242 | ||
| 1821 | /* Get and set the Nth saved pointer. */ | 2243 | #define TYPE_RANGED_INTEGERP(type, x) \ |
| 2244 | (INTEGERP (x) \ | ||
| 2245 | && (TYPE_SIGNED (type) ? TYPE_MINIMUM (type) <= XINT (x) : 0 <= XINT (x)) \ | ||
| 2246 | && XINT (x) <= TYPE_MAXIMUM (type)) | ||
| 2247 | |||
| 2248 | LISP_MACRO_DEFUN (CONSP, bool, (Lisp_Object x), (x)) | ||
| 2249 | LISP_MACRO_DEFUN (FLOATP, bool, (Lisp_Object x), (x)) | ||
| 2250 | LISP_MACRO_DEFUN (MISCP, bool, (Lisp_Object x), (x)) | ||
| 2251 | LISP_MACRO_DEFUN (SYMBOLP, bool, (Lisp_Object x), (x)) | ||
| 2252 | LISP_MACRO_DEFUN (INTEGERP, bool, (Lisp_Object x), (x)) | ||
| 2253 | LISP_MACRO_DEFUN (VECTORLIKEP, bool, (Lisp_Object x), (x)) | ||
| 2254 | LISP_MACRO_DEFUN (MARKERP, bool, (Lisp_Object x), (x)) | ||
| 1822 | 2255 | ||
| 1823 | LISP_INLINE void * | 2256 | LISP_INLINE bool |
| 1824 | XSAVE_POINTER (Lisp_Object obj, int n) | 2257 | STRINGP (Lisp_Object x) |
| 1825 | { | 2258 | { |
| 1826 | eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_POINTER); | 2259 | return XTYPE (x) == Lisp_String; |
| 1827 | return XSAVE_VALUE (obj)->data[n].pointer;; | ||
| 1828 | } | 2260 | } |
| 1829 | LISP_INLINE void | 2261 | LISP_INLINE bool |
| 1830 | set_save_pointer (Lisp_Object obj, int n, void *val) | 2262 | VECTORP (Lisp_Object x) |
| 1831 | { | 2263 | { |
| 1832 | eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_POINTER); | 2264 | return VECTORLIKEP (x) && ! (ASIZE (x) & PSEUDOVECTOR_FLAG); |
| 1833 | XSAVE_VALUE (obj)->data[n].pointer = val; | ||
| 1834 | } | 2265 | } |
| 1835 | 2266 | LISP_INLINE bool | |
| 1836 | /* Likewise for the saved integer. */ | 2267 | OVERLAYP (Lisp_Object x) |
| 1837 | |||
| 1838 | LISP_INLINE ptrdiff_t | ||
| 1839 | XSAVE_INTEGER (Lisp_Object obj, int n) | ||
| 1840 | { | 2268 | { |
| 1841 | eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_INTEGER); | 2269 | return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay; |
| 1842 | return XSAVE_VALUE (obj)->data[n].integer; | ||
| 1843 | } | 2270 | } |
| 1844 | LISP_INLINE void | 2271 | LISP_INLINE bool |
| 1845 | set_save_integer (Lisp_Object obj, int n, ptrdiff_t val) | 2272 | SAVE_VALUEP (Lisp_Object x) |
| 1846 | { | 2273 | { |
| 1847 | eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_INTEGER); | 2274 | return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value; |
| 1848 | XSAVE_VALUE (obj)->data[n].integer = val; | ||
| 1849 | } | 2275 | } |
| 1850 | 2276 | ||
| 1851 | /* Extract Nth saved object. */ | 2277 | LISP_INLINE bool |
| 1852 | 2278 | AUTOLOADP (Lisp_Object x) | |
| 1853 | LISP_INLINE Lisp_Object | ||
| 1854 | XSAVE_OBJECT (Lisp_Object obj, int n) | ||
| 1855 | { | 2279 | { |
| 1856 | eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_OBJECT); | 2280 | return CONSP (x) && EQ (Qautoload, XCAR (x)); |
| 1857 | return XSAVE_VALUE (obj)->data[n].object; | ||
| 1858 | } | 2281 | } |
| 1859 | 2282 | ||
| 1860 | #define AUTOLOADP(x) (CONSP (x) && EQ (Qautoload, XCAR (x))) | 2283 | LISP_INLINE bool |
| 1861 | 2284 | BUFFER_OBJFWDP (union Lisp_Fwd *a) | |
| 1862 | #define INTFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Int) | 2285 | { |
| 1863 | #define BOOLFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Bool) | 2286 | return XFWDTYPE (a) == Lisp_Fwd_Buffer_Obj; |
| 1864 | #define OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Obj) | 2287 | } |
| 1865 | #define BUFFER_OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Buffer_Obj) | ||
| 1866 | #define KBOARD_OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Kboard_Obj) | ||
| 1867 | 2288 | ||
| 1868 | /* True if object X is a pseudovector whose code is CODE. The cast to struct | 2289 | LISP_INLINE bool |
| 1869 | vectorlike_header * avoids aliasing issues. */ | 2290 | PSEUDOVECTOR_TYPEP (struct vectorlike_header *a, int code) |
| 1870 | #define PSEUDOVECTORP(x, code) \ | 2291 | { |
| 1871 | TYPED_PSEUDOVECTORP (x, vectorlike_header, code) | 2292 | return ((a->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) |
| 2293 | == (PSEUDOVECTOR_FLAG | (code << PSEUDOVECTOR_AREA_BITS))); | ||
| 2294 | } | ||
| 1872 | 2295 | ||
| 1873 | #define PSEUDOVECTOR_TYPEP(v, code) \ | 2296 | /* True if A is a pseudovector whose code is CODE. */ |
| 1874 | (((v)->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \ | 2297 | LISP_INLINE bool |
| 1875 | == (PSEUDOVECTOR_FLAG | ((code) << PSEUDOVECTOR_AREA_BITS))) | 2298 | PSEUDOVECTORP (Lisp_Object a, int code) |
| 2299 | { | ||
| 2300 | if (! VECTORLIKEP (a)) | ||
| 2301 | return 0; | ||
| 2302 | else | ||
| 2303 | { | ||
| 2304 | /* Converting to struct vectorlike_header * avoids aliasing issues. */ | ||
| 2305 | struct vectorlike_header *h = XUNTAG (a, Lisp_Vectorlike); | ||
| 2306 | return PSEUDOVECTOR_TYPEP (h, code); | ||
| 2307 | } | ||
| 2308 | } | ||
| 1876 | 2309 | ||
| 1877 | /* True if object X, with internal type struct T *, is a pseudovector whose | ||
| 1878 | code is CODE. */ | ||
| 1879 | #define TYPED_PSEUDOVECTORP(x, t, code) \ | ||
| 1880 | (VECTORLIKEP (x) \ | ||
| 1881 | && PSEUDOVECTOR_TYPEP ((struct t *) XUNTAG (x, Lisp_Vectorlike), code)) | ||
| 1882 | 2310 | ||
| 1883 | /* Test for specific pseudovector types. */ | 2311 | /* Test for specific pseudovector types. */ |
| 1884 | #define WINDOW_CONFIGURATIONP(x) PSEUDOVECTORP (x, PVEC_WINDOW_CONFIGURATION) | ||
| 1885 | #define PROCESSP(x) PSEUDOVECTORP (x, PVEC_PROCESS) | ||
| 1886 | #define WINDOWP(x) PSEUDOVECTORP (x, PVEC_WINDOW) | ||
| 1887 | #define TERMINALP(x) PSEUDOVECTORP (x, PVEC_TERMINAL) | ||
| 1888 | #define SUBRP(x) PSEUDOVECTORP (x, PVEC_SUBR) | ||
| 1889 | #define COMPILEDP(x) PSEUDOVECTORP (x, PVEC_COMPILED) | ||
| 1890 | #define BUFFERP(x) PSEUDOVECTORP (x, PVEC_BUFFER) | ||
| 1891 | #define CHAR_TABLE_P(x) PSEUDOVECTORP (x, PVEC_CHAR_TABLE) | ||
| 1892 | #define SUB_CHAR_TABLE_P(x) PSEUDOVECTORP (x, PVEC_SUB_CHAR_TABLE) | ||
| 1893 | #define BOOL_VECTOR_P(x) PSEUDOVECTORP (x, PVEC_BOOL_VECTOR) | ||
| 1894 | #define FRAMEP(x) PSEUDOVECTORP (x, PVEC_FRAME) | ||
| 1895 | |||
| 1896 | /* Test for image (image . spec) */ | ||
| 1897 | #define IMAGEP(x) (CONSP (x) && EQ (XCAR (x), Qimage)) | ||
| 1898 | 2312 | ||
| 1899 | /* Array types. */ | 2313 | LISP_INLINE bool |
| 1900 | 2314 | WINDOW_CONFIGURATIONP (Lisp_Object a) | |
| 1901 | #define ARRAYP(x) \ | 2315 | { |
| 1902 | (VECTORP (x) || STRINGP (x) || CHAR_TABLE_P (x) || BOOL_VECTOR_P (x)) | 2316 | return PSEUDOVECTORP (a, PVEC_WINDOW_CONFIGURATION); |
| 1903 | 2317 | } | |
| 1904 | #define CHECK_LIST(x) \ | ||
| 1905 | CHECK_TYPE (CONSP (x) || NILP (x), Qlistp, x) | ||
| 1906 | |||
| 1907 | #define CHECK_LIST_CONS(x, y) \ | ||
| 1908 | CHECK_TYPE (CONSP (x), Qlistp, y) | ||
| 1909 | |||
| 1910 | #define CHECK_LIST_END(x, y) \ | ||
| 1911 | CHECK_TYPE (NILP (x), Qlistp, y) | ||
| 1912 | |||
| 1913 | #define CHECK_STRING(x) \ | ||
| 1914 | CHECK_TYPE (STRINGP (x), Qstringp, x) | ||
| 1915 | |||
| 1916 | #define CHECK_STRING_CAR(x) \ | ||
| 1917 | CHECK_TYPE (STRINGP (XCAR (x)), Qstringp, XCAR (x)) | ||
| 1918 | 2318 | ||
| 1919 | #define CHECK_CONS(x) \ | 2319 | LISP_INLINE bool |
| 1920 | CHECK_TYPE (CONSP (x), Qconsp, x) | 2320 | PROCESSP (Lisp_Object a) |
| 2321 | { | ||
| 2322 | return PSEUDOVECTORP (a, PVEC_PROCESS); | ||
| 2323 | } | ||
| 1921 | 2324 | ||
| 1922 | #define CHECK_SYMBOL(x) \ | 2325 | LISP_INLINE bool |
| 1923 | CHECK_TYPE (SYMBOLP (x), Qsymbolp, x) | 2326 | WINDOWP (Lisp_Object a) |
| 2327 | { | ||
| 2328 | return PSEUDOVECTORP (a, PVEC_WINDOW); | ||
| 2329 | } | ||
| 1924 | 2330 | ||
| 1925 | #define CHECK_CHAR_TABLE(x) \ | 2331 | LISP_INLINE bool |
| 1926 | CHECK_TYPE (CHAR_TABLE_P (x), Qchar_table_p, x) | 2332 | TERMINALP (Lisp_Object a) |
| 2333 | { | ||
| 2334 | return PSEUDOVECTORP (a, PVEC_TERMINAL); | ||
| 2335 | } | ||
| 1927 | 2336 | ||
| 1928 | #define CHECK_VECTOR(x) \ | 2337 | LISP_INLINE bool |
| 1929 | CHECK_TYPE (VECTORP (x), Qvectorp, x) | 2338 | SUBRP (Lisp_Object a) |
| 2339 | { | ||
| 2340 | return PSEUDOVECTORP (a, PVEC_SUBR); | ||
| 2341 | } | ||
| 1930 | 2342 | ||
| 1931 | #define CHECK_VECTOR_OR_STRING(x) \ | 2343 | LISP_INLINE bool |
| 1932 | CHECK_TYPE (VECTORP (x) || STRINGP (x), Qarrayp, x) | 2344 | COMPILEDP (Lisp_Object a) |
| 2345 | { | ||
| 2346 | return PSEUDOVECTORP (a, PVEC_COMPILED); | ||
| 2347 | } | ||
| 1933 | 2348 | ||
| 1934 | #define CHECK_ARRAY(x, Qxxxp) \ | 2349 | LISP_INLINE bool |
| 1935 | CHECK_TYPE (ARRAYP (x), Qxxxp, x) | 2350 | BUFFERP (Lisp_Object a) |
| 2351 | { | ||
| 2352 | return PSEUDOVECTORP (a, PVEC_BUFFER); | ||
| 2353 | } | ||
| 1936 | 2354 | ||
| 1937 | #define CHECK_VECTOR_OR_CHAR_TABLE(x) \ | 2355 | LISP_INLINE bool |
| 1938 | CHECK_TYPE (VECTORP (x) || CHAR_TABLE_P (x), Qvector_or_char_table_p, x) | 2356 | CHAR_TABLE_P (Lisp_Object a) |
| 2357 | { | ||
| 2358 | return PSEUDOVECTORP (a, PVEC_CHAR_TABLE); | ||
| 2359 | } | ||
| 1939 | 2360 | ||
| 1940 | #define CHECK_BUFFER(x) \ | 2361 | LISP_INLINE bool |
| 1941 | CHECK_TYPE (BUFFERP (x), Qbufferp, x) | 2362 | SUB_CHAR_TABLE_P (Lisp_Object a) |
| 2363 | { | ||
| 2364 | return PSEUDOVECTORP (a, PVEC_SUB_CHAR_TABLE); | ||
| 2365 | } | ||
| 1942 | 2366 | ||
| 1943 | #define CHECK_WINDOW(x) \ | 2367 | LISP_INLINE bool |
| 1944 | CHECK_TYPE (WINDOWP (x), Qwindowp, x) | 2368 | BOOL_VECTOR_P (Lisp_Object a) |
| 2369 | { | ||
| 2370 | return PSEUDOVECTORP (a, PVEC_BOOL_VECTOR); | ||
| 2371 | } | ||
| 1945 | 2372 | ||
| 1946 | #define CHECK_WINDOW_CONFIGURATION(x) \ | 2373 | LISP_INLINE bool |
| 1947 | CHECK_TYPE (WINDOW_CONFIGURATIONP (x), Qwindow_configuration_p, x) | 2374 | FRAMEP (Lisp_Object a) |
| 2375 | { | ||
| 2376 | return PSEUDOVECTORP (a, PVEC_FRAME); | ||
| 2377 | } | ||
| 1948 | 2378 | ||
| 1949 | #define CHECK_PROCESS(x) \ | 2379 | /* Test for image (image . spec) */ |
| 1950 | CHECK_TYPE (PROCESSP (x), Qprocessp, x) | 2380 | LISP_INLINE bool |
| 2381 | IMAGEP (Lisp_Object x) | ||
| 2382 | { | ||
| 2383 | return CONSP (x) && EQ (XCAR (x), Qimage); | ||
| 2384 | } | ||
| 1951 | 2385 | ||
| 1952 | #define CHECK_SUBR(x) \ | 2386 | /* Array types. */ |
| 1953 | CHECK_TYPE (SUBRP (x), Qsubrp, x) | 2387 | LISP_INLINE bool |
| 2388 | ARRAYP (Lisp_Object x) | ||
| 2389 | { | ||
| 2390 | return VECTORP (x) || STRINGP (x) || CHAR_TABLE_P (x) || BOOL_VECTOR_P (x); | ||
| 2391 | } | ||
| 2392 | |||
| 2393 | LISP_INLINE void | ||
| 2394 | CHECK_LIST (Lisp_Object x) | ||
| 2395 | { | ||
| 2396 | CHECK_TYPE (CONSP (x) || NILP (x), Qlistp, x); | ||
| 2397 | } | ||
| 1954 | 2398 | ||
| 1955 | #define CHECK_NUMBER(x) \ | 2399 | LISP_MACRO_DEFUN_VOID (CHECK_LIST_CONS, (Lisp_Object x, Lisp_Object y), (x, y)) |
| 1956 | CHECK_TYPE (INTEGERP (x), Qintegerp, x) | 2400 | LISP_MACRO_DEFUN_VOID (CHECK_SYMBOL, (Lisp_Object x), (x)) |
| 2401 | LISP_MACRO_DEFUN_VOID (CHECK_NUMBER, (Lisp_Object x), (x)) | ||
| 1957 | 2402 | ||
| 1958 | #define CHECK_NATNUM(x) \ | 2403 | LISP_INLINE void |
| 1959 | CHECK_TYPE (NATNUMP (x), Qwholenump, x) | 2404 | CHECK_STRING (Lisp_Object x) |
| 2405 | { | ||
| 2406 | CHECK_TYPE (STRINGP (x), Qstringp, x); | ||
| 2407 | } | ||
| 2408 | LISP_INLINE void | ||
| 2409 | CHECK_STRING_CAR (Lisp_Object x) | ||
| 2410 | { | ||
| 2411 | CHECK_TYPE (STRINGP (XCAR (x)), Qstringp, XCAR (x)); | ||
| 2412 | } | ||
| 2413 | LISP_INLINE void | ||
| 2414 | CHECK_CONS (Lisp_Object x) | ||
| 2415 | { | ||
| 2416 | CHECK_TYPE (CONSP (x), Qconsp, x); | ||
| 2417 | } | ||
| 2418 | LISP_INLINE void | ||
| 2419 | CHECK_VECTOR (Lisp_Object x) | ||
| 2420 | { | ||
| 2421 | CHECK_TYPE (VECTORP (x), Qvectorp, x); | ||
| 2422 | } | ||
| 2423 | LISP_INLINE void | ||
| 2424 | CHECK_VECTOR_OR_STRING (Lisp_Object x) | ||
| 2425 | { | ||
| 2426 | CHECK_TYPE (VECTORP (x) || STRINGP (x), Qarrayp, x); | ||
| 2427 | } | ||
| 2428 | LISP_INLINE void | ||
| 2429 | CHECK_ARRAY (Lisp_Object x, Lisp_Object Qxxxp) | ||
| 2430 | { | ||
| 2431 | CHECK_TYPE (ARRAYP (x), Qxxxp, x); | ||
| 2432 | } | ||
| 2433 | LISP_INLINE void | ||
| 2434 | CHECK_BUFFER (Lisp_Object x) | ||
| 2435 | { | ||
| 2436 | CHECK_TYPE (BUFFERP (x), Qbufferp, x); | ||
| 2437 | } | ||
| 2438 | LISP_INLINE void | ||
| 2439 | CHECK_WINDOW (Lisp_Object x) | ||
| 2440 | { | ||
| 2441 | CHECK_TYPE (WINDOWP (x), Qwindowp, x); | ||
| 2442 | } | ||
| 2443 | LISP_INLINE void | ||
| 2444 | CHECK_PROCESS (Lisp_Object x) | ||
| 2445 | { | ||
| 2446 | CHECK_TYPE (PROCESSP (x), Qprocessp, x); | ||
| 2447 | } | ||
| 2448 | LISP_INLINE void | ||
| 2449 | CHECK_NATNUM (Lisp_Object x) | ||
| 2450 | { | ||
| 2451 | CHECK_TYPE (NATNUMP (x), Qwholenump, x); | ||
| 2452 | } | ||
| 1960 | 2453 | ||
| 1961 | #define CHECK_RANGED_INTEGER(x, lo, hi) \ | 2454 | #define CHECK_RANGED_INTEGER(x, lo, hi) \ |
| 1962 | do { \ | 2455 | do { \ |
| @@ -1977,57 +2470,43 @@ XSAVE_OBJECT (Lisp_Object obj, int n) | |||
| 1977 | CHECK_RANGED_INTEGER (x, 0, TYPE_MAXIMUM (type)); \ | 2470 | CHECK_RANGED_INTEGER (x, 0, TYPE_MAXIMUM (type)); \ |
| 1978 | } while (0) | 2471 | } while (0) |
| 1979 | 2472 | ||
| 1980 | #define CHECK_MARKER(x) \ | ||
| 1981 | CHECK_TYPE (MARKERP (x), Qmarkerp, x) | ||
| 1982 | |||
| 1983 | #define CHECK_NUMBER_COERCE_MARKER(x) \ | 2473 | #define CHECK_NUMBER_COERCE_MARKER(x) \ |
| 1984 | do { if (MARKERP ((x))) XSETFASTINT (x, marker_position (x)); \ | 2474 | do { if (MARKERP ((x))) XSETFASTINT (x, marker_position (x)); \ |
| 1985 | else CHECK_TYPE (INTEGERP (x), Qinteger_or_marker_p, x); } while (0) | 2475 | else CHECK_TYPE (INTEGERP (x), Qinteger_or_marker_p, x); } while (0) |
| 1986 | 2476 | ||
| 1987 | #define XFLOATINT(n) extract_float((n)) | 2477 | LISP_INLINE double |
| 1988 | 2478 | XFLOATINT (Lisp_Object n) | |
| 1989 | #define CHECK_FLOAT(x) \ | 2479 | { |
| 1990 | CHECK_TYPE (FLOATP (x), Qfloatp, x) | 2480 | return extract_float (n); |
| 2481 | } | ||
| 1991 | 2482 | ||
| 1992 | #define CHECK_NUMBER_OR_FLOAT(x) \ | 2483 | LISP_INLINE void |
| 1993 | CHECK_TYPE (FLOATP (x) || INTEGERP (x), Qnumberp, x) | 2484 | CHECK_NUMBER_OR_FLOAT (Lisp_Object x) |
| 2485 | { | ||
| 2486 | CHECK_TYPE (FLOATP (x) || INTEGERP (x), Qnumberp, x); | ||
| 2487 | } | ||
| 1994 | 2488 | ||
| 1995 | #define CHECK_NUMBER_OR_FLOAT_COERCE_MARKER(x) \ | 2489 | #define CHECK_NUMBER_OR_FLOAT_COERCE_MARKER(x) \ |
| 1996 | do { if (MARKERP (x)) XSETFASTINT (x, marker_position (x)); \ | 2490 | do { if (MARKERP (x)) XSETFASTINT (x, marker_position (x)); \ |
| 1997 | else CHECK_TYPE (INTEGERP (x) || FLOATP (x), Qnumber_or_marker_p, x); } while (0) | 2491 | else CHECK_TYPE (INTEGERP (x) || FLOATP (x), Qnumber_or_marker_p, x); } while (0) |
| 1998 | 2492 | ||
| 1999 | #define CHECK_OVERLAY(x) \ | ||
| 2000 | CHECK_TYPE (OVERLAYP (x), Qoverlayp, x) | ||
| 2001 | |||
| 2002 | /* Since we can't assign directly to the CAR or CDR fields of a cons | 2493 | /* Since we can't assign directly to the CAR or CDR fields of a cons |
| 2003 | cell, use these when checking that those fields contain numbers. */ | 2494 | cell, use these when checking that those fields contain numbers. */ |
| 2004 | #define CHECK_NUMBER_CAR(x) \ | 2495 | LISP_INLINE void |
| 2005 | do { \ | 2496 | CHECK_NUMBER_CAR (Lisp_Object x) |
| 2006 | Lisp_Object tmp = XCAR (x); \ | 2497 | { |
| 2007 | CHECK_NUMBER (tmp); \ | 2498 | Lisp_Object tmp = XCAR (x); |
| 2008 | XSETCAR ((x), tmp); \ | 2499 | CHECK_NUMBER (tmp); |
| 2009 | } while (0) | 2500 | XSETCAR (x, tmp); |
| 2010 | 2501 | } | |
| 2011 | #define CHECK_NUMBER_CDR(x) \ | ||
| 2012 | do { \ | ||
| 2013 | Lisp_Object tmp = XCDR (x); \ | ||
| 2014 | CHECK_NUMBER (tmp); \ | ||
| 2015 | XSETCDR ((x), tmp); \ | ||
| 2016 | } while (0) | ||
| 2017 | |||
| 2018 | #define CHECK_NATNUM_CAR(x) \ | ||
| 2019 | do { \ | ||
| 2020 | Lisp_Object tmp = XCAR (x); \ | ||
| 2021 | CHECK_NATNUM (tmp); \ | ||
| 2022 | XSETCAR ((x), tmp); \ | ||
| 2023 | } while (0) | ||
| 2024 | 2502 | ||
| 2025 | #define CHECK_NATNUM_CDR(x) \ | 2503 | LISP_INLINE void |
| 2026 | do { \ | 2504 | CHECK_NUMBER_CDR (Lisp_Object x) |
| 2027 | Lisp_Object tmp = XCDR (x); \ | 2505 | { |
| 2028 | CHECK_NATNUM (tmp); \ | 2506 | Lisp_Object tmp = XCDR (x); |
| 2029 | XSETCDR ((x), tmp); \ | 2507 | CHECK_NUMBER (tmp); |
| 2030 | } while (0) | 2508 | XSETCDR (x, tmp); |
| 2509 | } | ||
| 2031 | 2510 | ||
| 2032 | /* Define a built-in function for calling from Lisp. | 2511 | /* Define a built-in function for calling from Lisp. |
| 2033 | `lname' should be the name to give the function in Lisp, | 2512 | `lname' should be the name to give the function in Lisp, |
| @@ -2093,8 +2572,12 @@ XSAVE_OBJECT (Lisp_Object obj, int n) | |||
| 2093 | #define DEFUN_ARGS_8 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \ | 2572 | #define DEFUN_ARGS_8 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \ |
| 2094 | Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object) | 2573 | Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object) |
| 2095 | 2574 | ||
| 2096 | /* Non-zero if OBJ is a Lisp function. */ | 2575 | /* True if OBJ is a Lisp function. */ |
| 2097 | #define FUNCTIONP(OBJ) functionp(OBJ) | 2576 | LISP_INLINE bool |
| 2577 | FUNCTIONP (Lisp_Object obj) | ||
| 2578 | { | ||
| 2579 | return functionp (obj); | ||
| 2580 | } | ||
| 2098 | 2581 | ||
| 2099 | /* defsubr (Sname); | 2582 | /* defsubr (Sname); |
| 2100 | is how we define the symbol for function `name' at start-up time. */ | 2583 | is how we define the symbol for function `name' at start-up time. */ |
| @@ -2214,9 +2697,9 @@ typedef jmp_buf sys_jmp_buf; | |||
| 2214 | WHERE being a buffer or frame means we saw a buffer-local or frame-local | 2697 | WHERE being a buffer or frame means we saw a buffer-local or frame-local |
| 2215 | value. Other values of WHERE mean an internal error. | 2698 | value. Other values of WHERE mean an internal error. |
| 2216 | 2699 | ||
| 2217 | NOTE: The specbinding struct is defined here, because SPECPDL_INDEX is | 2700 | NOTE: The specbinding union is defined here, because SPECPDL_INDEX is |
| 2218 | used all over the place, needs to be fast, and needs to know the size of | 2701 | used all over the place, needs to be fast, and needs to know the size of |
| 2219 | struct specbinding. But only eval.c should access it. */ | 2702 | union specbinding. But only eval.c should access it. */ |
| 2220 | 2703 | ||
| 2221 | typedef Lisp_Object (*specbinding_func) (Lisp_Object); | 2704 | typedef Lisp_Object (*specbinding_func) (Lisp_Object); |
| 2222 | 2705 | ||
| @@ -2229,59 +2712,37 @@ enum specbind_tag { | |||
| 2229 | SPECPDL_LET_DEFAULT /* A global binding for a localized var. */ | 2712 | SPECPDL_LET_DEFAULT /* A global binding for a localized var. */ |
| 2230 | }; | 2713 | }; |
| 2231 | 2714 | ||
| 2232 | struct specbinding | 2715 | union specbinding |
| 2233 | { | 2716 | { |
| 2234 | enum specbind_tag kind; | 2717 | ENUM_BF (specbind_tag) kind : CHAR_BIT; |
| 2235 | union { | 2718 | struct { |
| 2236 | struct { | 2719 | ENUM_BF (specbind_tag) kind : CHAR_BIT; |
| 2237 | Lisp_Object arg; | 2720 | Lisp_Object arg; |
| 2238 | specbinding_func func; | 2721 | specbinding_func func; |
| 2239 | } unwind; | 2722 | } unwind; |
| 2240 | struct { | 2723 | struct { |
| 2241 | /* `where' is not used in the case of SPECPDL_LET. */ | 2724 | ENUM_BF (specbind_tag) kind : CHAR_BIT; |
| 2242 | Lisp_Object symbol, old_value, where; | 2725 | /* `where' is not used in the case of SPECPDL_LET. */ |
| 2243 | } let; | 2726 | Lisp_Object symbol, old_value, where; |
| 2244 | struct { | 2727 | } let; |
| 2245 | Lisp_Object function; | 2728 | struct { |
| 2246 | Lisp_Object *args; | 2729 | ENUM_BF (specbind_tag) kind : CHAR_BIT; |
| 2247 | ptrdiff_t nargs : BITS_PER_PTRDIFF_T - 1; | 2730 | bool debug_on_exit : 1; |
| 2248 | bool debug_on_exit : 1; | 2731 | Lisp_Object function; |
| 2249 | } bt; | 2732 | Lisp_Object *args; |
| 2250 | } v; | 2733 | ptrdiff_t nargs; |
| 2734 | } bt; | ||
| 2251 | }; | 2735 | }; |
| 2252 | 2736 | ||
| 2253 | LISP_INLINE Lisp_Object specpdl_symbol (struct specbinding *pdl) | 2737 | extern union specbinding *specpdl; |
| 2254 | { eassert (pdl->kind >= SPECPDL_LET); return pdl->v.let.symbol; } | 2738 | extern union specbinding *specpdl_ptr; |
| 2255 | |||
| 2256 | LISP_INLINE Lisp_Object specpdl_old_value (struct specbinding *pdl) | ||
| 2257 | { eassert (pdl->kind >= SPECPDL_LET); return pdl->v.let.old_value; } | ||
| 2258 | |||
| 2259 | LISP_INLINE Lisp_Object specpdl_where (struct specbinding *pdl) | ||
| 2260 | { eassert (pdl->kind > SPECPDL_LET); return pdl->v.let.where; } | ||
| 2261 | |||
| 2262 | LISP_INLINE Lisp_Object specpdl_arg (struct specbinding *pdl) | ||
| 2263 | { eassert (pdl->kind == SPECPDL_UNWIND); return pdl->v.unwind.arg; } | ||
| 2264 | |||
| 2265 | LISP_INLINE specbinding_func specpdl_func (struct specbinding *pdl) | ||
| 2266 | { eassert (pdl->kind == SPECPDL_UNWIND); return pdl->v.unwind.func; } | ||
| 2267 | |||
| 2268 | LISP_INLINE Lisp_Object backtrace_function (struct specbinding *pdl) | ||
| 2269 | { eassert (pdl->kind == SPECPDL_BACKTRACE); return pdl->v.bt.function; } | ||
| 2270 | |||
| 2271 | LISP_INLINE ptrdiff_t backtrace_nargs (struct specbinding *pdl) | ||
| 2272 | { eassert (pdl->kind == SPECPDL_BACKTRACE); return pdl->v.bt.nargs; } | ||
| 2273 | |||
| 2274 | LISP_INLINE Lisp_Object *backtrace_args (struct specbinding *pdl) | ||
| 2275 | { eassert (pdl->kind == SPECPDL_BACKTRACE); return pdl->v.bt.args; } | ||
| 2276 | |||
| 2277 | LISP_INLINE bool backtrace_debug_on_exit (struct specbinding *pdl) | ||
| 2278 | { eassert (pdl->kind == SPECPDL_BACKTRACE); return pdl->v.bt.debug_on_exit; } | ||
| 2279 | |||
| 2280 | extern struct specbinding *specpdl; | ||
| 2281 | extern struct specbinding *specpdl_ptr; | ||
| 2282 | extern ptrdiff_t specpdl_size; | 2739 | extern ptrdiff_t specpdl_size; |
| 2283 | 2740 | ||
| 2284 | #define SPECPDL_INDEX() (specpdl_ptr - specpdl) | 2741 | LISP_INLINE ptrdiff_t |
| 2742 | SPECPDL_INDEX (void) | ||
| 2743 | { | ||
| 2744 | return specpdl_ptr - specpdl; | ||
| 2745 | } | ||
| 2285 | 2746 | ||
| 2286 | /* Everything needed to describe an active condition case. | 2747 | /* Everything needed to describe an active condition case. |
| 2287 | 2748 | ||
| @@ -2597,27 +3058,12 @@ void staticpro (Lisp_Object *); | |||
| 2597 | #define EXFUN(fnname, maxargs) \ | 3058 | #define EXFUN(fnname, maxargs) \ |
| 2598 | extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs | 3059 | extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs |
| 2599 | 3060 | ||
| 3061 | #include "globals.h" | ||
| 3062 | |||
| 2600 | /* Forward declarations for prototypes. */ | 3063 | /* Forward declarations for prototypes. */ |
| 2601 | struct window; | 3064 | struct window; |
| 2602 | struct frame; | 3065 | struct frame; |
| 2603 | 3066 | ||
| 2604 | /* Simple access functions. */ | ||
| 2605 | |||
| 2606 | LISP_INLINE Lisp_Object * | ||
| 2607 | aref_addr (Lisp_Object array, ptrdiff_t idx) | ||
| 2608 | { | ||
| 2609 | return & XVECTOR (array)->contents[idx]; | ||
| 2610 | } | ||
| 2611 | |||
| 2612 | LISP_INLINE void | ||
| 2613 | gc_aset (Lisp_Object array, ptrdiff_t idx, Lisp_Object val) | ||
| 2614 | { | ||
| 2615 | /* Like ASET, but also can be used in the garbage collector: | ||
| 2616 | sweep_weak_table calls set_hash_key etc. while the table is marked. */ | ||
| 2617 | eassert (0 <= idx && idx < (ASIZE (array) & ~ARRAY_MARK_FLAG)); | ||
| 2618 | XVECTOR (array)->contents[idx] = val; | ||
| 2619 | } | ||
| 2620 | |||
| 2621 | /* Copy COUNT Lisp_Objects from ARGS to contents of V starting from OFFSET. */ | 3067 | /* Copy COUNT Lisp_Objects from ARGS to contents of V starting from OFFSET. */ |
| 2622 | 3068 | ||
| 2623 | LISP_INLINE void | 3069 | LISP_INLINE void |
| @@ -2630,12 +3076,6 @@ vcopy (Lisp_Object v, ptrdiff_t offset, Lisp_Object *args, ptrdiff_t count) | |||
| 2630 | /* Functions to modify hash tables. */ | 3076 | /* Functions to modify hash tables. */ |
| 2631 | 3077 | ||
| 2632 | LISP_INLINE void | 3078 | LISP_INLINE void |
| 2633 | set_hash_key_and_value (struct Lisp_Hash_Table *h, Lisp_Object key_and_value) | ||
| 2634 | { | ||
| 2635 | h->key_and_value = key_and_value; | ||
| 2636 | } | ||
| 2637 | |||
| 2638 | LISP_INLINE void | ||
| 2639 | set_hash_key_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val) | 3079 | set_hash_key_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val) |
| 2640 | { | 3080 | { |
| 2641 | gc_aset (h->key_and_value, 2 * idx, val); | 3081 | gc_aset (h->key_and_value, 2 * idx, val); |
| @@ -2647,52 +3087,10 @@ set_hash_value_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val) | |||
| 2647 | gc_aset (h->key_and_value, 2 * idx + 1, val); | 3087 | gc_aset (h->key_and_value, 2 * idx + 1, val); |
| 2648 | } | 3088 | } |
| 2649 | 3089 | ||
| 2650 | LISP_INLINE void | ||
| 2651 | set_hash_next (struct Lisp_Hash_Table *h, Lisp_Object next) | ||
| 2652 | { | ||
| 2653 | h->next = next; | ||
| 2654 | } | ||
| 2655 | |||
| 2656 | LISP_INLINE void | ||
| 2657 | set_hash_next_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val) | ||
| 2658 | { | ||
| 2659 | gc_aset (h->next, idx, val); | ||
| 2660 | } | ||
| 2661 | |||
| 2662 | LISP_INLINE void | ||
| 2663 | set_hash_hash (struct Lisp_Hash_Table *h, Lisp_Object hash) | ||
| 2664 | { | ||
| 2665 | h->hash = hash; | ||
| 2666 | } | ||
| 2667 | |||
| 2668 | LISP_INLINE void | ||
| 2669 | set_hash_hash_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val) | ||
| 2670 | { | ||
| 2671 | gc_aset (h->hash, idx, val); | ||
| 2672 | } | ||
| 2673 | |||
| 2674 | LISP_INLINE void | ||
| 2675 | set_hash_index (struct Lisp_Hash_Table *h, Lisp_Object index) | ||
| 2676 | { | ||
| 2677 | h->index = index; | ||
| 2678 | } | ||
| 2679 | |||
| 2680 | LISP_INLINE void | ||
| 2681 | set_hash_index_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val) | ||
| 2682 | { | ||
| 2683 | gc_aset (h->index, idx, val); | ||
| 2684 | } | ||
| 2685 | |||
| 2686 | /* Use these functions to set Lisp_Object | 3090 | /* Use these functions to set Lisp_Object |
| 2687 | or pointer slots of struct Lisp_Symbol. */ | 3091 | or pointer slots of struct Lisp_Symbol. */ |
| 2688 | 3092 | ||
| 2689 | LISP_INLINE void | 3093 | LISP_INLINE void |
| 2690 | set_symbol_name (Lisp_Object sym, Lisp_Object name) | ||
| 2691 | { | ||
| 2692 | XSYMBOL (sym)->name = name; | ||
| 2693 | } | ||
| 2694 | |||
| 2695 | LISP_INLINE void | ||
| 2696 | set_symbol_function (Lisp_Object sym, Lisp_Object function) | 3094 | set_symbol_function (Lisp_Object sym, Lisp_Object function) |
| 2697 | { | 3095 | { |
| 2698 | XSYMBOL (sym)->function = function; | 3096 | XSYMBOL (sym)->function = function; |
| @@ -2719,43 +3117,6 @@ blv_found (struct Lisp_Buffer_Local_Value *blv) | |||
| 2719 | return blv->found; | 3117 | return blv->found; |
| 2720 | } | 3118 | } |
| 2721 | 3119 | ||
| 2722 | LISP_INLINE void | ||
| 2723 | set_blv_found (struct Lisp_Buffer_Local_Value *blv, int found) | ||
| 2724 | { | ||
| 2725 | eassert (found == !EQ (blv->defcell, blv->valcell)); | ||
| 2726 | blv->found = found; | ||
| 2727 | } | ||
| 2728 | |||
| 2729 | LISP_INLINE Lisp_Object | ||
| 2730 | blv_value (struct Lisp_Buffer_Local_Value *blv) | ||
| 2731 | { | ||
| 2732 | return XCDR (blv->valcell); | ||
| 2733 | } | ||
| 2734 | |||
| 2735 | LISP_INLINE void | ||
| 2736 | set_blv_value (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val) | ||
| 2737 | { | ||
| 2738 | XSETCDR (blv->valcell, val); | ||
| 2739 | } | ||
| 2740 | |||
| 2741 | LISP_INLINE void | ||
| 2742 | set_blv_where (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val) | ||
| 2743 | { | ||
| 2744 | blv->where = val; | ||
| 2745 | } | ||
| 2746 | |||
| 2747 | LISP_INLINE void | ||
| 2748 | set_blv_defcell (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val) | ||
| 2749 | { | ||
| 2750 | blv->defcell = val; | ||
| 2751 | } | ||
| 2752 | |||
| 2753 | LISP_INLINE void | ||
| 2754 | set_blv_valcell (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val) | ||
| 2755 | { | ||
| 2756 | blv->valcell = val; | ||
| 2757 | } | ||
| 2758 | |||
| 2759 | /* Set overlay's property list. */ | 3120 | /* Set overlay's property list. */ |
| 2760 | 3121 | ||
| 2761 | LISP_INLINE void | 3122 | LISP_INLINE void |
| @@ -2784,21 +3145,11 @@ set_string_intervals (Lisp_Object s, INTERVAL i) | |||
| 2784 | of setting slots directly. */ | 3145 | of setting slots directly. */ |
| 2785 | 3146 | ||
| 2786 | LISP_INLINE void | 3147 | LISP_INLINE void |
| 2787 | set_char_table_ascii (Lisp_Object table, Lisp_Object val) | ||
| 2788 | { | ||
| 2789 | XCHAR_TABLE (table)->ascii = val; | ||
| 2790 | } | ||
| 2791 | LISP_INLINE void | ||
| 2792 | set_char_table_defalt (Lisp_Object table, Lisp_Object val) | 3148 | set_char_table_defalt (Lisp_Object table, Lisp_Object val) |
| 2793 | { | 3149 | { |
| 2794 | XCHAR_TABLE (table)->defalt = val; | 3150 | XCHAR_TABLE (table)->defalt = val; |
| 2795 | } | 3151 | } |
| 2796 | LISP_INLINE void | 3152 | LISP_INLINE void |
| 2797 | set_char_table_parent (Lisp_Object table, Lisp_Object val) | ||
| 2798 | { | ||
| 2799 | XCHAR_TABLE (table)->parent = val; | ||
| 2800 | } | ||
| 2801 | LISP_INLINE void | ||
| 2802 | set_char_table_purpose (Lisp_Object table, Lisp_Object val) | 3153 | set_char_table_purpose (Lisp_Object table, Lisp_Object val) |
| 2803 | { | 3154 | { |
| 2804 | XCHAR_TABLE (table)->purpose = val; | 3155 | XCHAR_TABLE (table)->purpose = val; |
| @@ -3242,7 +3593,7 @@ extern int valid_lisp_object_p (Lisp_Object); | |||
| 3242 | #ifdef GC_CHECK_CONS_LIST | 3593 | #ifdef GC_CHECK_CONS_LIST |
| 3243 | extern void check_cons_list (void); | 3594 | extern void check_cons_list (void); |
| 3244 | #else | 3595 | #else |
| 3245 | #define check_cons_list() ((void) 0) | 3596 | LISP_INLINE void (check_cons_list) (void) { lisp_h_check_cons_list (); } |
| 3246 | #endif | 3597 | #endif |
| 3247 | 3598 | ||
| 3248 | #ifdef REL_ALLOC | 3599 | #ifdef REL_ALLOC |
| @@ -3310,10 +3661,12 @@ extern Lisp_Object check_obarray (Lisp_Object); | |||
| 3310 | extern Lisp_Object intern_1 (const char *, ptrdiff_t); | 3661 | extern Lisp_Object intern_1 (const char *, ptrdiff_t); |
| 3311 | extern Lisp_Object intern_c_string_1 (const char *, ptrdiff_t); | 3662 | extern Lisp_Object intern_c_string_1 (const char *, ptrdiff_t); |
| 3312 | extern Lisp_Object oblookup (Lisp_Object, const char *, ptrdiff_t, ptrdiff_t); | 3663 | extern Lisp_Object oblookup (Lisp_Object, const char *, ptrdiff_t, ptrdiff_t); |
| 3313 | #define LOADHIST_ATTACH(x) \ | 3664 | LISP_INLINE void |
| 3314 | do { \ | 3665 | LOADHIST_ATTACH (Lisp_Object x) |
| 3315 | if (initialized) Vcurrent_load_list = Fcons (x, Vcurrent_load_list); \ | 3666 | { |
| 3316 | } while (0) | 3667 | if (initialized) |
| 3668 | Vcurrent_load_list = Fcons (x, Vcurrent_load_list); | ||
| 3669 | } | ||
| 3317 | extern int openp (Lisp_Object, Lisp_Object, Lisp_Object, | 3670 | extern int openp (Lisp_Object, Lisp_Object, Lisp_Object, |
| 3318 | Lisp_Object *, Lisp_Object); | 3671 | Lisp_Object *, Lisp_Object); |
| 3319 | extern Lisp_Object string_to_number (char const *, int, bool); | 3672 | extern Lisp_Object string_to_number (char const *, int, bool); |
| @@ -3599,10 +3952,9 @@ void fixup_locale (void); | |||
| 3599 | void synchronize_system_messages_locale (void); | 3952 | void synchronize_system_messages_locale (void); |
| 3600 | void synchronize_system_time_locale (void); | 3953 | void synchronize_system_time_locale (void); |
| 3601 | #else | 3954 | #else |
| 3602 | #define setlocale(category, locale) | 3955 | LISP_INLINE void fixup_locale (void) {} |
| 3603 | #define fixup_locale() | 3956 | LISP_INLINE void synchronize_system_messages_locale (void) {} |
| 3604 | #define synchronize_system_messages_locale() | 3957 | LISP_INLINE void synchronize_system_time_locale (void) {} |
| 3605 | #define synchronize_system_time_locale() | ||
| 3606 | #endif | 3958 | #endif |
| 3607 | extern void shut_down_emacs (int, Lisp_Object); | 3959 | extern void shut_down_emacs (int, Lisp_Object); |
| 3608 | 3960 | ||
| @@ -3961,8 +4313,6 @@ extern void *record_xmalloc (size_t); | |||
| 3961 | } while (0) | 4313 | } while (0) |
| 3962 | 4314 | ||
| 3963 | 4315 | ||
| 3964 | #include "globals.h" | ||
| 3965 | |||
| 3966 | /* Check whether it's time for GC, and run it if so. */ | 4316 | /* Check whether it's time for GC, and run it if so. */ |
| 3967 | 4317 | ||
| 3968 | LISP_INLINE void | 4318 | LISP_INLINE void |
| @@ -3975,7 +4325,7 @@ maybe_gc (void) | |||
| 3975 | Fgarbage_collect (); | 4325 | Fgarbage_collect (); |
| 3976 | } | 4326 | } |
| 3977 | 4327 | ||
| 3978 | LISP_INLINE int | 4328 | LISP_INLINE bool |
| 3979 | functionp (Lisp_Object object) | 4329 | functionp (Lisp_Object object) |
| 3980 | { | 4330 | { |
| 3981 | if (SYMBOLP (object) && !NILP (Ffboundp (object))) | 4331 | if (SYMBOLP (object) && !NILP (Ffboundp (object))) |