xref: /plan9-contrib/sys/src/cmd/gs/src/gsstruct.h (revision a84536681645e23c630ce4ef2e5c3b284d4c590b)
1 /* Copyright (C) 1993, 2000 Aladdin Enterprises.  All rights reserved.
2 
3   This file is part of AFPL Ghostscript.
4 
5   AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
6   distributor accepts any responsibility for the consequences of using it, or
7   for whether it serves any particular purpose or works at all, unless he or
8   she says so in writing.  Refer to the Aladdin Free Public License (the
9   "License") for full details.
10 
11   Every copy of AFPL Ghostscript must include a copy of the License, normally
12   in a plain ASCII text file named PUBLIC.  The License grants you the right
13   to copy, modify and redistribute AFPL Ghostscript, but only under certain
14   conditions described in the License.  Among other things, the License
15   requires that the copyright notice and this notice be preserved on all
16   copies.
17 */
18 
19 /*$Id: gsstruct.h,v 1.8 2001/04/04 18:45:08 alexcher 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 #define gs__st_simple_final(scope_st, stname, stype, sname, pfinal)\
519   scope_st stname = { sizeof(stype), sname, 0, 0, gs_no_struct_enum_ptrs, gs_no_struct_reloc_ptrs, pfinal }
520 #define gs_public_st_simple_final(stname, stype, sname, pfinal)\
521   gs__st_simple_final(public_st, stname, stype, sname, pfinal)
522 #define gs_private_st_simple_final(stname, stype, sname, pfinal)\
523   gs__st_simple_final(private_st, stname, stype, sname, pfinal)
524 
525 /* ---------------- Structures with explicit procedures. ---------------- */
526 
527 /*
528  * Boilerplate for clear_marks procedures.
529  */
530 #ifdef __PROTOTYPES__
531 #  define CLEAR_MARKS_PROC(proc)\
532     void proc(void *vptr, uint size, const gs_memory_struct_type_t *pstype)
533 #else
534 #  define CLEAR_MARKS_PROC(proc)\
535     void proc(vptr, size, pstype) void *vptr; uint size; const gs_memory_struct_type_t *pstype;
536 #endif
537 
538 	/* Complex structures with their own clear_marks, */
539 	/* enum, reloc, and finalize procedures. */
540 
541 #define gs__st_complex_only(scope_st, stname, stype, sname, pclear, penum, preloc, pfinal)\
542   scope_st stname = { sizeof(stype), sname, 0, pclear, penum, preloc, pfinal }
543 #define gs_public_st_complex_only(stname, stype, sname, pclear, penum, preloc, pfinal)\
544   gs__st_complex_only(public_st, stname, stype, sname, pclear, penum, preloc, pfinal)
545 #define gs_private_st_complex_only(stname, stype, sname, pclear, penum, preloc, pfinal)\
546   gs__st_complex_only(private_st, stname, stype, sname, pclear, penum, preloc, pfinal)
547 
548 #define gs__st_complex(scope_st, stname, stype, sname, pclear, penum, preloc, pfinal)\
549   private struct_proc_clear_marks(pclear);\
550   private struct_proc_enum_ptrs(penum);\
551   private struct_proc_reloc_ptrs(preloc);\
552   private struct_proc_finalize(pfinal);\
553   gs__st_complex_only(scope_st, stname, stype, sname, pclear, penum, preloc, pfinal)
554 #define gs_public_st_complex(stname, stype, sname, pclear, penum, preloc, pfinal)\
555   gs__st_complex(public_st, stname, stype, sname, pclear, penum, preloc, pfinal)
556 #define gs_private_st_complex(stname, stype, sname, pclear, penum, preloc, pfinal)\
557   gs__st_complex(private_st, stname, stype, sname, pclear, penum, preloc, pfinal)
558 
559 	/* Composite structures with their own enum and reloc procedures. */
560 
561 #define gs__st_composite(scope_st, stname, stype, sname, penum, preloc)\
562   private struct_proc_enum_ptrs(penum);\
563   private struct_proc_reloc_ptrs(preloc);\
564   gs__st_complex_only(scope_st, stname, stype, sname, 0, penum, preloc, 0)
565 #define gs_public_st_composite(stname, stype, sname, penum, preloc)\
566   gs__st_composite(public_st, stname, stype, sname, penum, preloc)
567 #define gs_private_st_composite(stname, stype, sname, penum, preloc)\
568   gs__st_composite(private_st, stname, stype, sname, penum, preloc)
569 
570 	/* Composite structures with inherited finalization. */
571 
572 #define gs__st_composite_use_final(scope_st, stname, stype, sname, penum, preloc, pfinal)\
573   private struct_proc_enum_ptrs(penum);\
574   private struct_proc_reloc_ptrs(preloc);\
575   gs__st_complex_only(scope_st, stname, stype, sname, 0, penum, preloc, pfinal)
576 #define gs_public_st_composite_use_final(stname, stype, sname, penum, preloc, pfinal)\
577   gs__st_composite_use_final(public_st, stname, stype, sname, penum, preloc, pfinal)
578 #define gs_private_st_composite_use_final(stname, stype, sname, penum, preloc, pfinal)\
579   gs__st_composite_use_final(private_st, stname, stype, sname, penum, preloc, pfinal)
580 
581 	/* Composite structures with finalization. */
582 
583 #define gs__st_composite_final(scope_st, stname, stype, sname, penum, preloc, pfinal)\
584   private struct_proc_finalize(pfinal);\
585   gs__st_composite_use_final(scope_st, stname, stype, sname, penum, preloc, pfinal)
586 #define gs_public_st_composite_final(stname, stype, sname, penum, preloc, pfinal)\
587   gs__st_composite_final(public_st, stname, stype, sname, penum, preloc, pfinal)
588 #define gs_private_st_composite_final(stname, stype, sname, penum, preloc, pfinal)\
589   gs__st_composite_final(private_st, stname, stype, sname, penum, preloc, pfinal)
590 
591 	/* Composite structures with enum and reloc procedures */
592 	/* already declared. */
593 
594 #define gs__st_composite_only(scope_st, stname, stype, sname, penum, preloc)\
595   gs__st_complex_only(scope_st, stname, stype, sname, 0, penum, preloc, 0)
596 #define gs_public_st_composite_only(stname, stype, sname, penum, preloc)\
597   gs__st_composite_only(public_st, stname, stype, sname, penum, preloc)
598 #define gs_private_st_composite_only(stname, stype, sname, penum, preloc)\
599   gs__st_composite_only(private_st, stname, stype, sname, penum, preloc)
600 
601 /* ---------------- Special kinds of structures ---------------- */
602 
603 	/* Element structures, for use in arrays of structures. */
604 	/* Note that these require that the underlying structure's */
605 	/* enum_ptrs procedure always return the same number of pointers. */
606 
607 #define gs__st_element(scope_st, stname, stype, sname, penum, preloc, basest)\
608   private ENUM_PTRS_BEGIN_PROC(penum) {\
609     uint count = size / (uint)sizeof(stype);\
610     if ( count == 0 ) return 0;\
611     return ENUM_USING(basest, (EV_CONST char *)vptr + (index % count) * sizeof(stype),\
612       sizeof(stype), index / count);\
613   } ENUM_PTRS_END_PROC\
614   private RELOC_PTRS_BEGIN(preloc) {\
615     uint count = size / (uint)sizeof(stype);\
616     for ( ; count; count--, vptr = (char *)vptr + sizeof(stype) )\
617       RELOC_USING(basest, vptr, sizeof(stype));\
618   } RELOC_PTRS_END\
619   gs__st_composite_only(scope_st, stname, stype, sname, penum, preloc)
620 #define gs_public_st_element(stname, stype, sname, penum, preloc, basest)\
621   gs__st_element(public_st, stname, stype, sname, penum, preloc, basest)
622 #define gs_private_st_element(stname, stype, sname, penum, preloc, basest)\
623   gs__st_element(private_st, stname, stype, sname, penum, preloc, basest)
624 
625 	/* A "structure" just consisting of a pointer. */
626 	/* Note that in this case only, stype is a pointer type. */
627 	/* Fortunately, C's bizarre 'const' syntax does what we want here. */
628 
629 #define gs__st_ptr(scope_st, stname, stype, sname, penum, preloc)\
630   private ENUM_PTRS_BEGIN(penum) return 0;\
631     case 0: return ENUM_OBJ(*(stype const *)vptr);\
632   ENUM_PTRS_END\
633   private RELOC_PTRS_BEGIN(preloc) ;\
634     RELOC_VAR(*(stype *)vptr);\
635   RELOC_PTRS_END\
636   gs__st_composite_only(scope_st, stname, stype, sname, penum, preloc)
637 #define gs_public_st_ptr(stname, stype, sname, penum, preloc)\
638   gs__st_ptr(public_st, stname, stype, sname, penum, preloc)
639 #define gs_private_st_ptr(stname, stype, sname, penum, preloc)\
640   gs__st_ptr(private_st, stname, stype, sname, penum, preloc)
641 
642 /* ---------- Ordinary structures with a fixed set of pointers ----------- */
643 /* Note that we "cannibalize" the penum and preloc names for elts and sdata. */
644 
645 	/* Structures with 1 pointer. */
646 
647 #define gs__st_ptrs1(scope_st, stname, stype, sname, penum, preloc, e1)\
648   BASIC_PTRS(penum) {\
649     GC_OBJ_ELT(stype, e1)\
650   };\
651   gs__st_basic(scope_st, stname, stype, sname, penum, preloc)
652 #define gs_public_st_ptrs1(stname, stype, sname, penum, preloc, e1)\
653   gs__st_ptrs1(public_st, stname, stype, sname, penum, preloc, e1)
654 #define gs_private_st_ptrs1(stname, stype, sname, penum, preloc, e1)\
655   gs__st_ptrs1(private_st, stname, stype, sname, penum, preloc, e1)
656 
657 	/* Structures with 1 string. */
658 
659 #define gs__st_strings1(scope_st, stname, stype, sname, penum, preloc, e1)\
660   BASIC_PTRS(penum) {\
661     GC_STRING_ELT(stype, e1)\
662   };\
663   gs__st_basic(scope_st, stname, stype, sname, penum, preloc)
664 #define gs_public_st_strings1(stname, stype, sname, penum, preloc, e1)\
665   gs__st_strings1(public_st, stname, stype, sname, penum, preloc, e1)
666 #define gs_private_st_strings1(stname, stype, sname, penum, preloc, e1)\
667   gs__st_strings1(private_st, stname, stype, sname, penum, preloc, e1)
668 
669 	/* Structures with 1 const string. */
670 
671 #define gs__st_const_strings1(scope_st, stname, stype, sname, penum, preloc, e1)\
672   BASIC_PTRS(penum) {\
673     GC_CONST_STRING_ELT(stype, e1)\
674   };\
675   gs__st_basic(scope_st, stname, stype, sname, penum, preloc)
676 #define gs_public_st_const_strings1(stname, stype, sname, penum, preloc, e1)\
677   gs__st_const_strings1(public_st, stname, stype, sname, penum, preloc, e1)
678 #define gs_private_st_const_strings1(stname, stype, sname, penum, preloc, e1)\
679   gs__st_const_strings1(private_st, stname, stype, sname, penum, preloc, e1)
680 
681 	/* Structures with 1 const string and 1 pointer. */
682 
683 #define gs__st_const_strings1_ptrs1(scope_st, stname, stype, sname, penum, preloc, e1, e2)\
684   BASIC_PTRS(penum) {\
685     GC_CONST_STRING_ELT(stype, e1), GC_OBJ_ELT(stype, e2)\
686   };\
687   gs__st_basic(scope_st, stname, stype, sname, penum, preloc)
688 #define gs_public_st_const_strings1_ptrs1(stname, stype, sname, penum, preloc, e1, e2)\
689   gs__st_const_strings1_ptrs1(public_st, stname, stype, sname, penum, preloc, e1, e2)
690 #define gs_private_st_const_strings1_ptrs1(stname, stype, sname, penum, preloc, e1, e2)\
691   gs__st_const_strings1_ptrs1(private_st, stname, stype, sname, penum, preloc, e1, e2)
692 
693 	/* Structures with 2 const strings. */
694 
695 #define gs__st_const_strings2(scope_st, stname, stype, sname, penum, preloc, e1, e2)\
696   BASIC_PTRS(penum) {\
697     GC_CONST_STRING_ELT(stype, e1), GC_CONST_STRING_ELT(stype, e2)\
698   };\
699   gs__st_basic(scope_st, stname, stype, sname, penum, preloc)
700 #define gs_public_st_const_strings2(stname, stype, sname, penum, preloc, e1, e2)\
701   gs__st_const_strings2(public_st, stname, stype, sname, penum, preloc, e1, e2)
702 #define gs_private_st_const_strings2(stname, stype, sname, penum, preloc, e1, e2)\
703   gs__st_const_strings2(private_st, stname, stype, sname, penum, preloc, e1, e2)
704 
705 	/* Structures with 2 pointers. */
706 
707 #define gs__st_ptrs2(scope_st, stname, stype, sname, penum, preloc, e1, e2)\
708   BASIC_PTRS(penum) {\
709     GC_OBJ_ELT2(stype, e1, e2)\
710   };\
711   gs__st_basic(scope_st, stname, stype, sname, penum, preloc)
712 #define gs_public_st_ptrs2(stname, stype, sname, penum, preloc, e1, e2)\
713   gs__st_ptrs2(public_st, stname, stype, sname, penum, preloc, e1, e2)
714 #define gs_private_st_ptrs2(stname, stype, sname, penum, preloc, e1, e2)\
715   gs__st_ptrs2(private_st, stname, stype, sname, penum, preloc, e1, e2)
716 
717 	/* Structures with 3 pointers. */
718 
719 #define gs__st_ptrs3(scope_st, stname, stype, sname, penum, preloc, e1, e2, e3)\
720   BASIC_PTRS(penum) {\
721     GC_OBJ_ELT3(stype, e1, e2, e3)\
722   };\
723   gs__st_basic(scope_st, stname, stype, sname, penum, preloc)
724 #define gs_public_st_ptrs3(stname, stype, sname, penum, preloc, e1, e2, e3)\
725   gs__st_ptrs3(public_st, stname, stype, sname, penum, preloc, e1, e2, e3)
726 #define gs_private_st_ptrs3(stname, stype, sname, penum, preloc, e1, e2, e3)\
727   gs__st_ptrs3(private_st, stname, stype, sname, penum, preloc, e1, e2, e3)
728 
729 	/* Structures with 4 pointers. */
730 
731 #define gs__st_ptrs4(scope_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4)\
732   BASIC_PTRS(penum) {\
733     GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT(stype, e4)\
734   };\
735   gs__st_basic(scope_st, stname, stype, sname, penum, preloc)
736 #define gs_public_st_ptrs4(stname, stype, sname, penum, preloc, e1, e2, e3, e4)\
737   gs__st_ptrs4(public_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4)
738 #define gs_private_st_ptrs4(stname, stype, sname, penum, preloc, e1, e2, e3, e4)\
739   gs__st_ptrs4(private_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4)
740 
741 	/* Structures with 5 pointers. */
742 
743 #define gs__st_ptrs5(scope_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5)\
744   BASIC_PTRS(penum) {\
745     GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT2(stype, e4, e5)\
746   };\
747   gs__st_basic(scope_st, stname, stype, sname, penum, preloc)
748 #define gs_public_st_ptrs5(stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5)\
749   gs__st_ptrs5(public_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5)
750 #define gs_private_st_ptrs5(stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5)\
751   gs__st_ptrs5(private_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5)
752 
753 	/* Structures with 6 pointers. */
754 
755 #define gs__st_ptrs6(scope_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6)\
756   BASIC_PTRS(penum) {\
757     GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT3(stype, e4, e5, e6)\
758   };\
759   gs__st_basic(scope_st, stname, stype, sname, penum, preloc)
760 #define gs_public_st_ptrs6(stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6)\
761   gs__st_ptrs6(public_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6)
762 #define gs_private_st_ptrs6(stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6)\
763   gs__st_ptrs6(private_st, stname, stype, sname, penum, preloc, e1, e2, e3, e4, e5, e6)
764 
765 /* ---------------- Suffix subclasses ---------------- */
766 
767 	/* Suffix subclasses with no additional pointers. */
768 
769 #define gs__st_suffix_add0(scope_st, stname, stype, sname, penum, preloc, supstname)\
770   gs__st_basic_with_super_final(scope_st, stname, stype, sname, 0, 0, preloc, &supstname, 0, 0)
771 #define gs_public_st_suffix_add0(stname, stype, sname, penum, preloc, supstname)\
772   gs__st_suffix_add0(public_st, stname, stype, sname, penum, preloc, supstname)
773 #define gs_private_st_suffix_add0(stname, stype, sname, penum, preloc, supstname)\
774   gs__st_suffix_add0(private_st, stname, stype, sname, penum, preloc, supstname)
775 
776 	/* Suffix subclasses with no additional pointers, */
777 	/* and with the superclass defined earlier in the same file */
778 	/* as a 'basic' type. */
779 	/* In this case, we don't even need new procedures. */
780 
781 #define gs__st_suffix_add0_local(scope_st, stname, stype, sname, supenum, supreloc, supstname)\
782   scope_st stname = {\
783     sizeof(stype), sname, 0, 0, basic_enum_ptrs, basic_reloc_ptrs,\
784     0, &supreloc\
785   }
786 #define gs_public_st_suffix_add0_local(stname, stype, sname, supenum, supreloc, supstname)\
787   gs__st_suffix_add0_local(public_st, stname, stype, sname, supenum, supreloc, supstname)
788 #define gs_private_st_suffix_add0_local(stname, stype, sname, supenum, supreloc, supstname)\
789   gs__st_suffix_add0_local(private_st, stname, stype, sname, supenum, supreloc, supstname)
790 
791 	/* Suffix subclasses with no additional pointers and finalization. */
792 	/* This is a hack -- subclasses should inherit finalization, */
793 	/* but that would require a superclass pointer in the descriptor, */
794 	/* which would perturb things too much right now. */
795 
796 #define gs__st_suffix_add0_final(scope_st, stname, stype, sname, penum, preloc, pfinal, supstname)\
797   private ENUM_PTRS_BEGIN_PROC(penum) {\
798     ENUM_PREFIX(supstname, 0);\
799   } ENUM_PTRS_END_PROC\
800   private RELOC_PTRS_BEGIN(preloc) {\
801     RELOC_PREFIX(supstname);\
802   } RELOC_PTRS_END\
803   gs__st_complex_only(scope_st, stname, stype, sname, 0, penum, preloc, pfinal)
804 #define gs_public_st_suffix_add0_final(stname, stype, sname, penum, preloc, pfinal, supstname)\
805   gs__st_suffix_add0_final(public_st, stname, stype, sname, penum, preloc, pfinal, supstname)
806 #define gs_private_st_suffix_add0_final(stname, stype, sname, penum, preloc, pfinal, supstname)\
807   gs__st_suffix_add0_final(private_st, stname, stype, sname, penum, preloc, pfinal, supstname)
808 
809 	/* Suffix subclasses with 1 additional pointer. */
810 
811 #define gs__st_suffix_add1(scope_st, stname, stype, sname, penum, preloc, supstname, e1)\
812   BASIC_PTRS(penum) {\
813     GC_OBJ_ELT(stype, e1)\
814   };\
815   gs__st_basic_super(scope_st, stname, stype, sname, penum, preloc, &supstname, 0)
816 #define gs_public_st_suffix_add1(stname, stype, sname, penum, preloc, supstname, e1)\
817   gs__st_suffix_add1(public_st, stname, stype, sname, penum, preloc, supstname, e1)
818 #define gs_private_st_suffix_add1(stname, stype, sname, penum, preloc, supstname, e1)\
819   gs__st_suffix_add1(private_st, stname, stype, sname, penum, preloc, supstname, e1)
820 
821 	/* Suffix subclasses with 1 additional pointer and finalization. */
822 	/* See above regarding finalization and subclasses. */
823 
824 #define gs__st_suffix_add1_final(scope_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1)\
825   BASIC_PTRS(penum) {\
826     GC_OBJ_ELT(stype, e1)\
827   };\
828   gs__st_basic_super_final(scope_st, stname, stype, sname, penum, preloc, &supstname, 0, pfinal)
829 #define gs_public_st_suffix_add1_final(stname, stype, sname, penum, preloc, pfinal, supstname, e1)\
830   gs__st_suffix_add1_final(public_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1)
831 #define gs_private_st_suffix_add1_final(stname, stype, sname, penum, preloc, pfinal, supstname, e1)\
832   gs__st_suffix_add1_final(private_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1)
833 
834 	/* Suffix subclasses with 1 additional string. */
835 
836 #define gs__st_suffix_add_strings1(scope_st, stname, stype, sname, penum, preloc, supstname, e1)\
837   BASIC_PTRS(penum) {\
838     GC_STRING_ELT(stype, e1)\
839   };\
840   gs__st_basic_super(scope_st, stname, stype, sname, penum, preloc, &supstname, 0)
841 #define gs_public_st_suffix_add_strings1(stname, stype, sname, penum, preloc, supstname, e1)\
842   gs__st_suffix_add_strings1(public_st, stname, stype, sname, penum, preloc, supstname, e1)
843 #define gs_private_st_suffix_add_strings1(stname, stype, sname, penum, preloc, supstname, e1)\
844   gs__st_suffix_add_strings1(private_st, stname, stype, sname, penum, preloc, supstname, e1)
845 
846 	/* Suffix subclasses with 2 additional pointers. */
847 
848 #define gs__st_suffix_add2(scope_st, stname, stype, sname, penum, preloc, supstname, e1, e2)\
849   BASIC_PTRS(penum) {\
850     GC_OBJ_ELT2(stype, e1, e2)\
851   };\
852   gs__st_basic_super(scope_st, stname, stype, sname, penum, preloc, &supstname, 0)
853 #define gs_public_st_suffix_add2(stname, stype, sname, penum, preloc, supstname, e1, e2)\
854   gs__st_suffix_add2(public_st, stname, stype, sname, penum, preloc, supstname, e1, e2)
855 #define gs_private_st_suffix_add2(stname, stype, sname, penum, preloc, supstname, e1, e2)\
856   gs__st_suffix_add2(private_st, stname, stype, sname, penum, preloc, supstname, e1, e2)
857 
858 	/* Suffix subclasses with 2 additional pointers and finalization. */
859 	/* See above regarding finalization and subclasses. */
860 
861 #define gs__st_suffix_add2_final(scope_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2)\
862   BASIC_PTRS(penum) {\
863     GC_OBJ_ELT2(stype, e1, e2)\
864   };\
865   gs__st_basic_super_final(scope_st, stname, stype, sname, penum, preloc, &supstname, 0, pfinal)
866 #define gs_public_st_suffix_add2_final(stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2)\
867   gs__st_suffix_add2_final(public_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2)
868 #define gs_private_st_suffix_add2_final(stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2)\
869   gs__st_suffix_add2_final(private_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2)
870 
871 	/* Suffix subclasses with 3 additional pointers. */
872 
873 #define gs__st_suffix_add3(scope_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3)\
874   BASIC_PTRS(penum) {\
875     GC_OBJ_ELT3(stype, e1, e2, e3)\
876   };\
877   gs__st_basic_super(scope_st, stname, stype, sname, penum, preloc, &supstname, 0)
878 #define gs_public_st_suffix_add3(stname, stype, sname, penum, preloc, supstname, e1, e2, e3)\
879   gs__st_suffix_add3(public_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3)
880 #define gs_private_st_suffix_add3(stname, stype, sname, penum, preloc, supstname, e1, e2, e3)\
881   gs__st_suffix_add3(private_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3)
882 
883 	/* Suffix subclasses with 3 additional pointers and finalization. */
884 	/* See above regarding finalization and subclasses. */
885 
886 #define gs__st_suffix_add3_final(scope_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2, e3)\
887   BASIC_PTRS(penum) {\
888     GC_OBJ_ELT3(stype, e1, e2, e3)\
889   };\
890   gs__st_basic_super_final(scope_st, stname, stype, sname, penum, preloc, &supstname, 0, pfinal)
891 #define gs_public_st_suffix_add3_final(stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2, e3)\
892   gs__st_suffix_add3_final(public_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2, e3)
893 #define gs_private_st_suffix_add3_final(stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2, e3)\
894   gs__st_suffix_add3_final(private_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2, e3)
895 
896 	/* Suffix subclasses with 4 additional pointers. */
897 
898 #define gs__st_suffix_add4(scope_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4)\
899   BASIC_PTRS(penum) {\
900     GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT(stype, e4)\
901   };\
902   gs__st_basic_super(scope_st, stname, stype, sname, penum, preloc, &supstname, 0)
903 #define gs_public_st_suffix_add4(stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4)\
904   gs__st_suffix_add4(public_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4)
905 #define gs_private_st_suffix_add4(stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4)\
906   gs__st_suffix_add4(private_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4)
907 
908 	/* Suffix subclasses with 4 additional pointers and finalization. */
909 	/* See above regarding finalization and subclasses. */
910 
911 #define gs__st_suffix_add4_final(scope_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2, e3, e4)\
912   BASIC_PTRS(penum) {\
913     GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT(stype, e4)\
914   };\
915   gs__st_basic_super_final(scope_st, stname, stype, sname, penum, preloc, &supstname, 0, pfinal)
916 #define gs_public_st_suffix_add4_final(stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2, e3, e4)\
917   gs__st_suffix_add4_final(public_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2, e3, e4)
918 #define gs_private_st_suffix_add4_final(stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2, e3, e4)\
919   gs__st_suffix_add4_final(private_st, stname, stype, sname, penum, preloc, pfinal, supstname, e1, e2, e3, e4)
920 
921 	/* Suffix subclasses with 5 additional pointers. */
922 
923 #define gs__st_suffix_add5(scope_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5)\
924   BASIC_PTRS(penum) {\
925     GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT2(stype, e4, e5)\
926   };\
927   gs__st_basic_super(scope_st, stname, stype, sname, penum, preloc, &supstname, 0)
928 #define gs_public_st_suffix_add5(stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5)\
929   gs__st_suffix_add5(public_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5)
930 #define gs_private_st_suffix_add5(stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5)\
931   gs__st_suffix_add5(private_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5)
932 
933 	/* Suffix subclasses with 6 additional pointers. */
934 
935 #define gs__st_suffix_add6(scope_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6)\
936   BASIC_PTRS(penum) {\
937     GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT3(stype, e4, e5, e6)\
938   };\
939   gs__st_basic_super(scope_st, stname, stype, sname, penum, preloc, &supstname, 0)
940 #define gs_public_st_suffix_add6(stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6)\
941   gs__st_suffix_add6(public_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6)
942 #define gs_private_st_suffix_add6(stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6)\
943   gs__st_suffix_add6(private_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6)
944 
945 	/* Suffix subclasses with 7 additional pointers. */
946 
947 #define gs__st_suffix_add7(scope_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6, e7)\
948   BASIC_PTRS(penum) {\
949     GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT3(stype, e4, e5, e6),\
950     GC_OBJ_ELT(stype, e7)\
951   };\
952   gs__st_basic_super(scope_st, stname, stype, sname, penum, preloc, &supstname, 0)
953 #define gs_public_st_suffix_add7(stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6, e7)\
954   gs__st_suffix_add7(public_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6, e7)
955 #define gs_private_st_suffix_add7(stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6, e7)\
956   gs__st_suffix_add7(private_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6, e7)
957 
958 	/* Suffix subclasses with 8 additional pointers. */
959 
960 #define gs__st_suffix_add8(scope_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6, e7, e8)\
961   BASIC_PTRS(penum) {\
962     GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT3(stype, e4, e5, e6),\
963     GC_OBJ_ELT2(stype, e7, e8)\
964   };\
965   gs__st_basic_super(scope_st, stname, stype, sname, penum, preloc, &supstname, 0)
966 #define gs_public_st_suffix_add8(stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6, e7, e8)\
967   gs__st_suffix_add8(public_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6, e7, e8)
968 #define gs_private_st_suffix_add8(stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6, e7, e8)\
969   gs__st_suffix_add8(private_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6, e7, e8)
970 
971 	/* Suffix subclasses with 9 additional pointers. */
972 
973 #define gs__st_suffix_add9(scope_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6, e7, e8, e9)\
974   BASIC_PTRS(penum) {\
975     GC_OBJ_ELT3(stype, e1, e2, e3), GC_OBJ_ELT3(stype, e4, e5, e6),\
976     GC_OBJ_ELT3(stype, e7, e8, e9)\
977   };\
978   gs__st_basic_super(scope_st, stname, stype, sname, penum, preloc, &supstname, 0)
979 #define gs_public_st_suffix_add9(stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6, e7, e8, e9)\
980   gs__st_suffix_add9(public_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6, e7, e8, e9)
981 #define gs_private_st_suffix_add9(stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6, e7, e8, e9)\
982   gs__st_suffix_add9(private_st, stname, stype, sname, penum, preloc, supstname, e1, e2, e3, e4, e5, e6, e7, e8, e9)
983 
984 /* ---------------- General subclasses ---------------- */
985 
986 	/* General subclasses with no additional pointers. */
987 
988 #define gs__st_ptrs_add0(scope_st, stname, stype, sname, penum, preloc, supstname, member)\
989   gs__st_basic_with_super_final(scope_st, stname, stype, sname, 0, 0, preloc, &supstname, offset_of(stype, member), 0)
990 #define gs_public_st_ptrs_add0(stname, stype, sname, penum, preloc, supstname, member)\
991   gs__st_ptrs_add0(public_st, stname, stype, sname, penum, preloc, supstname, member)
992 #define gs_private_st_ptrs_add0(stname, stype, sname, penum, preloc, supstname, member)\
993   gs__st_ptrs_add0(private_st, stname, stype, sname, penum, preloc, supstname, member)
994 
995 	/* General subclasses with 1 additional pointer. */
996 
997 #define gs__st_ptrs_add1(scope_st, stname, stype, sname, penum, preloc, supstname, member, e1)\
998   BASIC_PTRS(penum) {\
999     GC_OBJ_ELT(stype, e1)\
1000   };\
1001   gs__st_basic_super(scope_st, stname, stype, sname, penum, preloc, &supstname, offset_of(stype, member))
1002 #define gs_public_st_ptrs_add1(stname, stype, sname, penum, preloc, supstname, member, e1)\
1003   gs__st_ptrs_add1(public_st, stname, stype, sname, penum, preloc, supstname, member, e1)
1004 #define gs_private_st_ptrs_add1(stname, stype, sname, penum, preloc, supstname, member, e1)\
1005   gs__st_ptrs_add1(private_st, stname, stype, sname, penum, preloc, supstname, member, e1)
1006 
1007 	/* General subclasses with 2 additional pointers. */
1008 
1009 #define gs__st_ptrs_add2(scope_st, stname, stype, sname, penum, preloc, supstname, member, e1, e2)\
1010   BASIC_PTRS(penum) {\
1011     GC_OBJ_ELT2(stype, e1, e2)\
1012   };\
1013   gs__st_basic_super(scope_st, stname, stype, sname, penum, preloc, &supstname, offset_of(stype, member))
1014 #define gs_public_st_ptrs_add2(stname, stype, sname, penum, preloc, supstname, member, e1, e2)\
1015   gs__st_ptrs_add2(public_st, stname, stype, sname, penum, preloc, supstname, member, e1, e2)
1016 #define gs_private_st_ptrs_add2(stname, stype, sname, penum, preloc, supstname, member, e1, e2)\
1017   gs__st_ptrs_add2(private_st, stname, stype, sname, penum, preloc, supstname, member, e1, e2)
1018 
1019 #endif /* gsstruct_INCLUDED */
1020