428
+ − 1 /* The "lrecord" structure (header of a compound lisp object).
+ − 2 Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
788
+ − 3 Copyright (C) 1996, 2001, 2002 Ben Wing.
428
+ − 4
+ − 5 This file is part of XEmacs.
+ − 6
+ − 7 XEmacs is free software; you can redistribute it and/or modify it
+ − 8 under the terms of the GNU General Public License as published by the
+ − 9 Free Software Foundation; either version 2, or (at your option) any
+ − 10 later version.
+ − 11
+ − 12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ − 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ − 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ − 15 for more details.
+ − 16
+ − 17 You should have received a copy of the GNU General Public License
+ − 18 along with XEmacs; see the file COPYING. If not, write to
+ − 19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ − 20 Boston, MA 02111-1307, USA. */
+ − 21
+ − 22 /* Synched up with: Not in FSF. */
+ − 23
440
+ − 24 #ifndef INCLUDED_lrecord_h_
+ − 25 #define INCLUDED_lrecord_h_
428
+ − 26
+ − 27 /* The "lrecord" type of Lisp object is used for all object types
+ − 28 other than a few simple ones. This allows many types to be
442
+ − 29 implemented but only a few bits required in a Lisp object for type
+ − 30 information. (The tradeoff is that each object has its type marked
+ − 31 in it, thereby increasing its size.) All lrecords begin with a
+ − 32 `struct lrecord_header', which identifies the lisp object type, by
+ − 33 providing an index into a table of `struct lrecord_implementation',
+ − 34 which describes the behavior of the lisp object. It also contains
+ − 35 some other data bits.
428
+ − 36
+ − 37 Lrecords are of two types: straight lrecords, and lcrecords.
+ − 38 Straight lrecords are used for those types of objects that have
+ − 39 their own allocation routines (typically allocated out of 2K chunks
+ − 40 of memory called `frob blocks'). These objects have a `struct
+ − 41 lrecord_header' at the top, containing only the bits needed to find
+ − 42 the lrecord_implementation for the object. There are special
+ − 43 routines in alloc.c to deal with each such object type.
+ − 44
442
+ − 45 Lcrecords are used for less common sorts of objects that don't do
+ − 46 their own allocation. Each such object is malloc()ed individually,
+ − 47 and the objects are chained together through a `next' pointer.
+ − 48 Lcrecords have a `struct lcrecord_header' at the top, which
+ − 49 contains a `struct lrecord_header' and a `next' pointer, and are
+ − 50 allocated using alloc_lcrecord().
428
+ − 51
+ − 52 Creating a new lcrecord type is fairly easy; just follow the
+ − 53 lead of some existing type (e.g. hash tables). Note that you
+ − 54 do not need to supply all the methods (see below); reasonable
+ − 55 defaults are provided for many of them. Alternatively, if you're
+ − 56 just looking for a way of encapsulating data (which possibly
+ − 57 could contain Lisp_Objects in it), you may well be able to use
+ − 58 the opaque type. */
+ − 59
+ − 60 struct lrecord_header
+ − 61 {
+ − 62 /* index into lrecord_implementations_table[] */
442
+ − 63 unsigned int type :8;
+ − 64
+ − 65 /* If `mark' is 0 after the GC mark phase, the object will be freed
+ − 66 during the GC sweep phase. There are 2 ways that `mark' can be 1:
+ − 67 - by being referenced from other objects during the GC mark phase
+ − 68 - because it is permanently on, for c_readonly objects */
+ − 69 unsigned int mark :1;
+ − 70
+ − 71 /* 1 if the object resides in logically read-only space, and does not
+ − 72 reference other non-c_readonly objects.
+ − 73 Invariant: if (c_readonly == 1), then (mark == 1 && lisp_readonly == 1) */
+ − 74 unsigned int c_readonly :1;
+ − 75
428
+ − 76 /* 1 if the object is readonly from lisp */
442
+ − 77 unsigned int lisp_readonly :1;
771
+ − 78
+ − 79 unsigned int unused :21;
428
+ − 80 };
+ − 81
+ − 82 struct lrecord_implementation;
442
+ − 83 int lrecord_type_index (const struct lrecord_implementation *implementation);
428
+ − 84
430
+ − 85 #define set_lheader_implementation(header,imp) do { \
428
+ − 86 struct lrecord_header* SLI_header = (header); \
442
+ − 87 SLI_header->type = (imp)->lrecord_type_index; \
430
+ − 88 SLI_header->mark = 0; \
+ − 89 SLI_header->c_readonly = 0; \
+ − 90 SLI_header->lisp_readonly = 0; \
428
+ − 91 } while (0)
+ − 92
+ − 93 struct lcrecord_header
+ − 94 {
+ − 95 struct lrecord_header lheader;
+ − 96
442
+ − 97 /* The `next' field is normally used to chain all lcrecords together
428
+ − 98 so that the GC can find (and free) all of them.
442
+ − 99 `alloc_lcrecord' threads lcrecords together.
428
+ − 100
+ − 101 The `next' field may be used for other purposes as long as some
+ − 102 other mechanism is provided for letting the GC do its work.
+ − 103
+ − 104 For example, the event and marker object types allocate members
+ − 105 out of memory chunks, and are able to find all unmarked members
+ − 106 by sweeping through the elements of the list of chunks. */
+ − 107 struct lcrecord_header *next;
+ − 108
+ − 109 /* The `uid' field is just for debugging/printing convenience.
+ − 110 Having this slot doesn't hurt us much spacewise, since an
+ − 111 lcrecord already has the above slots plus malloc overhead. */
+ − 112 unsigned int uid :31;
+ − 113
+ − 114 /* The `free' field is a flag that indicates whether this lcrecord
+ − 115 is on a "free list". Free lists are used to minimize the number
+ − 116 of calls to malloc() when we're repeatedly allocating and freeing
+ − 117 a number of the same sort of lcrecord. Lcrecords on a free list
+ − 118 always get marked in a different fashion, so we can use this flag
+ − 119 as a sanity check to make sure that free lists only have freed
+ − 120 lcrecords and there are no freed lcrecords elsewhere. */
+ − 121 unsigned int free :1;
+ − 122 };
+ − 123
+ − 124 /* Used for lcrecords in an lcrecord-list. */
+ − 125 struct free_lcrecord_header
+ − 126 {
+ − 127 struct lcrecord_header lcheader;
+ − 128 Lisp_Object chain;
+ − 129 };
+ − 130
442
+ − 131 enum lrecord_type
+ − 132 {
+ − 133 /* Symbol value magic types come first to make SYMBOL_VALUE_MAGIC_P fast.
+ − 134 #### This should be replaced by a symbol_value_magic_p flag
+ − 135 in the Lisp_Symbol lrecord_header. */
+ − 136 lrecord_type_symbol_value_forward,
+ − 137 lrecord_type_symbol_value_varalias,
+ − 138 lrecord_type_symbol_value_lisp_magic,
+ − 139 lrecord_type_symbol_value_buffer_local,
+ − 140 lrecord_type_max_symbol_value_magic = lrecord_type_symbol_value_buffer_local,
+ − 141
+ − 142 lrecord_type_symbol,
+ − 143 lrecord_type_subr,
+ − 144 lrecord_type_cons,
+ − 145 lrecord_type_vector,
+ − 146 lrecord_type_string,
+ − 147 lrecord_type_lcrecord_list,
+ − 148 lrecord_type_compiled_function,
+ − 149 lrecord_type_weak_list,
+ − 150 lrecord_type_bit_vector,
+ − 151 lrecord_type_float,
+ − 152 lrecord_type_hash_table,
+ − 153 lrecord_type_lstream,
+ − 154 lrecord_type_process,
+ − 155 lrecord_type_charset,
+ − 156 lrecord_type_coding_system,
+ − 157 lrecord_type_char_table,
+ − 158 lrecord_type_char_table_entry,
+ − 159 lrecord_type_range_table,
+ − 160 lrecord_type_opaque,
+ − 161 lrecord_type_opaque_ptr,
+ − 162 lrecord_type_buffer,
+ − 163 lrecord_type_extent,
+ − 164 lrecord_type_extent_info,
+ − 165 lrecord_type_extent_auxiliary,
+ − 166 lrecord_type_marker,
+ − 167 lrecord_type_event,
+ − 168 lrecord_type_keymap,
+ − 169 lrecord_type_command_builder,
+ − 170 lrecord_type_timeout,
+ − 171 lrecord_type_specifier,
+ − 172 lrecord_type_console,
+ − 173 lrecord_type_device,
+ − 174 lrecord_type_frame,
+ − 175 lrecord_type_window,
617
+ − 176 lrecord_type_window_mirror,
442
+ − 177 lrecord_type_window_configuration,
+ − 178 lrecord_type_gui_item,
+ − 179 lrecord_type_popup_data,
+ − 180 lrecord_type_toolbar_button,
617
+ − 181 lrecord_type_scrollbar_instance,
442
+ − 182 lrecord_type_color_instance,
+ − 183 lrecord_type_font_instance,
+ − 184 lrecord_type_image_instance,
+ − 185 lrecord_type_glyph,
+ − 186 lrecord_type_face,
+ − 187 lrecord_type_database,
+ − 188 lrecord_type_tooltalk_message,
+ − 189 lrecord_type_tooltalk_pattern,
+ − 190 lrecord_type_ldap,
+ − 191 lrecord_type_pgconn,
+ − 192 lrecord_type_pgresult,
+ − 193 lrecord_type_devmode,
+ − 194 lrecord_type_mswindows_dialog_id,
446
+ − 195 lrecord_type_case_table,
462
+ − 196 lrecord_type_emacs_ffi,
+ − 197 lrecord_type_emacs_gtk_object,
+ − 198 lrecord_type_emacs_gtk_boxed,
858
+ − 199 lrecord_type_weak_box,
454
+ − 200 lrecord_type_free, /* only used for "free" lrecords */
+ − 201 lrecord_type_undefined, /* only used for debugging */
442
+ − 202 lrecord_type_last_built_in_type /* must be last */
+ − 203 };
+ − 204
647
+ − 205 extern int lrecord_type_count;
428
+ − 206
+ − 207 struct lrecord_implementation
+ − 208 {
442
+ − 209 const char *name;
+ − 210
+ − 211 /* `marker' is called at GC time, to make sure that all Lisp_Objects
428
+ − 212 pointed to by this object get properly marked. It should call
+ − 213 the mark_object function on all Lisp_Objects in the object. If
+ − 214 the return value is non-nil, it should be a Lisp_Object to be
+ − 215 marked (don't call the mark_object function explicitly on it,
+ − 216 because the GC routines will do this). Doing it this way reduces
+ − 217 recursion, so the object returned should preferably be the one
+ − 218 with the deepest level of Lisp_Object pointers. This function
+ − 219 can be NULL, meaning no GC marking is necessary. */
+ − 220 Lisp_Object (*marker) (Lisp_Object);
442
+ − 221
+ − 222 /* `printer' converts the object to a printed representation.
+ − 223 This can be NULL; in this case default_object_printer() will be
+ − 224 used instead. */
428
+ − 225 void (*printer) (Lisp_Object, Lisp_Object printcharfun, int escapeflag);
442
+ − 226
+ − 227 /* `finalizer' is called at GC time when the object is about to
428
+ − 228 be freed, and at dump time (FOR_DISKSAVE will be non-zero in this
+ − 229 case). It should perform any necessary cleanup (e.g. freeing
442
+ − 230 malloc()ed memory). This can be NULL, meaning no special
428
+ − 231 finalization is necessary.
+ − 232
442
+ − 233 WARNING: remember that `finalizer' is called at dump time even
428
+ − 234 though the object is not being freed. */
+ − 235 void (*finalizer) (void *header, int for_disksave);
442
+ − 236
428
+ − 237 /* This can be NULL, meaning compare objects with EQ(). */
+ − 238 int (*equal) (Lisp_Object obj1, Lisp_Object obj2, int depth);
442
+ − 239
+ − 240 /* `hash' generates hash values for use with hash tables that have
+ − 241 `equal' as their test function. This can be NULL, meaning use
+ − 242 the Lisp_Object itself as the hash. But, you must still satisfy
+ − 243 the constraint that if two objects are `equal', then they *must*
+ − 244 hash to the same value in order for hash tables to work properly.
+ − 245 This means that `hash' can be NULL only if the `equal' method is
+ − 246 also NULL. */
428
+ − 247 unsigned long (*hash) (Lisp_Object, int);
+ − 248
+ − 249 /* External data layout description */
+ − 250 const struct lrecord_description *description;
+ − 251
442
+ − 252 /* These functions allow any object type to have builtin property
+ − 253 lists that can be manipulated from the lisp level with
+ − 254 `get', `put', `remprop', and `object-plist'. */
428
+ − 255 Lisp_Object (*getprop) (Lisp_Object obj, Lisp_Object prop);
+ − 256 int (*putprop) (Lisp_Object obj, Lisp_Object prop, Lisp_Object val);
+ − 257 int (*remprop) (Lisp_Object obj, Lisp_Object prop);
+ − 258 Lisp_Object (*plist) (Lisp_Object obj);
+ − 259
442
+ − 260 /* Only one of `static_size' and `size_in_bytes_method' is non-0.
+ − 261 If both are 0, this type is not instantiable by alloc_lcrecord(). */
665
+ − 262 Bytecount static_size;
+ − 263 Bytecount (*size_in_bytes_method) (const void *header);
442
+ − 264
+ − 265 /* The (constant) index into lrecord_implementations_table */
+ − 266 enum lrecord_type lrecord_type_index;
+ − 267
428
+ − 268 /* A "basic" lrecord is any lrecord that's not an lcrecord, i.e.
+ − 269 one that does not have an lcrecord_header at the front and which
+ − 270 is (usually) allocated in frob blocks. We only use this flag for
+ − 271 some consistency checking, and that only when error-checking is
+ − 272 enabled. */
442
+ − 273 unsigned int basic_p :1;
428
+ − 274 };
+ − 275
617
+ − 276 /* All the built-in lisp object types are enumerated in `enum lrecord_type'.
442
+ − 277 Additional ones may be defined by a module (none yet). We leave some
+ − 278 room in `lrecord_implementations_table' for such new lisp object types. */
+ − 279 #define MODULE_DEFINABLE_TYPE_COUNT 32
+ − 280
647
+ − 281 extern const struct lrecord_implementation *lrecord_implementations_table[lrecord_type_last_built_in_type + MODULE_DEFINABLE_TYPE_COUNT];
428
+ − 282
+ − 283 #define XRECORD_LHEADER_IMPLEMENTATION(obj) \
442
+ − 284 LHEADER_IMPLEMENTATION (XRECORD_LHEADER (obj))
+ − 285 #define LHEADER_IMPLEMENTATION(lh) lrecord_implementations_table[(lh)->type]
428
+ − 286
+ − 287 extern int gc_in_progress;
+ − 288
442
+ − 289 #define MARKED_RECORD_P(obj) (XRECORD_LHEADER (obj)->mark)
428
+ − 290 #define MARKED_RECORD_HEADER_P(lheader) ((lheader)->mark)
+ − 291 #define MARK_RECORD_HEADER(lheader) ((void) ((lheader)->mark = 1))
+ − 292 #define UNMARK_RECORD_HEADER(lheader) ((void) ((lheader)->mark = 0))
+ − 293
+ − 294 #define C_READONLY_RECORD_HEADER_P(lheader) ((lheader)->c_readonly)
+ − 295 #define LISP_READONLY_RECORD_HEADER_P(lheader) ((lheader)->lisp_readonly)
442
+ − 296 #define SET_C_READONLY_RECORD_HEADER(lheader) do { \
+ − 297 struct lrecord_header *SCRRH_lheader = (lheader); \
+ − 298 SCRRH_lheader->c_readonly = 1; \
+ − 299 SCRRH_lheader->lisp_readonly = 1; \
+ − 300 SCRRH_lheader->mark = 1; \
+ − 301 } while (0)
428
+ − 302 #define SET_LISP_READONLY_RECORD_HEADER(lheader) \
+ − 303 ((void) ((lheader)->lisp_readonly = 1))
442
+ − 304 #define RECORD_MARKER(lheader) lrecord_markers[(lheader)->type]
428
+ − 305
+ − 306 /* External description stuff
+ − 307
771
+ − 308 PLEASE NOTE: Both lrecord_description and struct_description are
+ − 309 badly misnamed. In reality, an lrecord_description is nothing more
+ − 310 than a list of the elements in a block of memory that need
+ − 311 relocating or other special handling, and a struct_description is
+ − 312 no more than an lrecord_description plus the size of the block of
+ − 313 memory. (In fact, a struct_description can now have its size given
+ − 314 as zero, i.e. unspecified, meaning that the last element in the
+ − 315 structure is noted in the list and the size of the block can
+ − 316 therefore be computed from it.) The names stem from the fact
+ − 317 lrecord_descriptions are used to describe lrecords (the size of the
+ − 318 lrecord is elsewhere in its description, attached to its methods,
+ − 319 so it does not need to be given here), while struct_descriptions
+ − 320 are used to describe C structs; but both are used in various
+ − 321 additional ways. Much better terms would be memory_description and
+ − 322 sized_memory_description.
428
+ − 323
771
+ − 324 An lrecord_description is an array of values. (This is actually
+ − 325 misnamed, in that it does not just describe lrecords, but any
+ − 326 blocks of memory.) The first value of each line is a type, the
+ − 327 second the offset in the lrecord structure. The third and
+ − 328 following elements are parameters; their presence, type and number
+ − 329 is type-dependent.
+ − 330
+ − 331 The description ends with a "XD_END", "XD_SPECIFIER_END" or
+ − 332 "XD_CODING_SYSTEM_END" record.
+ − 333
+ − 334 The top-level description of an lrecord or lcrecord does not need
+ − 335 to describe every element, just the ones that need to be relocated,
+ − 336 since the size of the lrecord is known. (The same goes for nested
+ − 337 structures, whenever the structure size is given, rather than being
+ − 338 defaulted by specifying 0 for the size.)
+ − 339
814
+ − 340 A struct_description is used for describing nested "structures". (Again
+ − 341 a misnomer, since it can be used for any blocks of memory, not just
+ − 342 structures.) It just contains a size for the memory block, a pointer to
+ − 343 an lrecord_description, and (for unions only) a union constant,
+ − 344 described below. The size can be 0, in which case the size will be
+ − 345 determined from the largest offset logically referenced (i.e. last
+ − 346 offset mentioned + size of that object). This is useful for stretchy
+ − 347 arrays.
428
+ − 348
+ − 349 Some example descriptions :
440
+ − 350
814
+ − 351 struct Lisp_String
+ − 352 {
+ − 353 struct lrecord_header lheader;
+ − 354 Bytecount size;
867
+ − 355 Ibyte *data;
814
+ − 356 Lisp_Object plist;
+ − 357 };
+ − 358
428
+ − 359 static const struct lrecord_description cons_description[] = {
440
+ − 360 { XD_LISP_OBJECT, offsetof (Lisp_Cons, car) },
+ − 361 { XD_LISP_OBJECT, offsetof (Lisp_Cons, cdr) },
428
+ − 362 { XD_END }
+ − 363 };
+ − 364
440
+ − 365 Which means "two lisp objects starting at the 'car' and 'cdr' elements"
428
+ − 366
814
+ − 367 static const struct lrecord_description string_description[] = {
+ − 368 { XD_BYTECOUNT, offsetof (Lisp_String, size) },
+ − 369 { XD_OPAQUE_DATA_PTR, offsetof (Lisp_String, data), XD_INDIRECT(0, 1) },
+ − 370 { XD_LISP_OBJECT, offsetof (Lisp_String, plist) },
+ − 371 { XD_END }
+ − 372 };
+ − 373
+ − 374 "A pointer to string data at 'data', the size of the pointed array being
+ − 375 the value of the size variable plus 1, and one lisp object at 'plist'"
+ − 376
+ − 377 If your object has a pointer to an array of Lisp_Objects in it, something
+ − 378 like this:
+ − 379
+ − 380 struct Lisp_Foo
+ − 381 {
+ − 382 ...;
+ − 383 int count;
+ − 384 Lisp_Object *objects;
+ − 385 ...;
+ − 386 }
+ − 387
+ − 388 You'd use XD_STRUCT_PTR, something like:
+ − 389
+ − 390 static const struct lrecord_description lo_description_1[] = {
+ − 391 { XD_LISP_OBJECT, 0 },
+ − 392 { XD_END }
+ − 393 };
+ − 394
+ − 395 static const struct struct_description lo_description = {
+ − 396 sizeof (Lisp_Object),
+ − 397 lo_description_1
+ − 398 };
+ − 399
+ − 400 static const struct lrecord_description foo_description[] = {
+ − 401 ...
+ − 402 { XD_INT, offsetof (Lisp_Foo, count) },
+ − 403 { XD_STRUCT_PTR, offsetof (Lisp_Foo, objects),
+ − 404 XD_INDIRECT (0, 0), &lo_description },
+ − 405 ...
+ − 406 };
+ − 407
+ − 408
+ − 409 Another example of XD_STRUCT_PTR:
428
+ − 410
814
+ − 411 typedef struct hentry
+ − 412 {
+ − 413 Lisp_Object key;
+ − 414 Lisp_Object value;
+ − 415 } hentry;
+ − 416
+ − 417 struct Lisp_Hash_Table
+ − 418 {
+ − 419 struct lcrecord_header header;
+ − 420 Elemcount size;
+ − 421 Elemcount count;
+ − 422 Elemcount rehash_count;
+ − 423 double rehash_size;
+ − 424 double rehash_threshold;
+ − 425 Elemcount golden_ratio;
+ − 426 hash_table_hash_function_t hash_function;
+ − 427 hash_table_test_function_t test_function;
+ − 428 hentry *hentries;
+ − 429 enum hash_table_weakness weakness;
+ − 430 Lisp_Object next_weak; // Used to chain together all of the weak
+ − 431 // hash tables. Don't mark through this.
+ − 432 };
+ − 433
+ − 434 static const struct lrecord_description hentry_description_1[] = {
+ − 435 { XD_LISP_OBJECT, offsetof (hentry, key) },
+ − 436 { XD_LISP_OBJECT, offsetof (hentry, value) },
+ − 437 { XD_END }
+ − 438 };
+ − 439
+ − 440 static const struct struct_description hentry_description = {
+ − 441 sizeof (hentry),
+ − 442 hentry_description_1
+ − 443 };
+ − 444
+ − 445 const struct lrecord_description hash_table_description[] = {
+ − 446 { XD_ELEMCOUNT, offsetof (Lisp_Hash_Table, size) },
+ − 447 { XD_STRUCT_PTR, offsetof (Lisp_Hash_Table, hentries), XD_INDIRECT(0, 1),
+ − 448 &hentry_description },
+ − 449 { XD_LO_LINK, offsetof (Lisp_Hash_Table, next_weak) },
+ − 450 { XD_END }
+ − 451 };
+ − 452
+ − 453 Note that we don't need to declare all the elements in the structure, just
+ − 454 the ones that need to be relocated (Lisp_Objects and structures) or that
+ − 455 need to be referenced as counts for relocated objects.
+ − 456
+ − 457
+ − 458 The existing types :
+ − 459
+ − 460
428
+ − 461 XD_LISP_OBJECT
440
+ − 462 A Lisp object. This is also the type to use for pointers to other lrecords.
428
+ − 463
440
+ − 464 XD_LISP_OBJECT_ARRAY
771
+ − 465 An array of Lisp objects or (equivalently) pointers to lrecords.
+ − 466 The parameter (i.e. third element) is the count. This would be declared
+ − 467 as Lisp_Object foo[666]. For something declared as Lisp_Object *foo,
+ − 468 use XD_STRUCT_PTR, whose description parameter is a struct_description
+ − 469 consisting of only XD_LISP_OBJECT and XD_END.
440
+ − 470
428
+ − 471 XD_LO_LINK
771
+ − 472 Weak link in a linked list of objects of the same type. This is a
+ − 473 link that does NOT generate a GC reference. Thus the pdumper will
+ − 474 not automatically add the referenced object to the table of all
+ − 475 objects to be dumped, and when storing and loading the dumped data
+ − 476 will automatically prune unreferenced objects in the chain and link
+ − 477 each referenced object to the next referenced object, even if it's
+ − 478 many links away. We also need to special handling of a similar
+ − 479 nature for the root of the chain, which will be a staticpro()ed
+ − 480 object.
432
+ − 481
428
+ − 482 XD_OPAQUE_PTR
+ − 483 Pointer to undumpable data. Must be NULL when dumping.
+ − 484
+ − 485 XD_STRUCT_PTR
771
+ − 486 Pointer to block of described memory. (This is misnamed: It is NOT
+ − 487 necessarily a pointer to a struct foo.) Parameters are number of
+ − 488 contiguous blocks and struct_description.
+ − 489
+ − 490 XD_STRUCT_ARRAY
+ − 491 Array of blocks of described memory. Parameters are number of
+ − 492 structures and struct_description. This differs from XD_STRUCT_PTR
+ − 493 in that the parameter is declared as struct foo[666] instead of
+ − 494 struct *foo. In other words, the block of memory holding the
+ − 495 structures is within the containing structure, rather than being
+ − 496 elsewhere, with a pointer in the containing structure.
428
+ − 497
+ − 498 XD_OPAQUE_DATA_PTR
+ − 499 Pointer to dumpable opaque data. Parameter is the size of the data.
+ − 500 Pointed data must be relocatable without changes.
+ − 501
771
+ − 502 XD_UNION
+ − 503 Union of two or more different types of data. Parameters are a
+ − 504 constant which determines which type the data is (this is usually an
+ − 505 XD_INDIRECT, referring to one of the fields in the structure), and
+ − 506 an array of struct_descriptions, whose values are used as follows,
+ − 507 which is *DIFFERENT* from their usage in XD_STRUCT_PTR: the first
+ − 508 field is a constant, which is compared to the first parameter of the
+ − 509 XD_UNION descriptor to determine if this description applies to the
+ − 510 data at the given offset, and the second is a pointer to a *SINGLE*
+ − 511 lrecord_description structure, describing the data being pointed at
+ − 512 when the associated constant matches. You can go ahead and create
+ − 513 an array of lrecord_description structures and put an XD_END on it,
+ − 514 but only the first one is used. If the data being pointed at is a
+ − 515 structure, you *MAY NOT* substitute an array of lrecord_description
+ − 516 structures describing the structure; instead, use a single
+ − 517 lrecord_description structure with an XD_STRUCT_PTR in it, and point
+ − 518 it in turn to the description of the structure. See charset.h for a
+ − 519 description of how to use XD_UNION. (In other words, if the constant
+ − 520 matches, the lrecord_description pointed at will in essence be
+ − 521 substituted for the XD_UNION declaration.)
+ − 522
428
+ − 523 XD_C_STRING
+ − 524 Pointer to a C string.
+ − 525
+ − 526 XD_DOC_STRING
+ − 527 Pointer to a doc string (C string if positive, opaque value if negative)
+ − 528
+ − 529 XD_INT_RESET
+ − 530 An integer which will be reset to a given value in the dump file.
+ − 531
771
+ − 532
665
+ − 533 XD_ELEMCOUNT
+ − 534 Elemcount value. Used for counts.
647
+ − 535
665
+ − 536 XD_BYTECOUNT
+ − 537 Bytecount value. Used for counts.
647
+ − 538
665
+ − 539 XD_HASHCODE
+ − 540 Hashcode value. Used for the results of hashing functions.
428
+ − 541
+ − 542 XD_INT
+ − 543 int value. Used for counts.
+ − 544
+ − 545 XD_LONG
+ − 546 long value. Used for counts.
+ − 547
771
+ − 548 XD_BYTECOUNT
+ − 549 bytecount value. Used for counts.
+ − 550
428
+ − 551 XD_END
+ − 552 Special type indicating the end of the array.
+ − 553
+ − 554 XD_SPECIFIER_END
+ − 555 Special type indicating the end of the array for a specifier. Extra
771
+ − 556 description, describing the specifier-type-specific data at the end
+ − 557 of the specifier object, is going to be fetched from the specifier
+ − 558 methods. This should occur exactly once, in the description of the
+ − 559 specifier object, and the dump code knows how to special-case this
+ − 560 by fetching the specifier_methods pointer from the appropriate place
+ − 561 in the memory block (which will, of course, be a struct
+ − 562 Lisp_Specifier), fetching the description of the
+ − 563 specifier-type-specific data from this, and continuing processing
+ − 564 the memory block.
+ − 565
+ − 566 XD_CODING_SYSTEM_END
+ − 567 Special type indicating the end of the array for a coding system.
+ − 568 Extra description is going to be fetched from the coding system
+ − 569 methods. Works just like XD_SPECIFIER_END.
428
+ − 570
+ − 571
+ − 572 Special macros:
+ − 573 XD_INDIRECT(line, delta)
+ − 574 Usable where a "count" or "size" is requested. Gives the value of
+ − 575 the element which is at line number 'line' in the description (count
+ − 576 starts at zero) and adds delta to it.
+ − 577 */
+ − 578
647
+ − 579 enum lrecord_description_type
+ − 580 {
440
+ − 581 XD_LISP_OBJECT_ARRAY,
428
+ − 582 XD_LISP_OBJECT,
+ − 583 XD_LO_LINK,
+ − 584 XD_OPAQUE_PTR,
+ − 585 XD_STRUCT_PTR,
771
+ − 586 XD_STRUCT_ARRAY,
428
+ − 587 XD_OPAQUE_DATA_PTR,
771
+ − 588 XD_UNION,
428
+ − 589 XD_C_STRING,
+ − 590 XD_DOC_STRING,
+ − 591 XD_INT_RESET,
665
+ − 592 XD_BYTECOUNT,
+ − 593 XD_ELEMCOUNT,
+ − 594 XD_HASHCODE,
428
+ − 595 XD_INT,
+ − 596 XD_LONG,
+ − 597 XD_END,
771
+ − 598 XD_SPECIFIER_END,
+ − 599 XD_CODING_SYSTEM_END
428
+ − 600 };
+ − 601
647
+ − 602 struct lrecord_description
+ − 603 {
428
+ − 604 enum lrecord_description_type type;
+ − 605 int offset;
+ − 606 EMACS_INT data1;
+ − 607 const struct struct_description *data2;
+ − 608 };
+ − 609
647
+ − 610 struct struct_description
+ − 611 {
665
+ − 612 Bytecount size;
428
+ − 613 const struct lrecord_description *description;
+ − 614 };
+ − 615
+ − 616 #define XD_INDIRECT(val, delta) (-1-((val)|(delta<<8)))
+ − 617
+ − 618 #define XD_IS_INDIRECT(code) (code<0)
+ − 619 #define XD_INDIRECT_VAL(code) ((-1-code) & 255)
+ − 620 #define XD_INDIRECT_DELTA(code) (((-1-code)>>8) & 255)
+ − 621
+ − 622 #define XD_DYNARR_DESC(base_type, sub_desc) \
440
+ − 623 { XD_STRUCT_PTR, offsetof (base_type, base), XD_INDIRECT(1, 0), sub_desc }, \
+ − 624 { XD_INT, offsetof (base_type, cur) }, \
+ − 625 { XD_INT_RESET, offsetof (base_type, max), XD_INDIRECT(1, 0) }
428
+ − 626
+ − 627 /* DEFINE_LRECORD_IMPLEMENTATION is for objects with constant size.
+ − 628 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION is for objects whose size varies.
+ − 629 */
+ − 630
800
+ − 631 #if defined (ERROR_CHECK_TYPES)
+ − 632 # define DECLARE_ERROR_CHECK_TYPES(c_name, structtype)
428
+ − 633 #else
800
+ − 634 # define DECLARE_ERROR_CHECK_TYPES(c_name, structtype)
428
+ − 635 #endif
+ − 636
+ − 637 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \
+ − 638 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype)
+ − 639
442
+ − 640 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \
+ − 641 MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof(structtype),0,1,structtype)
428
+ − 642
+ − 643 #define DEFINE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \
+ − 644 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype)
+ − 645
442
+ − 646 #define DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \
+ − 647 MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof (structtype),0,0,structtype)
428
+ − 648
+ − 649 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \
+ − 650 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,sizer,structtype)
+ − 651
442
+ − 652 #define DEFINE_BASIC_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \
+ − 653 MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,sizer,1,structtype)
428
+ − 654
442
+ − 655 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \
771
+ − 656 MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype)
442
+ − 657
+ − 658 #define MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \
800
+ − 659 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \
442
+ − 660 const struct lrecord_implementation lrecord_##c_name = \
428
+ − 661 { name, marker, printer, nuker, equal, hash, desc, \
442
+ − 662 getprop, putprop, remprop, plist, size, sizer, \
+ − 663 lrecord_type_##c_name, basic_p }
+ − 664
+ − 665 #define DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,structtype) \
+ − 666 DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,structtype)
+ − 667
+ − 668 #define DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,structtype) \
+ − 669 MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizeof (structtype),0,0,structtype)
+ − 670
+ − 671 #define DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \
+ − 672 DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,sizer,structtype)
+ − 673
+ − 674 #define DEFINE_EXTERNAL_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \
+ − 675 MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype)
+ − 676
+ − 677 #define MAKE_EXTERNAL_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \
800
+ − 678 DECLARE_ERROR_CHECK_TYPES(c_name, structtype) \
647
+ − 679 int lrecord_type_##c_name; \
444
+ − 680 struct lrecord_implementation lrecord_##c_name = \
442
+ − 681 { name, marker, printer, nuker, equal, hash, desc, \
+ − 682 getprop, putprop, remprop, plist, size, sizer, \
444
+ − 683 lrecord_type_last_built_in_type, basic_p }
442
+ − 684
+ − 685
+ − 686 extern Lisp_Object (*lrecord_markers[]) (Lisp_Object);
+ − 687
+ − 688 #define INIT_LRECORD_IMPLEMENTATION(type) do { \
+ − 689 lrecord_implementations_table[lrecord_type_##type] = &lrecord_##type; \
+ − 690 lrecord_markers[lrecord_type_##type] = \
+ − 691 lrecord_implementations_table[lrecord_type_##type]->marker; \
+ − 692 } while (0)
428
+ − 693
444
+ − 694 #define INIT_EXTERNAL_LRECORD_IMPLEMENTATION(type) do { \
+ − 695 lrecord_type_##type = lrecord_type_count++; \
+ − 696 lrecord_##type.lrecord_type_index = lrecord_type_##type; \
+ − 697 INIT_LRECORD_IMPLEMENTATION(type); \
+ − 698 } while (0)
+ − 699
428
+ − 700 #define LRECORDP(a) (XTYPE (a) == Lisp_Type_Record)
+ − 701 #define XRECORD_LHEADER(a) ((struct lrecord_header *) XPNTR (a))
+ − 702
+ − 703 #define RECORD_TYPEP(x, ty) \
647
+ − 704 (LRECORDP (x) && (XRECORD_LHEADER (x)->type == (unsigned int) (ty)))
442
+ − 705
+ − 706 /* Steps to create a new object:
+ − 707
+ − 708 1. Declare the struct for your object in a header file somewhere.
+ − 709 Remember that it must begin with
+ − 710
+ − 711 struct lcrecord_header header;
+ − 712
793
+ − 713 2. Put the "standard junk" (DECLARE_RECORD()/XFOO/etc.) below the
617
+ − 714 struct definition -- see below.
442
+ − 715
+ − 716 3. Add this header file to inline.c.
+ − 717
+ − 718 4. Create the methods for your object. Note that technically you don't
+ − 719 need any, but you will almost always want at least a mark method.
+ − 720
+ − 721 5. Define your object with DEFINE_LRECORD_IMPLEMENTATION() or some
+ − 722 variant.
+ − 723
+ − 724 6. Include the header file in the .c file where you defined the object.
+ − 725
+ − 726 7. Put a call to INIT_LRECORD_IMPLEMENTATION() for the object in the
+ − 727 .c file's syms_of_foo() function.
+ − 728
+ − 729 8. Add a type enum for the object to enum lrecord_type, earlier in this
+ − 730 file.
+ − 731
+ − 732 An example:
428
+ − 733
442
+ − 734 ------------------------------ in toolbar.h -----------------------------
+ − 735
+ − 736 struct toolbar_button
+ − 737 {
+ − 738 struct lcrecord_header header;
+ − 739
+ − 740 Lisp_Object next;
+ − 741 Lisp_Object frame;
+ − 742
+ − 743 Lisp_Object up_glyph;
+ − 744 Lisp_Object down_glyph;
+ − 745 Lisp_Object disabled_glyph;
+ − 746
+ − 747 Lisp_Object cap_up_glyph;
+ − 748 Lisp_Object cap_down_glyph;
+ − 749 Lisp_Object cap_disabled_glyph;
+ − 750
+ − 751 Lisp_Object callback;
+ − 752 Lisp_Object enabled_p;
+ − 753 Lisp_Object help_string;
+ − 754
+ − 755 char enabled;
+ − 756 char down;
+ − 757 char pushright;
+ − 758 char blank;
+ − 759
+ − 760 int x, y;
+ − 761 int width, height;
+ − 762 int dirty;
+ − 763 int vertical;
+ − 764 int border_width;
+ − 765 };
428
+ − 766
617
+ − 767 [[ the standard junk: ]]
+ − 768
442
+ − 769 DECLARE_LRECORD (toolbar_button, struct toolbar_button);
+ − 770 #define XTOOLBAR_BUTTON(x) XRECORD (x, toolbar_button, struct toolbar_button)
617
+ − 771 #define wrap_toolbar_button(p) wrap_record (p, toolbar_button)
442
+ − 772 #define TOOLBAR_BUTTONP(x) RECORDP (x, toolbar_button)
+ − 773 #define CHECK_TOOLBAR_BUTTON(x) CHECK_RECORD (x, toolbar_button)
+ − 774 #define CONCHECK_TOOLBAR_BUTTON(x) CONCHECK_RECORD (x, toolbar_button)
+ − 775
+ − 776 ------------------------------ in toolbar.c -----------------------------
+ − 777
+ − 778 #include "toolbar.h"
+ − 779
+ − 780 ...
+ − 781
+ − 782 static Lisp_Object
+ − 783 mark_toolbar_button (Lisp_Object obj)
+ − 784 {
+ − 785 struct toolbar_button *data = XTOOLBAR_BUTTON (obj);
+ − 786 mark_object (data->next);
+ − 787 mark_object (data->frame);
+ − 788 mark_object (data->up_glyph);
+ − 789 mark_object (data->down_glyph);
+ − 790 mark_object (data->disabled_glyph);
+ − 791 mark_object (data->cap_up_glyph);
+ − 792 mark_object (data->cap_down_glyph);
+ − 793 mark_object (data->cap_disabled_glyph);
+ − 794 mark_object (data->callback);
+ − 795 mark_object (data->enabled_p);
+ − 796 return data->help_string;
+ − 797 }
+ − 798
617
+ − 799 [[ If your object should never escape to Lisp, declare its print method
+ − 800 as internal_object_printer instead of 0. ]]
+ − 801
442
+ − 802 DEFINE_LRECORD_IMPLEMENTATION ("toolbar-button", toolbar_button,
617
+ − 803 mark_toolbar_button, 0,
+ − 804 0, 0, 0, 0, struct toolbar_button);
442
+ − 805
+ − 806 ...
+ − 807
+ − 808 void
+ − 809 syms_of_toolbar (void)
+ − 810 {
+ − 811 INIT_LRECORD_IMPLEMENTATION (toolbar_button);
+ − 812
+ − 813 ...;
+ − 814 }
+ − 815
+ − 816 ------------------------------ in inline.c -----------------------------
+ − 817
+ − 818 #ifdef HAVE_TOOLBARS
+ − 819 #include "toolbar.h"
+ − 820 #endif
+ − 821
+ − 822 ------------------------------ in lrecord.h -----------------------------
+ − 823
+ − 824 enum lrecord_type
+ − 825 {
+ − 826 ...
+ − 827 lrecord_type_toolbar_button,
+ − 828 ...
+ − 829 };
+ − 830
+ − 831 */
+ − 832
+ − 833 /*
+ − 834
+ − 835 Note: Object types defined in external dynamically-loaded modules (not
+ − 836 part of the XEmacs main source code) should use DECLARE_EXTERNAL_LRECORD
+ − 837 and DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION rather than DECLARE_LRECORD
+ − 838 and DEFINE_LRECORD_IMPLEMENTATION.
+ − 839
+ − 840 */
+ − 841
428
+ − 842
800
+ − 843 #ifdef ERROR_CHECK_TYPES
428
+ − 844
788
+ − 845 # define DECLARE_LRECORD(c_name, structtype) \
+ − 846 extern const struct lrecord_implementation lrecord_##c_name; \
826
+ − 847 DECLARE_INLINE_HEADER ( \
+ − 848 structtype * \
788
+ − 849 error_check_##c_name (Lisp_Object obj, const char *file, int line) \
826
+ − 850 ) \
788
+ − 851 { \
+ − 852 assert_at_line (RECORD_TYPEP (obj, lrecord_type_##c_name), file, line); \
+ − 853 return (structtype *) XPNTR (obj); \
+ − 854 } \
428
+ − 855 extern Lisp_Object Q##c_name##p
+ − 856
788
+ − 857 # define DECLARE_EXTERNAL_LRECORD(c_name, structtype) \
+ − 858 extern int lrecord_type_##c_name; \
+ − 859 extern struct lrecord_implementation lrecord_##c_name; \
826
+ − 860 DECLARE_INLINE_HEADER ( \
+ − 861 structtype * \
788
+ − 862 error_check_##c_name (Lisp_Object obj, const char *file, int line) \
826
+ − 863 ) \
788
+ − 864 { \
+ − 865 assert_at_line (RECORD_TYPEP (obj, lrecord_type_##c_name), file, line); \
+ − 866 return (structtype *) XPNTR (obj); \
+ − 867 } \
444
+ − 868 extern Lisp_Object Q##c_name##p
442
+ − 869
788
+ − 870 # define DECLARE_NONRECORD(c_name, type_enum, structtype) \
826
+ − 871 DECLARE_INLINE_HEADER ( \
+ − 872 structtype * \
788
+ − 873 error_check_##c_name (Lisp_Object obj, const char *file, int line) \
826
+ − 874 ) \
788
+ − 875 { \
+ − 876 assert_at_line (XTYPE (obj) == type_enum, file, line); \
+ − 877 return (structtype *) XPNTR (obj); \
+ − 878 } \
428
+ − 879 extern Lisp_Object Q##c_name##p
+ − 880
788
+ − 881 # define XRECORD(x, c_name, structtype) \
+ − 882 error_check_##c_name (x, __FILE__, __LINE__)
+ − 883 # define XNONRECORD(x, c_name, type_enum, structtype) \
+ − 884 error_check_##c_name (x, __FILE__, __LINE__)
428
+ − 885
826
+ − 886 DECLARE_INLINE_HEADER (
+ − 887 Lisp_Object
800
+ − 888 wrap_record_1 (const void *ptr, enum lrecord_type ty, const char *file,
+ − 889 int line)
826
+ − 890 )
617
+ − 891 {
793
+ − 892 Lisp_Object obj = wrap_pointer_1 (ptr);
+ − 893
788
+ − 894 assert_at_line (RECORD_TYPEP (obj, ty), file, line);
617
+ − 895 return obj;
+ − 896 }
+ − 897
788
+ − 898 #define wrap_record(ptr, ty) \
+ − 899 wrap_record_1 (ptr, lrecord_type_##ty, __FILE__, __LINE__)
617
+ − 900
800
+ − 901 #else /* not ERROR_CHECK_TYPES */
428
+ − 902
+ − 903 # define DECLARE_LRECORD(c_name, structtype) \
+ − 904 extern Lisp_Object Q##c_name##p; \
442
+ − 905 extern const struct lrecord_implementation lrecord_##c_name
+ − 906 # define DECLARE_EXTERNAL_LRECORD(c_name, structtype) \
+ − 907 extern Lisp_Object Q##c_name##p; \
647
+ − 908 extern int lrecord_type_##c_name; \
444
+ − 909 extern struct lrecord_implementation lrecord_##c_name
428
+ − 910 # define DECLARE_NONRECORD(c_name, type_enum, structtype) \
+ − 911 extern Lisp_Object Q##c_name##p
+ − 912 # define XRECORD(x, c_name, structtype) ((structtype *) XPNTR (x))
+ − 913 # define XNONRECORD(x, c_name, type_enum, structtype) \
+ − 914 ((structtype *) XPNTR (x))
617
+ − 915 /* wrap_pointer_1 is so named as a suggestion not to use it unless you
+ − 916 know what you're doing. */
+ − 917 #define wrap_record(ptr, ty) wrap_pointer_1 (ptr)
428
+ − 918
800
+ − 919 #endif /* not ERROR_CHECK_TYPES */
428
+ − 920
442
+ − 921 #define RECORDP(x, c_name) RECORD_TYPEP (x, lrecord_type_##c_name)
428
+ − 922
+ − 923 /* Note: we now have two different kinds of type-checking macros.
+ − 924 The "old" kind has now been renamed CONCHECK_foo. The reason for
+ − 925 this is that the CONCHECK_foo macros signal a continuable error,
+ − 926 allowing the user (through debug-on-error) to substitute a different
+ − 927 value and return from the signal, which causes the lvalue argument
+ − 928 to get changed. Quite a lot of code would crash if that happened,
+ − 929 because it did things like
+ − 930
+ − 931 foo = XCAR (list);
+ − 932 CHECK_STRING (foo);
+ − 933
+ − 934 and later on did XSTRING (XCAR (list)), assuming that the type
+ − 935 is correct (when it might be wrong, if the user substituted a
+ − 936 correct value in the debugger).
+ − 937
+ − 938 To get around this, I made all the CHECK_foo macros signal a
+ − 939 non-continuable error. Places where a continuable error is OK
+ − 940 (generally only when called directly on the argument of a Lisp
+ − 941 primitive) should be changed to use CONCHECK().
+ − 942
+ − 943 FSF Emacs does not have this problem because RMS took the cheesy
+ − 944 way out and disabled returning from a signal entirely. */
+ − 945
+ − 946 #define CONCHECK_RECORD(x, c_name) do { \
442
+ − 947 if (!RECORD_TYPEP (x, lrecord_type_##c_name)) \
428
+ − 948 x = wrong_type_argument (Q##c_name##p, x); \
+ − 949 } while (0)
+ − 950 #define CONCHECK_NONRECORD(x, lisp_enum, predicate) do {\
+ − 951 if (XTYPE (x) != lisp_enum) \
+ − 952 x = wrong_type_argument (predicate, x); \
+ − 953 } while (0)
+ − 954 #define CHECK_RECORD(x, c_name) do { \
442
+ − 955 if (!RECORD_TYPEP (x, lrecord_type_##c_name)) \
428
+ − 956 dead_wrong_type_argument (Q##c_name##p, x); \
+ − 957 } while (0)
+ − 958 #define CHECK_NONRECORD(x, lisp_enum, predicate) do { \
+ − 959 if (XTYPE (x) != lisp_enum) \
+ − 960 dead_wrong_type_argument (predicate, x); \
+ − 961 } while (0)
+ − 962
826
+ − 963 /* Various ways of allocating lcrecords. All bytes (except lcrecord
+ − 964 header) are zeroed in returned structure. */
+ − 965
665
+ − 966 void *alloc_lcrecord (Bytecount size,
647
+ − 967 const struct lrecord_implementation *);
428
+ − 968
771
+ − 969 void *alloc_automanaged_lcrecord (Bytecount size,
+ − 970 const struct lrecord_implementation *);
+ − 971
+ − 972 #define alloc_unmanaged_lcrecord_type(type, lrecord_implementation) \
+ − 973 ((type *) alloc_lcrecord (sizeof (type), lrecord_implementation))
+ − 974
428
+ − 975 #define alloc_lcrecord_type(type, lrecord_implementation) \
771
+ − 976 ((type *) alloc_automanaged_lcrecord (sizeof (type), lrecord_implementation))
+ − 977
+ − 978 void free_lcrecord (Lisp_Object rec);
+ − 979
428
+ − 980
+ − 981 /* Copy the data from one lcrecord structure into another, but don't
+ − 982 overwrite the header information. */
+ − 983
771
+ − 984 #define copy_sized_lcrecord(dst, src, size) \
430
+ − 985 memcpy ((char *) (dst) + sizeof (struct lcrecord_header), \
+ − 986 (char *) (src) + sizeof (struct lcrecord_header), \
771
+ − 987 (size) - sizeof (struct lcrecord_header))
+ − 988
+ − 989 #define copy_lcrecord(dst, src) copy_sized_lcrecord (dst, src, sizeof (*(dst)))
428
+ − 990
771
+ − 991 #define zero_sized_lcrecord(lcr, size) \
430
+ − 992 memset ((char *) (lcr) + sizeof (struct lcrecord_header), 0, \
771
+ − 993 (size) - sizeof (struct lcrecord_header))
+ − 994
+ − 995 #define zero_lcrecord(lcr) zero_sized_lcrecord(lcr, sizeof (*(lcr)))
428
+ − 996
440
+ − 997 #endif /* INCLUDED_lrecord_h_ */