Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/* Copyright (C) 1989, 1995, 1999 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: store.h,v 1.4 2002/02/21 22:24:54 giles Exp $ */
18
/* Assignment-related macros */
19
 
20
#ifndef store_INCLUDED
21
#  define store_INCLUDED
22
 
23
#include "ialloc.h"		/* for imemory masks & checks */
24
#include "idosave.h"
25
 
26
/*
27
 * Macros for storing a ref.  We use macros for storing into objects,
28
 * since the storage manager needs to be able to track stores for
29
 * save/restore and also for global/local checking.
30
 * We also use macros for other ref assignments, because (as it happens)
31
 * Turbo C generates pretty awful code for doing this.
32
 *
33
 * There are three cases that we need to distinguish:
34
 *      - Storing to a stack (no special action);
35
 *      - Storing into a newly created object (set l_new);
36
 *      - Storing into a slot of an existing object (check l_new in
37
 *          old value, set in new value).
38
 * The macros are called
39
 *      <make/store><new_type><case>(place_to_store, new_value)
40
 * where <case> is nothing for storing to the stack, _new for storing into
41
 * a new object, and _old for storing into an existing object.
42
 * (The _old macros also take a client name for tracing and debugging.)
43
 * <new_type> and new_value are chosen from the following alternatives:
44
 *      ref_assign      POINTER TO arbitrary ref
45
 *      make_t          type (only for null and mark)
46
 *      make_tv         type, value field name, value
47
 *                        (only for scalars, which don't have attributes)
48
 *      make_tav        type, attributes, value field name, value
49
 *      make_tasv       type, attributes, size, value field name, value
50
 * There are also specialized make_ macros for specific types:
51
 *      make_array, make_int, make_real, make_bool, make_false, make_true,
52
 *      make_mark, make_null, make_oper, make_[const_]string, make_struct.
53
 * Not all of the specialized make_ macros have _new and _old variants.
54
 *
55
 * For _tav and _tasv, we must store the value first, because sometimes
56
 * it depends on the contents of the place being stored into.
57
 *
58
 * Note that for composite objects (dictionary, file, array, string, device,
59
 * struct), we must set a_foreign if the contents are allocated statically
60
 * (e.g., for constant C strings) or not by the Ghostscript allocator
61
 * (e.g., with malloc).
62
 */
63
 
64
/*
65
 * Define the most efficient ref assignment macro for the platform.
66
 */
67
/*
68
 * Assigning the components individually is fastest on Turbo C,
69
 * and on Watcom C when one or both of the addresses are
70
 * already known or in a register.
71
 */
72
#define ref_assign_inline(pto,pfrom)\
73
	((pto)->value = (pfrom)->value,\
74
	 (pto)->tas = (pfrom)->tas)
75
#ifdef __TURBOC__
76
	/*
77
	 * Move the data in two 32-bit chunks, because
78
	 * otherwise the compiler calls SCOPY@.
79
	 * The cast to void is to discourage the compiler from
80
	 * wanting to deliver the value of the expression.
81
	 */
82
#  define ref_assign(pto,pfrom)\
83
	discard(ref_assign_inline(pto, pfrom))
84
#else
85
	/*
86
	 * Trust the compiler and hope for the best.
87
	 * The MIPS compiler doesn't like the cast to void.
88
	 */
89
#  define ref_assign(pto,pfrom)\
90
	(*(pto) = *(pfrom))
91
#endif
92
 
93
#define ialloc_new_mask (idmemory->new_mask)
94
     /*
95
      * The mmem argument may be either a gs_dual_memory_t or a
96
      * gs_ref_memory_t, since it is only used for accessing the masks.
97
      */
98
#define ref_saving_in(mmem)\
99
  ((mmem)->new_mask != 0)
100
#define ref_must_save_in(mmem,pto)\
101
  ((r_type_attrs(pto) & (mmem)->test_mask) == 0)
102
#define ref_must_save(pto) ref_must_save_in(idmemory, pto)
103
#define ref_do_save_in(mem, pcont, pto, cname)\
104
  alloc_save_change_in(mem, pcont, (ref_packed *)(pto), cname)
105
#define ref_do_save(pcont, pto, cname)\
106
  alloc_save_change(idmemory, pcont, (ref_packed *)(pto), cname)
107
#define ref_save_in(mem, pcont, pto, cname)\
108
  discard((ref_must_save_in(mem, pto) ?\
109
	   ref_do_save_in(mem, pcont, pto, cname) : 0))
