2 |
- |
1 |
/* Copyright (C) 1992, 1993, 1994, 1996, 1997 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: ivmspace.h,v 1.4 2002/02/21 22:24:53 giles Exp $ */
|
|
|
18 |
/* Local/global space management */
|
|
|
19 |
/* Requires iref.h */
|
|
|
20 |
|
|
|
21 |
#ifndef ivmspace_INCLUDED
|
|
|
22 |
# define ivmspace_INCLUDED
|
|
|
23 |
|
|
|
24 |
#include "gsgc.h"
|
|
|
25 |
|
|
|
26 |
/*
|
|
|
27 |
* r_space_bits and r_space_shift, which define the bits in a ref
|
|
|
28 |
* that carry VM space information, are defined in iref.h.
|
|
|
29 |
* r_space_bits must be at least 2.
|
|
|
30 |
*/
|
|
|
31 |
#define a_space (((1 << r_space_bits) - 1) << r_space_shift)
|
|
|
32 |
/*
|
|
|
33 |
* The i_vm_xxx values are defined in gsgc.h.
|
|
|
34 |
*/
|
|
|
35 |
typedef enum {
|
|
|
36 |
avm_foreign = (i_vm_foreign << r_space_shift),
|
|
|
37 |
avm_system = (i_vm_system << r_space_shift),
|
|
|
38 |
avm_global = (i_vm_global << r_space_shift),
|
|
|
39 |
avm_local = (i_vm_local << r_space_shift),
|
|
|
40 |
avm_max = avm_local
|
|
|
41 |
} avm_space;
|
|
|
42 |
|
|
|
43 |
#define r_space(rp) (avm_space)(r_type_attrs(rp) & a_space)
|
|
|
44 |
#define r_space_index(rp) ((int)r_space(rp) >> r_space_shift)
|
|
|
45 |
#define r_set_space(rp,space) r_store_attrs(rp, a_space, (uint)space)
|
|
|
46 |
|
|
|
47 |
/*
|
|
|
48 |
* According to the PostScript language specification, attempting to store
|
|
|
49 |
* a reference to a local object into a global object must produce an
|
|
|
50 |
* invalidaccess error. However, systemdict must be able to refer to
|
|
|
51 |
* a number of local dictionaries such as userdict and errordict.
|
|
|
52 |
* Therefore, we implement a special hack in 'def' that allows such stores
|
|
|
53 |
* if the dictionary being stored into is systemdict (which is normally
|
|
|
54 |
* only writable during initialization) or a dictionary that appears
|
|
|
55 |
* in systemdict (such as level2dict), and the current save level is zero
|
|
|
56 |
* (to guarantee that we can't get dangling pointers).
|
|
|
57 |
* We could allow this for any global dictionary, except that the garbage
|
|
|
58 |
* collector must treat any such dictionaries as roots when collecting
|
|
|
59 |
* local VM without collecting global VM.
|
|
|
60 |
* We make a similar exception for .makeglobaloperator; this requires
|
|
|
61 |
* treating the operator table as a GC root as well.
|
|
|
62 |
*
|
|
|
63 |
* We extend the local-into-global store check because we have four VM
|
|
|
64 |
* spaces (local, global, system, and foreign), and we allow PostScript
|
|
|
65 |
* programs to create objects in any of the first three. If we define
|
|
|
66 |
* the "generation" of an object as foreign = 0, system = 1, global = 2,
|
|
|
67 |
* and local = 3, then a store is legal iff the generation of the object
|
|
|
68 |
* into which a pointer is being stored is greater than or equal to
|
|
|
69 |
* the generation of the object into which the store is occurring.
|
|
|
70 |
*
|
|
|
71 |
* We must check for local-into-global stores in three categories of places:
|
|
|
72 |
*
|
|
|
73 |
* - The scanner, when it encounters a //name inside {}.
|
|
|
74 |
*
|
|
|
75 |
* - All operators that allocate ref-containing objects and also
|
|
|
76 |
* store into them:
|
|
|
77 |
* packedarray gstate makepattern?
|
|
|
78 |
* makefont scalefont definefont filter
|
|
|
79 |
*
|
|
|
80 |
* - All operators that store refs into existing objects
|
|
|
81 |
* ("operators" marked with * are actually PostScript procedures):
|
|
|
82 |
* put(array) putinterval(array) astore copy(to array)
|
|
|
83 |
* def store* put(dict) copy(dict)
|
|
|
84 |
* dictstack execstack .make(global)operator
|
|
|
85 |
* currentgstate defineusername
|
|
|
86 |
*/
|
|
|
87 |
|
|
|
88 |
/* Test whether an object is in local space, */
|
|
|
89 |
/* which implies that we need not check when storing into it. */
|
|
|
90 |
#define r_is_local(rp) (r_space(rp) == avm_local)
|
|
|
91 |
/* Test whether an object is foreign, i.e., outside known space. */
|
|
|
92 |
#define r_is_foreign(rp) (r_space(rp) == avm_foreign)
|
|
|
93 |
/* Check whether a store is allowed. */
|
|
|
94 |
#define store_check_space(destspace,rpnew)\
|
|
|
95 |
if ( r_space(rpnew) > (destspace) )\
|
|
|
96 |
return_error(e_invalidaccess)
|
|
|
97 |
#define store_check_dest(rpdest,rpnew)\
|
|
|
98 |
store_check_space(r_space(rpdest), rpnew)
|
|
|
99 |
/* BACKWARD COMPATIBILITY (not used by any Ghostscript code per se) */
|
|
|
100 |
#define check_store_space(rdest,rnewcont)\
|
|
|
101 |
store_check_dest(&(rdest),&(rnewcont))
|
|
|
102 |
|
|
|
103 |
#endif /* ivmspace_INCLUDED */
|