Mercurial > hg > xemacs-beta
diff src/lrecord.h @ 5120:d1247f3cc363 ben-lisp-object
latest work on lisp-object workspace;
more changes eliminating LCRECORD in place of LISP_OBJECT;
now compiles and runs.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Mon, 28 Dec 2009 01:15:52 -0600 |
parents | e0db3c197671 |
children | 623d57b7fbe8 |
line wrap: on
line diff
--- a/src/lrecord.h Sat Dec 26 21:22:48 2009 -0600 +++ b/src/lrecord.h Mon Dec 28 01:15:52 2009 -0600 @@ -26,36 +26,16 @@ #ifndef INCLUDED_lrecord_h_ #define INCLUDED_lrecord_h_ -#ifdef NEW_GC -/* The "lrecord" type of Lisp object is used for all object types - other than a few simple ones (like char and int). This allows many - types to be implemented but only a few bits required in a Lisp - object for type information. (The tradeoff is that each object has - its type marked in it, thereby increasing its size.) All lrecords - begin with a `struct lrecord_header', which identifies the lisp - object type, by providing an index into a table of `struct - lrecord_implementation', which describes the behavior of the lisp - object. It also contains some other data bits. +/* The "lrecord" type of Lisp object is used for all object types other + than a few simple ones (like char and int). This allows many types to be + implemented but only a few bits required in a Lisp object for type + information. (The tradeoff is that each object has its type marked in + it, thereby increasing its size.) All lrecords begin with a `struct + lrecord_header', which identifies the lisp object type, by providing an + index into a table of `struct lrecord_implementation', which describes + the behavior of the lisp object. It also contains some other data bits. - Creating a new lrecord type is fairly easy; just follow the - lead of some existing type (e.g. hash tables). Note that you - do not need to supply all the methods (see below); reasonable - defaults are provided for many of them. Alternatively, if you're - just looking for a way of encapsulating data (which possibly - could contain Lisp_Objects in it), you may well be able to use - the opaque type. -*/ -#else /* not NEW_GC */ -/* The "lrecord" type of Lisp object is used for all object types - other than a few simple ones. This allows many types to be - implemented but only a few bits required in a Lisp object for type - information. (The tradeoff is that each object has its type marked - in it, thereby increasing its size.) All lrecords begin with a - `struct lrecord_header', which identifies the lisp object type, by - providing an index into a table of `struct lrecord_implementation', - which describes the behavior of the lisp object. It also contains - some other data bits. - +#ifndef NEW_GC Lrecords are of two types: straight lrecords, and lcrecords. Straight lrecords are used for those types of objects that have their own allocation routines (typically allocated out of 2K chunks @@ -70,38 +50,45 @@ Lcrecords have a `struct old_lcrecord_header' at the top, which contains a `struct lrecord_header' and a `next' pointer, and are allocated using old_alloc_lcrecord_type() or its variants. +#endif - Creating a new lcrecord type is fairly easy; just follow the + Creating a new Lisp object type is fairly easy; just follow the lead of some existing type (e.g. hash tables). Note that you do not need to supply all the methods (see below); reasonable defaults are provided for many of them. Alternatively, if you're just looking for a way of encapsulating data (which possibly could contain Lisp_Objects in it), you may well be able to use - the opaque type. --ben + the opaque type. + + The "public API's" meant for use by regular Lisp objects are macros + in capital letters, involving the word "LISP_OBJECT". Underlyingly, + the functions and structures use "lrecord" or "lcrecord", but most + code shouldn't have to worry about this. */ -#endif /* not NEW_GC */ #ifdef NEW_GC #define ALLOC_LISP_OBJECT(type) alloc_lrecord (&lrecord_##type) #define ALLOC_SIZED_LISP_OBJECT(size, type) \ alloc_sized_lrecord (size, &lrecord_##type) -#define COPY_SIZED_LCRECORD copy_sized_lrecord -#define COPY_LCRECORD copy_lrecord -#define LISPOBJ_STORAGE_SIZE(ptr, size, stats) \ +#define COPY_SIZED_LISP_OBJECT copy_sized_lrecord +#define COPY_LISP_OBJECT copy_lrecord +#define LISP_OBJECT_STORAGE_SIZE(ptr, size, stats) \ mc_alloced_storage_size (size, stats) -#define ZERO_LCRECORD zero_lrecord -#define LCRECORD_HEADER lrecord_header -#define FREE_LCRECORD free_lrecord +#define ZERO_LISP_OBJECT zero_lrecord +#define LISP_OBJECT_HEADER struct lrecord_header +#define FROB_BLOCK_LISP_OBJECT_HEADER struct lrecord_header +#define FREE_LISP_OBJECT free_lrecord #else /* not NEW_GC */ #define ALLOC_LISP_OBJECT(type) alloc_automanaged_lcrecord (&lrecord_##type) #define ALLOC_SIZED_LISP_OBJECT(size, type) \ old_alloc_sized_lcrecord (size, &lrecord_##type) -#define COPY_SIZED_LCRECORD old_copy_sized_lcrecord -#define COPY_LCRECORD old_copy_lcrecord -#define LISPOBJ_STORAGE_SIZE malloced_storage_size -#define ZERO_LCRECORD old_zero_lcrecord -#define LCRECORD_HEADER old_lcrecord_header -#define FREE_LCRECORD old_free_lcrecord +#define COPY_SIZED_LISP_OBJECT old_copy_sized_lcrecord +#define COPY_LISP_OBJECT old_copy_lcrecord +#define LISP_OBJECT_STORAGE_SIZE malloced_storage_size +#define ZERO_LISP_OBJECT old_zero_lcrecord +#define LISP_OBJECT_HEADER struct old_lcrecord_header +#define FROB_BLOCK_LISP_OBJECT_HEADER struct lrecord_header +#define FREE_LISP_OBJECT old_free_lcrecord #endif /* not NEW_GC */ BEGIN_C_DECLS @@ -730,7 +717,7 @@ struct Lisp_Hash_Table { - struct LCRECORD_HEADER header; + LISP_OBJECT_HEADER header; Elemcount size; Elemcount count; Elemcount rehash_count; @@ -795,7 +782,7 @@ struct Lisp_Specifier { - struct LCRECORD_HEADER header; + LISP_OBJECT_HEADER header; struct specifier_methods *methods; ... @@ -1155,6 +1142,16 @@ objects need special handling in alloc.c. This does not apply to NEW_GC, because it does this automatically. + DEFINE_*_INTERNAL_LISP_OBJECT is for "internal" objects that should + never be visible on the Lisp level. This is a shorthand for the + most common type of internal objects, which have no equal or hash + method (since they generally won't appear in hash tables), no + finalizer and internal_object_printer() as their print method + (which prints that the object is internal and shouldn't be visible + externally). For internal objects needing a finalizer, equal or + hash method, use the normal DEFINE_*_LISP_OBJECT mechanism for + defining these objects. + DEFINE_*_WITH_PROPS is for objects which support the unified property interface using `get', `put', `remprop' and `object-plist'. @@ -1357,9 +1354,9 @@ 1. Declare the struct for your object in a header file somewhere. Remember that it must begin with - struct LCRECORD_HEADER header; + LISP_OBJECT_HEADER header; - 2. Put the "standard junk" (DECLARE_RECORD()/XFOO/etc.) below the + 2. Put the "standard junk" (DECLARE_LISP_OBJECT()/XFOO/etc.) below the struct definition -- see below. 3. Add this header file to inline.c. @@ -1372,8 +1369,13 @@ describing the purpose of the descriptions; and comments elsewhere in this file describing the exact syntax of the description structures. - 6. Define your object with DEFINE_LISP_OBJECT() or some - variant. + 6. Define your object with DEFINE_*_LISP_OBJECT() or some + variant. At the minimum, you need to decide whether your object can + be dumped. Objects that are created as part of the loadup process and + need to be persistent across dumping should be created dumpable. + Nondumpable objects are generally those associated with display, + particularly those containing a pointer to an external library object + (e.g. a window-system window). 7. Include the header file in the .c file where you defined the object. @@ -1391,7 +1393,7 @@ struct toolbar_button { - struct LCRECORD_HEADER header; + LISP_OBJECT_HEADER header; Lisp_Object next; Lisp_Object frame; @@ -1506,9 +1508,9 @@ /* Note: Object types defined in external dynamically-loaded modules (not -part of the XEmacs main source code) should use DECLARE_MODULE_LRECORD -and DEFINE_MODULE_LISP_OBJECT rather than DECLARE_LISP_OBJECT -and DEFINE_LISP_OBJECT. The MODULE versions declare and +part of the XEmacs main source code) should use DECLARE_*_MODULE_LISP_OBJECT +and DEFINE_*_MODULE_LISP_OBJECT rather than DECLARE_*_LISP_OBJECT +and DEFINE_*_LISP_OBJECT. The MODULE versions declare and allocate an enumerator for the type being defined. */ @@ -1516,7 +1518,7 @@ #ifdef ERROR_CHECK_TYPES -# define DECLARE_LISP_OBJECT(c_name, structtype) \ +# define DECLARE_LISP_OBJECT(c_name, structtype) \ extern const struct lrecord_implementation lrecord_##c_name; \ DECLARE_INLINE_HEADER ( \ structtype * \ @@ -1528,7 +1530,7 @@ } \ extern Lisp_Object Q##c_name##p -# define DECLARE_MODULE_API_LRECORD(c_name, structtype) \ +# define DECLARE_MODULE_API_LISP_OBJECT(c_name, structtype) \ extern MODULE_API const struct lrecord_implementation lrecord_##c_name; \ DECLARE_INLINE_HEADER ( \ structtype * \ @@ -1540,7 +1542,7 @@ } \ extern MODULE_API Lisp_Object Q##c_name##p -# define DECLARE_MODULE_LRECORD(c_name, structtype) \ +# define DECLARE_MODULE_LISP_OBJECT(c_name, structtype) \ extern int lrecord_type_##c_name; \ extern struct lrecord_implementation lrecord_##c_name; \ DECLARE_INLINE_HEADER ( \ @@ -1553,21 +1555,8 @@ } \ extern Lisp_Object Q##c_name##p -# define DECLARE_NONRECORD(c_name, type_enum, structtype) \ -DECLARE_INLINE_HEADER ( \ -structtype * \ -error_check_##c_name (Lisp_Object obj, const Ascbyte *file, int line) \ -) \ -{ \ - assert_at_line (XTYPE (obj) == type_enum, file, line); \ - return (structtype *) XPNTR (obj); \ -} \ -extern Lisp_Object Q##c_name##p - # define XRECORD(x, c_name, structtype) \ error_check_##c_name (x, __FILE__, __LINE__) -# define XNONRECORD(x, c_name, type_enum, structtype) \ - error_check_##c_name (x, __FILE__, __LINE__) DECLARE_INLINE_HEADER ( Lisp_Object @@ -1586,21 +1575,17 @@ #else /* not ERROR_CHECK_TYPES */ -# define DECLARE_LISP_OBJECT(c_name, structtype) \ +# define DECLARE_LISP_OBJECT(c_name, structtype) \ extern Lisp_Object Q##c_name##p; \ extern const struct lrecord_implementation lrecord_##c_name -# define DECLARE_MODULE_API_LRECORD(c_name, structtype) \ -extern MODULE_API Lisp_Object Q##c_name##p; \ +# define DECLARE_MODULE_API_LISP_OBJECT(c_name, structtype) \ +extern MODULE_API Lisp_Object Q##c_name##p; \ extern MODULE_API const struct lrecord_implementation lrecord_##c_name -# define DECLARE_MODULE_LRECORD(c_name, structtype) \ +# define DECLARE_MODULE_LISP_OBJECT(c_name, structtype) \ extern Lisp_Object Q##c_name##p; \ extern int lrecord_type_##c_name; \ extern struct lrecord_implementation lrecord_##c_name -# define DECLARE_NONRECORD(c_name, type_enum, structtype) \ -extern Lisp_Object Q##c_name##p # define XRECORD(x, c_name, structtype) ((structtype *) XPNTR (x)) -# define XNONRECORD(x, c_name, type_enum, structtype) \ - ((structtype *) XPNTR (x)) /* wrap_pointer_1 is so named as a suggestion not to use it unless you know what you're doing. */ #define wrap_record(ptr, ty) wrap_pointer_1 (ptr) @@ -1653,12 +1638,12 @@ - For most objects, simply call ALLOC_LISP_OBJECT (type), where TYPE is the name of the type (e.g. toolbar_button). Such objects can be freed - manually using FREE_LCRECORD. + manually using FREE_LISP_OBJECT. - For objects whose size can vary (and hence which have a size_in_bytes_method rather than a static_size), call ALLOC_SIZED_LISP_OBJECT (size, type), where TYPE is the - name of the type. NOTE: You cannot call FREE_LCRECORD() on such + name of the type. NOTE: You cannot call FREE_LISP_OBJECT() on such on object! (At least when not NEW_GC) - Basic lrecords (of which there are a limited number, which exist only @@ -1674,7 +1659,7 @@ struct lcrecord_list { - struct LCRECORD_HEADER header; + LISP_OBJECT_HEADER header; Lisp_Object free; Elemcount size; const struct lrecord_implementation *implementation; @@ -1695,7 +1680,7 @@ lrecords. lcrecords themselves are divided into three types: (1) auto-managed, (2) hand-managed, and (3) unmanaged. "Managed" refers to using a special object called an lcrecord-list to keep track of freed - lcrecords, which can freed with FREE_LCRECORD() or the like and later be + lcrecords, which can freed with FREE_LISP_OBJECT() or the like and later be recycled when a new lcrecord is required, rather than requiring new malloc(). Thus, allocation of lcrecords can be very cheap. (Technically, the lcrecord-list manager could divide up large @@ -1711,7 +1696,7 @@ -- "Auto-managed" means that you just go ahead and allocate the lcrecord whenever you want, using ALLOC_LISP_OBJECT(), and the appropriate lcrecord-list manager is automatically created. To free, you just call - "FREE_LCRECORD()" and the appropriate lcrecord-list manager is + "FREE_LISP_OBJECT()" and the appropriate lcrecord-list manager is automatically located and called. The limitation here of course is that all your objects are of the same size. (#### Eventually we should have a more sophisticated system that tracks the sizes seen and creates one @@ -1809,23 +1794,18 @@ #else /* NEW_GC */ -Lisp_Object alloc_sized_lrecord (Bytecount size, - const struct lrecord_implementation *imp); +MODULE_API Lisp_Object alloc_sized_lrecord (Bytecount size, + const struct lrecord_implementation *imp); Lisp_Object noseeum_alloc_sized_lrecord (Bytecount size, - const struct lrecord_implementation *); -Lisp_Object alloc_lrecord (const struct lrecord_implementation *imp); + const struct lrecord_implementation *imp); +MODULE_API Lisp_Object alloc_lrecord (const struct lrecord_implementation *imp); Lisp_Object noseeum_alloc_lrecord (const struct lrecord_implementation *imp); -Lisp_Object alloc_lrecord_array (int elemcount, +MODULE_API Lisp_Object alloc_lrecord_array (int elemcount, const struct lrecord_implementation *imp); -Lisp_Object alloc_sized_lrecord_array (Bytecount size, int elemcount, - const struct lrecord_implementation *imp); - -#define alloc_lrecord_type(type, imp) \ - ((type *) XPNTR (alloc_sized_lrecord (sizeof (type), imp))) - -#define noseeum_alloc_lrecord_type(type, imp) \ - ((type *) XPNTR (noseeum_alloc_sized_lrecord (sizeof (type), imp))) +MODULE_API Lisp_Object alloc_sized_lrecord_array (Bytecount size, + int elemcount, + const struct lrecord_implementation *imp); void free_lrecord (Lisp_Object rec);