2 |
- |
1 |
/* Copyright (C) 1989, 1995, 1997, 1998, 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: inamedef.h,v 1.5 2002/06/16 04:47:10 lpd Exp $ */
|
|
|
18 |
/* Name table definition */
|
|
|
19 |
|
|
|
20 |
#ifndef inamedef_INCLUDED
|
|
|
21 |
# define inamedef_INCLUDED
|
|
|
22 |
|
|
|
23 |
#include "inameidx.h"
|
|
|
24 |
#include "inamestr.h"
|
|
|
25 |
#include "inames.h"
|
|
|
26 |
#include "gsstruct.h" /* for gc_state_t */
|
|
|
27 |
|
|
|
28 |
/*
|
|
|
29 |
* The name table machinery has two slightly different configurations:
|
|
|
30 |
* a faster one that limits the total number of names to 64K and allows
|
|
|
31 |
* names up to 16K in size, and a slightly slower one that limits
|
|
|
32 |
* the total to 4M and restricts names to 256 characters.
|
|
|
33 |
* The maximum number of names is 2^(16+EXTEND_NAMES)-1.
|
|
|
34 |
*/
|
|
|
35 |
#define max_name_extension_bits 6
|
|
|
36 |
#if EXTEND_NAMES > max_name_extension_bits
|
|
|
37 |
# undef EXTEND_NAMES
|
|
|
38 |
# define EXTEND_NAMES max_name_extension_bits
|
|
|
39 |
#endif
|
|
|
40 |
/*
|
|
|
41 |
* We capture the small algorithmic differences between these two
|
|
|
42 |
* configurations entirely in this header file;
|
|
|
43 |
* the implementation doesn't need any conditionals on EXTEND_NAMES.
|
|
|
44 |
*/
|
|
|
45 |
#define max_name_index (uint)((0x10000 << EXTEND_NAMES) - 1)
|
|
|
46 |
/* As explained below, we distinguish name indices from name counts. */
|
|
|
47 |
#define max_name_count max_name_index
|
|
|
48 |
|
|
|
49 |
/* ---------------- Structure definitions ---------------- */
|
|
|
50 |
|
|
|
51 |
/*
|
|
|
52 |
* Define the structure of a name. The pvalue member implements an
|
|
|
53 |
* important optimization to avoid lookup for operator and other global
|
|
|
54 |
* names.
|
|
|
55 |
*/
|
|
|
56 |
struct name_s {
|
|
|
57 |
/* pvalue specifies the definition status of the name: */
|
|
|
58 |
/* pvalue == pv_no_defn: no definitions */
|
|
|
59 |
#define pv_no_defn ((ref *)0)
|
|
|
60 |
/* pvalue == pv_other: other status */
|
|
|
61 |
#define pv_other ((ref *)1)
|
|
|
62 |
/* pvalue != pv_no_defn, pvalue != pv_other: pvalue is valid */
|
|
|
63 |
#define pv_valid(pvalue) ((unsigned long)(pvalue) > 1)
|
|
|
64 |
ref *pvalue; /* if only defined in systemdict or */
|
|
|
65 |
/* userdict, this points to the value */
|
|
|
66 |
};
|
|
|
67 |
|
|
|
68 |
/*typedef struct name_s name; *//* in iref.h */
|
|
|
69 |
|
|
|
70 |
/*
|
|
|
71 |
* Define the structure of a name table. Normally we would make this
|
|
|
72 |
* an opaque type, but we want to be able to in-line some of the
|
|
|
73 |
* access procedures.
|
|
|
74 |
*
|
|
|
75 |
* The name table is a two-level indexed table, consisting of
|
|
|
76 |
* sub-tables of size nt_sub_size each.
|
|
|
77 |
*
|
|
|
78 |
* First we define the name sub-table structure.
|
|
|
79 |
*/
|
|
|
80 |
#define nt_log2_sub_size NT_LOG2_SUB_SIZE /* in inameidx.h */
|
|
|
81 |
# define nt_sub_size (1 << nt_log2_sub_size)
|
|
|
82 |
# define nt_sub_index_mask (nt_sub_size - 1)
|
|
|
83 |
typedef struct name_sub_table_s {
|
|
|
84 |
name names[NT_SUB_SIZE]; /* must be first */
|
|
|
85 |
#ifdef EXTEND_NAMES
|
|
|
86 |
uint high_index; /* sub-table base index & (-1 << 16) */
|
|
|
87 |
#endif
|
|
|
88 |
} name_sub_table;
|
|
|
89 |
|
|
|
90 |
/*
|
|
|
91 |
* Now define the name table itself.
|
|
|
92 |
* This must be made visible so that the interpreter can use the
|
|
|
93 |
* inline macros defined below.
|
|
|
94 |
*/
|
|
|
95 |
struct name_table_s {
|
|
|
96 |
uint free; /* head of free list, which is sorted in */
|
|
|
97 |
/* increasing count (not index) order */
|
|
|
98 |
uint sub_next; /* index of next sub-table to allocate */
|
|
|
99 |
/* if not already allocated */
|
|
|
100 |
uint perm_count; /* # of permanent (read-only) strings */
|
|
|
101 |
uint sub_count; /* index of highest allocated sub-table +1 */
|
|
|
102 |
uint max_sub_count; /* max allowable value of sub_count */
|
|
|
103 |
uint name_string_attrs; /* imemory_space(memory) | a_readonly */
|
|
|
104 |
gs_memory_t *memory;
|
|
|
105 |
uint hash[NT_HASH_SIZE];
|
|
|
106 |
struct sub_ { /* both ptrs are 0 or both are non-0 */
|
|
|
107 |
name_sub_table *names;
|
|
|
108 |
name_string_sub_table_t *strings;
|
|
|
109 |
} sub[max_name_index / nt_sub_size + 1];
|
|
|
110 |
};
|
|
|
111 |
/*typedef struct name_table_s name_table; *//* in inames.h */
|
|
|
112 |
|
|
|
113 |
/* ---------------- Procedural interface ---------------- */
|
|
|
114 |
|
|
|
115 |
/*
|
|
|
116 |
* Convert between names, indices, and strings. Note that the inline
|
|
|
117 |
* versions, but not the procedure versions, take a name_table argument.
|
|
|
118 |
*/
|
|
|
119 |
/* index => string */
|
|
|
120 |
#define names_index_string_inline(nt, nidx)\
|
|
|
121 |
((nt)->sub[(nidx) >> nt_log2_sub_size].strings->strings +\
|
|
|
122 |
((nidx) & nt_sub_index_mask))
|
|
|
123 |
/* ref => string */
|
|
|
124 |
#define names_string_inline(nt, pnref)\
|
|
|
125 |
names_index_string_inline(nt, names_index_inline(nt, pnref))
|
|
|
126 |
/* ref => index */
|
|
|
127 |
#if EXTEND_NAMES
|
|
|
128 |
# define names_index_inline(nt_ignored, pnref)\
|
|
|
129 |
( ((const name_sub_table *)\
|
|
|
130 |
((pnref)->value.pname - (r_size(pnref) & nt_sub_index_mask)))->high_index + r_size(pnref) )
|
|
|
131 |
#else
|
|
|
132 |
# define names_index_inline(nt_ignored, pnref) r_size(pnref)
|
|
|
133 |
#endif
|
|
|
134 |
#define names_index(nt_ignored, pnref) names_index_inline(nt_ignored, pnref)
|
|
|
135 |
/* index => name */
|
|
|
136 |
#define names_index_ptr_inline(nt, nidx)\
|
|
|
137 |
((nt)->sub[(nidx) >> nt_log2_sub_size].names->names +\
|
|
|
138 |
((nidx) & nt_sub_index_mask))
|
|
|
139 |
/* index => ref */
|
|
|
140 |
#define names_index_ref_inline(nt, nidx, pnref)\
|
|
|
141 |
make_name(pnref, nidx, names_index_ptr_inline(nt, nidx));
|
|
|
142 |
/* Backward compatibility */
|
|
|
143 |
#define name_index_inline(pnref) names_index_inline(ignored, pnref)
|
|
|
144 |
#define name_index_ptr_inline(nt, pnref) names_index_ptr_inline(nt, pnref)
|
|
|
145 |
#define name_index_ref_inline(nt, nidx, pnref)\
|
|
|
146 |
names_index_ref_inline(nt, nidx, pnref)
|
|
|
147 |
/* name => ref */
|
|
|
148 |
/* We have to set the space to system so that the garbage collector */
|
|
|
149 |
/* won't think names are foreign and therefore untraceable. */
|
|
|
150 |
#define make_name(pnref, nidx, pnm)\
|
|
|
151 |
make_tasv(pnref, t_name, avm_system, (ushort)(nidx), pname, pnm)
|
|
|
152 |
|
|
|
153 |
/* ------ Garbage collection ------ */
|
|
|
154 |
|
|
|
155 |
/* Unmark all non-permanent names before a garbage collection. */
|
|
|
156 |
void names_unmark_all(name_table * nt);
|
|
|
157 |
|
|
|
158 |
/* Finish tracing the name table by putting free names on the free list. */
|
|
|
159 |
void names_trace_finish(name_table * nt, gc_state_t * gcst);
|
|
|
160 |
|
|
|
161 |
/* ------ Save/restore ------ */
|
|
|
162 |
|
|
|
163 |
/* Clean up the name table before a restore. */
|
|
|
164 |
#ifndef alloc_save_t_DEFINED /* also in isave.h */
|
|
|
165 |
typedef struct alloc_save_s alloc_save_t;
|
|
|
166 |
# define alloc_save_t_DEFINED
|
|
|
167 |
#endif
|
|
|
168 |
void names_restore(name_table * nt, alloc_save_t * save);
|
|
|
169 |
|
|
|
170 |
#endif /* inamedef_INCLUDED */
|