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