2 |
- |
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 */
|