xref: /plan9/sys/src/cmd/gs/src/iref.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1989, 2000 Aladdin Enterprises.  All rights reserved.
2 
3   This software is provided AS-IS with no warranty, either express or
4   implied.
5 
6   This software is distributed under license and may not be copied,
7   modified or distributed except as expressly authorized under the terms
8   of the license contained in the file LICENSE in this distribution.
9 
10   For more information about licensing, please refer to
11   http://www.ghostscript.com/licensing/. For information on
12   commercial licensing, go to http://www.artifex.com/licensing/ or
13   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15 */
16 
17 /* $Id: iref.h,v 1.9 2002/06/16 04:47:10 lpd Exp $ */
18 /* Object structure and type definitions for Ghostscript */
19 
20 #ifndef iref_INCLUDED
21 #  define iref_INCLUDED
22 
23 /*
24  * Note: this file defines a large number of macros.  Many of these are
25  * only used for internal purposes within this file, to help in the
26  * definition of other macros or data structures, and should never be
27  * referenced outside this file.  It is intended that all such internal
28  * macros have names beginning with an underscore (_).
29  */
30 
31 /* The typedef for object references */
32 #ifndef ref_DEFINED
33 typedef struct ref_s ref;
34 #  define ref_DEFINED
35 #endif
36 
37 /*
38  * Define the type for packed object references.  This is opaque here:
39  * the details are in ipacked.h.
40  */
41 typedef ushort ref_packed;
42 
43 #define log2_sizeof_ref_packed arch_log2_sizeof_short
44 #define sizeof_ref_packed (1 << log2_sizeof_ref_packed)
45 
46 /*
47  * Define the object types.
48  * The types marked with @ are composite and hence use the a_space field;
49  * objects of all other types must have a_space cleared.
50  * The types marked with ! behave differently in the interpreter
51  * depending on whether they are executable or literal.
52  * The types marked with + use the read/write/execute
53  * attributes; the rest only use the executable attribute.
54  * The types marked with # use the size field.
55  *
56  * Note that for the object types that support getinterval (array and
57  * string types), there is no way to tell whether a given reference
58  * designates an original object or a sub-interval.  This is a deliberate
59  * design decision.
60  */
61 typedef enum {
62 
63 /*
64  * Type 0 must be left unassigned, so that the type (and type_attrs)
65  * of a valid ref will never be zero.  This speeds up simultaneous
66  * type/space checking in def (see dstack.h for details) and a similar
67  * check in ref_save (see store.h for details).  We may as well use
68  * type 0 for t__invalid, which will never appear in a real ref.
69  *
70  * The "invalid" type is only used in a few special places: the guard
71  * entries at the bottom of the o-stack that detect stack underflow, and
72  * (perhaps eventually) the ref that the cached value pointer in names
73  * points to if the binding isn't known.  It never appears on a stack or in
74  * a program-visible data structure.
75  */
76 
77     t__invalid,			/*      (no value) */
78     t_boolean,			/*      value.boolval */
79     t_dictionary,		/* @ +  value.pdict */
80     t_file,			/* @!+# value.pfile, uses size for id */
81 
82 /*
83  * The 4 array types must be kept together, and must start at
84  * a multiple of 4, for the sake of r_is_array and r_is_proc (see below).
85  */
86 
87 #define _REF_T_ARRAY_SPAN 4
88     t_array,			/* @!+# value.refs */
89     /*
90      * The following are the two implementations of packed arrays.
91      * See ipacked.h for details.
92      */
93     t_mixedarray,		/* @!+# value.packed */
94     t_shortarray,		/* @!+# value.packed */
95     t_unused_array_,		/*      (an unused array type) */
96 
97 /*
98  * t_[a]struct is an "umbrella" for other types that are represented by
99  * allocated objects (structures).  Objects of these types are composite
100  * and hence use the a_local attribute.  The type name is taken from
101  * the allocator template for the structure.  t_astruct objects use the
102  * access attributes; t_struct objects do not.  Neither t_struct nor
103  * t_astruct objects use the size.
104  *
105  * t_struct is currently used for the following PostScript types:
106  *      condition, lock.
107  * We could use it for fontIDs, except that they may have subclasses.
108  * Eventually it will also be used for the new 'device' type.
109  * t_astruct is currently used for the following PostScript types:
110  *      gstate.
111  *
112  * The 2 structure types must be kept together, and must start at
113  * a multiple of 2, for the sake of r_has_stype (see below).
114  */
115 
116 #define _REF_T_STRUCT_SPAN 2
117     t_struct,			/* @    value.pstruct */
118     t_astruct,			/* @ +  value.pstruct */
119 
120 /*
121  * We now continue with individual types.
122  */
123     t_fontID,			/* @    value.pstruct */
124     t_integer,			/*      value.intval */
125     t_mark,			/*        (no value) */
126 /*
127  * Name objects use the a_space field because they really are composite
128  * objects internally.
129  */
130     t_name,			/* @! # value.pname, uses size for index */
131     t_null,			/*  ! # (value.opproc, uses size for mark */
132 				/*        type, on e-stack only) */
133 /*
134  * Operator objects use the a_space field because they may actually be
135  * disguised procedures.  (Real operators always have a_space = 0.)
136  */
137     t_operator,			/* @! # value.opproc, uses size for index */
138     t_real,			/*      value.realval */
139     t_save,			/*      value.saveid, see isave.h for why */
140 				/*        this isn't a t_struct */
141     t_string,			/* @!+# value.bytes */
142 /*
143  * The following are extensions to the PostScript type set.
144  * If you add new types, be sure to edit:
145  *      - REF_TYPE_*STRINGS* and REF_TYPE_PROPERTIES_DATA below;
146  *      - the table in gs_init.ps (==only operator);
147  *      - the printing routine in idebug.c;
148  *      - the dispatches in igc.c, igcref.c, and interp.c;
149  *      - obj_cvs, obj_cvp, and obj_eq in iutil.c;
150  *      - restore_check_stack in zvmem.c.
151  */
152     t_device,			/* @ +   value.pdevice */
153     t_oparray,			/* @! #  value.const_refs, uses size */
154 				/*         for index */
155     t_next_index		/*** first available index ***/
156 } ref_type;
157 
158 /*
159  * The interpreter uses types starting at t_next_index for representing
160  * a few high-frequency operators.
161  * Since there are no operations specifically on operators,
162  * there is no need for any operators to check specifically for these
163  * types.  The r_btype macro takes care of the conversion when required.
164  */
165 /*extern const int tx_next_index; *//* in interp.c */
166 /*
167  * Define a table giving properties of types, similar to the table used
168  * by the isxxx functions (macros) in <ctype.h>.
169  */
170 #define _REF_TYPE_USES_ACCESS 1	/* type uses w/r/x attributes ("+" above) */
171 #define _REF_TYPE_USES_SIZE 2	/* type uses size attribute ("#" above) */
172 #define _REF_TYPE_IS_NULL 4	/* type is t_null */
173 #define _REF_TYPE_IS_DICTIONARY 8 /* type is t_dictionary */
174 extern const byte ref_type_properties[1 << 6];	/* r_type_bits */
175 
176 #define REF_TYPE_PROPERTIES_DATA\
177   0,				/* t__invalid */\
178   0,				/* t_boolean */\
179   _REF_TYPE_USES_ACCESS | _REF_TYPE_IS_DICTIONARY, /* t_dictionary */\
180   _REF_TYPE_USES_ACCESS | _REF_TYPE_USES_SIZE, /* t_file */\
181   _REF_TYPE_USES_ACCESS | _REF_TYPE_USES_SIZE, /* t_array */\
182   _REF_TYPE_USES_ACCESS | _REF_TYPE_USES_SIZE, /* t_mixedarray */\
183   _REF_TYPE_USES_ACCESS | _REF_TYPE_USES_SIZE, /* t_shortarray */\
184   _REF_TYPE_USES_ACCESS | _REF_TYPE_USES_SIZE, /* (unused array type) */\
185   0,				/* t_struct */\
186   _REF_TYPE_USES_ACCESS,		/* t_astruct */\
187   0,				/* t_fontID */\
188   0,				/* t_integer */\
189   0,				/* t_mark */\
190   _REF_TYPE_USES_SIZE,		/* t_name */\
191   _REF_TYPE_IS_NULL,		/* t_null, uses size only on e-stack */\
192   _REF_TYPE_USES_SIZE,		/* t_operator */\
193   0,				/* t_real */\
194   0,				/* t_save */\
195   _REF_TYPE_USES_ACCESS | _REF_TYPE_USES_SIZE, /* t_string */\
196   _REF_TYPE_USES_ACCESS,		/* t_device */\
197   _REF_TYPE_USES_SIZE,		/* t_oparray */\
198     /*\
199      * The remaining types are the extended pseudo-types used by the\
200      * interpreter for operators.  We need to fill up the table.\
201      */\
202   _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*24*/\
203   _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*28*/\
204   _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*32*/\
205   _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*36*/\
206   _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*40*/\
207   _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*44*/\
208   _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*48*/\
209   _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*52*/\
210   _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*56*/\
211   _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE, /*60*/\
212   _REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE,_REF_TYPE_USES_SIZE	/*64 */
213 #define _REF_TYPE_HAS(rtype,props)\
214   ((ref_type_properties[rtype] & (props)) != 0)
215 #define ref_type_uses_access(rtype)\
216  _REF_TYPE_HAS(rtype, _REF_TYPE_USES_ACCESS)
217 #define ref_type_uses_size(rtype)\
218  _REF_TYPE_HAS(rtype, _REF_TYPE_USES_SIZE)
219 #define ref_type_uses_size_or_null(rtype)\
220  _REF_TYPE_HAS(rtype, _REF_TYPE_USES_SIZE | _REF_TYPE_IS_NULL)
221 /*
222  * Define the type names for debugging printout.
223  * All names must be the same length, so that columns will line up.
224  */
225 #define REF_TYPE_DEBUG_PRINT_STRINGS\
226   "INVL","bool","dict","file",\
227   "arry","mpry","spry","u?ry",\
228   "STRC","ASTR",\
229   "font","int ","mark","name","null",\
230   "oper","real","save","str ",\
231   "devc","opry"
232 /*
233  * Define the type names for the type operator.
234  */
235 #define REF_TYPE_NAME_STRINGS\
236   0,"booleantype","dicttype","filetype",\
237   "arraytype","packedarraytype","packedarraytype","arraytype",\
238   0,0,\
239   "fonttype","integertype","marktype","nametype","nulltype",\
240   "operatortype","realtype","savetype","stringtype",\
241   "devicetype","operatortype"
242 /*
243  * Define the type names for obj_cvp (the == operator).  We only need these
244  * for types that obj_cvp and obj_cvs don't handle specially.
245  */
246 #define REF_TYPE_PRINT_STRINGS\
247   0,0,"-dict-","-file-",\
248   "-array-","-packedarray-","-packedarray-","-array-",\
249   0,0,\
250   "-fontID-",0,"-mark-",0,0,\
251   0,0,"-save-","-string-",\
252   "-device-",0
253 
254 /*
255  * The following factors affect the encoding of attributes:
256  *
257  *      - The packed array format requires the high-order bits of the
258  *        type/attributes field to be 0.  (see packed.h)
259  *
260  *      - The interpreter wants the type, executable bit, and execute
261  *        permission to be adjacent, and in that order from high to low.
262  *
263  *      - Type testing is most efficient if the type is in a byte by itself.
264  *
265  * The layout given below results in the most efficient code overall.
266  */
267 
268 /*
269  * A few of the fields of a ref are associated with the *location*;
270  * most are associated with the ref that is *stored* in that location.
271  * When a ref is copied from one location to another, the former are
272  * preserved in the destination, the latter are copied.
273  */
274 /*
275  * The following are the attributes associated with the location:
276  */
277 #define l_mark 1		/* mark for garbage collector */
278 #define l_new 2			/* stored into since last save */
279 /*
280  * The following are attributes associated with the ref itself (the
281  * contents of the location).  These are visible to PostScript code.
282  */
283 /*
284  * Reserve bits for VM space information (defined in ivmspace.h).  Note that
285  * These bits refer to the VM space of the pointer in the ref, if any, not
286  * the location in which the ref itself is stored.  For scalars, these bits
287  * are always zero.
288  */
289 #define r_space_bits 2
290 #define r_space_shift 2
291 /*
292  * Define the protection attributes.  Only 4 combinations are legal:
293  * 0, execute, execute + read, execute + read + write.  Note that some
294  * refs (such as scalars) do not use these: in such refs, they are
295  * always zero.
296  */
297 #define a_write 0x10
298 #define a_read 0x20
299 #define a_execute 0x40
300 #define a_readonly (a_read + a_execute)
301 #define a_all (a_write + a_read+a_execute)
302 /*
303  * Define the executable attribute.  All refs use this.
304  */
305 #define a_executable 0x80
306 /*
307  * Define the bits used for the ref type.  See ipacked.h for more
308  * information about the possible values of the type byte.
309  */
310 #define r_type_shift 8
311 #define r_type_bits 6
312 
313 /*
314  * Define the attribute names for debugging printout.
315  * Each entry has the form <mask, value, character>.
316  */
317 typedef struct ref_attr_print_mask_s {
318     ushort mask;
319     ushort value;
320     char print;
321 } ref_attr_print_mask_t;
322 
323 #define _REF_ATTR_PRINT_FLAG(m,c)\
324   {m,m,c},{m,0,'-'}
325 #define _REF_ATTR_PRINT_SPACE(v,c)\
326   {((1<<r_space_bits)-1)<<r_space_shift,v,c}
327 #define REF_ATTR_PRINT_MASKS\
328   _REF_ATTR_PRINT_FLAG(l_mark,'m'),\
329   _REF_ATTR_PRINT_FLAG(l_new,'n'),\
330   _REF_ATTR_PRINT_SPACE(avm_foreign,'F'),\
331   _REF_ATTR_PRINT_SPACE(avm_system,'S'),\
332   _REF_ATTR_PRINT_SPACE(avm_global,'G'),\
333   _REF_ATTR_PRINT_SPACE(avm_local,'L'),\
334   _REF_ATTR_PRINT_FLAG(a_write,'w'),\
335   _REF_ATTR_PRINT_FLAG(a_read,'r'),\
336   _REF_ATTR_PRINT_FLAG(a_execute,'x'),\
337   _REF_ATTR_PRINT_FLAG(a_executable,'e'),\
338   _REF_ATTR_PRINT_FLAG(0x4000,'?'),\
339   _REF_ATTR_PRINT_FLAG(0x8000,'?')
340 
341 /* Abstract types */
342 typedef struct dict_s dict;
343 typedef struct name_s name;
344 
345 #ifndef stream_DEFINED
346 #  define stream_DEFINED
347 typedef struct stream_s stream;
348 #endif
349 #ifndef gx_device_DEFINED
350 #  define gx_device_DEFINED
351 typedef struct gx_device_s gx_device;
352 #endif
353 #ifndef obj_header_DEFINED
354 #  define obj_header_DEFINED
355 typedef struct obj_header_s obj_header_t;
356 #endif
357 
358 /*
359  * Define the argument type for operator procedures.  Note that the
360  * argument name is not arbitrary: it is used in access macros, so all
361  * operator procedures must use it.
362  */
363 #ifndef i_ctx_t_DEFINED
364 #  define i_ctx_t_DEFINED
365 typedef struct gs_context_state_s i_ctx_t;
366 #endif
367 typedef int (*op_proc_t)(i_ctx_t *i_ctx_p);
368 /* real_opproc is a holdover.... */
369 #define real_opproc(pref) ((pref)->value.opproc)
370 
371 /* Object reference */
372 /*
373  * Note that because of the way packed arrays are represented,
374  * the type_attrs member must be the first one in the ref structure.
375  */
376 struct tas_s {
377 /* type_attrs is a single element for fast dispatching in the interpreter */
378     ushort type_attrs;
379     ushort rsize;
380 };
381 struct ref_s {
382 
383     struct tas_s tas;
384 
385     union v {			/* name the union to keep gdb happy */
386 	long intval;
387 	ushort boolval;
388 	float realval;
389 	ulong saveid;
390 	byte *bytes;
391 	const byte *const_bytes;
392 	ref *refs;
393 	const ref *const_refs;
394 	name *pname;
395 	const name *const_pname;
396 	dict *pdict;
397 	const dict *const_pdict;
398 	/*
399 	 * packed is the normal variant for referring to packed arrays,
400 	 * but we need a writable variant for memory management and for
401 	 * storing into packed dictionary key arrays.
402 	 */
403 	const ref_packed *packed;
404 	ref_packed *writable_packed;
405 	op_proc_t opproc;
406 	struct stream_s *pfile;
407 	struct gx_device_s *pdevice;
408 	obj_header_t *pstruct;
409     } value;
410 };
411 
412 /* ---------------- Private ref macros ---------------- */
413 
414 /*
415  * Test whether a ref has a type within a given span, and also has all of a
416  * given set of attributes.
417  */
418 #define _REF_HAS_MASKED_TYPE_ATTRS(rp,typ,tspan,mask)\
419  (((rp)->tas.type_attrs &\
420    ((((1 << r_type_bits) - (tspan)) << r_type_shift) + (mask))) ==\
421   (((typ) << r_type_shift) + (mask)))
422 
423 /* ---------------- Public ref macros ---------------- */
424 
425 /*
426  * All of these macros take an argument "rp" which is a pointer to a ref.
427  * Unless otherwise specified, they only apply to full-size (not packed)
428  * refs.
429  */
430 
431 /*
432  * Read, set, increment, and decrement the size field of a ref.
433  */
434 #define r_size(rp) ((rp)->tas.rsize)
435 #define r_inc_size(rp,inc) ((rp)->tas.rsize += (inc))
436 #define r_dec_size(rp,dec) ((rp)->tas.rsize -= (dec))
437 #define r_set_size(rp,siz) ((rp)->tas.rsize = (siz))
438 
439 /*
440  * Get the type of a ref; test whether a ref has a given type.  The
441  * difference between r_type and r_btype is that for refs with types greater
442  * than or equal to t_next_index, r_type returns that type, but r_btype
443  * returns t_operator (since those types just encode specific operators for
444  * faster dispatch in the interpreter -- see interp.h for more information).
445  */
446 #if r_type_shift == 8
447 #  if arch_is_big_endian
448 #    define r_type(rp) (((const byte *)&((rp)->tas.type_attrs))[sizeof(ushort)-2])
449 #  else
450 #    define r_type(rp) (((const byte *)&((rp)->tas.type_attrs))[1])
451 #  endif
452 #  define r_has_type(rp,typ) (r_type(rp) == (typ))
453 #else
454 #  define r_type(rp) ((rp)->tas.type_attrs >> r_type_shift)
455 #  define r_has_type(rp,typ) r_has_type_attrs(rp,typ,0)		/* see below */
456 #endif
457 #define r_btype(rp)\
458  ((rp)->tas.type_attrs >= (t_next_index << r_type_shift) ?\
459   t_operator : r_type(rp))
460 
461 /*
462  * Test whether a ref is an array, or a procedure, or a(n) [a]struct.
463  */
464 #define r_is_array(rp)\
465   _REF_HAS_MASKED_TYPE_ATTRS(rp,t_array,_REF_T_ARRAY_SPAN,0)
466 #define r_is_proc(rp)\
467   _REF_HAS_MASKED_TYPE_ATTRS(rp,t_array,_REF_T_ARRAY_SPAN,a_execute+a_executable)
468 #define r_is_struct(rp)\
469   _REF_HAS_MASKED_TYPE_ATTRS(rp,t_struct,_REF_T_STRUCT_SPAN,0)
470 
471 /*
472  * Test whether a ref is a struct or astruct with a specific structure type
473  * (GC descriptor).
474  */
475 #define r_has_stype(rp,mem,styp)\
476   (r_is_struct(rp) && gs_object_type(mem, (rp)->value.pstruct) == &styp)
477 
478 /*
479  * Set the type of a ref.  This is only used in a few very special places.
480  * Normally the type of a ref is set when the ref is created (by one of
481  * the make_xxx macros in store.h) and never changed.
482  */
483 #define r_set_type(rp,typ) ((rp)->tas.type_attrs = (typ) << r_type_shift)
484 
485 /*
486  * Get, test, or set the type and attributes of a ref together as a single
487  * value.  This too is only used in a few special places.
488  */
489 #define r_type_attrs(rp) ((rp)->tas.type_attrs)		/* reading only */
490 #define r_has_type_attrs(rp,typ,mask)\
491   _REF_HAS_MASKED_TYPE_ATTRS(rp,typ,1,mask)
492 #define r_set_type_attrs(rp,typ,mask)\
493   ((rp)->tas.type_attrs = ((typ) << r_type_shift) + (mask))
494 
495 /*
496  * Get the combined type, a_executable, and a_execute bits of a ref,
497  * for fast dispatching in the interpreter.
498  */
499 /*
500  * The r_type_xe macro is used in (and only in) the main interpreter loop,
501  * where its rp operand may be a ref_packed, not necessarily aligned as
502  * strictly as a full-size ref.  The DEC C compiler, and possibly others,
503  * may compile code assuming that rp is ref-aligned.  Therefore, we
504  * explicitly cast the pointer to a less-strictly-aligned type.
505  * In order to convince the compiler, we have to do the cast before
506  * indexing into the structure.
507  */
508 #define _REF_TYPE_XE_SHIFT (r_type_shift - 2)
509 #define _REF_TAS_TYPE_XE(tas) ((tas) >> _REF_TYPE_XE_SHIFT)
510 #define r_type_xe(rp)\
511   _REF_TAS_TYPE_XE(((const ushort *)(rp))[offset_of(ref, tas.type_attrs) / sizeof(ushort)])
512 #define type_xe_value(typ,xe) _REF_TAS_TYPE_XE(((typ) << r_type_shift) + (xe))
513 
514 /*
515  * Test whether a ref has a given attribute, or all the given attributes.
516  */
517 #define r_has_attr(rp,mask1)		/* optimize 1-bit case */\
518    (r_type_attrs(rp) & (mask1))
519 #define r_has_attrs(rp,mask) !(~r_type_attrs(rp) & (mask))
520 
521 /*
522  * Test whether those attributes of a ref selected by a mask have a
523  * given value.
524  */
525 #define r_has_masked_attrs(rp,attrs,mask)\
526   ((r_type_attrs(rp) & (mask)) == (attrs))
527 
528 /*
529  * Set, clear, store, or copy the attributes of a ref.  These are rarely
530  * needed.  Note that, unfortunately, the attrs and mask parameters of
531  * r_store_attrs are reversed from r_has_masked_attrs.
532  */
533 #define r_set_attrs(rp,mask) ((rp)->tas.type_attrs |= (mask))
534 #define r_clear_attrs(rp,mask) ((rp)->tas.type_attrs &= ~(mask))
535 #define r_store_attrs(rp,mask,attrs)\
536   ((rp)->tas.type_attrs = ((rp)->tas.type_attrs & ~(mask)) | (attrs))
537 #define r_copy_attrs(rp,mask,sp)\
538   r_store_attrs(rp,mask,(sp)->tas.type_attrs & (mask))
539 
540 /*
541  * Get or set the pointer field of a struct or astruct ref.  The typ
542  * argument of r_ptr is the (C) type of the structure.
543  */
544 #define r_ptr(rp,typ) ((typ *)((rp)->value.pstruct))
545 #define r_set_ptr(rp,ptr) ((rp)->value.pstruct = (obj_header_t *)(ptr))
546 
547 /* ---------------- End of ref macros ---------------- */
548 
549 /* Define data for initializing an empty array or string. */
550 #define empty_ref_data(type, attrs)\
551   { /*tas*/ { /*type_attrs*/ ((type) << r_type_shift) | (attrs),\
552 	      /*rsize*/ 0 } }
553 
554 /* Define the size of a ref. */
555 #define arch_sizeof_ref sizeof(ref)
556 /* Define the required alignment for refs. */
557 /* We assume all alignment values are powers of 2. */
558 #define arch_align_ref_mod\
559  (((arch_align_long_mod - 1) | (arch_align_float_mod - 1) |\
560    (arch_align_ptr_mod - 1)) + 1)
561 
562 /* Define the maximum size of an array or a string. */
563 /* The maximum array size is determined by the fact that */
564 /* the allocator cannot allocate a block larger than max_uint. */
565 #define max_array_size (max_ushort & (max_uint / (uint)arch_sizeof_ref))
566 #define max_string_size max_ushort
567 
568 #endif /* iref_INCLUDED */
569