xref: /plan9/sys/src/cmd/gs/src/opdef.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1991, 1995, 1998, 1999 artofcode LLC.  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: opdef.h,v 1.6 2002/06/16 04:47:10 lpd Exp $ */
18 /* Operator definition interface for Ghostscript */
19 
20 #ifndef opdef_INCLUDED
21 #  define opdef_INCLUDED
22 
23 /*
24  * Define the structure for initializing the operator table.  Each operator
25  * file zxxx.c declares an array of these as follows:
26 
27    const op_def * const zxxx_op_defs[] = {
28       {"1name", zname},
29       ...
30       op_def_end(iproc)
31    };
32 
33  * where iproc is an initialization procedure for the file or 0, and, for
34  * each operator defined, the initial digit of the name string indicates
35  * the number of arguments and zname is the address of the associated C
36  * function to invoke.
37  *
38  * The array definition always appears at the END of the file, to avoid
39  * the need for forward declarations for all the operator procedures.
40  *
41  * Operators may be stored in dictionaries other than systemdict.
42  * We support this with op_def entries of a special form:
43 
44    op_def_begin_dict("dictname"),
45 
46  */
47 typedef struct {
48     const char *oname;
49     op_proc_t proc;
50 } op_def;
51 
52 #define op_def_begin_dict(dname) {dname, 0}
53 #define op_def_begin_filter() op_def_begin_dict("filterdict")
54 #define op_def_begin_level2() op_def_begin_dict("level2dict")
55 #define op_def_begin_ll3() op_def_begin_dict("ll3dict")
56 #define op_def_is_begin_dict(def) ((def)->proc == 0)
57 #define op_def_end(iproc) {0, iproc}
58 
59 /*
60  * NOTE: for implementation reasons, a single table of operator definitions
61  * is limited to 16 entries, including op_def_begin_xxx entries.  If a file
62  * defines more operators than this, it must split them into multiple
63  * tables and have multiple -oper entries in the makefile.  Currently,
64  * only 4 out of 85 operator files require this.
65  */
66 #define OP_DEFS_LOG2_MAX_SIZE 4
67 #define OP_DEFS_MAX_SIZE (1 << OP_DEFS_LOG2_MAX_SIZE)
68 
69 /*
70  * Define the table of pointers to all operator definition tables.
71  */
72 extern const op_def *const op_defs_all[];
73 
74 /*
75  * Internal operators whose names begin with %, such as continuation
76  * operators, do not appear in systemdict.  Ghostscript assumes
77  * that these operators cannot appear anywhere (in executable form)
78  * except on the e-stack; to maintain this invariant, the execstack
79  * operator converts them to literal form, and cvx refuses to convert
80  * them back.  As a result of this invariant, they do not need to
81  * push themselves back on the e-stack when executed, since the only
82  * place they could have come from was the e-stack.
83  */
84 #define op_def_is_internal(def) ((def)->oname[1] == '%')
85 
86 /*
87  * All operators are catalogued in a table; this is necessary because
88  * they must have a short packed representation for the sake of 'bind'.
89  * The `size' of an operator is normally its index in this table;
90  * however, internal operators have a `size' of 0, and their true index
91  * must be found by searching the table for their procedure address.
92  */
93 ushort op_find_index(const ref *);
94 
95 #define op_index(opref)\
96   (r_size(opref) == 0 ? op_find_index(opref) : r_size(opref))
97 
98 /*
99  * There are actually two kinds of operators: the real ones (t_operator),
100  * and ones defined by procedures (t_oparray).  The catalog for t_operators
101  * is (indirectly) op_defs_all, and their index is in the range
102  * [1..op_def_count-1].
103  */
104 #define op_index_is_operator(index) ((index) < op_def_count)
105 extern const uint op_def_count;
106 
107 #define op_index_def(index)\
108   (&op_defs_all[(index) >> OP_DEFS_LOG2_MAX_SIZE]\
109     [(index) & (OP_DEFS_MAX_SIZE - 1)])
110 #define op_num_args(opref) (op_index_def(op_index(opref))->oname[0] - '0')
111 #define op_index_proc(index) (op_index_def(index)->proc)
112 
113 /*
114  * There are two catalogs for t_oparrays, one global and one local.
115  * Operator indices for the global table are in the range
116  *      [op_def_count..op_def_count+op_array_global.count-1]
117  * Operator indices for the local table are in the range
118  *      [op_def_count+r_size(&op_array_global.table)..
119  *        op_def_count+r_size(&op_array_global.table)+op_array_local.count-1]
120  */
121 typedef struct op_array_table_s {
122     ref table;			/* t_array */
123     ushort *nx_table;		/* name indices */
124     uint count;			/* # of occupied entries */
125     uint base_index;		/* operator index of first entry */
126     uint attrs;			/* ref attrs of ops in this table */
127     ref *root_p;		/* self-pointer for GC root */
128 } op_array_table;
129 extern op_array_table
130        op_array_table_global, op_array_table_local;
131 
132 #define op_index_op_array_table(index)\
133   ((index) < op_array_table_local.base_index ?\
134    &op_array_table_global : &op_array_table_local)
135 
136 /*
137  * Convert an operator index to an operator or oparray ref.
138  * This is only used for debugging and for 'get' from packed arrays,
139  * so it doesn't have to be very fast.
140  */
141 void op_index_ref(uint, ref *);
142 
143 #endif /* opdef_INCLUDED */
144