Coverage Report

Created: 2025-06-10 06:58

/src/ghostpdl/psi/zarray.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2023 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.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
/* Array operators */
18
#include "memory_.h"
19
#include "ghost.h"
20
#include "ialloc.h"
21
#include "ipacked.h"
22
#include "oper.h"
23
#include "store.h"
24
25
/* The generic operators (copy, get, put, getinterval, putinterval, */
26
/* length, and forall) are implemented in zgeneric.c. */
27
28
/* <int> array <array> */
29
int
30
zarray(i_ctx_t *i_ctx_p)
31
46.5M
{
32
46.5M
    os_ptr op = osp;
33
46.5M
    uint size;
34
46.5M
    int code;
35
36
46.5M
    check_op(1);
37
46.5M
    check_type(*op, t_integer);
38
46.5M
    if (op->value.intval < 0)
39
3
        return_error(gs_error_rangecheck);
40
46.5M
    if (op->value.intval > max_array_size)
41
0
        return_error(gs_error_limitcheck);
42
46.5M
    size = op->value.intval;
43
46.5M
    code = ialloc_ref_array((ref *)op, a_all, size, "array");
44
46.5M
    if (code < 0)
45
0
        return code;
46
46.5M
    refset_null(op->value.refs, size);
47
46.5M
    return 0;
48
46.5M
}
49
50
/* <array> aload <obj_0> ... <obj_n-1> <array> */
51
static int
52
zaload(i_ctx_t *i_ctx_p)
53
12.6M
{
54
12.6M
    os_ptr op = osp;
55
12.6M
    ref aref;
56
12.6M
    uint asize;
57
58
12.6M
    check_op(1);
59
12.6M
    ref_assign(&aref, op);
60
12.6M
    if (!r_is_array(&aref))
61
12.6M
        return_op_typecheck(op);
62
12.6M
    check_read(aref);
63
12.6M
    asize = r_size(&aref);
64
12.6M
    if (asize > ostop - op) { /* Use the slow, general algorithm. */
65
102
        int code = ref_stack_push(&o_stack, asize);
66
102
        uint i;
67
102
        const ref_packed *packed = aref.value.packed;
68
69
102
        if (code < 0)
70
0
            return code;
71
1.20M
        for (i = asize; i > 0; i--, packed = packed_next(packed)) {
72
1.20M
            ref *o = ref_stack_index(&o_stack, i);
73
1.20M
            if (o == NULL)
74
0
                continue;
75
1.20M
            packed_get(imemory, packed, o);
76
1.20M
        }
77
102
        *osp = aref;
78
102
        return 0;
79
102
    }
80
12.6M
    if (r_has_type(&aref, t_array))
81
12.5M
        memcpy(op, aref.value.refs, asize * sizeof(ref));
82
113k
    else {
83
113k
        uint i;
84
113k
        const ref_packed *packed = aref.value.packed;
85
113k
        os_ptr pdest = op;
86
87
2.33M
        for (i = 0; i < asize; i++, pdest++, packed = packed_next(packed))
88
2.22M
            packed_get(imemory, packed, pdest);
89
113k
    }
90
12.6M
    push(asize);
91
12.6M
    ref_assign(op, &aref);
92
12.6M
    return 0;
93
12.6M
}
94
95
/* <obj_0> ... <obj_n-1> <array> astore <array> */
96
static int
97
zastore(i_ctx_t *i_ctx_p)
98
44.8M
{
99
44.8M
    os_ptr op = osp;
100
44.8M
    uint size;
101
44.8M
    int code;
102
103
44.8M
    check_op(1);
104
44.8M
    if (!r_is_array(op))
105
44.8M
        return_op_typecheck(op);
106
44.8M
    size = r_size(op);
107
    /* Amazingly, the following is valid: 0 array noaccess astore */
108
44.8M
    if (size == 0)
109
228k
        return 0;
110
44.6M
    if (!r_has_type_attrs(op, t_array, a_write))
111
0
        return_error(gs_error_invalidaccess);
112
44.6M
    if (size > op - osbot) {
113
        /* The store operation might involve other stack segments. */
114
11.4k
        ref arr, *o;
115
116
11.4k
        if (size >= ref_stack_count(&o_stack))
117
0
            return_error(gs_error_stackunderflow);
118
11.4k
        arr = *op;
119
11.4k
        code = ref_stack_store(&o_stack, &arr, size, 1, 0, true, idmemory,
120
11.4k
                               "astore");
121
11.4k
        if (code < 0)
122
0
            return code;
123
11.4k
        ref_stack_pop(&o_stack, size);
124
11.4k
        o = ref_stack_index(&o_stack, 0);
125
11.4k
        if (o == NULL)
126
0
            return_error(gs_error_stackunderflow);
127
11.4k
        *o = arr;
128
44.6M
    } else {
129
44.6M
        code = refcpy_to_old(op, 0, op - size, size, idmemory, "astore");
130
44.6M
        if (code < 0)
131
0
            return code;
132
44.6M
        op[-(int)size] = *op;
133
44.6M
        pop(size);
134
44.6M
    }
135
44.6M
    return 0;
136
44.6M
}
137
138
/* ------ Initialization procedure ------ */
139
140
const op_def zarray_op_defs[] =
141
{
142
    {"1aload", zaload},
143
    {"1array", zarray},
144
    {"1astore", zastore},
145
    op_def_end(0)
146
};