Coverage Report

Created: 2022-04-16 11:23

/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
2.77M
{
37
2.77M
    register os_ptr op = osp;
38
2.77M
    float result;
39
40
2.77M
    switch (r_type(op)) {
41
0
    default:
42
0
        return_op_typecheck(op);
43
427k
    case t_real:
44
427k
        switch (r_type(op - 1)) {
45
0
        default:
46
0
            return_op_typecheck(op - 1);
47
213k
        case t_real:
48
213k
            result = op[-1].value.realval + op->value.realval;
49
213k
#ifdef HAVE_ISINF
50
213k
            if (isinf(result))
51
0
                return_error(gs_error_undefinedresult);
52
213k
#endif
53
213k
#ifdef HAVE_ISNAN
54
213k
            if (isnan(result))
55
0
                return_error(gs_error_undefinedresult);
56
213k
#endif
57
213k
            op[-1].value.realval = result;
58
213k
            break;
59
213k
        case t_integer:
60
213k
            make_real(op - 1, (double)op[-1].value.intval + op->value.realval);
61
427k
        }
62
427k
        break;
63
2.35M
    case t_integer:
64
2.35M
        switch (r_type(op - 1)) {
65
0
        default:
66
0
            return_op_typecheck(op - 1);
67
427k
        case t_real:
68
427k
            result = op[-1].value.realval + (double)op->value.intval;
69
427k
#ifdef HAVE_ISINF
70
427k
            if (isinf(result))
71
0
                return_error(gs_error_undefinedresult);
72
427k
#endif
73
427k
#ifdef HAVE_ISNAN
74
427k
            if (isnan(result))
75
0
                return_error(gs_error_undefinedresult);
76
427k
#endif
77
427k
            op[-1].value.realval = result;
78
427k
            break;
79
1.92M
        case t_integer: {
80
1.92M
            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
1.92M
            else {
94
1.92M
                ps_int int2 = op->value.intval;
95
96
1.92M
                if (((op[-1].value.intval += int2) ^ int2) < 0 &&
97
1.92M
                    ((op[-1].value.intval - int2) ^ int2) >= 0
98
1.92M
                    ) {                     /* Overflow, convert to real */
99
0
                    make_real(op - 1, (double)(op[-1].value.intval - int2) + int2);
100
0
                }
101
1.92M
            }
102
1.92M
        }
103
2.35M
        }
104
2.77M
    }
105
2.77M
    return 0;
106
2.77M
}
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
222k
{
122
222k
    os_ptr op = osp;
123
222k
    os_ptr op1 = op - 1;
124
222k
    float result;
125
126
    /* We can't use the non_int_cases macro, */
127
    /* because we have to check explicitly for op == 0. */
128
222k
    switch (r_type(op)) {
129
0
        default:
130
0
            return_op_typecheck(op);
131
3.14k
        case t_real:
132
3.14k
            if (op->value.realval == 0)
133
0
                return_error(gs_error_undefinedresult);
134
3.14k
            switch (r_type(op1)) {
135
0
                default:
136
0
                    return_op_typecheck(op1);
137
3.14k
                case t_real:
138
3.14k
                    result = op1->value.realval / op->value.realval;
139
3.14k
#ifdef HAVE_ISINF
140
3.14k
                    if (isinf(result))
141
0
                        return_error(gs_error_undefinedresult);
142
3.14k
#endif
143
3.14k
#ifdef HAVE_ISNAN
144
3.14k
                    if (isnan(result))
145
0
                        return_error(gs_error_undefinedresult);
146
3.14k
#endif
147
3.14k
                    op1->value.realval = result;
148
3.14k
                    break;
149
0
                case t_integer:
150
0
                    result = (double)op1->value.intval / op->value.realval;
151
0
#ifdef HAVE_ISINF
152
0
                    if (isinf(result))
153
0
                        return_error(gs_error_undefinedresult);
154
0
#endif
155
0
#ifdef HAVE_ISNAN
156
0
                    if (isnan(result))
157
0
                        return_error(gs_error_undefinedresult);
158
0
#endif
159
3.14k
                    make_real(op1, result);
160
3.14k
            }
161
3.14k
            break;
162
219k
        case t_integer:
163
219k
            if (op->value.intval == 0)
164
0
                return_error(gs_error_undefinedresult);
165
219k
            switch (r_type(op1)) {
166
0
                default:
167
0
                    return_op_typecheck(op1);
168
219k
                case t_real:
169
219k
                    result = op1->value.realval / (double)op->value.intval;
170
219k
#ifdef HAVE_ISINF
171
219k
                    if (isinf(result))
172
0
                        return_error(gs_error_undefinedresult);
173
219k
#endif
174
219k
#ifdef HAVE_ISNAN
175
219k
                    if (isnan(result))
176
0
                        return_error(gs_error_undefinedresult);
177
219k
#endif
178
219k
                    op1->value.realval = result;
179
219k
                    break;
180
0
                case t_integer:
181
0
                    result = (double)op1->value.intval / (double)op->value.intval;
182
0
#ifdef HAVE_ISINF
183
0
                    if (isinf(result))
184
0
                        return_error(gs_error_undefinedresult);
185
0
#endif
186
0
#ifdef HAVE_ISNAN
187
0
                    if (isnan(result))
188
0
                        return_error(gs_error_undefinedresult);
189
0
#endif
190
219k
                    make_real(op1, result);
191
219k
            }
192
222k
    }
193
222k
    pop(1);
194
222k
    return 0;
195
222k
}
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
50.5k
{
219
50.5k
  uint32_t b = (abc>>32);
220
50.5k
  uint32_t c = (uint32_t)abc;
221
50.5k
  uint32_t e = (def>>32);
222
50.5k
  uint32_t f = (uint32_t)def;
223
50.5k
  uint64_t low, mid, high, bf, ec;
224
225
  /* Low contribution */
226
50.5k
  low = (uint64_t)c * (uint64_t)f;
227
  /* Mid contributions */
228
50.5k
  bf = (uint64_t)b * (uint64_t)f;
229
50.5k
  ec = (uint64_t)e * (uint64_t)c;
230
  /* Top contribution */
231
50.5k
  high = (uint64_t)b * (uint64_t)e;
232
50.5k
  if (abc < 0)
233
0
      high -= def;
234
50.5k
  if (def < 0)
235
0
      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
50.5k
  if (bf > ~ec)
243
0
      high += ((uint64_t)1)<<32;
244
50.5k
  mid = bf + ec;
245
50.5k
  if (low > ~(mid<<32))
246
0
      high += 1;
247
50.5k
  high += (mid>>32);
248
50.5k
  low += (mid<<32);
249
250
50.5k
  *res = low;
251
252
50.5k
  return (int64_t)low < 0 ? high != -1 : high != 0;
253
50.5k
}
254
255
/* <num1> <num2> mul <product> */
256
int
257
zmul(i_ctx_t *i_ctx_p)
258
910k
{
259
910k
    os_ptr op = osp;
260
910k
    float result;
261
262
910k
    switch (r_type(op)) {
263
0
    default:
264
0
        return_op_typecheck(op);
265
430k
    case t_real:
266
430k
        switch (r_type(op - 1)) {
267
0
        default:
268
0
            return_op_typecheck(op - 1);
269
427k
        case t_real:
270
427k
            result = op[-1].value.realval * op->value.realval;
271
427k
#ifdef HAVE_ISINF
272
427k
            if (isinf(result))
273
0
                return_error(gs_error_undefinedresult);
274
427k
#endif
275
427k
#ifdef HAVE_ISNAN
276
427k
            if (isnan(result))
277
0
                return_error(gs_error_undefinedresult);
278
427k
#endif
279
427k
            op[-1].value.realval = result;
280
427k
            break;
281
3.14k
        case t_integer:
282
3.14k
            result = (double)op[-1].value.intval * op->value.realval;
283
3.14k
            make_real(op - 1, result);
284
430k
        }
285
430k
        break;
286
480k
    case t_integer:
287
480k
        switch (r_type(op - 1)) {
288
0
        default:
289
0
            return_op_typecheck(op - 1);
290
429k
        case t_real:
291
429k
            result = op[-1].value.realval * (double)op->value.intval;
292
429k
#ifdef HAVE_ISINF
293
429k
            if (isinf(result))
294
0
                return_error(gs_error_undefinedresult);
295
429k
#endif
296
429k
#ifdef HAVE_ISNAN
297
429k
            if (isnan(result))
298
0
                return_error(gs_error_undefinedresult);
299
429k
#endif
300
429k
            op[-1].value.realval = result;
301
429k
            break;
302
50.5k
        case t_integer: {
303
50.5k
            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
50.5k
            else {
313
50.5k
                int64_t result;
314
50.5k
                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
50.5k
                } else {
318
50.5k
                    op[-1].value.intval = result;
319
50.5k
                }
320
50.5k
            }
321
50.5k
        }
322
480k
        }
323
910k
    }
