xref: /plan9-contrib/sys/src/cmd/gs/src/gsstruct.h (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
1 /* Copyright (C) 1993, 1996, 1997, 1998, 1999 Aladdin Enterprises.  All rights reserved.
2 
3    This file is part of Aladdin Ghostscript.
4 
5    Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
6    or distributor accepts any responsibility for the consequences of using it,
7    or for whether it serves any particular purpose or works at all, unless he
8    or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
9    License (the "License") for full details.
10 
11    Every copy of Aladdin Ghostscript must include a copy of the License,
12    normally in a plain ASCII text file named PUBLIC.  The License grants you
13    the right to copy, modify and redistribute Aladdin Ghostscript, but only
14    under certain conditions described in the License.  Among other things, the
15    License requires that the copyright notice and this notice be preserved on
16    all copies.
17  */
18 
19 /*$Id: gsstruct.h,v 1.1 2000/03/09 08:40:42 lpd Exp $ */
20 /* Definitions for Ghostscript modules that define allocatable structures */
21 /* Requires gstypes.h */
22 
23 #ifndef gsstruct_INCLUDED
24 #  define gsstruct_INCLUDED
25 
26 #include "gsstype.h"
27 
28 /*
29  * Ghostscript structures are defined with names of the form (gs_)xxx_s,
30  * with a corresponding typedef of the form (gs_)xxx or (gs_)xxx_t.
31  * By extension, the structure descriptor is named st_[gs_]xxx.
32  * (Note that the descriptor name may omit the gs_ even if the type has it.)
33  * Structure descriptors are always allocated statically and are
34  * always const; they may be either public or private.
35  *
36  * In order to ensure that there is a descriptor for each structure type,
37  * we require, by convention, that the following always appear together
38  * if the structure is defined in a .h file:
39  *      - The definition of the structure xxx_s;
40  *      - If the descriptor is public, an extern_st(st_xxx);
41  *      - The definition of a macro public_st_xxx() or private_st_xxx()
42  *      that creates the actual descriptor.
43  * This convention makes the descriptor visible (if public) to any module
44  * that can see the structure definition.  This is more liberal than
45  * we would like, but it is a reasonable compromise between restricting
46  * visibility and keeping all the definitional elements of a structure
47  * together.  We require that there be no other externs for (public)
48  * structure descriptors; if the definer of a structure wants to make
49  * available the ability to create an instance but does not want to
50  * expose the structure definition, it must export a creator procedure.
51  */
52 /*
53  * If the structure is defined in a .c file, we require that the following
54  * appear together:
55  *      - The definition of the structure xxx_s;
56  *      - The gs_private_st_xxx macro that creates the descriptor.
57  * Note that we only allow this if the structure is completely private
58  * to a single file.  Again, the file must export a creator procedure
59  * if it wants external clients to be able to create instances.
60  *
61  * Some structures are embedded inside others.  In order to be able to
62  * construct the composite pointer enumeration procedures, for such
63  * structures we must define not only the st_xxx descriptor, but also
64  * a st_xxx_max_ptrs constant that gives the maximum number of pointers
65  * the enumeration procedure will return.  This is an unfortunate consequence
66  * of the method we have chosen for implementing pointer enumeration.
67  *
68  * Some structures may exist as elements of homogenous arrays.
69  * In order to be able to enumerate and relocate such arrays, we adopt
70  * the convention that the structure representing an element must be
71  * distinguished from the structure per se, and the name of the element
72  * structure always ends with "_element".  Element structures cannot be
73  * embedded in other structures.
74  *
75  * Note that the definition of the xxx_s structure may be separate from
76  * the typedef for the type xxx(_t).  This still allows us to have full
77  * structure type abstraction.
78  *
79  * Descriptor definitions are not required for structures to which
80  * no traceable pointers from garbage-collectable space will ever exist.
81  * For example, the struct that defines structure types themselves does not
82  * require a descriptor.
83  */
84 
85 /* An opaque type for an object header. */
86 #ifndef obj_header_DEFINED
87 #  define obj_header_DEFINED
88 typedef struct obj_header_s obj_header_t;
89 #endif
90 
91 /*
92  * Define pointer types, which define how to mark the referent of the
93  * pointer.
94  */
95 /*typedef struct gs_ptr_procs_s gs_ptr_procs_t;*/  /* in gsmemory.h */
96 struct gs_ptr_procs_s {
97 
98     /* Unmark the referent of a pointer. */
99 
100 #define ptr_proc_unmark(proc)\
101   void proc(P2(enum_ptr_t *, gc_state_t *))
102     ptr_proc_unmark((*unmark));
103 
104     /* Mark the referent of a pointer. */
105     /* Return true iff it was unmarked before. */
106 
107 #define ptr_proc_mark(proc)\
108   bool proc(P2(enum_ptr_t *, gc_state_t *))
109     ptr_proc_mark((*mark));
110 
111     /* Relocate a pointer. */
112     /* Note that the argument is const, but the */
113     /* return value is not: this shifts the compiler */
114     /* 'discarding const' warning from the call sites */
115     /* (the reloc_ptr routines) to the implementations. */
116 
117 #define ptr_proc_reloc(proc, typ)\
118   typ *proc(P2(const typ *, gc_state_t *))
119     ptr_proc_reloc((*reloc), void);
120 
121 };
122 /*typedef const gs_ptr_procs_t *gs_ptr_type_t;*/  /* in gsmemory.h */
123 
124 /* Define the pointer type for ordinary structure pointers. */
125 extern const gs_ptr_procs_t ptr_struct_procs;
126 #define ptr_struct_type (&ptr_struct_procs)
127 
128 /* Define the pointer types for a pointer to a gs_[const_]string. */
129 extern const gs_ptr_procs_t ptr_string_procs;
130 #define ptr_string_type (&ptr_string_procs)
131 extern const gs_ptr_procs_t ptr_const_string_procs;
132 #define ptr_const_string_type (&ptr_const_string_procs)
133 
134 /*
135  * Define the type for a GC root.
136  */
137 /*typedef struct gs_gc_root_s gs_gc_root_t;*/  /* in gsmemory.h */
138 struct gs_gc_root_s {
139     gs_gc_root_t *next;
140     gs_ptr_type_t ptype;
141     void **p;
142     bool free_on_unregister;
143 };
144 
145 #define public_st_gc_root_t()	/* in gsmemory.c */\
146   gs_public_st_ptrs1(st_gc_root_t, gs_gc_root_t, "gs_gc_root_t",\
147     gc_root_enum_ptrs, gc_root_reloc_ptrs, next)
148 
149 /* Print a root debugging message. */
150 #define if_debug_root(c, msg, rp)\
151   if_debug4(c, "%s 0x%lx: 0x%lx -> 0x%lx\n",\
152 	    msg, (ulong)(rp), (ulong)(rp)->p, (ulong)*(rp)->p)
153 
154 /*
155  * We don't want to tie the allocator to using a single garbage collector,
156  * so we pass all the relevant GC procedures in to the structure pointer
157  * enumeration and relocation procedures.  The GC state must begin with
158  * a pointer to the following procedure vector.
159  *
160  * By default, this is all the procedures we know about, but there are
161  * additional procedures defined in the interpreter for dealing with
162  * 'ref' objects.
163  */
164 #define string_proc_reloc(proc)\
165   void proc(P2(gs_string *, gc_state_t *))
166 #define const_string_proc_reloc(proc)\
167   void proc(P2(gs_const_string *, gc_state_t *))
168 #define gc_procs_common\
169 	/* Relocate a pointer to an object. */\
170   ptr_proc_reloc((*reloc_struct_ptr), void /*obj_header_t*/);\
171 	/* Relocate a pointer to a string. */\
172   string_proc_reloc((*reloc_string));\
173 	/* Relocate a pointer to a const string. */\
174   const_string_proc_reloc((*reloc_const_string))
175 typedef struct gc_procs_common_s {
176     gc_procs_common;
177 } gc_procs_common_t;
178 
179 #define gc_proc(gcst, proc) ((*(const gc_procs_common_t **)(gcst))->proc)
180 
181 /* Define the accessor for structure type names. */
182 #define struct_type_name_string(pstype) ((const char *)((pstype)->sname))
183 
184 /* Default pointer processing */
185 struct_proc_enum_ptrs(gs_no_struct_enum_ptrs);
186 struct_proc_reloc_ptrs(gs_no_struct_reloc_ptrs);
187 
188 /* Define 'type' descriptors for some standard objects. */
189 
190     /* Free blocks */
191 
192 extern_st(st_free);
193 
194     /* Byte objects */
195 
196 extern_st(st_bytes);
197 
198     /* GC roots */
199 
200 extern_st(st_gc_root_t);
201 
202     /* Elements and arrays of const strings. */
203 
204 #define private_st_const_string()\
205   BASIC_PTRS(const_string_elts) {\
206     { GC_ELT_CONST_STRING, 0 }\
207   };\
208   gs__st_basic(private_st, st_const_string, gs_const_string,\
209     "gs_const_string", const_string_elts, const_string_sdata)
210 
211 extern_st(st_const_string_element);
212 #define public_st_const_string_element()\
213   gs_public_st_element(st_const_string_element, gs_const_string,\
214     "gs_const_string[]", const_string_elt_enum_ptrs,\
215     const_string_elt_reloc_ptrs, st_const_string)
216 
217 /* ================ Macros for defining structure types ================ */
218 
219 #define public_st public const gs_memory_struct_type_t
220 #define private_st private const gs_memory_struct_type_t
221 
222 /*
223  * As an alternative to defining different enum_ptrs and reloc_ptrs
224  * procedures for basic structure types that only have a fixed number of
225  * pointers and possibly a single supertype, we can define the type's GC
226  * information using stock procedures and a table.  Each entry in the table
227  * defines one element of the structure.
228  */
229 
230 /* Define the pointer types of individual elements. */
231 
232 typedef enum {
233     GC_ELT_OBJ,			/* obj * or const obj * */
234     GC_ELT_STRING,		/* gs_string */
235     GC_ELT_CONST_STRING		/* gs_const_string */
236 } gc_ptr_type_index_t;
237 
238 typedef struct gc_ptr_element_s {
239     ushort /*gc_ptr_type_index_t */ type;
240     ushort offset;
241 } gc_ptr_element_t;
242 
243 #define GC_OBJ_ELT(typ, elt)\
244   { GC_ELT_OBJ, offset_of(typ, elt) }
245 #define GC_OBJ_ELT2(typ, e1, e2)\
246   GC_OBJ_ELT(typ, e1), GC_OBJ_ELT(typ, e2)
247 #define GC_OBJ_ELT3(typ, e1, e2, e3)\
248   GC_OBJ_ELT(typ, e1), GC_OBJ_ELT(typ, e2), GC_OBJ_ELT(typ, e3)
249 #define GC_STRING_ELT(typ, elt)\
250   { GC_ELT_STRING, offset_of(typ, elt) }
251 #define GC_CONST_STRING_ELT(typ, elt)\
252   { GC_ELT_CONST_STRING, offset_of(typ, elt) }
253 
254 /* Define the complete table of descriptor data. */
255 
256 typedef struct gc_struct_data_s {
257     ushort num_ptrs;
258     ushort super_offset;
259     const gs_memory_struct_type_t *super_type; /* 0 if none */
260     const gc_ptr_element_t *ptrs;
261 } gc_struct_data_t;
262 
263 /*
264  * Define the enum_ptrs and reloc_ptrs procedures, and the declaration
265  * macros, for table-specified structures.  For such structures, the
266  * proc_data points to a gc_struct_data_t.  The standard defining form
267  * is:
268 
269  BASIC_PTRS(xxx_ptrs) {
270     ... elements ...
271  };
272  gs_(private|public)_st_basic_super_final(stname, stype, sname, xxx_ptrs,
273     xxx_data, supst, supoff, pfinal);
274  gs_(private|public)_st_basic_super(stname, stype, sname, xxx_ptrs, xxx_data,
275     supst, supoff);
276  gs_(private|public)_st_basic(stname, stype, sname, xxx_ptrs, xxx_data);
277 
278  */
279 struct_proc_enum_ptrs(basic_enum_ptrs);
280 struct_proc_reloc_ptrs(basic_reloc_ptrs);
281 
282 #define BASIC_PTRS(elts)\
283   private const gc_ptr_element_t elts[] =
284 #define gs__st_basic_with_super_final(scope_st, stname, stype, sname, nelts, elts, sdata, supst, supoff, pfinal)\
285   private const gc_struct_data_t sdata = {\
286     nelts, supoff, supst, elts\
287   };\
288   scope_st stname = {\
289     sizeof(stype), sname, 0, 0, basic_enum_ptrs, basic_reloc_ptrs,\
290     pfinal, &sdata\
291   }
292      /* Basic objects with superclass and finalization. */
293 #define gs__st_basic_super_final(scope_st, stname, stype, sname, elts, sdata, supst, supoff, pfinal)\
294   gs__st_basic_with_super_final(scope_st, stname, stype, sname, countof(elts), elts, sdata, supst, supoff, pfinal)
295 #define gs_public_st_basic_super_final(stname, stype, sname, elts, sdata, supst, supoff, pfinal)\
296   gs__st_basic_super_final(public_st, stname, stype, sname, elts, sdata, supst, supoff, pfinal)
297 #define gs_private_st_basic_super_final(stname, stype, sname, elts, sdata, supst, supoff, pfinal)\
298   gs__st_basic_super_final(private_st, stname, stype, sname, elts, sdata, supst, supoff, pfinal)
299      /* Basic objects with only superclass. */
300 #define gs__st_basic_super(scope_st, stname, stype, sname, elts, sdata, supst, supoff)\
301   gs__st_basic_super_final(scope_st, stname, stype, sname, elts, sdata, supst, supoff, 0)
302 #define gs_public_st_basic_super(stname, stype, sname, elts, sdata, supst, supoff)\
303   gs__st_basic_super(public_st, stname, stype, sname, elts, sdata, supst, supoff)
304 #define gs_private_st_basic_super(stname, stype, sname, elts, sdata, supst, supoff)\
305   gs__st_basic_super(private_st, stname, stype, sname, elts, sdata, supst, supoff)
306      /* Basic objects with no frills. */
307 #define gs__st_basic(scope_st, stname, stype, sname, elts, sdata)\
308   gs__st_basic_super(scope_st, stname, stype, sname, elts, sdata, 0, 0)
309 #define gs_public_st_basic(stname, stype, sname, elts, sdata)\
310   gs__st_basic(public_st, stname, stype, sname, elts, sdata)
311 #define gs_private_st_basic(stname, stype, sname, elts, sdata)\
312   gs__st_basic(private_st, stname, stype, sname, elts, sdata)
313 
314 /*
315  * The simplest kind of composite structure is one with a fixed set of
316  * pointers, each of which points to a struct.  We provide macros for
317  * defining this kind of structure conveniently, either all at once in
318  * the structure definition macro, or using the following template:
319 
320  ENUM_PTRS_WITH(xxx_enum_ptrs, stype *const myptr) return 0;
321  ... ENUM_PTR(i, xxx, elt); ...
322  ENUM_PTRS_END
323  RELOC_PTRS_WITH(xxx_reloc_ptrs, stype *const myptr)
324  {
325      ...
326      RELOC_VAR(myptr->elt);
327      ...
328  }
329 
330  */
331 /*
332  * We have to pull the 'private' outside the ENUM_PTRS_BEGIN and
333  * RELOC_PTRS_BEGIN macros because of a bug in the Borland C++ preprocessor.
334  * We also have to make sure there is more on the line after these
335  * macros, so as not to confuse ansi2knr.
336  */
337 
338      /* Begin enumeration */
339 
340 #ifdef __PROTOTYPES__
341 #  define ENUM_PTRS_BEGIN_PROC(proc)\
342     gs_ptr_type_t proc(EV_CONST void *vptr, uint size, int index, enum_ptr_t *pep, const gs_memory_struct_type_t *pstype, gc_state_t *gcst)
343 #else
344 #  define ENUM_PTRS_BEGIN_PROC(proc)\
345     gs_ptr_type_t proc(vptr, size, index, pep, pstype, gcst) EV_CONST void *vptr; uint size; int index; enum_ptr_t *pep; const gs_memory_struct_type_t *pstype; gc_state_t *gcst;
346 #endif
347 #define ENUM_PTRS_BEGIN(proc)\
348   ENUM_PTRS_BEGIN_PROC(proc)\
349   { switch ( index ) { default:
350 #define ENUM_PTRS_WITH(proc, stype_ptr)\
351   ENUM_PTRS_BEGIN_PROC(proc)\
352   { EV_CONST stype_ptr = vptr; switch ( index ) { default:
353 
354     /* Enumerate elements */
355 
356 #define ENUM_OBJ(optr)		/* pointer to object */\
357   (pep->ptr = (const void *)(optr), ptr_struct_type)
358 #define ENUM_STRING2(sdata, ssize) /* gs_string */\
359   (pep->ptr = sdata, pep->size = ssize, ptr_string_type)
360 #define ENUM_STRING(sptr)	/* pointer to gs_string */\
361   ENUM_STRING2((sptr)->data, (sptr)->size)
362 #define ENUM_CONST_STRING2(sdata, ssize)	/* gs_const_string */\
363   (pep->ptr = sdata, pep->size = ssize, ptr_const_string_type)
364 #define ENUM_CONST_STRING(sptr)	/* pointer to gs_const_string */\
365   ENUM_CONST_STRING2((sptr)->data, (sptr)->size)
366 extern gs_ptr_type_t
367     enum_bytestring(P2(enum_ptr_t *pep, const gs_bytestring *pbs));
368 #define ENUM_BYTESTRING(ptr)	/* pointer to gs_bytestring */\
369   enum_bytestring(pep, ptr)
370 extern gs_ptr_type_t
371     enum_const_bytestring(P2(enum_ptr_t *pep, const gs_const_bytestring *pbs));
372 #define ENUM_CONST_BYTESTRING(ptr)  /* pointer to gs_const_bytestring */\
373   enum_const_bytestring(pep, ptr)
374 
375 #define ENUM_OBJ_ELT(typ, elt)\
376   ENUM_OBJ(((const typ *)vptr)->elt)
377 #define ENUM_STRING_ELT(typ, elt)\
378   ENUM_STRING(&((const typ *)vptr)->elt)
379 #define ENUM_CONST_STRING_ELT(typ, elt)\
380   ENUM_CONST_STRING(&((const typ *)vptr)->elt)
381 
382 #define ENUM_PTR(i, typ, elt)\
383   case i: return ENUM_OBJ_ELT(typ, elt)
384 #define ENUM_PTR3(i, typ, e1, e2, e3) /* just an abbreviation */\
385   ENUM_PTR(i, typ, e1); ENUM_PTR((i)+1, typ, e2); ENUM_PTR((i)+2, typ, e3)
386 #define ENUM_STRING_PTR(i, typ, elt)\
387   case i: return ENUM_STRING_ELT(typ, elt)
388 #define ENUM_CONST_STRING_PTR(i, typ, elt)\
389   case i: return ENUM_CONST_STRING_ELT(typ, elt)
390 
391     /* End enumeration */
392 
393 #define ENUM_PTRS_END\
394   } /* mustn't fall through! */ ENUM_PTRS_END_PROC }
395 #define ENUM_PTRS_END_PROC	/* */
396 
397     /* Begin relocation */
398 
399 #ifdef __PROTOTYPES__
400 #  define RELOC_PTRS_BEGIN(proc)\
401     void proc(void *vptr, uint size, const gs_memory_struct_type_t *pstype, gc_state_t *gcst) {
402 #else
403 #  define RELOC_PTRS_BEGIN(proc)\
404     void proc(vptr, size, pstype, gcst) void *vptr; uint size; const gs_memory_struct_type_t *pstype; gc_state_t *gcst; {
405 #endif
406 #define RELOC_PTRS_WITH(proc, stype_ptr)\
407     RELOC_PTRS_BEGIN(proc) stype_ptr = vptr;
408 
409     /* Relocate elements */
410 
411 #define RELOC_OBJ(ptr)\
412   (gc_proc(gcst, reloc_struct_ptr)((const void *)(ptr), gcst))
413 #define RELOC_OBJ_VAR(ptrvar)\
414   (ptrvar = RELOC_OBJ(ptrvar))
415 #define RELOC_VAR(ptrvar)	/* a handy abbreviation */\
416   RELOC_OBJ_VAR(ptrvar)
417 #define RELOC_STRING_VAR(ptrvar)\
418   (gc_proc(gcst, reloc_string)(&(ptrvar), gcst))
419 #define RELOC_CONST_STRING_VAR(ptrvar)\
420   (gc_proc(gcst, reloc_const_string)(&(ptrvar), gcst))
421 extern void reloc_bytestring(P2(gs_bytestring *pbs, gc_state_t *gcst));
422 #define RELOC_BYTESTRING_VAR(ptrvar)\
423   reloc_bytestring(&(ptrvar), gcst)
424 extern void reloc_const_bytestring(P2(gs_const_bytestring *pbs, gc_state_t *gcst));
425 #define RELOC_CONST_BYTESTRING_VAR(ptrvar)\
426   reloc_const_bytestring(&(ptrvar), gcst)
427 
428 #define RELOC_OBJ_ELT(typ, elt)\
429   RELOC_VAR(((typ *)vptr)->elt)
430 #define RELOC_STRING_ELT(typ, elt)\
431   RELOC_STRING_VAR(((typ *)vptr)->elt)
432 #define RELOC_CONST_STRING_ELT(typ, elt)\
433   RELOC_CONST_STRING_VAR(((typ *)vptr)->elt)
434 
435 /* Relocate a pointer that points to a known offset within an object. */
436 /* OFFSET is for byte offsets, TYPED_OFFSET is for element offsets. */
437 #define RELOC_OFFSET_ELT(typ, elt, offset)\
438   ((typ *)vptr)->elt = (void *)\
439     ((char *)RELOC_OBJ((char *)((typ *)vptr)->elt - (offset)) +\
440      (offset))
441 #define RELOC_TYPED_OFFSET_ELT(typ, elt, offset)\
442   (((typ *)vptr)->elt = (void *)RELOC_OBJ(((typ *)vptr)->elt - (offset)),\
443    ((typ *)vptr)->elt += (offset))
444 
445     /* Backward compatibility */
446 
447 #define RELOC_PTR(typ, elt)\
448   RELOC_OBJ_ELT(typ, elt)
449 #define RELOC_PTR3(typ, e1, e2, e3) /* just an abbreviation */\
450   RELOC_PTR(typ,e1); RELOC_PTR(typ,e2); RELOC_PTR(typ,e3)
451 #define RELOC_OFFSET_PTR(typ, elt, offset)\
452   RELOC_OFFSET_ELT(typ, elt, offset)
453 #define RELOC_TYPED_OFFSET_PTR(typ, elt, offset)\
454   RELOC_TYPED_OFFSET_ELT(typ, elt, offset)
455 #define RELOC_STRING_PTR(typ, elt)\
456   RELOC_STRING_ELT(typ, elt)
457 #define RELOC_CONST_STRING_PTR(typ, elt)\
458   RELOC_CONST_STRING_ELT(typ, elt)
459 
460     /* End relocation */
461 
462 #define RELOC_PTRS_END\
463   }
464 
465     /* Subclass support */
466 
467 #define ENUM_USING(supst, ptr, size, index)\
468   (*(supst).enum_ptrs)(ptr, size, index, pep, &(supst), gcst)
469 
470 #define RELOC_USING(supst, ptr, size)\
471   (*(supst).reloc_ptrs)(ptr, size, &(supst), gcst)
472 
473     /*
474      * Support for suffix subclasses.  Special subclasses constructed
475      * 'by hand' may use this also.
476      */
477 
478 #define ENUM_USING_PREFIX(supst, n)\
479   ENUM_USING(supst, vptr, size, index-(n))
480 
481 #define ENUM_PREFIX(supst, n)\
482   return ENUM_USING_PREFIX(supst, n)
483 
484 #define RELOC_PREFIX(supst)\
485   RELOC_USING(supst, vptr, size)
486 
487     /*
488      * Support for general subclasses.
489      */
490 
491 #define ENUM_SUPER_ELT(stype, supst, member, n)\
492   ENUM_USING(supst, &((EV_CONST stype *)vptr)->member, sizeof(((EV_CONST stype *)vptr)->member), index-(n))
493 #define ENUM_SUPER(stype, supst, member, n)\
494   return ENUM_SUPER_ELT(stype, supst, member, n)
495 
496 #define RELOC_SUPER_ELT(stype, supst, member)\
497   RELOC_USING(supst, &((stype *)vptr)->member, sizeof(((stype *)vptr)->member))
498 #define RELOC_SUPER(stype, supst, member)\
499   RELOC_SUPER_ELT(stype, supst, member)
500 
501     /* Backward compatibility. */
502 
503 #define ENUM_RETURN(ptr) return ENUM_OBJ(ptr)
504 #define ENUM_RETURN_PTR(typ, elt) return ENUM_OBJ_ELT(typ, elt)
505 #define ENUM_RETURN_STRING_PTR(typ, elt) return ENUM_STRING_ELT(typ, elt)
506 #define ENUM_RETURN_CONST_STRING(ptr) return ENUM_CONST_STRING(ptr)
507 #define ENUM_RETURN_CONST_STRING_PTR(typ, elt) return ENUM_CONST_STRING_ELT(typ, elt)
508 
509 /* -------------- Simple structures (no internal pointers). -------------- */
510 
511 #define gs__st_simple(scope_st, stname, stype, sname)\
512   scope_st stname = { sizeof(stype), sname, 0, 0, gs_no_struct_enum_ptrs, gs_no_struct_reloc_ptrs, 0 }
513 #define gs_public_st_simple(stname, stype, sname)\
514   gs__st_simple(public_st, stname, stype, sname)
515 #define gs_private_st_simple(stname, stype, sname)\
516   gs__st_simple(private_st, stname, stype, sname)
517 
518 /* ---------------- Structures with explicit procedures. ---------------- */
519 
520 /*
521  * Boilerplate for clear_marks procedures.
522  */
523 #ifdef __PROTOTYPES__
524 #  define CLEAR_MARKS_PROC(proc)\
525     void proc(void *vptr, uint size, const gs_memory_struct_type_t *pstype)
526 #else
527 #  define CLEAR_MARKS_PROC(proc)\
528     void proc(vptr, size, pstype) void *vptr; uint size; const gs_memory_struct_type_t *pstype;
529 #endif
530 
531 	/* Complex structures with their own clear_marks, */
532 	/* enum, reloc, and finalize procedures. */
533 
534 #define gs__st_complex_only(scope_st, stname, stype, sname, pclear, penum, preloc, pfinal)\
535   scope_st stname = { sizeof(stype), sname, 0, pclear, penum, preloc, pfinal }
536 #define gs_public_st_complex_only(stname, stype, sname, pclear, penum, preloc, pfinal)\
537   gs__st_complex_only(public_st, stname, stype, sname, pclear, penum, preloc, pfinal)
538 #define gs_private_st_complex_only(stname, stype, sname, pclear, penum, preloc, pfinal)\
539   gs__st_complex_only(private_st, stname, stype, sname, pclear, penum, preloc, pfinal)
540 
541 #define gs__st_complex(scope_st, stname, stype, sname, pclear, penum, preloc, pfinal)\
542   private struct_proc_clear_marks(pclear);\
543   private struct_proc_enum_ptrs(penum);\
544   private struct_proc_reloc_ptrs(preloc);\
545   private struct_proc_finalize(pfinal);\
546   gs__st_complex_only(scope_st, stname, stype, sname, pclear, penum, preloc, pfinal)
547 #define gs_public_st_complex(stname, stype, sname, pclear, penum, preloc, pfinal)\
548   gs__st_complex(public_st, stname, stype, sname, pclear, penum, preloc, pfinal)
549 #define gs_private_st_complex(stname, stype, sname, pclear, penum, preloc, pfinal)\
550   gs__st_complex(private_st, stname, stype, sname, pclear, penum, preloc, pfinal)
551 
552 	/* Composite structures with their own enum and reloc procedures. */
553 
554 #define gs__st_composite(scope_st, stname, stype, sname, penum, preloc)\
555   private struct_proc_enum_ptrs(penum);\
556   private struct_proc_reloc_ptrs(preloc);\
557   gs__st_complex_only(scope_st, stname, stype, sname, 0, penum, preloc, 0)
558 #define gs_public_st_composite(stname, stype, sname, penum, preloc)\
559   gs__st_composite(public_st, stname, stype, sname, penum, preloc)
560 #define gs_private_st_composite(stname, stype, sname, penum, preloc)\
561   gs__st_composite(private_st, stname, stype, sname, penum, preloc)
562 
563 	/* Composite structures with inherited finalization. */
564 
565 #define gs__st_composite_use_final(scope_st, stname, stype, sname, penum, preloc, pfinal)\
566   private struct_proc_enum_ptrs(penum);\
567   private struct_proc_reloc_ptrs(preloc);\
568   gs__st_complex_only(scope_st, stname, stype, sname, 0, penum, preloc, pfinal)
569 #define gs_public_st_composite_use_final(stname, stype, sname, penum, preloc, pfinal)\
570   gs__st_composite_use_final(public_st, stname, stype, sname, penum, preloc, pfinal)
571 #define gs_private_st_composite_use_final(stname, stype, sname, penum, preloc, pfinal)\
572   gs__st_composite_use_final(private_st, stname, stype, sname, penum, preloc, pfinal)
573 
574 	/* Composite structures with finalization. */
575 
576 #define gs__st_composite_final(scope_st, stname, stype, sname, penum, preloc, pfinal)\
577   private struct_proc_finalize(pfinal);\
578   gs__st_composite_use_final(scope_st, stname, stype, sname, penum, preloc, pfinal)
579 #define gs_public_st_composite_final(stname, stype, sname, penum, preloc, pfinal)\
580   gs__st_composite_final(public_st, stname, stype, sname, penum, preloc, pfinal)
581 #define gs_private_st_composite_final(stname, stype, sname, penum, preloc, pfinal)\
582   gs__st_composite_final(private_st, stname, stype, sname, penum, preloc, pfinal)
583 
584 	/* Composite structures with enum and reloc procedures */
585 	/* already declared. */
586 
587 #define gs__st_composite_only(scope_st, stname, stype, sname, penum, preloc)\
588   gs__st_complex_only(scope_st, stname, stype, sname, 0, penum, preloc, 0)
589 #define gs_public_st_composite_only(stname, stype, sname, penum, preloc)\
590   gs__st_composite_only(public_st, stname, stype, sname, penum, preloc)
591 #define gs_private_st_composite_only(stname, stype, sname, penum, preloc)\
592   gs__st_composite_only(private_st, stname, stype, sname, penum, preloc)
593 
594 /* ---------------- Special kinds of structures ---------------- */
595 
596 	/* Element structures, for use in arrays of structures. */
597 	/* Note that these require that the underlying structure's */
598 	/* enum_ptrs procedure always return the same number of pointers. */
599 
600 #define gs__st_element(scope_st, stname, stype, sname, penum, preloc, basest)\
601   private ENUM_PTRS_BEGIN_PROC(penum) {\
602     uint count = size / (uint)sizeof(stype);\
603     if ( count == 0 ) return 0;\
604     return ENUM_USING(basest, (EV_CONST char *)vptr + (index % count) * sizeof(stype),\
605       sizeof(stype), index / count);\
606   } ENUM_PTRS_END_PROC\
607   private RELOC_PTRS_BEGIN(preloc) {\
608     uint count = size / (uint)sizeof(stype);\
609     for ( ; count; count--, vptr = (char *)vptr + sizeof(stype) )\
610       RELOC_USING(basest, vptr, sizeof(stype));\
611   } RELOC_PTRS_END\
612   gs__st_composite_only(scope_st, stname, stype, sname, penum, preloc)
613 #define gs_public_st_element(stname, stype, sname, penum, preloc, basest)\
614   gs__st_element(public_st, stname, stype, sname, penum, preloc, basest)
615 #define gs_private_st_element(stname, stype, sname, penum, preloc, basest)\
616   gs__st_element(private_st, stname, stype, sname, penum, preloc, basest)
617 
618 	/* A "structure" just consisting of a pointer. */
619 	/* Note that in this case only, stype is a pointer type. */
620 	/* Fortunately, C's bizarre 'const' syntax does what we want here. */
621 
622 #define gs__st_ptr(scope_st, stname, stype, sname, penum, preloc)\
623   private ENUM_PTRS_BEGIN(penum) return 0;\
624     case 0: return ENUM_OBJ(*(stype const *)vptr);\
625   ENUM_PTRS_END\
626   private RELOC_PTRS_BEGIN(preloc) ;\
627     RELOC_VAR(*(stype *)vptr);\
628   RELOC_PTRS_END\
629   gs__st_composite_only(scope_st, stname, stype, sname, penum, preloc)
630 #define gs_public_st_ptr(stname, stype, sname, penum, preloc)\
631   gs__st_ptr(public_st, stname, stype, sname, penum, preloc)
632 #define gs_private_st_ptr(stname, stype, sname, penum, preloc)\
633   gs__st_ptr(private_st, stname, stype, sname, penum, preloc)
634 
635 /* ---------- Ordinary structures with a fixed set of pointers ----------- */
636 /* Note that we "cannibalize" the penum and preloc names for elts and sdata. */
637 
638 	/* Structures with 1 pointer. */
639 
640 #define gs__st_ptrs1(scope_st, stname, stype, sname, penum, preloc, e1)\
641   BASIC_PTRS(penum) {\
642     GC_OBJ_ELT(stype, e1)\
643   };\
644   gs__st_basic(scope_st, stname, stype, sname, penum, preloc)
645 #define gs_public_st_ptrs1(stname, stype, sname, penum, preloc, e1)\
646   gs__st_ptrs1(public_st, stname, stype, sname, penum, preloc, e1)
647 #define gs_private_st_ptrs1(stname, stype, sname, penum, preloc, e1)\
648   gs__st_ptrs1(private_st, stname, stype, sname, penum, preloc, e1)
649 
650 	/* Structures with 1 string. */
651 
652 #define gs__st_strings1(scope_st, stname, stype, sname, penum, preloc, e1)\
653   BASIC_PTRS(penum) {\
654     GC_STRING_ELT(stype, e1)\
655   };\
656   gs__st_basic(scope_st, stname, stype, sname, penum, preloc)
657 #define gs_public_st_strings1(stname, stype, sname, penum, preloc, e1)\
658   gs__st_strings1(public_st, stname, stype, sname, penum, preloc, e1)
659 #define gs_private_st_strings1(stname, stype, sname, penum, preloc, e1)\
660   gs__st_strings1(private_st, stname, stype, sname, penum, preloc, e1)
661 
662 	/* Structures with 1 const string. */
663 
664 #define gs__st_const_strings1(scope_st, stname, stype, sname, penum, preloc, e1)\
665   BASIC_PTRS(penum) {\
666     GC_CONST_STRING_ELT(stype, e1)\
667   };\
668   gs__st_basic(scope_st, stname, stype, sname, penum, preloc)
669 #define gs_public_st_const_strings1(stname, stype, sname, penum, preloc, e1)\
670   gs__st_const_strings1(public_st, stname, stype, sname, penum, preloc, e1)
671 #define gs_private_st_const_strings1(stname, stype, sname, penum, preloc, e1)\
672   gs__st_const_strings1(private_st, stname, stype, sname, penum, preloc, e1)
673 
674 	/* Structures with 2 const strings. */
675 
676 #define gs__st_const_strings2(scope_st, stname, stype, sname, penum, preloc, e1, e2)\
677   BASIC_PTRS(penum) {\
678     GC_CONST_STRING_ELT(stype, e1), GC_CONST_STRING_ELT(stype, e2)\
679   };\
680   gs__st_basic(scope_st, stname, stype, sname, penum, preloc)
681 #define gs_public_st_const_strings2(stname, stype, sname, penum, preloc, e1, e2)\
682   gs__st_const_strings2(public_st, stname, stype, sname, penum, preloc, e1, e2)
683 #define gs_private_st_const_strings2(stname, stype, sname, penum, preloc, e1, e2)\
684   gs__st_const_strings2(private_st, stname, stype, sname, penum, preloc, e1, e2)
685 
686 	/* Structures with 2 pointers. */
687 
688 #define gs__st_ptrs2(scope_st, stname, stype, sname, penum, preloc, e1, e2)\
689   BASIC_PTRS(penum) {\
690     GC_OBJ_ELT2(stype, e1, e2)\
691   };\
692   gs__st_basic(scope_st, stname, stype, sname, penum, preloc)
693 #define gs_public_st_ptrs2(stname, stype, sname, penum, preloc, e1, e2)\
694   gs__st_ptrs2(public_st, stname, stype, sname, penum, preloc, e1, e2)
695 #define gs_private_st_ptrs2(stname, stype, sname, penum, preloc, e1, e2)\
696   gs__st_ptrs2(private_st, stname, stype, sname, penum, preloc, e1, e2)
697 
698 	/* Structures with 3 pointers. */
699 
700 #define gs__st_ptrs3(scope_st, stname, stype, sname, penum, preloc, e1, e2, e3)\
701   BASIC_PTRS(penum) {\
702     GC_OBJ_ELT3(stype, e1, e2, e3)\
703   };\
704   gs__st_basic(scope_st, stname, stype, sname, penum, preloc)
705 #define gs_public_st_ptrs3(stname, stype, sname, penum, preloc, e1, e2, e3)\
706   gs__st_ptrs3(public_st, stname, stype, sname, penum, preloc, e1, e2, e3)
707 #define gs_private_st_ptrs3(stname, stype, sname, penum, preloc, e1, e2, e3)\
708   gs__st_ptrs3(private_st, stname, stype, sname, penum, preloc, e1, e2, e3)
709 
710 	/* Structures with 4 pointers. */
711 
712 #define gs__st_ptrs4(scope_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4)\
713   BASIC_PTRS(penum) {\
714     GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT(stype, e4)\
715   };\
716   gs__st_basic(scope_st, stname, stype, sname, penum, preloc)
717 #define gs_public_st_ptrs4(stname, stype, sname, penum, preloc, e1, e2, e3, e4)\
718   gs__st_ptrs4(public_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4)
719 #define gs_private_st_ptrs4(stname, stype, sname, penum, preloc, e1, e2, e3, e4)\
720   gs__st_ptrs4(private_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4)
721 
722 	/* Structures with 5 pointers. */
723 
724 #define gs__st_ptrs5(scope_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5)\
725   BASIC_PTRS(penum) {\
726     GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT2(stype, e4, e5)\
727   };\
728   gs__st_basic(scope_st, stname, stype, sname, penum, preloc)
729 #define gs_public_st_ptrs5(stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5)\
730   gs__st_ptrs5(public_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5)
731 #define gs_private_st_ptrs5(stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5)\
732   gs__st_ptrs5(private_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5)
733 
734 	/* Structures with 6 pointers. */
735 
736 #define gs__st_ptrs6(scope_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6)\
737   BASIC_PTRS(penum) {\
738     GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT3(stype, e4, e5, e6)\
739   };\
740   gs__st_basic(scope_st, stname, stype, sname, penum, preloc)
741 #define gs_public_st_ptrs6(stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6)\
742   gs__st_ptrs6(public_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6)
743 #define gs_private_st_ptrs6(stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6)\
744   gs__st_ptrs6(private_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6)
745 
746 /* ---------------- Suffix subclasses ---------------- */
747 
748 	/* Suffix subclasses with no additional pointers. */
749 
750 #define gs__st_suffix_add0(scope_st, stname, stype, sname, penum, preloc, supstname)\
751   gs__st_basic_with_super_final(scope_st, stname, stype, sname, 0, 0, preloc, &supstname, 0, 0)
752 #define gs_public_st_suffix_add0(stname, stype, sname, penum, preloc, supstname)\
753   gs__st_suffix_add0(public_st, stname, stype, sname, penum, preloc, supstname)
754 #define gs_private_st_suffix_add0(stname, stype, sname, penum, preloc, supstname)\
755   gs__st_suffix_add0(private_st, stname, stype, sname, penum, preloc, supstname)
756 
757 	/* Suffix subclasses with no additional pointers, */
758 	/* and with the superclass defined earlier in the same file */
759 	/* as a 'basic' type. */
760 	/* In this case, we don't even need new procedures. */
761 
762 #define gs__st_suffix_add0_local(scope_st, stname, stype, sname, supenum, supreloc, supstname)\
763   scope_st stname = {\
764     sizeof(stype), sname, 0, 0, basic_enum_ptrs, basic_reloc_ptrs,\
765     0, &supreloc\
766   }
767 #define gs_public_st_suffix_add0_local(stname, stype, sname, supenum, supreloc, supstname)\
768   gs__st_suffix_add0_local(public_st, stname, stype, sname, supenum, supreloc, supstname)
769 #define gs_private_st_suffix_add0_local(stname, stype, sname, supenum, supreloc, supstname)\
770   gs__st_suffix_add0_local(private_st, stname, stype, sname, supenum, supreloc, supstname)
771 
772 	/* Suffix subclasses with no additional pointers and finalization. */
773 	/* This is a hack -- subclasses should inherit finalization, */
774 	/* but that would require a superclass pointer in the descriptor, */
775 	/* which would perturb things too much right now. */
776 
777 #define gs__st_suffix_add0_final(scope_st, stname, stype, sname, penum, preloc, pfinal, supstname)\
778   private ENUM_PTRS_BEGIN_PROC(penum) {\
779     ENUM_PREFIX(supstname, 0);\
780   } ENUM_PTRS_END_PROC\
781   private RELOC_PTRS_BEGIN(preloc) {\
782     RELOC_PREFIX(supstname);\
783   } RELOC_PTRS_END\
784   gs__st_complex_only(scope_st, stname, stype, sname, 0, penum, preloc, pfinal)
785 #define gs_public_st_suffix_add0_final(stname, stype, sname, penum, preloc, pfinal, supstname)\
786   gs__st_suffix_add0_final(public_st, stname, stype, sname, penum, preloc, pfinal, supstname)
787 #define gs_private_st_suffix_add0_final(stname, stype, sname, penum, preloc, pfinal, supstname)\
788   gs__st_suffix_add0_final(private_st, stname, stype, sname, penum, preloc, pfinal, supstname)
789 
790 	/* Suffix subclasses with 1 additional pointer. */
791 
792 #define gs__st_suffix_add1(scope_st, stname, stype, sname, penum, preloc, supstname, e1)\
793   BASIC_PTRS(penum) {\
794     GC_OBJ_ELT(stype, e1)\
795   };\
796   gs__st_basic_super(scope_st, stname, stype, sname, penum, preloc, &supstname, 0)
797 #define gs_public_st_suffix_add1(stname, stype, sname, penum, preloc, supstname, e1)\
798   gs__st_suffix_add1(public_st, stname, stype, sname, penum, preloc, supstname, e1)
799 #define gs_private_st_suffix_add1(stname, stype, sname, penum, preloc, supstname, e1)\
800   gs__st_suffix_add1(private_st, stname, stype, sname, penum, preloc, supstname, e1)
801 
802 	/* Suffix subclasses with 1 additional pointer and finalization. */
803 	/* See above regarding finalization and subclasses. */
804 
805 #define gs__st_suffix_add1_final(scope_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1)\
806   BASIC_PTRS(penum) {\
807     GC_OBJ_ELT(stype, e1)\
808   };\
809   gs__st_basic_super_final(scope_st, stname, stype, sname, penum, preloc, &supstname, 0, pfinal)
810 #define gs_public_st_suffix_add1_final(stname, stype, sname, penum, preloc, pfinal, supstname, e1)\
811   gs__st_suffix_add1_final(public_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1)
812 #define gs_private_st_suffix_add1_final(stname, stype, sname, penum, preloc, pfinal, supstname, e1)\
813   gs__st_suffix_add1_final(private_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1)
814 
815 	/* Suffix subclasses with 2 additional pointers. */
816 
817 #define gs__st_suffix_add2(scope_st, stname, stype, sname, penum, preloc, supstname, e1, e2)\
818   BASIC_PTRS(penum) {\
819     GC_OBJ_ELT2(stype, e1, e2)\
820   };\
821   gs__st_basic_super(scope_st, stname, stype, sname, penum, preloc, &supstname, 0)
822 #define gs_public_st_suffix_add2(stname, stype, sname, penum, preloc, supstname, e1, e2)\
823   gs__st_suffix_add2(public_st, stname, stype, sname, penum, preloc, supstname, e1, e2)
824 #define gs_private_st_suffix_add2(stname, stype, sname, penum, preloc, supstname, e1, e2)\
825   gs__st_suffix_add2(private_st, stname, stype, sname, penum, preloc, supstname, e1, e2)
826 
827 	/* Suffix subclasses with 2 additional pointers and finalization. */
828 	/* See above regarding finalization and subclasses. */
829 
830 #define gs__st_suffix_add2_final(scope_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2)\
831   BASIC_PTRS(penum) {\
832     GC_OBJ_ELT2(stype, e1, e2)\
833   };\
834   gs__st_basic_super_final(scope_st, stname, stype, sname, penum, preloc, &supstname, 0, pfinal)
835 #define gs_public_st_suffix_add2_final(stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2)\
836   gs__st_suffix_add2_final(public_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2)
837 #define gs_private_st_suffix_add2_final(stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2)\
838   gs__st_suffix_add2_final(private_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2)
839 
840 	/* Suffix subclasses with 3 additional pointers. */
841 
842 #define gs__st_suffix_add3(scope_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3)\
843   BASIC_PTRS(penum) {\
844     GC_OBJ_ELT3(stype, e1, e2, e3)\
845   };\
846   gs__st_basic_super(scope_st, stname, stype, sname, penum, preloc, &supstname, 0)
847 #define gs_public_st_suffix_add3(stname, stype, sname, penum, preloc, supstname, e1, e2, e3)\
848   gs__st_suffix_add3(public_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3)
849 #define gs_private_st_suffix_add3(stname, stype, sname, penum, preloc, supstname, e1, e2, e3)\
850   gs__st_suffix_add3(private_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3)
851 
852 	/* Suffix subclasses with 3 additional pointers and finalization. */
853 	/* See above regarding finalization and subclasses. */
854 
855 #define gs__st_suffix_add3_final(scope_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2, e3)\
856   BASIC_PTRS(penum) {\
857     GC_OBJ_ELT3(stype, e1, e2, e3)\
858   };\
859   gs__st_basic_super_final(scope_st, stname, stype, sname, penum, preloc, &supstname, 0, pfinal)
860 #define gs_public_st_suffix_add3_final(stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2, e3)\
861   gs__st_suffix_add3_final(public_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2, e3)
862 #define gs_private_st_suffix_add3_final(stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2, e3)\
863   gs__st_suffix_add3_final(private_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2, e3)
864 
865 	/* Suffix subclasses with 4 additional pointers. */
866 
867 #define gs__st_suffix_add4(scope_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4)\
868   BASIC_PTRS(penum) {\
869     GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT(stype, e4)\
870   };\
871   gs__st_basic_super(scope_st, stname, stype, sname, penum, preloc, &supstname, 0)
872 #define gs_public_st_suffix_add4(stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4)\
873   gs__st_suffix_add4(public_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4)
874 #define gs_private_st_suffix_add4(stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4)\
875   gs__st_suffix_add4(private_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4)
876 
877 	/* Suffix subclasses with 4 additional pointers and finalization. */
878 	/* See above regarding finalization and subclasses. */
879 
880 #define gs__st_suffix_add4_final(scope_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2, e3, e4)\
881   BASIC_PTRS(penum) {\
882     GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT(stype, e4)\
883   };\
884   gs__st_basic_super_final(scope_st, stname, stype, sname, penum, preloc, &supstname, 0, pfinal)
885 #define gs_public_st_suffix_add4_final(stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2, e3, e4)\
886   gs__st_suffix_add4_final(public_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2, e3, e4)
887 #define gs_private_st_suffix_add4_final(stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2, e3, e4)\
888   gs__st_suffix_add4_final(private_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2, e3, e4)
889 
890 	/* Suffix subclasses with 6 additional pointers. */
891 
892 #define gs__st_suffix_add6(scope_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6)\
893   BASIC_PTRS(penum) {\
894     GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT3(stype, e4, e5, e6)\
895   };\
896   gs__st_basic_super(scope_st, stname, stype, sname, penum, preloc, &supstname, 0)
897 #define gs_public_st_suffix_add6(stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6)\
898   gs__st_suffix_add6(public_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6)
899 #define gs_private_st_suffix_add6(stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6)\
900   gs__st_suffix_add6(private_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6)
901 
902 /* ---------------- General subclasses ---------------- */
903 
904 	/* General subclasses with no additional pointers. */
905 
906 #define gs__st_ptrs_add0(scope_st, stname, stype, sname, penum, preloc, supstname, member)\
907   gs__st_basic_with_super_final(scope_st, stname, stype, sname, 0, 0, preloc, &supstname, offset_of(stype, member), 0)
908 #define gs_public_st_ptrs_add0(stname, stype, sname, penum, preloc, supstname, member)\
909   gs__st_ptrs_add0(public_st, stname, stype, sname, penum, preloc, supstname, member)
910 #define gs_private_st_ptrs_add0(stname, stype, sname, penum, preloc, supstname, member)\
911   gs__st_ptrs_add0(private_st, stname, stype, sname, penum, preloc, supstname, member)
912 
913 	/* General subclasses with 1 additional pointer. */
914 
915 #define gs__st_ptrs_add1(scope_st, stname, stype, sname, penum, preloc, supstname, member, e1)\
916   BASIC_PTRS(penum) {\
917     GC_OBJ_ELT(stype, e1)\
918   };\
919   gs__st_basic_super(scope_st, stname, stype, sname, penum, preloc, &supstname, offset_of(stype, member))
920 #define gs_public_st_ptrs_add1(stname, stype, sname, penum, preloc, supstname, member, e1)\
921   gs__st_ptrs_add1(public_st, stname, stype, sname, penum, preloc, supstname, member, e1)
922 #define gs_private_st_ptrs_add1(stname, stype, sname, penum, preloc, supstname, member, e1)\
923   gs__st_ptrs_add1(private_st, stname, stype, sname, penum, preloc, supstname, member, e1)
924 
925 	/* General subclasses with 2 additional pointers. */
926 
927 #define gs__st_ptrs_add2(scope_st, stname, stype, sname, penum, preloc, supstname, member, e1, e2)\
928   BASIC_PTRS(penum) {\
929     GC_OBJ_ELT2(stype, e1, e2)\
930   };\
931   gs__st_basic_super(scope_st, stname, stype, sname, penum, preloc, &supstname, offset_of(stype, member))
932 #define gs_public_st_ptrs_add2(stname, stype, sname, penum, preloc, supstname, member, e1, e2)\
933   gs__st_ptrs_add2(public_st, stname, stype, sname, penum, preloc, supstname, member, e1, e2)
934 #define gs_private_st_ptrs_add2(stname, stype, sname, penum, preloc, supstname, member, e1, e2)\
935   gs__st_ptrs_add2(private_st, stname, stype, sname, penum, preloc, supstname, member, e1, e2)
936 
937 #endif /* gsstruct_INCLUDED */
938