Coverage Report

Created: 2025-04-22 06:20

/src/libspectre/ghostscript/psi/zarray.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2020 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
/* 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
1.17M
{
32
1.17M
    os_ptr op = osp;
33
1.17M
    uint size;
34
1.17M
    int code;
35
36
1.17M
    check_type(*op, t_integer);
37
1.17M
    if (op->value.intval < 0)
38
0
        return_error(gs_error_rangecheck);
39
1.17M
    if (op->value.intval > max_array_size)
40
0
        return_error(gs_error_limitcheck);
41
1.17M
    size = op->value.intval;
42
1.17M
    code = ialloc_ref_array((ref *)op, a_all, size, "array");
43
1.17M
    if (code < 0)
44
0
        return code;
45
1.17M
    refset_null(op->value.refs, size);
46
1.17M
    return 0;
47
1.17M
}
48
49
/* <array> aload <obj_0> ... <obj_n-1> <array> */
50
static int
51
zaload(i_ctx_t *i_ctx_p)
52
245k
{
53
245k
    os_ptr op = osp;
54
245k
    ref aref;
55
245k
    uint asize;
56
57
245k
    ref_assign(&aref, op);
58
245k
    if (!r_is_array(&aref))
59
245k
        return_op_typecheck(op);
60
245k
    check_read(aref);
61
245k
    asize = r_size(&aref);
62
245k
    if (asize > ostop - op) { /* Use the slow, general algorithm. */
63
0
        int code = ref_stack_push(&o_stack, asize);
64
0
        uint i;
65
0
        const ref_packed *packed = aref.value.packed;
66
67
0
        if (code < 0)
68
0
            return code;
69
0
        for (i = asize; i > 0; i--, packed = packed_next(packed))
70
0
            packed_get(imemory, packed, ref_stack_index(&o_stack, i));
71
0
        *osp = aref;
72
0
        return 0;
73
0
    }
74
245k
    if (r_has_type(&aref, t_array))
75
243k
        memcpy(op, aref.value.refs, asize * sizeof(ref));
76
2.39k
    else {
77
2.39k
        uint i;
78
2.39k
        const ref_packed *packed = aref.value.packed;
79
2.39k
        os_ptr pdest = op;
80
81
49.4k
        for (i = 0; i < asize; i++, pdest++, packed = packed_next(packed))
82
47.0k
            packed_get(imemory, packed, pdest);
83
2.39k
    }
84
245k
    push(asize);
85
245k
    ref_assign(op, &aref);
86
245k
    return 0;
87
245k
}
88
89
/* <obj_0> ... <obj_n-1> <array> astore <array> */
90
static int
91
zastore(i_ctx_t *i_ctx_p)
92
1.14M
{
93
1.14M
    os_ptr op = osp;
94
1.14M
    uint size;
95
1.14M
    int code;
96
97
1.14M
    if (!r_is_array(op))
98
1.14M
        return_op_typecheck(op);
99
1.14M
    size = r_size(op);
100
    /* Amazingly, the following is valid: 0 array noaccess astore */
101
1.14M
    if (size == 0)
102
4.57k
        return 0;
103
1.13M
    if (!r_has_type_attrs(op, t_array, a_write))
104
0
        return_error(gs_error_invalidaccess);
105
1.13M
    if (size > op - osbot) {
106
        /* The store operation might involve other stack segments. */
107
218
        ref arr;
108
109
218
        if (size >= ref_stack_count(&o_stack))
110
0
            return_error(gs_error_stackunderflow);
111
218
        arr = *op;
112
218
        code = ref_stack_store(&o_stack, &arr, size, 1, 0, true, idmemory,
113
218
                               "astore");
114
218
        if (code < 0)
115
0
            return code;
116
218
        ref_stack_pop(&o_stack, size);
117
218
        *ref_stack_index(&o_stack, 0) = arr;
118
1.13M
    } else {
119
1.13M
        code = refcpy_to_old(op, 0, op - size, size, idmemory, "astore");
120
1.13M
        if (code < 0)
121
0
            return code;
122
1.13M
        op[-(int)size] = *op;
123
1.13M
        pop(size);
124
1.13M
    }
125
1.13M
    return 0;
126
1.13M
}
127
128
/* ------ Initialization procedure ------ */
129
130
const op_def zarray_op_defs[] =
131
{
132
    {"1aload", zaload},
133
    {"1array", zarray},
134
    {"1astore", zastore},
135
    op_def_end(0)
136
};