/* Copyright (C) 1989, 1995, 1997, 1998, 1999 artofcode LLC. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA, 02111-1307. */ /*$Id: inamedef.h,v 1.2.6.1.2.1 2003/01/17 00:49:04 giles Exp $ */ /* Name table definition */ #ifndef inamedef_INCLUDED # define inamedef_INCLUDED #include "inameidx.h" #include "inamestr.h" #include "inames.h" #include "gsstruct.h" /* for gc_state_t */ /* * The name table machinery has two slightly different configurations: * a faster one that limits the total number of names to 64K and allows * names up to 16K in size, and a slightly slower one that limits * the total to 4M and restricts names to 256 characters. * The maximum number of names is 2^(16+EXTEND_NAMES)-1. */ #define max_name_extension_bits 6 #if EXTEND_NAMES > max_name_extension_bits # undef EXTEND_NAMES # define EXTEND_NAMES max_name_extension_bits #endif /* * We capture the small algorithmic differences between these two * configurations entirely in this header file; * the implementation doesn't need any conditionals on EXTEND_NAMES. */ #define max_name_index (uint)((0x10000 << EXTEND_NAMES) - 1) /* As explained below, we distinguish name indices from name counts. */ #define max_name_count max_name_index /* ---------------- Structure definitions ---------------- */ /* * Define the structure of a name. The pvalue member implements an * important optimization to avoid lookup for operator and other global * names. */ struct name_s { /* pvalue specifies the definition status of the name: */ /* pvalue == pv_no_defn: no definitions */ #define pv_no_defn ((ref *)0) /* pvalue == pv_other: other status */ #define pv_other ((ref *)1) /* pvalue != pv_no_defn, pvalue != pv_other: pvalue is valid */ #define pv_valid(pvalue) ((unsigned long)(pvalue) > 1) ref *pvalue; /* if only defined in systemdict or */ /* userdict, this points to the value */ }; /*typedef struct name_s name; *//* in iref.h */ /* * Define the structure of a name table. Normally we would make this * an opaque type, but we want to be able to in-line some of the * access procedures. * * The name table is a two-level indexed table, consisting of * sub-tables of size nt_sub_size each. * * First we define the name sub-table structure. */ #define nt_log2_sub_size NT_LOG2_SUB_SIZE /* in inameidx.h */ # define nt_sub_size (1 << nt_log2_sub_size) # define nt_sub_index_mask (nt_sub_size - 1) typedef struct name_sub_table_s { name names[NT_SUB_SIZE]; /* must be first */ #ifdef EXTEND_NAMES uint high_index; /* sub-table base index & (-1 << 16) */ #endif } name_sub_table; /* * Now define the name table itself. * This must be made visible so that the interpreter can use the * inline macros defined below. */ struct name_table_s { uint free; /* head of free list, which is sorted in */ /* increasing count (not index) order */ uint sub_next; /* index of next sub-table to allocate */ /* if not already allocated */ uint perm_count; /* # of permanent (read-only) strings */ uint sub_count; /* index of highest allocated sub-table +1 */ uint max_sub_count; /* max allowable value of sub_count */ uint name_string_attrs; /* imemory_space(memory) | a_readonly */ gs_memory_t *memory; uint hash[NT_HASH_SIZE]; struct sub_ { /* both ptrs are 0 or both are non-0 */ name_sub_table *names; name_string_sub_table_t *strings; } sub[max_name_index / nt_sub_size + 1]; }; /*typedef struct name_table_s name_table; *//* in inames.h */ /* ---------------- Procedural interface ---------------- */ /* * Convert between names, indices, and strings. Note that the inline * versions, but not the procedure versions, take a name_table argument. */ /* index => string */ #define names_index_string_inline(nt, nidx)\ ((nt)->sub[(nidx) >> nt_log2_sub_size].strings->strings +\ ((nidx) & nt_sub_index_mask)) /* ref => string */ #define names_string_inline(nt, pnref)\ names_index_string_inline(nt, names_index_inline(nt, pnref)) /* ref => index */ #if EXTEND_NAMES # define names_index_inline(nt_ignored, pnref)\ ( ((const name_sub_table *)\ ((pnref)->value.pname - (r_size(pnref) & nt_sub_index_mask)))->high_index + r_size(pnref) ) #else # define names_index_inline(nt_ignored, pnref) r_size(pnref) #endif #define names_index(nt_ignored, pnref) names_index_inline(nt_ignored, pnref) /* index => name */ #define names_index_ptr_inline(nt, nidx)\ ((nt)->sub[(nidx) >> nt_log2_sub_size].names->names +\ ((nidx) & nt_sub_index_mask)) /* index => ref */ #define names_index_ref_inline(nt, nidx, pnref)\ make_name(pnref, nidx, names_index_ptr_inline(nt, nidx)); /* Backward compatibility */ #define name_index_inline(pnref) names_index_inline(ignored, pnref) #define name_index_ptr_inline(nt, pnref) names_index_ptr_inline(nt, pnref) #define name_index_ref_inline(nt, nidx, pnref)\ names_index_ref_inline(nt, nidx, pnref) /* name => ref */ /* We have to set the space to system so that the garbage collector */ /* won't think names are foreign and therefore untraceable. */ #define make_name(pnref, nidx, pnm)\ make_tasv(pnref, t_name, avm_system, (ushort)(nidx), pname, pnm) /* ------ Garbage collection ------ */ /* Unmark all non-permanent names before a garbage collection. */ void names_unmark_all(P1(name_table * nt)); /* Finish tracing the name table by putting free names on the free list. */ void names_trace_finish(P2(name_table * nt, gc_state_t * gcst)); /* ------ Save/restore ------ */ /* Clean up the name table before a restore. */ #ifndef alloc_save_t_DEFINED /* also in isave.h */ typedef struct alloc_save_s alloc_save_t; # define alloc_save_t_DEFINED #endif void names_restore(P2(name_table * nt, alloc_save_t * save)); #endif /* inamedef_INCLUDED */