Coverage Report

Created: 2022-10-31 07:00

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