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