Mercurial > hg > xemacs-beta
comparison src/lrecord.h @ 771:943eaba38521
[xemacs-hg @ 2002-03-13 08:51:24 by ben]
The big ben-mule-21-5 check-in!
Various files were added and deleted. See CHANGES-ben-mule.
There are still some test suite failures. No crashes, though.
Many of the failures have to do with problems in the test suite itself
rather than in the actual code. I'll be addressing these in the next
day or so -- none of the test suite failures are at all critical.
Meanwhile I'll be trying to address the biggest issues -- i.e. build
or run failures, which will almost certainly happen on various platforms.
All comments should be sent to ben@xemacs.org -- use a Cc: if necessary
when sending to mailing lists. There will be pre- and post- tags,
something like
pre-ben-mule-21-5-merge-in, and
post-ben-mule-21-5-merge-in.
author | ben |
---|---|
date | Wed, 13 Mar 2002 08:54:06 +0000 |
parents | fdefd0186b75 |
children | 026c5bf9c134 |
comparison
equal
deleted
inserted
replaced
770:336a418893b5 | 771:943eaba38521 |
---|---|
1 /* The "lrecord" structure (header of a compound lisp object). | 1 /* The "lrecord" structure (header of a compound lisp object). |
2 Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. | 2 Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. |
3 Copyright (C) 1996 Ben Wing. | 3 Copyright (C) 1996, 2001 Ben Wing. |
4 | 4 |
5 This file is part of XEmacs. | 5 This file is part of XEmacs. |
6 | 6 |
7 XEmacs is free software; you can redistribute it and/or modify it | 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 | 8 under the terms of the GNU General Public License as published by the |
73 Invariant: if (c_readonly == 1), then (mark == 1 && lisp_readonly == 1) */ | 73 Invariant: if (c_readonly == 1), then (mark == 1 && lisp_readonly == 1) */ |
74 unsigned int c_readonly :1; | 74 unsigned int c_readonly :1; |
75 | 75 |
76 /* 1 if the object is readonly from lisp */ | 76 /* 1 if the object is readonly from lisp */ |
77 unsigned int lisp_readonly :1; | 77 unsigned int lisp_readonly :1; |
78 | |
79 unsigned int unused :21; | |
78 }; | 80 }; |
79 | 81 |
80 struct lrecord_implementation; | 82 struct lrecord_implementation; |
81 int lrecord_type_index (const struct lrecord_implementation *implementation); | 83 int lrecord_type_index (const struct lrecord_implementation *implementation); |
82 | 84 |
300 ((void) ((lheader)->lisp_readonly = 1)) | 302 ((void) ((lheader)->lisp_readonly = 1)) |
301 #define RECORD_MARKER(lheader) lrecord_markers[(lheader)->type] | 303 #define RECORD_MARKER(lheader) lrecord_markers[(lheader)->type] |
302 | 304 |
303 /* External description stuff | 305 /* External description stuff |
304 | 306 |
305 A lrecord external description is an array of values. The first | 307 PLEASE NOTE: Both lrecord_description and struct_description are |
306 value of each line is a type, the second the offset in the lrecord | 308 badly misnamed. In reality, an lrecord_description is nothing more |
307 structure. Following values are parameters, their presence, type | 309 than a list of the elements in a block of memory that need |
308 and number is type-dependent. | 310 relocating or other special handling, and a struct_description is |
309 | 311 no more than an lrecord_description plus the size of the block of |
310 The description ends with a "XD_END" or "XD_SPECIFIER_END" record. | 312 memory. (In fact, a struct_description can now have its size given |
313 as zero, i.e. unspecified, meaning that the last element in the | |
314 structure is noted in the list and the size of the block can | |
315 therefore be computed from it.) The names stem from the fact | |
316 lrecord_descriptions are used to describe lrecords (the size of the | |
317 lrecord is elsewhere in its description, attached to its methods, | |
318 so it does not need to be given here), while struct_descriptions | |
319 are used to describe C structs; but both are used in various | |
320 additional ways. Much better terms would be memory_description and | |
321 sized_memory_description. | |
322 | |
323 An lrecord_description is an array of values. (This is actually | |
324 misnamed, in that it does not just describe lrecords, but any | |
325 blocks of memory.) The first value of each line is a type, the | |
326 second the offset in the lrecord structure. The third and | |
327 following elements are parameters; their presence, type and number | |
328 is type-dependent. | |
329 | |
330 The description ends with a "XD_END", "XD_SPECIFIER_END" or | |
331 "XD_CODING_SYSTEM_END" record. | |
332 | |
333 The top-level description of an lrecord or lcrecord does not need | |
334 to describe every element, just the ones that need to be relocated, | |
335 since the size of the lrecord is known. (The same goes for nested | |
336 structures, whenever the structure size is given, rather than being | |
337 defaulted by specifying 0 for the size.) | |
338 | |
339 A struct_description is used for describing nested "structures". | |
340 (Again a misnomer, since it can be used for any blocks of memory, | |
341 not just structures.) It just contains a size for the memory block, | |
342 a pointer to an lrecord_description, and (for unions only) a union | |
343 constant, described below. The size can be 0 (#### not yet | |
344 implemented!), in which case the size will be determined from the | |
345 largest offset logically referenced (i.e. last offset mentioned + | |
346 size of that object). This is useful for stretchy arrays. | |
311 | 347 |
312 Some example descriptions : | 348 Some example descriptions : |
313 | 349 |
314 static const struct lrecord_description cons_description[] = { | 350 static const struct lrecord_description cons_description[] = { |
315 { XD_LISP_OBJECT, offsetof (Lisp_Cons, car) }, | 351 { XD_LISP_OBJECT, offsetof (Lisp_Cons, car) }, |
331 The existing types : | 367 The existing types : |
332 XD_LISP_OBJECT | 368 XD_LISP_OBJECT |
333 A Lisp object. This is also the type to use for pointers to other lrecords. | 369 A Lisp object. This is also the type to use for pointers to other lrecords. |
334 | 370 |
335 XD_LISP_OBJECT_ARRAY | 371 XD_LISP_OBJECT_ARRAY |
336 An array of Lisp objects or pointers to lrecords. | 372 An array of Lisp objects or (equivalently) pointers to lrecords. |
337 The third element is the count. | 373 The parameter (i.e. third element) is the count. This would be declared |
374 as Lisp_Object foo[666]. For something declared as Lisp_Object *foo, | |
375 use XD_STRUCT_PTR, whose description parameter is a struct_description | |
376 consisting of only XD_LISP_OBJECT and XD_END. | |
338 | 377 |
339 XD_LO_LINK | 378 XD_LO_LINK |
340 Link in a linked list of objects of the same type. | 379 Weak link in a linked list of objects of the same type. This is a |
380 link that does NOT generate a GC reference. Thus the pdumper will | |
381 not automatically add the referenced object to the table of all | |
382 objects to be dumped, and when storing and loading the dumped data | |
383 will automatically prune unreferenced objects in the chain and link | |
384 each referenced object to the next referenced object, even if it's | |
385 many links away. We also need to special handling of a similar | |
386 nature for the root of the chain, which will be a staticpro()ed | |
387 object. | |
341 | 388 |
342 XD_OPAQUE_PTR | 389 XD_OPAQUE_PTR |
343 Pointer to undumpable data. Must be NULL when dumping. | 390 Pointer to undumpable data. Must be NULL when dumping. |
344 | 391 |
345 XD_STRUCT_PTR | 392 XD_STRUCT_PTR |
346 Pointer to described struct. Parameters are number of structures and | 393 Pointer to block of described memory. (This is misnamed: It is NOT |
347 struct_description. | 394 necessarily a pointer to a struct foo.) Parameters are number of |
395 contiguous blocks and struct_description. | |
396 | |
397 XD_STRUCT_ARRAY | |
398 Array of blocks of described memory. Parameters are number of | |
399 structures and struct_description. This differs from XD_STRUCT_PTR | |
400 in that the parameter is declared as struct foo[666] instead of | |
401 struct *foo. In other words, the block of memory holding the | |
402 structures is within the containing structure, rather than being | |
403 elsewhere, with a pointer in the containing structure. | |
348 | 404 |
349 XD_OPAQUE_DATA_PTR | 405 XD_OPAQUE_DATA_PTR |
350 Pointer to dumpable opaque data. Parameter is the size of the data. | 406 Pointer to dumpable opaque data. Parameter is the size of the data. |
351 Pointed data must be relocatable without changes. | 407 Pointed data must be relocatable without changes. |
352 | 408 |
409 XD_UNION | |
410 Union of two or more different types of data. Parameters are a | |
411 constant which determines which type the data is (this is usually an | |
412 XD_INDIRECT, referring to one of the fields in the structure), and | |
413 an array of struct_descriptions, whose values are used as follows, | |
414 which is *DIFFERENT* from their usage in XD_STRUCT_PTR: the first | |
415 field is a constant, which is compared to the first parameter of the | |
416 XD_UNION descriptor to determine if this description applies to the | |
417 data at the given offset, and the second is a pointer to a *SINGLE* | |
418 lrecord_description structure, describing the data being pointed at | |
419 when the associated constant matches. You can go ahead and create | |
420 an array of lrecord_description structures and put an XD_END on it, | |
421 but only the first one is used. If the data being pointed at is a | |
422 structure, you *MAY NOT* substitute an array of lrecord_description | |
423 structures describing the structure; instead, use a single | |
424 lrecord_description structure with an XD_STRUCT_PTR in it, and point | |
425 it in turn to the description of the structure. See charset.h for a | |
426 description of how to use XD_UNION. (In other words, if the constant | |
427 matches, the lrecord_description pointed at will in essence be | |
428 substituted for the XD_UNION declaration.) | |
429 | |
353 XD_C_STRING | 430 XD_C_STRING |
354 Pointer to a C string. | 431 Pointer to a C string. |
355 | 432 |
356 XD_DOC_STRING | 433 XD_DOC_STRING |
357 Pointer to a doc string (C string if positive, opaque value if negative) | 434 Pointer to a doc string (C string if positive, opaque value if negative) |
358 | 435 |
359 XD_INT_RESET | 436 XD_INT_RESET |
360 An integer which will be reset to a given value in the dump file. | 437 An integer which will be reset to a given value in the dump file. |
361 | 438 |
362 | 439 |
363 XD_CHARCOUNT | |
364 Charcount value. Used for counts. | |
365 | |
366 XD_ELEMCOUNT | 440 XD_ELEMCOUNT |
367 Elemcount value. Used for counts. | 441 Elemcount value. Used for counts. |
368 | 442 |
369 XD_BYTECOUNT | 443 XD_BYTECOUNT |
370 Bytecount value. Used for counts. | 444 Bytecount value. Used for counts. |
376 int value. Used for counts. | 450 int value. Used for counts. |
377 | 451 |
378 XD_LONG | 452 XD_LONG |
379 long value. Used for counts. | 453 long value. Used for counts. |
380 | 454 |
455 XD_BYTECOUNT | |
456 bytecount value. Used for counts. | |
457 | |
381 XD_END | 458 XD_END |
382 Special type indicating the end of the array. | 459 Special type indicating the end of the array. |
383 | 460 |
384 XD_SPECIFIER_END | 461 XD_SPECIFIER_END |
385 Special type indicating the end of the array for a specifier. Extra | 462 Special type indicating the end of the array for a specifier. Extra |
386 description is going to be fetched from the specifier methods. | 463 description, describing the specifier-type-specific data at the end |
464 of the specifier object, is going to be fetched from the specifier | |
465 methods. This should occur exactly once, in the description of the | |
466 specifier object, and the dump code knows how to special-case this | |
467 by fetching the specifier_methods pointer from the appropriate place | |
468 in the memory block (which will, of course, be a struct | |
469 Lisp_Specifier), fetching the description of the | |
470 specifier-type-specific data from this, and continuing processing | |
471 the memory block. | |
472 | |
473 XD_CODING_SYSTEM_END | |
474 Special type indicating the end of the array for a coding system. | |
475 Extra description is going to be fetched from the coding system | |
476 methods. Works just like XD_SPECIFIER_END. | |
387 | 477 |
388 | 478 |
389 Special macros: | 479 Special macros: |
390 XD_INDIRECT(line, delta) | 480 XD_INDIRECT(line, delta) |
391 Usable where a "count" or "size" is requested. Gives the value of | 481 Usable where a "count" or "size" is requested. Gives the value of |
398 XD_LISP_OBJECT_ARRAY, | 488 XD_LISP_OBJECT_ARRAY, |
399 XD_LISP_OBJECT, | 489 XD_LISP_OBJECT, |
400 XD_LO_LINK, | 490 XD_LO_LINK, |
401 XD_OPAQUE_PTR, | 491 XD_OPAQUE_PTR, |
402 XD_STRUCT_PTR, | 492 XD_STRUCT_PTR, |
493 XD_STRUCT_ARRAY, | |
403 XD_OPAQUE_DATA_PTR, | 494 XD_OPAQUE_DATA_PTR, |
495 XD_UNION, | |
404 XD_C_STRING, | 496 XD_C_STRING, |
405 XD_DOC_STRING, | 497 XD_DOC_STRING, |
406 XD_INT_RESET, | 498 XD_INT_RESET, |
407 XD_CHARCOUNT, | |
408 XD_BYTECOUNT, | 499 XD_BYTECOUNT, |
409 XD_ELEMCOUNT, | 500 XD_ELEMCOUNT, |
410 XD_HASHCODE, | 501 XD_HASHCODE, |
411 XD_INT, | 502 XD_INT, |
412 XD_LONG, | 503 XD_LONG, |
413 XD_END, | 504 XD_END, |
414 XD_SPECIFIER_END | 505 XD_SPECIFIER_END, |
506 XD_CODING_SYSTEM_END | |
415 }; | 507 }; |
416 | 508 |
417 struct lrecord_description | 509 struct lrecord_description |
418 { | 510 { |
419 enum lrecord_description_type type; | 511 enum lrecord_description_type type; |
466 | 558 |
467 #define DEFINE_BASIC_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \ | 559 #define DEFINE_BASIC_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,sizer,structtype) \ |
468 MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,sizer,1,structtype) | 560 MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,0,0,0,0,0,sizer,1,structtype) |
469 | 561 |
470 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \ | 562 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,sizer,structtype) \ |
471 MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype) \ | 563 MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,0,sizer,0,structtype) |
472 | 564 |
473 #define MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ | 565 #define MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,desc,getprop,putprop,remprop,plist,size,sizer,basic_p,structtype) \ |
474 DECLARE_ERROR_CHECK_TYPECHECK(c_name, structtype) \ | 566 DECLARE_ERROR_CHECK_TYPECHECK(c_name, structtype) \ |
475 const struct lrecord_implementation lrecord_##c_name = \ | 567 const struct lrecord_implementation lrecord_##c_name = \ |
476 { name, marker, printer, nuker, equal, hash, desc, \ | 568 { name, marker, printer, nuker, equal, hash, desc, \ |
779 } while (0) | 871 } while (0) |
780 | 872 |
781 void *alloc_lcrecord (Bytecount size, | 873 void *alloc_lcrecord (Bytecount size, |
782 const struct lrecord_implementation *); | 874 const struct lrecord_implementation *); |
783 | 875 |
876 void *alloc_automanaged_lcrecord (Bytecount size, | |
877 const struct lrecord_implementation *); | |
878 | |
879 #define alloc_unmanaged_lcrecord_type(type, lrecord_implementation) \ | |
880 ((type *) alloc_lcrecord (sizeof (type), lrecord_implementation)) | |
881 | |
784 #define alloc_lcrecord_type(type, lrecord_implementation) \ | 882 #define alloc_lcrecord_type(type, lrecord_implementation) \ |
785 ((type *) alloc_lcrecord (sizeof (type), lrecord_implementation)) | 883 ((type *) alloc_automanaged_lcrecord (sizeof (type), lrecord_implementation)) |
884 | |
885 void free_lcrecord (Lisp_Object rec); | |
886 | |
786 | 887 |
787 /* Copy the data from one lcrecord structure into another, but don't | 888 /* Copy the data from one lcrecord structure into another, but don't |
788 overwrite the header information. */ | 889 overwrite the header information. */ |
789 | 890 |
790 #define copy_lcrecord(dst, src) \ | 891 #define copy_sized_lcrecord(dst, src, size) \ |
791 memcpy ((char *) (dst) + sizeof (struct lcrecord_header), \ | 892 memcpy ((char *) (dst) + sizeof (struct lcrecord_header), \ |
792 (char *) (src) + sizeof (struct lcrecord_header), \ | 893 (char *) (src) + sizeof (struct lcrecord_header), \ |
793 sizeof (*(dst)) - sizeof (struct lcrecord_header)) | 894 (size) - sizeof (struct lcrecord_header)) |
794 | 895 |
795 #define zero_lcrecord(lcr) \ | 896 #define copy_lcrecord(dst, src) copy_sized_lcrecord (dst, src, sizeof (*(dst))) |
897 | |
898 #define zero_sized_lcrecord(lcr, size) \ | |
796 memset ((char *) (lcr) + sizeof (struct lcrecord_header), 0, \ | 899 memset ((char *) (lcr) + sizeof (struct lcrecord_header), 0, \ |
797 sizeof (*(lcr)) - sizeof (struct lcrecord_header)) | 900 (size) - sizeof (struct lcrecord_header)) |
901 | |
902 #define zero_lcrecord(lcr) zero_sized_lcrecord(lcr, sizeof (*(lcr))) | |
798 | 903 |
799 #endif /* INCLUDED_lrecord_h_ */ | 904 #endif /* INCLUDED_lrecord_h_ */ |