1 /* Copyright (C) 2001-2012 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,
8    modified or distributed except as expressly authorized under the terms
9    of the license contained in the file LICENSE in this distribution.
10 
11    Refer to licensing information at http://www.artifex.com or contact
12    Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134, San Rafael,
13    CA  94903, U.S.A., +1(415)492-9861, for further information.
14 */
15 
16 
17 /* Relational, boolean, and bit operators */
18 #include "ghost.h"
19 #include "oper.h"
20 #include "gsutil.h"
21 #include "idict.h"
22 #include "store.h"
23 
24 /*
25  * Many of the procedures in this file are public only so they can be
26  * called from the FunctionType 4 interpreter (zfunc4.c).
27  */
28 
29 /* ------ Standard operators ------ */
30 
31 /* Define the type test for eq and its relatives. */
32 #define EQ_CHECK_READ(opp, dflt)\
33     switch ( r_type(opp) ) {\
34         case t_string:\
35             check_read(*(opp));\
36             break;\
37         default:\
38             dflt;\
39   }
40 
41 /* Forward references */
42 static int obj_le(os_ptr, os_ptr);
43 
44 /* <obj1> <obj2> eq <bool> */
45 int
zeq(i_ctx_t * i_ctx_p)46 zeq(i_ctx_t *i_ctx_p)
47 {
48     os_ptr op = osp;
49     EQ_CHECK_READ(op - 1, check_op(2));
50     EQ_CHECK_READ(op, DO_NOTHING);
51     make_bool(op - 1, (obj_eq(imemory, op - 1, op) ? 1 : 0));
52     pop(1);
53     return 0;
54 }
55 
56 /* <obj1> <obj2> ne <bool> */
57 int
zne(i_ctx_t * i_ctx_p)58 zne(i_ctx_t *i_ctx_p)
59 {	/* We'll just be lazy and use eq. */
60     int code = zeq(i_ctx_p);
61 
62     if (!code)
63         osp->value.boolval ^= 1;
64     return code;
65 }
66 
67 /* <num1> <num2> ge <bool> */
68 /* <str1> <str2> ge <bool> */
69 int
zge(i_ctx_t * i_ctx_p)70 zge(i_ctx_t *i_ctx_p)
71 {
72     os_ptr op = osp;
73     int code = obj_le(op, op - 1);
74 
75     if (code < 0)
76         return code;
77     make_bool(op - 1, code);
78     pop(1);
79     return 0;
80 }
81 
82 /* <num1> <num2> gt <bool> */
83 /* <str1> <str2> gt <bool> */
84 int
zgt(i_ctx_t * i_ctx_p)85 zgt(i_ctx_t *i_ctx_p)
86 {
87     os_ptr op = osp;
88     int code = obj_le(op - 1, op);
89 
90     if (code < 0)
91         return code;
92     make_bool(op - 1, code ^ 1);
93     pop(1);
94     return 0;
95 }
96 
97 /* <num1> <num2> le <bool> */
98 /* <str1> <str2> le <bool> */
99 int
zle(i_ctx_t * i_ctx_p)100 zle(i_ctx_t *i_ctx_p)
101 {
102     os_ptr op = osp;
103     int code = obj_le(op - 1, op);
104 
105     if (code < 0)
106         return code;
107     make_bool(op - 1, code);
108     pop(1);
109     return 0;
110 }
111 
112 /* <num1> <num2> lt <bool> */
113 /* <str1> <str2> lt <bool> */
114 int
zlt(i_ctx_t * i_ctx_p)115 zlt(i_ctx_t *i_ctx_p)
116 {
117     os_ptr op = osp;
118     int code = obj_le(op, op - 1);
119 
120     if (code < 0)
121         return code;
122     make_bool(op - 1, code ^ 1);
123     pop(1);
124     return 0;
125 }
126 
127 /* <num1> <num2> .max <num> */
128 /* <str1> <str2> .max <str> */
129 static int
zmax(i_ctx_t * i_ctx_p)130 zmax(i_ctx_t *i_ctx_p)
131 {
132     os_ptr op = osp;
133     int code = obj_le(op - 1, op);
134 
135     if (code < 0)
136         return code;
137     if (code) {
138         ref_assign(op - 1, op);
139     }
140     pop(1);
141     return 0;
142 }
143 
144 /* <num1> <num2> .min <num> */
145 /* <str1> <str2> .min <str> */
146 static int
zmin(i_ctx_t * i_ctx_p)147 zmin(i_ctx_t *i_ctx_p)
148 {
149     os_ptr op = osp;
150     int code = obj_le(op - 1, op);
151 
152     if (code < 0)
153         return code;
154     if (!code) {
155         ref_assign(op - 1, op);
156     }
157     pop(1);
158     return 0;
159 }
160 
161 /* <bool1> <bool2> and <bool> */
162 /* <int1> <int2> and <int> */
163 int
zand(i_ctx_t * i_ctx_p)164 zand(i_ctx_t *i_ctx_p)
165 {
166     os_ptr op = osp;
167 
168     switch (r_type(op)) {
169         case t_boolean:
170             check_type(op[-1], t_boolean);
171             op[-1].value.boolval &= op->value.boolval;
172             break;
173         case t_integer:
174             check_type(op[-1], t_integer);
175             op[-1].value.intval &= op->value.intval;
176             break;
177         default:
178             return_op_typecheck(op);
179     }
180     pop(1);
181     return 0;
182 }
183 
184 /* <bool> not <bool> */
185 /* <int> not <int> */
186 int
znot(i_ctx_t * i_ctx_p)187 znot(i_ctx_t *i_ctx_p)
188 {
189     os_ptr op = osp;
190 
191     switch (r_type(op)) {
192         case t_boolean:
193             op->value.boolval = !op->value.boolval;
194             break;
195         case t_integer:
196             op->value.intval = ~op->value.intval;
197             break;
198         default:
199             return_op_typecheck(op);
200     }
201     return 0;
202 }
203 
204 /* <bool1> <bool2> or <bool> */
205 /* <int1> <int2> or <int> */
206 int
zor(i_ctx_t * i_ctx_p)207 zor(i_ctx_t *i_ctx_p)
208 {
209     os_ptr op = osp;
210 
211     switch (r_type(op)) {
212         case t_boolean:
213             check_type(op[-1], t_boolean);
214             op[-1].value.boolval |= op->value.boolval;
215             break;
216         case t_integer:
217             check_type(op[-1], t_integer);
218             op[-1].value.intval |= op->value.intval;
219             break;
220         default:
221             return_op_typecheck(op);
222     }
223     pop(1);
224     return 0;
225 }
226 
227 /* <bool1> <bool2> xor <bool> */
228 /* <int1> <int2> xor <int> */
229 int
zxor(i_ctx_t * i_ctx_p)230 zxor(i_ctx_t *i_ctx_p)
231 {
232     os_ptr op = osp;
233 
234     switch (r_type(op)) {
235         case t_boolean:
236             check_type(op[-1], t_boolean);
237             op[-1].value.boolval ^= op->value.boolval;
238             break;
239         case t_integer:
240             check_type(op[-1], t_integer);
241             op[-1].value.intval ^= op->value.intval;
242             break;
243         default:
244             return_op_typecheck(op);
245     }
246     pop(1);
247     return 0;
248 }
249 
250 /* <int> <shift> bitshift <int> */
251 int
zbitshift(i_ctx_t * i_ctx_p)252 zbitshift(i_ctx_t *i_ctx_p)
253 {
254     os_ptr op = osp;
255     int shift;
256 
257     check_type(*op, t_integer);
258     check_type(op[-1], t_integer);
259     if (op->value.intval < -31 || op->value.intval > 31)
260         op[-1].value.intval = 0;
261     else if ((shift = op->value.intval) < 0)
262         op[-1].value.intval = ((uint)(op[-1].value.intval)) >> -shift;
263     else
264         op[-1].value.intval <<= shift;
265     pop(1);
266     return 0;
267 }
268 
269 /* ------ Extensions ------ */
270 
271 /* <obj1> <obj2> .identeq <bool> */
272 static int
zidenteq(i_ctx_t * i_ctx_p)273 zidenteq(i_ctx_t *i_ctx_p)
274 {
275     os_ptr op = osp;
276 
277     EQ_CHECK_READ(op - 1, check_op(2));
278     EQ_CHECK_READ(op, DO_NOTHING);
279     make_bool(op - 1, (obj_ident_eq(imemory, op - 1, op) ? 1 : 0));
280     pop(1);
281     return 0;
282 
283 }
284 
285 /* <obj1> <obj2> .identne <bool> */
286 static int
zidentne(i_ctx_t * i_ctx_p)287 zidentne(i_ctx_t *i_ctx_p)
288 {
289         /* We'll just be lazy and use .identeq. */
290     int code = zidenteq(i_ctx_p);
291 
292     if (!code)
293         osp->value.boolval ^= 1;
294     return code;
295 }
296 
297 /* ------ Initialization procedure ------ */
298 
299 const op_def zrelbit_op_defs[] =
300 {
301     {"2and", zand},
302     {"2bitshift", zbitshift},
303     {"2eq", zeq},
304     {"2ge", zge},
305     {"2gt", zgt},
306     {"2le", zle},
307     {"2lt", zlt},
308     {"2.max", zmax},
309     {"2.min", zmin},
310     {"2ne", zne},
311     {"1not", znot},
312     {"2or", zor},
313     {"2xor", zxor},
314                 /* Extensions */
315     {"2.identeq", zidenteq},
316     {"2.identne", zidentne},
317     op_def_end(0)
318 };
319 
320 /* ------ Internal routines ------ */
321 
322 /* Compare two operands (both numeric, or both strings). */
323 /* Return 1 if op[-1] <= op[0], 0 if op[-1] > op[0], */
324 /* or a (negative) error code. */
325 static int
obj_le(register os_ptr op1,register os_ptr op)326 obj_le(register os_ptr op1, register os_ptr op)
327 {
328     switch (r_type(op1)) {
329         case t_integer:
330             switch (r_type(op)) {
331                 case t_integer:
332                     return (op1->value.intval <= op->value.intval);
333                 case t_real:
334                     return ((double)op1->value.intval <= op->value.realval);
335                 default:
336                     return_op_typecheck(op);
337             }
338         case t_real:
339             switch (r_type(op)) {
340                 case t_real:
341                     return (op1->value.realval <= op->value.realval);
342                 case t_integer:
343                     return (op1->value.realval <= (double)op->value.intval);
344                 default:
345                     return_op_typecheck(op);
346             }
347         case t_string:
348             check_read(*op1);
349             check_read_type(*op, t_string);
350             return (bytes_compare(op1->value.bytes, r_size(op1),
351                                   op->value.bytes, r_size(op)) <= 0);
352         default:
353             return_op_typecheck(op1);
354     }
355 }
356