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