XEmacs 21.2.14.
[chise/xemacs-chise.git.1] / src / lrecord.h
1 /* The "lrecord" structure (header of a compound lisp object).
2    Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
3    Copyright (C) 1996 Ben Wing.
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
24 #ifndef _XEMACS_LRECORD_H_
25 #define _XEMACS_LRECORD_H_
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
29    implemented but only a few bits required in a Lisp object for
30    type information. (The tradeoff is that each object has its
31    type marked in it, thereby increasing its size.) The first
32    four bytes of all lrecords is either a pointer to a struct
33    lrecord_implementation, which contains methods describing how
34    to process this object, or an index into an array of pointers
35    to struct lrecord_implementations plus some other data bits.
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
45    Lcrecords are used for less common sorts of objects that don't
46    do their own allocation.  Each such object is malloc()ed
47    individually, and the objects are chained together through
48    a `next' pointer.  Lcrecords have a `struct lcrecord_header'
49    at the top, which contains a `struct lrecord_header' and
50    a `next' pointer, and are allocated using alloc_lcrecord().
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[] */
63   unsigned char type;
64   struct {
65     /* 1 if the object is marked during GC. */
66     unsigned mark :1;
67     /* 1 if the object resides in read-only space */
68     unsigned c_readonly : 1;
69     /* 1 if the object is readonly from lisp */
70     unsigned lisp_readonly : 1;
71   } flags;
72 };
73
74 struct lrecord_implementation;
75 int lrecord_type_index (CONST struct lrecord_implementation *implementation);
76
77 # define set_lheader_implementation(header,imp) do {    \
78   struct lrecord_header* SLI_header = (header);         \
79   (SLI_header)->type = lrecord_type_index (imp);        \
80   (SLI_header)->flags.mark = 0;                         \
81   (SLI_header)->flags.c_readonly = 0;                   \
82   (SLI_header)->flags.lisp_readonly = 0;                \
83 } while (0)
84
85 struct lcrecord_header
86 {
87   struct lrecord_header lheader;
88
89   /* The `next' field is normally used to chain all lrecords together
90      so that the GC can find (and free) all of them.
91      `alloc_lcrecord' threads records together.
92
93      The `next' field may be used for other purposes as long as some
94      other mechanism is provided for letting the GC do its work.
95
96      For example, the event and marker object types allocate members
97      out of memory chunks, and are able to find all unmarked members
98      by sweeping through the elements of the list of chunks.  */
99   struct lcrecord_header *next;
100
101   /* The `uid' field is just for debugging/printing convenience.
102      Having this slot doesn't hurt us much spacewise, since an
103      lcrecord already has the above slots plus malloc overhead. */
104   unsigned int uid :31;
105
106   /* The `free' field is a flag that indicates whether this lcrecord
107      is on a "free list".  Free lists are used to minimize the number
108      of calls to malloc() when we're repeatedly allocating and freeing
109      a number of the same sort of lcrecord.  Lcrecords on a free list
110      always get marked in a different fashion, so we can use this flag
111      as a sanity check to make sure that free lists only have freed
112      lcrecords and there are no freed lcrecords elsewhere. */
113   unsigned int free :1;
114 };
115
116 /* Used for lcrecords in an lcrecord-list. */
117 struct free_lcrecord_header
118 {
119   struct lcrecord_header lcheader;
120   Lisp_Object chain;
121 };
122
123 /* see alloc.c for an explanation */
124 Lisp_Object this_one_is_unmarkable (Lisp_Object obj,
125                                     void (*markobj) (Lisp_Object));
126
127 struct lrecord_implementation
128 {
129   CONST char *name;
130   /* This function is called at GC time, to make sure that all Lisp_Objects
131      pointed to by this object get properly marked.  It should call
132      the mark_object function on all Lisp_Objects in the object.  If
133      the return value is non-nil, it should be a Lisp_Object to be
134      marked (don't call the mark_object function explicitly on it,
135      because the GC routines will do this).  Doing it this way reduces
136      recursion, so the object returned should preferably be the one
137      with the deepest level of Lisp_Object pointers.  This function
138      can be NULL, meaning no GC marking is necessary. */
139   Lisp_Object (*marker) (Lisp_Object, void (*mark_object) (Lisp_Object));
140   /* This can be NULL if the object is an lcrecord; the
141      default_object_printer() in print.c will be used. */
142   void (*printer) (Lisp_Object, Lisp_Object printcharfun, int escapeflag);
143   /* This function is called at GC time when the object is about to
144      be freed, and at dump time (FOR_DISKSAVE will be non-zero in this
145      case).  It should perform any necessary cleanup (e.g. freeing
146      malloc()ed memory.  This can be NULL, meaning no special
147      finalization is necessary.
148
149      WARNING: remember that the finalizer is called at dump time even
150      though the object is not being freed. */
151   void (*finalizer) (void *header, int for_disksave);
152   /* This can be NULL, meaning compare objects with EQ(). */
153   int (*equal) (Lisp_Object obj1, Lisp_Object obj2, int depth);
154   /* This can be NULL, meaning use the Lisp_Object itself as the hash;
155      but *only* if the `equal' function is EQ (if two objects are
156      `equal', they *must* hash to the same value or the hashing won't
157      work). */
158   unsigned long (*hash) (Lisp_Object, int);
159   Lisp_Object (*getprop) (Lisp_Object obj, Lisp_Object prop);
160   int (*putprop) (Lisp_Object obj, Lisp_Object prop, Lisp_Object val);
161   int (*remprop) (Lisp_Object obj, Lisp_Object prop);
162   Lisp_Object (*plist) (Lisp_Object obj);
163
164   /* Only one of these is non-0.  If both are 0, it means that this type
165      is not instantiable by alloc_lcrecord(). */
166   size_t static_size;
167   size_t (*size_in_bytes_method) (CONST void *header);
168   /* A unique subtag-code (dynamically) assigned to this datatype. */
169   /* (This is a pointer so the rest of this structure can be read-only.) */
170   int *lrecord_type_index;
171   /* A "basic" lrecord is any lrecord that's not an lcrecord, i.e.
172      one that does not have an lcrecord_header at the front and which
173      is (usually) allocated in frob blocks.  We only use this flag for
174      some consistency checking, and that only when error-checking is
175      enabled. */
176   int basic_p;
177 };
178
179 extern CONST struct lrecord_implementation *lrecord_implementations_table[];
180
181 #define XRECORD_LHEADER_IMPLEMENTATION(obj) \
182    (lrecord_implementations_table[XRECORD_LHEADER (obj)->type])
183 #define LHEADER_IMPLEMENTATION(lh) (lrecord_implementations_table[(lh)->type])
184
185 extern int gc_in_progress;
186
187 #define MARKED_RECORD_P(obj) (gc_in_progress && XRECORD_LHEADER (obj)->flags.mark)
188 #define MARKED_RECORD_HEADER_P(lheader) ((lheader)->flags.mark)
189 #define MARK_RECORD_HEADER(lheader)   ((void) ((lheader)->flags.mark = 1))
190 #define UNMARK_RECORD_HEADER(lheader) ((void) ((lheader)->flags.mark = 0))
191
192 #define UNMARKABLE_RECORD_HEADER_P(lheader) \
193   (LHEADER_IMPLEMENTATION (lheader)->marker == this_one_is_unmarkable)
194
195 #define C_READONLY_RECORD_HEADER_P(lheader)  ((lheader)->flags.c_readonly)
196 #define LISP_READONLY_RECORD_HEADER_P(lheader)  ((lheader)->flags.lisp_readonly)
197 #define SET_C_READONLY_RECORD_HEADER(lheader) \
198   ((void) ((lheader)->flags.c_readonly = (lheader)->flags.lisp_readonly = 1))
199 #define SET_LISP_READONLY_RECORD_HEADER(lheader) \
200   ((void) ((lheader)->flags.lisp_readonly = 1))
201
202 /* Declaring the following structures as const puts them in the
203    text (read-only) segment, which makes debugging inconvenient
204    because this segment is not mapped when processing a core-
205    dump file */
206
207 #ifdef DEBUG_XEMACS
208 #define CONST_IF_NOT_DEBUG
209 #else
210 #define CONST_IF_NOT_DEBUG CONST
211 #endif
212
213 /* DEFINE_LRECORD_IMPLEMENTATION is for objects with constant size.
214    DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION is for objects whose size varies.
215  */
216
217 #if defined (ERROR_CHECK_TYPECHECK)
218 # define DECLARE_ERROR_CHECK_TYPECHECK(c_name, structtype)
219 #else
220 # define DECLARE_ERROR_CHECK_TYPECHECK(c_name, structtype)
221 #endif
222
223 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,structtype) \
224 DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,0,0,0,0,structtype)
225
226 #define DEFINE_BASIC_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,structtype) \
227 MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,sizeof(structtype),0,1,structtype)
228
229 #define DEFINE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,structtype) \
230 DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,0,0,0,0,structtype)
231
232 #define DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,structtype) \
233 MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,sizeof (structtype),0,0,structtype)
234
235 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,sizer,structtype) \
236 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,0,0,0,0,sizer,structtype)
237
238 #define DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION_WITH_PROPS(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,sizer,structtype) \
239 MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,0,sizer,0,structtype) \
240
241 #define MAKE_LRECORD_IMPLEMENTATION(name,c_name,marker,printer,nuker,equal,hash,getprop,putprop,remprop,props,size,sizer,basic_p,structtype) \
242 DECLARE_ERROR_CHECK_TYPECHECK(c_name, structtype)                       \
243 static int lrecord_##c_name##_lrecord_type_index;                       \
244 CONST_IF_NOT_DEBUG struct lrecord_implementation lrecord_##c_name =     \
245   { name, marker, printer, nuker, equal, hash,                          \
246     getprop, putprop, remprop, props, size, sizer,                      \
247     &(lrecord_##c_name##_lrecord_type_index), basic_p }                 \
248
249 #define LRECORDP(a) (XTYPE ((a)) == Lisp_Type_Record)
250 #define XRECORD_LHEADER(a) ((struct lrecord_header *) XPNTR (a))
251
252 #define RECORD_TYPEP(x, ty) \
253   (LRECORDP (x) && \
254    lrecord_implementations_table[XRECORD_LHEADER (x)->type] == (ty))
255
256 /* NOTE: the DECLARE_LRECORD() must come before the associated
257    DEFINE_LRECORD_*() or you will get compile errors.
258
259    Furthermore, you always need to put the DECLARE_LRECORD() in a header
260    file, and make sure the header file is included in inline.c, even
261    if the type is private to a particular file.  Otherwise, you will
262    get undefined references for the error_check_foo() inline function
263    under GCC. */
264
265 #ifdef ERROR_CHECK_TYPECHECK
266
267 # define DECLARE_LRECORD(c_name, structtype)                    \
268 extern CONST_IF_NOT_DEBUG struct lrecord_implementation         \
269   lrecord_##c_name;                                             \
270 INLINE structtype *error_check_##c_name (Lisp_Object obj);      \
271 INLINE structtype *                                             \
272 error_check_##c_name (Lisp_Object obj)                          \
273 {                                                               \
274   assert (RECORD_TYPEP (obj, &lrecord_##c_name) ||              \
275           MARKED_RECORD_P (obj));                               \
276   return (structtype *) XPNTR (obj);                            \
277 }                                                               \
278 extern Lisp_Object Q##c_name##p
279
280 # define DECLARE_NONRECORD(c_name, type_enum, structtype)       \
281 INLINE structtype *error_check_##c_name (Lisp_Object obj);      \
282 INLINE structtype *                                             \
283 error_check_##c_name (Lisp_Object obj)                          \
284 {                                                               \
285   assert (XGCTYPE (obj) == type_enum);                          \
286   return (structtype *) XPNTR (obj);                            \
287 }                                                               \
288 extern Lisp_Object Q##c_name##p
289
290 # define XRECORD(x, c_name, structtype) error_check_##c_name (x)
291 # define XNONRECORD(x, c_name, type_enum, structtype) error_check_##c_name (x)
292
293 # define XSETRECORD(var, p, c_name) do                          \
294 {                                                               \
295   XSETOBJ (var, Lisp_Type_Record, p);                           \
296   assert (RECORD_TYPEP (var, &lrecord_##c_name) ||              \
297           MARKED_RECORD_P (var));                               \
298 } while (0)
299
300 #else /* not ERROR_CHECK_TYPECHECK */
301
302 # define DECLARE_LRECORD(c_name, structtype)                    \
303 extern Lisp_Object Q##c_name##p;                                \
304 extern CONST_IF_NOT_DEBUG struct lrecord_implementation         \
305   lrecord_##c_name
306 # define DECLARE_NONRECORD(c_name, type_enum, structtype)       \
307 extern Lisp_Object Q##c_name##p
308 # define XRECORD(x, c_name, structtype) ((structtype *) XPNTR (x))
309 # define XNONRECORD(x, c_name, type_enum, structtype)           \
310   ((structtype *) XPNTR (x))
311 # define XSETRECORD(var, p, c_name) XSETOBJ (var, Lisp_Type_Record, p)
312
313 #endif /* not ERROR_CHECK_TYPECHECK */
314
315 #define RECORDP(x, c_name) RECORD_TYPEP (x, &lrecord_##c_name)
316 #define GC_RECORDP(x, c_name) gc_record_type_p (x, &lrecord_##c_name)
317
318 /* Note: we now have two different kinds of type-checking macros.
319    The "old" kind has now been renamed CONCHECK_foo.  The reason for
320    this is that the CONCHECK_foo macros signal a continuable error,
321    allowing the user (through debug-on-error) to substitute a different
322    value and return from the signal, which causes the lvalue argument
323    to get changed.  Quite a lot of code would crash if that happened,
324    because it did things like
325
326    foo = XCAR (list);
327    CHECK_STRING (foo);
328
329    and later on did XSTRING (XCAR (list)), assuming that the type
330    is correct (when it might be wrong, if the user substituted a
331    correct value in the debugger).
332
333    To get around this, I made all the CHECK_foo macros signal a
334    non-continuable error.  Places where a continuable error is OK
335    (generally only when called directly on the argument of a Lisp
336    primitive) should be changed to use CONCHECK().
337
338    FSF Emacs does not have this problem because RMS took the cheesy
339    way out and disabled returning from a signal entirely. */
340
341 #define CONCHECK_RECORD(x, c_name) do {                 \
342  if (!RECORD_TYPEP (x, &lrecord_##c_name))              \
343    x = wrong_type_argument (Q##c_name##p, x);           \
344 }  while (0)
345 #define CONCHECK_NONRECORD(x, lisp_enum, predicate) do {\
346  if (XTYPE (x) != lisp_enum)                            \
347    x = wrong_type_argument (predicate, x);              \
348  } while (0)
349 #define CHECK_RECORD(x, c_name) do {                    \
350  if (!RECORD_TYPEP (x, &lrecord_##c_name))              \
351    dead_wrong_type_argument (Q##c_name##p, x);          \
352  } while (0)
353 #define CHECK_NONRECORD(x, lisp_enum, predicate) do {   \
354  if (XTYPE (x) != lisp_enum)                            \
355    dead_wrong_type_argument (predicate, x);             \
356  } while (0)
357
358 void *alloc_lcrecord (size_t size, CONST struct lrecord_implementation *);
359
360 #define alloc_lcrecord_type(type, lrecord_implementation) \
361   ((type *) alloc_lcrecord (sizeof (type), lrecord_implementation))
362
363 int gc_record_type_p (Lisp_Object frob,
364                       CONST struct lrecord_implementation *type);
365
366 /* Copy the data from one lcrecord structure into another, but don't
367    overwrite the header information. */
368
369 #define copy_lcrecord(dst, src)                                 \
370   memcpy ((char *) dst + sizeof (struct lcrecord_header),       \
371           (char *) src + sizeof (struct lcrecord_header),       \
372           sizeof (*dst) - sizeof (struct lcrecord_header))
373
374 #define zero_lcrecord(lcr)                                      \
375    memset ((char *) lcr + sizeof (struct lcrecord_header), 0,   \
376            sizeof (*lcr) - sizeof (struct lcrecord_header))
377
378 #endif /* _XEMACS_LRECORD_H_ */