324
910k
    pop(1);
325
910k
    return 0;
326
910k
}
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
462k
{
334
462k
    register os_ptr op = osp;
335
336
462k
    switch (r_type(op)) {
337
0
    default:
338
0
        return_op_typecheck(op);
339
217k
    case t_real:
340
217k
        switch (r_type(op - 1)) {
341
0
        default:
342
0
            return_op_typecheck(op - 1);
343
3.37k
        case t_real:
344
3.37k
            op[-1].value.realval -= op->value.realval;
345
3.37k
            break;
346
213k
        case t_integer:
347
213k
            make_real(op - 1, (double)op[-1].value.intval - op->value.realval);
348
217k
        }
349
217k
        break;
350
244k
    case t_integer:
351
244k
        switch (r_type(op - 1)) {
352
0
        default:
353
0
            return_op_typecheck(op - 1);
354
6
        case t_real:
355
6
            op[-1].value.realval -= (double)op->value.intval;
356
6
            break;
357
244k
        case t_integer: {
358
244k
            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
244k
            else {
373
244k
                ps_int int1 = op[-1].value.intval;
374
375
244k
                if ((int1 ^ (op[-1].value.intval = int1 - op->value.intval)) < 0 &&
376
244k
                    (int1 ^ op->value.intval) < 0
377
244k
                    ) {                     /* Overflow, convert to real */
378
0
                    make_real(op - 1, (float)int1 - op->value.intval);
379
0
                }
380
244k
            }
381
244k
        }
382
244k
        }
383
462k
    }
384
462k
    return 0;
385
462k
}
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
124k
{
401
124k
    os_ptr op = osp;
402
403
124k
    check_type(*op, t_integer);
404
124k
    check_type(op[-1], t_integer);
405
124k
    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
124k
    else {
415
124k
        if ((op->value.intval == 0) || (op[-1].value.intval == MIN_PS_INT && op->value.intval == -1)) {
416
            /* Anomalous boundary case: -MININT / -1, fail. */
417
0
            return_error(gs_error_undefinedresult);
418
0
        }
419
124k
        op[-1].value.intval /= op->value.intval;
420
124k
    }
421
124k
    pop(1);
422
124k
    return 0;
423
124k
}
424
425
/* <int1> <int2> mod <remainder> */
426
int
427
zmod(i_ctx_t *i_ctx_p)
428
0
{
429
0
    os_ptr op = osp;
430
431
0
    check_type(*op, t_integer);
432
0
    check_type(op[-1], t_integer);
433
0
    if (op->value.intval == 0)
434
0
        return_error(gs_error_undefinedresult);
435
0
    op[-1].value.intval %= op->value.intval;
436
0
    pop(1);
437
0
    return 0;
438
0
}
439
440
/* <num1> neg <num2> */
441
int
442
zneg(i_ctx_t *i_ctx_p)
443
6.28k
{
444
6.28k
    os_ptr op = osp;
445
446
6.28k
    switch (r_type(op)) {
447
0
        default:
448
0
            return_op_typecheck(op);
449
6.27k
        case t_real:
450
6.27k
            op->value.realval = -op->value.realval;
451
6.27k
            break;
452
8
        case t_integer:
453
8
            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
8
            else {
460
8
                if (op->value.intval == MIN_PS_INT)
461
8
                    make_real(op, -(float)MIN_PS_INT);
462
8
                else
463
8
                    op->value.intval = -op->value.intval;
464
8
            }
465
6.28k
    }
466
6.28k
    return 0;
467
6.28k
}
468
469
/* <num1> abs <num2> */
470
int
471
zabs(i_ctx_t *i_ctx_p)
472
7.65k
{
473
7.65k
    os_ptr op = osp;
474
475
7.65k
    switch (r_type(op)) {
476
0
        default:
477
0
            return_op_typecheck(op);
478
7.65k
        case t_real:
479
7.65k
            if (op->value.realval >= 0)
480
3.82k
                return 0;
481
3.82k
            break;
482
3.82k
        case t_integer:
483
0
            if (op->value.intval >= 0)
484
0
                return 0;
485
0
            break;
486
7.65k
    }
487
3.82k
    return zneg(i_ctx_p);
488
7.65k
}
489
490
/* <num1> ceiling <num2> */
491
int
492
zceiling(i_ctx_t *i_ctx_p)
493
0
{
494
0
    os_ptr op = osp;
495
496
0
    switch (r_type(op)) {
497
0
        default:
498
0
            return_op_typecheck(op);
499
0
        case t_real:
500
0
            op->value.realval = ceil(op->value.realval);
501
0
        case t_integer:;
502
0
    }
503
0
    return 0;
504
0
}
505
506
/* <num1> floor <num2> */
507
int
508
zfloor(i_ctx_t *i_ctx_p)
509
0
{
510
0
    os_ptr op = osp;
511
512
0
    switch (r_type(op)) {
513
0
        default:
514
0
            return_op_typecheck(op);
515
0
        case t_real:
516
0
            op->value.realval = floor(op->value.realval);
517
0
        case t_integer:;
518
0
    }
519
0
    return 0;
520
0
}
521
522
/* <num1> round <num2> */
523
int
524
zround(i_ctx_t *i_ctx_p)
525
0
{
526
0
    os_ptr op = osp;
527
528
0
    switch (r_type(op)) {
529
0
        default:
530
0
            return_op_typecheck(op);
531
0
        case t_real:
532
0
            op->value.realval = floor(op->value.realval + 0.5);
533
0
        case t_integer:;
534
0
    }
535
0
    return 0;
536
0
}
537
538
/* <num1> truncate <num2> */
539
int
540
ztruncate(i_ctx_t *i_ctx_p)
541
0
{
542
0
    os_ptr op = osp;
543
544
0
    switch (r_type(op)) {
545
0
        default:
546
0
            return_op_typecheck(op);
547
0
        case t_real:
548
0
            op->value.realval =
549
0
                (op->value.realval < 0.0 ?
550
0
                 ceil(op->value.realval) :
551
0
                 floor(op->value.realval));
552
0
        case t_integer:;
553
0
    }
554
0
    return 0;
555
0
}
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
};