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