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