110
#define ref_save(pcont, pto, cname)\
111
  discard((ref_must_save(pto) ? ref_do_save(pcont, pto, cname) : 0))
112
#define ref_mark_new_in(mmem,pto)\
113
  ((pto)->tas.type_attrs |= (mmem)->new_mask)
114
#define ref_mark_new(pto) ref_mark_new_in(idmemory, pto)
115
#define ref_assign_new_in(mem,pto,pfrom)\
116
  discard((ref_assign(pto,pfrom), ref_mark_new_in(mem,pto)))
117
#define ref_assign_new(pto,pfrom)\
118
  discard((ref_assign(pto,pfrom), ref_mark_new(pto)))
119
#define ref_assign_new_inline(pto,pfrom)\
120
  discard((ref_assign_inline(pto,pfrom), ref_mark_new(pto)))
121
#define ref_assign_old_in(mem,pcont,pto,pfrom,cname)\
122
  (ref_save_in(mem,pcont,pto,cname), ref_assign_new_in(mem,pto,pfrom))
123
#define ref_assign_old(pcont,pto,pfrom,cname)\
124
  (ref_save(pcont,pto,cname), ref_assign_new(pto,pfrom))
125
#define ref_assign_old_inline(pcont,pto,pfrom,cname)\
126
  (ref_save(pcont,pto,cname), ref_assign_new_inline(pto,pfrom))
127
/* ref_mark_old is only needed in very unusual situations, namely, */
128
/* when we want to do a ref_save just before a save instead of */
129
/* when the actual assignment occurs. */
130
#define ref_mark_old(pto) ((pto)->tas.type_attrs &= ~ialloc_new_mask)
131
 
132
/* Define macros for conditionally clearing the parts of a ref */
133
/* that aren't being set to anything useful. */
134
 
135
#ifdef DEBUG
136
#  define and_fill_s(pref)\
137
    , (gs_debug['$'] ? r_set_size(pref, 0xfeed) : 0)
138
/*
139
 * The following nonsense avoids compiler warnings about signed/unsigned
140
 * integer constants.
141
 */
142
#define DEADBEEF ((int)(((uint)0xdead << 16) | 0xbeef))
143
#  define and_fill_sv(pref)\
144
    , (gs_debug['$'] ? (r_set_size(pref, 0xfeed),\
145
			(pref)->value.intval = DEADBEEF) : 0)
146
#else /* !DEBUG */
147
#  define and_fill_s(pref)	/* */
148
#  define and_fill_sv(pref)	/* */
149
#endif
150
 
151
/* make_t must set the attributes to 0 to clear a_local! */
152
#define make_ta(pref,newtype,newattrs)\
153
  (r_set_type_attrs(pref, newtype, newattrs) and_fill_sv(pref))
154
#define make_t(pref,newtype)\
155
  make_ta(pref, newtype, 0)
156
#define make_t_new_in(mem,pref,newtype)\
157
  make_ta(pref, newtype, imemory_new_mask(mem))
158
#define make_t_new(pref,newtype)\
159
  make_ta(pref, newtype, ialloc_new_mask)
160
#define make_t_old_in(mem,pcont,pref,newtype,cname)\
161
  (ref_save_in(mem,pcont,pref,cname), make_t_new_in(mem,pref,newtype))
162
#define make_t_old(pcont,pref,newtype,cname)\
163
  (ref_save(pcont,pref,cname), make_t_new(pref,newtype))
164
 
165
#define make_tav(pref,newtype,newattrs,valfield,newvalue)\
166
  ((pref)->value.valfield = (newvalue),\
167
   r_set_type_attrs(pref, newtype, newattrs)\
168
   and_fill_s(pref))
169
#define make_tav_new(pref,t,a,vf,v)\
170
  make_tav(pref,t,(a)|ialloc_new_mask,vf,v)
171
#define make_tav_old(pcont,pref,t,a,vf,v,cname)\
172
  (ref_save(pcont,pref,cname), make_tav_new(pref,t,a,vf,v))
173
 
174
#define make_tv(pref,newtype,valfield,newvalue)\
175
  make_tav(pref,newtype,0,valfield,newvalue)
176
#define make_tv_new(pref,t,vf,v)\
177
  make_tav_new(pref,t,0,vf,v)
178
#define make_tv_old(pcont,pref,t,vf,v,cname)\
179
  make_tav_old(pcont,pref,t,0,vf,v,cname)
