Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/psi/zarith.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
/* Arithmetic operators */
18
#include "math_.h"
19
#include "ghost.h"
20
#include "oper.h"
21
#include "store.h"
22
#include "gsstate.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
static int mul_64_64_overflowcheck(int64_t abc, int64_t def, int64_t *res);
30
31
/* <num1> <num2> add <sum> */
32
/* We make this into a separate procedure because */
33
/* the interpreter will almost always call it directly. */
34
int
35
zop_add(i_ctx_t *i_ctx_p)
36
321M
{
37
321M
    register os_ptr op = osp;
38
321M
    float result;
39
40
321M
    switch (r_type(op)) {
41
16
    default:
42
16
        return_op_typecheck(op);
43
33.9M
    case t_real:
44
33.9M
        switch (r_type(op - 1)) {
45
10
        default:
46
10
            return_op_typecheck(op - 1);
47
18.0M
        case t_real:
48
18.0M
            result = op[-1].value.realval + op->value.realval;
49
18.0M
#ifdef HAVE_ISINF
50
18.0M
            if (isinf(result))
51
0
                return_error(gs_error_undefinedresult);
52
18.0M
#endif
53
18.0M
#ifdef HAVE_ISNAN
54
18.0M
            if (isnan(result))
55
0
                return_error(gs_error_undefinedresult);
56
18.0M
#endif
57
18.0M
            op[-1].value.realval = result;
58
18.0M
            break;
59
15.8M
        case t_integer:
60
15.8M
            make_real(op - 1, (double)op[-1].value.intval + op->value.realval);
61
33.9M
        }
62
33.9M
        break;
63
287M
    case t_integer:
64
287M
        switch (r_type(op - 1)) {
65
13
        default:
66
13
            return_op_typecheck(op - 1);
67
32.3M
        case t_real:
68
32.3M
            result = op[-1].value.realval + (double)op->value.intval;
69
32.3M
#ifdef HAVE_ISINF
70
32.3M
            if (isinf(result))
71
2
                return_error(gs_error_undefinedresult);
72
32.3M
#endif
73
32.3M
#ifdef HAVE_ISNAN
74
32.3M
            if (isnan(result))
75
0
                return_error(gs_error_undefinedresult);
76
32.3M
#endif
77
32.3M
            op[-1].value.realval = result;
78
32.3M
            break;
79
254M
        case t_integer: {
80
254M
            if (sizeof(ps_int) != 4 && gs_currentcpsimode(imemory)) {
81
0
                ps_int32 int1 = (ps_int32)op[-1].value.intval;
82
0
                ps_int32 int2 = (ps_int32)op->value.intval;
83
84
0
                if (((int1 += int2) ^ int2) < 0 &&
85
0
                    ((int1 - int2) ^ int2) >= 0
86
0
                    ) {                     /* Overflow, convert to real */
87
0
                    make_real(op - 1, (double)(int1 - int2) + int2);
88
0
                }
89
0
                else {
90
0
                    op[-1].value.intval = (ps_int)int1;
91
0
                }
92
0
            }
93
254M
            else {
94
254M
                ps_int int2 = op->value.intval;
95
96
254M
                if (((op[-1].value.intval += int2) ^ int2) < 0 &&
97
254M
                    ((op[-1].value.intval - int2) ^ int2) >= 0
98
254M
                    ) {                     /* Overflow, convert to real */
99
36
                    make_real(op - 1, (double)(op[-1].value.intval - int2) + int2);
100
36
                }
101
254M
            }
102
254M
        }
103
287M
        }
104
321M
    }
105
321M
    return 0;
106
321M
}
107
int
108
zadd(i_ctx_t *i_ctx_p)
109
0
{
110
0
    int code = zop_add(i_ctx_p);
111
112
0
    if (code == 0) {
113
0
        pop(1);
114
0
    }
115
0
    return code;
116
0
}
117
118
/* <num1> <num2> div <real_quotient> */
119
int
120
zdiv(i_ctx_t *i_ctx_p)
121
18.7M
{
122
18.7M
    os_ptr op = osp;
123
18.7M
    os_ptr op1 = op - 1;
124
18.7M
    float result;
125
126
    /* We can't use the non_int_cases macro, */
127
    /* because we have to check explicitly for op == 0. */
128
18.7M
    switch (r_type(op)) {
129
16
        default:
130
16
            return_op_typecheck(op);
131
964k
        case t_real:
132
964k
            if (op->value.realval == 0)
133
13
                return_error(gs_error_undefinedresult);
134
964k
            switch (r_type(op1)) {
135
8
                default:
136
8
                    return_op_typecheck(op1);
137
953k
                case t_real:
138
953k
                    result = op1->value.realval / op->value.realval;
139
953k
#ifdef HAVE_ISINF
140
953k
                    if (isinf(result))
141
2
                        return_error(gs_error_undefinedresult);
142
953k
#endif
143
953k
#ifdef HAVE_ISNAN
144
953k
                    if (isnan(result))
145
1
                        return_error(gs_error_undefinedresult);
146
953k
#endif
147
953k
                    op1->value.realval = result;
148
953k
                    break;
149
10.4k
                case t_integer:
150
10.4k
                    result = (double)op1->value.intval / op->value.realval;
151
10.4k
#ifdef HAVE_ISINF
152
10.4k
                    if (isinf(result))
153
1
                        return_error(gs_error_undefinedresult);
154
10.4k
#endif
155
10.4k
#ifdef HAVE_ISNAN
156
10.4k
                    if (isnan(result))
157
0
                        return_error(gs_error_undefinedresult);
158
10.4k
#endif
159
964k
                    make_real(op1, result);
160
964k
            }
161
964k
            break;
162
17.8M
        case t_integer:
163
17.8M
            if (op->value.intval == 0)
164
20
                return_error(gs_error_undefinedresult);
165
17.8M
            switch (r_type(op1)) {
166
27
                default:
167
27
                    return_op_typecheck(op1);
168
17.2M
                case t_real:
169
17.2M
                    result = op1->value.realval / (double)op->value.intval;
170
17.2M
#ifdef HAVE_ISINF
171
17.2M
                    if (isinf(result))
172
1
                        return_error(gs_error_undefinedresult);
173
17.2M
#endif
174
17.2M
#ifdef HAVE_ISNAN
175
17.2M
                    if (isnan(result))
176
0
                        return_error(gs_error_undefinedresult);
177
17.2M
#endif
178
17.2M
                    op1->value.realval = result;
179
17.2M
                    break;
180
589k
                case t_integer:
181
589k
                    result = (double)op1->value.intval / (double)op->value.intval;
182
589k
#ifdef HAVE_ISINF
183
589k
                    if (isinf(result))
184
0
                        return_error(gs_error_undefinedresult);
185
589k
#endif
186
589k
#ifdef HAVE_ISNAN
187
589k
                    if (isnan(result))
188
0
                        return_error(gs_error_undefinedresult);
189
589k
#endif
190
17.8M
                    make_real(op1, result);
191
17.8M
            }
192
18.7M
    }
193
18.7M
    pop(1);
194
18.7M
    return 0;
195
18.7M
}
196
197
/*
198
To detect 64bit x 64bit multiplication overflowing, consider
199
breaking the numbers down into 32bit chunks.
200
201
  abc = (a<<64) + (b<<32) + c
202
      (where a is 0 or -1, and b and c are 32bit unsigned.
203
204
Similarly:
205
206
  def = (d<<64) + (b<<32) + f
207
208
Then:
209
210
  abc.def = ((a<<64) + (b<<32) + c) * ((d<<64) + (e<<32) + f)
211
          = (a<<64).def + (d<<64).abc + (b<<32).(e<<32) +
212
            (b<<32).f + (e<<32).c + cf
213
          = (a.def + d.abc + b.e)<<64 + (b.f + e.c)<<32 + cf
214
215
*/
216
217
static int mul_64_64_overflowcheck(int64_t abc, int64_t def, int64_t *res)
218
6.60M
{
219
6.60M
  uint32_t b = (abc>>32);
220
6.60M
  uint32_t c = (uint32_t)abc;
221
6.60M
  uint32_t e = (def>>32);
222
6.60M
  uint32_t f = (uint32_t)def;
223
6.60M
  uint64_t low, mid, high, bf, ec;
224
225
  /* Low contribution */
226
6.60M
  low = (uint64_t)c * (uint64_t)f;
227
  /* Mid contributions */
228
6.60M
  bf = (uint64_t)b * (uint64_t)f;
229
6.60M
  ec = (uint64_t)e * (uint64_t)c;
230
  /* Top contribution */
231
6.60M
  high = (uint64_t)b * (uint64_t)e;
232
6.60M
  if (abc < 0)
233
21
      high -= def;
234
6.60M
  if (def < 0)
235
27
      high -= abc;
236
  /* How do we check for carries from 64bit unsigned adds?
237
   *  x + y >= (1<<64) == x >= (1<<64) - y
238
   *                   == x >  (1<<64) - y - 1
239
   * if we consider just 64bits, this is:
240
   * x > NOT y
241
   */
242
6.60M
  if (bf > ~ec)
243
11
      high += ((uint64_t)1)<<32;
244
6.60M
  mid = bf + ec;
245
6.60M
  if (low > ~(mid<<32))
246
11
      high += 1;
247
6.60M
  high += (mid>>32);
248
6.60M
  low += (mid<<32);
249
250
6.60M
  *res = low;
251
252
6.60M
  return (int64_t)low < 0 ? high != -1 : high != 0;
253
6.60M
}
254
255
/* <num1> <num2> mul <product> */
256
int
257
zmul(i_ctx_t *i_ctx_p)
258
74.6M
{
259
74.6M
    os_ptr op = osp;
260
74.6M
    float result;
261
262
74.6M
    switch (r_type(op)) {
263
19
    default:
264
19
        return_op_typecheck(op);
265
35.1M
    case t_real:
266
35.1M
        switch (r_type(op - 1)) {
267
13
        default:
268
13
            return_op_typecheck(op - 1);
269
34.6M
        case t_real:
270
34.6M
            result = op[-1].value.realval * op->value.realval;
271
34.6M
#ifdef HAVE_ISINF
272
34.6M
            if (isinf(result))
273
3
                return_error(gs_error_undefinedresult);
274
34.6M
#endif
275
34.6M
#ifdef HAVE_ISNAN
276
34.6M
            if (isnan(result))
277
0
                return_error(gs_error_undefinedresult);
278
34.6M
#endif
279
34.6M
            op[-1].value.realval = result;
280
34.6M
            break;
281
486k
        case t_integer:
282
486k
            result = (double)op[-1].value.intval * op->value.realval;
283
486k
            make_real(op - 1, result);
284
35.1M
        }
285
35.1M
        break;
286
39.4M
    case t_integer:
287
39.4M
        switch (r_type(op - 1)) {
288
23
        default:
289
23
            return_op_typecheck(op - 1);
290
32.8M
        case t_real:
291
32.8M
            result = op[-1].value.realval * (double)op->value.intval;
292
32.8M
#ifdef HAVE_ISINF
293
32.8M
            if (isinf(result))
294
0
                return_error(gs_error_undefinedresult);
295
32.8M
#endif
296
32.8M
#ifdef HAVE_ISNAN
297
32.8M
            if (isnan(result))
298
0
                return_error(gs_error_undefinedresult);
299
32.8M
#endif
300
32.8M
            op[-1].value.realval = result;
301
32.8M
            break;
302
6.60M
        case t_integer: {
303
6.60M
            if (sizeof(ps_int) != 4 && gs_currentcpsimode(imemory)) {
304
0
                double ab = (double)op[-1].value.intval * op->value.intval;
305
0
                if (ab > (double)MAX_PS_INT32)       /* (double)0x7fffffff */
306
0
                    make_real(op - 1, ab);
307
0
                else if (ab < (double)MIN_PS_INT32) /* (double)(int)0x80000000 */
308
0
                    make_real(op - 1, ab);
309
0
                else
310
0
                    op[-1].value.intval = (ps_int)ab;
311
0
            }
312
6.60M
            else {
313
6.60M
                int64_t result;
314
6.60M
                if (mul_64_64_overflowcheck(op[-1].value.intval, op->value.intval, &result)) {
315
0
                    double ab = (double)op[-1].value.intval * op->value.intval;
316
0
                    make_real(op - 1, ab);
317
6.60M
                } else {
318
6.60M
                    op[-1].value.intval = result;
319
6.60M
                }
320
6.60M
            }
321
6.60M
        }
322
39.4M
        }
323
74.6M
    }
324
74.6M
    pop(1);
325
74.6M
    return 0;
326
74.6M
}
327
328
/* <num1> <num2> sub <difference> */
329
/* We make this into a separate procedure because */
330
/* the interpreter will almost always call it directly. */
331
int
332
zop_sub(i_ctx_t *i_ctx_p)
333
55.1M
{
334
55.1M
    register os_ptr op = osp;
335
336
55.1M
    switch (r_type(op)) {
337
134
    default:
338
134
        return_op_typecheck(op);
339
16.7M
    case t_real:
340
16.7M
        switch (r_type(op - 1)) {
341
14
        default:
342
14
            return_op_typecheck(op - 1);
343
95.0k
        case t_real:
344
95.0k
            op[-1].value.realval -= op->value.realval;
345
95.0k
            break;
346
16.6M
        case t_integer:
347
16.6M
            make_real(op - 1, (double)op[-1].value.intval - op->value.realval);
348
16.7M
        }
349
16.7M
        break;
350
38.4M
    case t_integer:
351
38.4M
        switch (r_type(op - 1)) {
352
14
        default:
353
14
            return_op_typecheck(op - 1);
354
10.8k
        case t_real:
355
10.8k
            op[-1].value.realval -= (double)op->value.intval;
356
10.8k
            break;
357
38.4M
        case t_integer: {
358
38.4M
            if (sizeof(ps_int) != 4 && gs_currentcpsimode(imemory)) {
359
0
                ps_int32 int1 = (ps_int)op[-1].value.intval;
360
0
                ps_int32 int2 = (ps_int)op->value.intval;
361
0
                ps_int32 int3;
362
363
0
                if ((int1 ^ (int3 = int1 - int2)) < 0 &&
364
0
                    (int1 ^ int2) < 0
365
0
                    ) {                     /* Overflow, convert to real */
366
0
                    make_real(op - 1, (float)int1 - op->value.intval);
367
0
                }
368
0
                else {
369
0
                    op[-1].value.intval = (ps_int)int3;
370
0
                }
371
0
            }
372
38.4M
            else {
373
38.4M
                ps_int int1 = op[-1].value.intval;
374
375
38.4M
                if ((int1 ^ (op[-1].value.intval = int1 - op->value.intval)) < 0 &&
376
38.4M
                    (int1 ^ op->value.intval) < 0
377
38.4M
                    ) {                     /* Overflow, convert to real */
378
0
                    make_real(op - 1, (float)int1 - op->value.intval);
379
0
                }
380
38.4M
            }
381
38.4M
        }
382
38.4M
        }
383
55.1M
    }
384
55.1M
    return 0;
385
55.1M
}
386
int
387
zsub(i_ctx_t *i_ctx_p)
388
0
{
389
0
    int code = zop_sub(i_ctx_p);
390
391
0
    if (code == 0) {
392
0
        pop(1);
393
0
    }
394
0
    return code;
395
0
}
396
397
/* <num1> <num2> idiv <int_quotient> */
398
int
399
zidiv(i_ctx_t *i_ctx_p)
400
21.8M
{
401
21.8M
    os_ptr op = osp;
402
403
21.8M
    check_type(*op, t_integer);
404
21.8M
    check_type(op[-1], t_integer);
405
21.8M
    if (sizeof(ps_int) && gs_currentcpsimode(imemory)) {
406
0
        int tmpval;
407
0
        if ((op->value.intval == 0) || (op[-1].value.intval == (ps_int)MIN_PS_INT32 && op->value.intval == -1)) {
408
            /* Anomalous boundary case: -MININT / -1, fail. */
409
0
            return_error(gs_error_undefinedresult);
410
0
        }
411
0
        tmpval = (int)op[-1].value.intval / op->value.intval;
412
0
        op[-1].value.intval = (int64_t)tmpval;
413
0
    }
414
21.8M
    else {
415
21.8M
        if ((op->value.intval == 0) || (op[-1].value.intval == MIN_PS_INT && op->value.intval == -1)) {
416
            /* Anomalous boundary case: -MININT / -1, fail. */
417
3
            return_error(gs_error_undefinedresult);
418
3
        }
419
21.8M
        op[-1].value.intval /= op->value.intval;
420
21.8M
    }
421
21.8M
    pop(1);
422
21.8M
    return 0;
423
21.8M
}
424
425
/* <int1> <int2> mod <remainder> */
426
int
427
zmod(i_ctx_t *i_ctx_p)
428
1.01M
{
429
1.01M
    os_ptr op = osp;
430
431
1.01M
    check_type(*op, t_integer);
432
1.01M
    check_type(op[-1], t_integer);
433
1.01M
    if (op->value.intval == 0)
434
5
        return_error(gs_error_undefinedresult);
435
1.01M
    op[-1].value.intval %= op->value.intval;
436
1.01M
    pop(1);
437
1.01M
    return 0;
438
1.01M
}
439
440
/* <num1> neg <num2> */
441
int
442
zneg(i_ctx_t *i_ctx_p)
443
1.47M
{
444
1.47M
    os_ptr op = osp;
445
446
1.47M
    switch (r_type(op)) {
447
14
        default:
448
14
            return_op_typecheck(op);
449
1.26M
        case t_real:
450
1.26M
            op->value.realval = -op->value.realval;
451
1.26M
            break;
452
207k
        case t_integer:
453
207k
            if (sizeof(ps_int) != 32 && gs_currentcpsimode(imemory)) {
454
0
                if (((unsigned int)op->value.intval) == MIN_PS_INT32)
455
0
                    make_real(op, -(float)(ps_uint32)MIN_PS_INT32);
456
0
                else
457
0
                    op->value.intval = -op->value.intval;
458
0
            }
459
207k
            else {
460
207k
                if (op->value.intval == MIN_PS_INT)
461
207k
                    make_real(op, -(float)MIN_PS_INT);
462
207k
                else
463
207k
                    op->value.intval = -op->value.intval;
464
207k
            }
465
1.47M
    }
466
1.47M
    return 0;
467
1.47M
}
468
469
/* <num1> abs <num2> */
470
int
471
zabs(i_ctx_t *i_ctx_p)
472
2.69M
{
473
2.69M
    os_ptr op = osp;
474
475
2.69M
    switch (r_type(op)) {
476
87
        default:
477
87
            return_op_typecheck(op);
478
1.73M
        case t_real:
479
1.73M
            if (op->value.realval >= 0)
480
885k
                return 0;
481
853k
            break;
482
958k
        case t_integer:
483
958k
            if (op->value.intval >= 0)
484
957k
                return 0;
485
141
            break;
486
2.69M
    }
487
853k
    return zneg(i_ctx_p);
488
2.69M
}
489
490
/* <num1> ceiling <num2> */
491
int
492
zceiling(i_ctx_t *i_ctx_p)
493
131
{
494
131
    os_ptr op = osp;
495
496
131
    switch (r_type(op)) {
497
12
        default:
498
12
            return_op_typecheck(op);
499
60
        case t_real:
500
60
            op->value.realval = ceil(op->value.realval);
501
119
        case t_integer:;
502
131
    }
503
119
    return 0;
504
131
}
505
506
/* <num1> floor <num2> */
507
int
508
zfloor(i_ctx_t *i_ctx_p)
509
114
{
510
114
    os_ptr op = osp;
511
512
114
    switch (r_type(op)) {
513
11
        default:
514
11
            return_op_typecheck(op);
515
47
        case t_real:
516
47
            op->value.realval = floor(op->value.realval);
517
103
        case t_integer:;
518
114
    }
519
103
    return 0;
520
114
}
521
522
/* <num1> round <num2> */
523
int
524
zround(i_ctx_t *i_ctx_p)
525
1.73k
{
526
1.73k
    os_ptr op = osp;
527
528
1.73k
    switch (r_type(op)) {
529
15
        default:
530
15
            return_op_typecheck(op);
531
628
        case t_real:
532
628
            op->value.realval = floor(op->value.realval + 0.5);
533
1.72k
        case t_integer:;
534
1.73k
    }
535
1.72k
    return 0;
536
1.73k
}
537
538
/* <num1> truncate <num2> */
539
int
540
ztruncate(i_ctx_t *i_ctx_p)
541
1.22k
{
542
1.22k
    os_ptr op = osp;
543
544
1.22k
    switch (r_type(op)) {
545
12
        default:
546
12
            return_op_typecheck(op);
547
1.17k
        case t_real:
548
1.17k
            op->value.realval =
549
1.17k
                (op->value.realval < 0.0 ?
550
4
                 ceil(op->value.realval) :
551
1.17k
                 floor(op->value.realval));
552
1.21k
        case t_integer:;
553
1.22k
    }
554
1.21k
    return 0;
555
1.22k
}
556
557
/* Non-standard operators */
558
559
/* <int1> <int2> .bitadd <sum> */
560
static int
561
zbitadd(i_ctx_t *i_ctx_p)
562
0
{
563
0
    os_ptr op = osp;
564
565
0
    check_type(*op, t_integer);
566
0
    check_type(op[-1], t_integer);
567
0
    op[-1].value.intval += op->value.intval;
568
0
    pop(1);
569
0
    return 0;
570
0
}
571
572
/* ------ Initialization table ------ */
573
574
const op_def zarith_op_defs[] =
575
{
576
    {"1abs", zabs},
577
    {"2add", zadd},
578
    {"2.bitadd", zbitadd},
579
    {"1ceiling", zceiling},
580
    {"2div", zdiv},
581
    {"2idiv", zidiv},
582
    {"1floor", zfloor},
583
    {"2mod", zmod},
584
    {"2mul", zmul},
585
    {"1neg", zneg},
586
    {"1round", zround},
587
    {"2sub", zsub},
588
    {"1truncate", ztruncate},
589
    op_def_end(0)
590
};