1 /* Copyright (C) 1989, 1992, 1993, 1999 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: zarray.c,v 1.5 2004/08/04 19:36:13 stefan Exp $ */
18 /* Array operators */
19 #include "memory_.h"
20 #include "ghost.h"
21 #include "ialloc.h"
22 #include "ipacked.h"
23 #include "oper.h"
24 #include "store.h"
25
26 /* The generic operators (copy, get, put, getinterval, putinterval, */
27 /* length, and forall) are implemented in zgeneric.c. */
28
29 /* <int> array <array> */
30 int
zarray(i_ctx_t * i_ctx_p)31 zarray(i_ctx_t *i_ctx_p)
32 {
33 os_ptr op = osp;
34 uint size;
35 int code;
36
37 check_int_leu(*op, max_array_size);
38 size = op->value.intval;
39 code = ialloc_ref_array((ref *)op, a_all, size, "array");
40 if (code < 0)
41 return code;
42 refset_null(op->value.refs, size);
43 return 0;
44 }
45
46 /* <array> aload <obj_0> ... <obj_n-1> <array> */
47 private int
zaload(i_ctx_t * i_ctx_p)48 zaload(i_ctx_t *i_ctx_p)
49 {
50 os_ptr op = osp;
51 ref aref;
52 uint asize;
53
54 ref_assign(&aref, op);
55 if (!r_is_array(&aref))
56 return_op_typecheck(op);
57 check_read(aref);
58 asize = r_size(&aref);
59 if (asize > ostop - op) { /* Use the slow, general algorithm. */
60 int code = ref_stack_push(&o_stack, asize);
61 uint i;
62 const ref_packed *packed = aref.value.packed;
63
64 if (code < 0)
65 return code;
66 for (i = asize; i > 0; i--, packed = packed_next(packed))
67 packed_get(imemory, packed, ref_stack_index(&o_stack, i));
68 *osp = aref;
69 return 0;
70 }
71 if (r_has_type(&aref, t_array))
72 memcpy(op, aref.value.refs, asize * sizeof(ref));
73 else {
74 uint i;
75 const ref_packed *packed = aref.value.packed;
76 os_ptr pdest = op;
77
78 for (i = 0; i < asize; i++, pdest++, packed = packed_next(packed))
79 packed_get(imemory, packed, pdest);
80 }
81 push(asize);
82 ref_assign(op, &aref);
83 return 0;
84 }
85
86 /* <obj_0> ... <obj_n-1> <array> astore <array> */
87 private int
zastore(i_ctx_t * i_ctx_p)88 zastore(i_ctx_t *i_ctx_p)
89 {
90 os_ptr op = osp;
91 uint size;
92 int code;
93
94 check_write_type(*op, t_array);
95 size = r_size(op);
96 if (size > op - osbot) {
97 /* The store operation might involve other stack segments. */
98 ref arr;
99
100 if (size >= ref_stack_count(&o_stack))
101 return_error(e_stackunderflow);
102 arr = *op;
103 code = ref_stack_store(&o_stack, &arr, size, 1, 0, true, idmemory,
104 "astore");
105 if (code < 0)
106 return code;
107 ref_stack_pop(&o_stack, size);
108 *ref_stack_index(&o_stack, 0) = arr;
109 } else {
110 code = refcpy_to_old(op, 0, op - size, size, idmemory, "astore");
111 if (code < 0)
112 return code;
113 op[-(int)size] = *op;
114 pop(size);
115 }
116 return 0;
117 }
118
119 /* ------ Initialization procedure ------ */
120
121 const op_def zarray_op_defs[] =
122 {
123 {"1aload", zaload},
124 {"1array", zarray},
125 {"1astore", zastore},
126 op_def_end(0)
127 };
128