180
 
181
#define make_tasv(pref,newtype,newattrs,newsize,valfield,newvalue)\
182
  ((pref)->value.valfield = (newvalue),\
183
   r_set_type_attrs(pref, newtype, newattrs),\
184
   r_set_size(pref, newsize))
185
#define make_tasv_new(pref,t,a,s,vf,v)\
186
  make_tasv(pref,t,(a)|ialloc_new_mask,s,vf,v)
187
#define make_tasv_old(pcont,pref,t,a,s,vf,v,cname)\
188
  (ref_save(pcont,pref,cname), make_tasv_new(pref,t,a,s,vf,v))
189
 
190
/* Type-specific constructor macros for scalar (non-composite) types */
191
 
192
#define make_bool(pref,bval)\
193
  make_tv(pref, t_boolean, boolval, bval)
194
#define make_false(pref)\
195
  make_bool(pref, 0)
196
#define make_true(pref)\
197
  make_bool(pref, 1)
198
 
199
#define make_int(pref,ival)\
200
  make_tv(pref, t_integer, intval, ival)
201
#define make_int_new(pref,ival)\
202
  make_tv_new(pref, t_integer, intval, ival)
203
 
204
#define make_mark(pref)\
205
  make_t(pref, t_mark)
206
 
207
#define make_null(pref)\
208
  make_t(pref, t_null)
209
#define make_null_new(pref)\
210
  make_t_new(pref, t_null)
211
#define make_null_old_in(mem,pcont,pref,cname)\
212
  make_t_old_in(mem, pcont, pref, t_null, cname)
213
#define make_null_old(pcont,pref,cname)\
214
  make_t_old(pcont, pref, t_null, cname)
215
 
216
#define make_oper(pref,opidx,proc)\
217
  make_tasv(pref, t_operator, a_executable, opidx, opproc, proc)
218
#define make_oper_new(pref,opidx,proc)\
219
  make_tasv_new(pref, t_operator, a_executable, opidx, opproc, proc)
220
 
221
#define make_real(pref,rval)\
222
  make_tv(pref, t_real, realval, rval)
223
#define make_real_new(pref,rval)\
224
  make_tv_new(pref, t_real, realval, rval)
225
 
226
/* Type-specific constructor macros for composite types */
227
 
228
/* For composite types, the a_space field is relevant; however, */
229
/* as noted in ivmspace.h, a value of 0 designates the most static space, */
230
/* so for making empty composites, a space value of 0 is appropriate. */
231
 
232
#define make_array(pref,attrs,size,elts)\
233
  make_tasv(pref, t_array, attrs, size, refs, elts)
234
#define make_array_new(pref,attrs,size,elts)\
235
  make_tasv_new(pref, t_array, attrs, size, refs, elts)
236
#define make_const_array(pref,attrs,size,elts)\
237
  make_tasv(pref, t_array, attrs, size, const_refs, elts)
238
#define make_empty_array(pref,attrs)\
239
  make_array(pref, attrs, 0, (ref *)NULL)
240
#define make_empty_const_array(pref,attrs)\
241
  make_const_array(pref, attrs, 0, (const ref *)NULL)
242
 
243
#define make_string(pref,attrs,size,chars)\
244
  make_tasv(pref, t_string, attrs, size, bytes, chars)
245
#define make_const_string(pref,attrs,size,chars)\
246
  make_tasv(pref, t_string, attrs, size, const_bytes, chars)
247
#define make_empty_string(pref,attrs)\
248
  make_string(pref, attrs, 0, (byte *)NULL)
249
#define make_empty_const_string(pref,attrs)\
250
  make_const_string(pref, attrs, 0, (const byte *)NULL)
251
 
252
#define make_struct(pref,attrs,ptr)\
253
  make_tav(pref, t_struct, attrs, pstruct, (obj_header_t *)(ptr))
254
#define make_struct_new(pref,attrs,ptr)\
255
  make_tav_new(pref, t_struct, attrs, pstruct, (obj_header_t *)(ptr))
256
 
257
#define make_astruct(pref,attrs,ptr)\
258
  make_tav(pref, t_astruct, attrs, pstruct, (obj_header_t *)(ptr))
259
#define make_astruct_new(pref,attrs,ptr)\
260
  make_tav_new(pref, t_astruct, attrs, pstruct, (obj_header_t *)(ptr))
261
 
262
#endif /* store_INCLUDED */