1 /* Copyright (C) 1989, 1992, 1993, 1999 artofcode LLC. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify it
4 under the terms of the GNU General Public License as published by the
5 Free Software Foundation; either version 2 of the License, or (at your
6 option) any later version.
7
8 This program is distributed in the hope that it will be useful, but
9 WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 General Public License for more details.
12
13 You should have received a copy of the GNU General Public License along
14 with this program; if not, write to the Free Software Foundation, Inc.,
15 59 Temple Place, Suite 330, Boston, MA, 02111-1307.
16
17 */
18
19 /*$Id: zarray.c,v 1.2.6.1.2.1 2003/01/17 00:49:05 giles Exp $ */
20 /* Array operators */
21 #include "memory_.h"
22 #include "ghost.h"
23 #include "ialloc.h"
24 #include "ipacked.h"
25 #include "oper.h"
26 #include "store.h"
27
28 /* The generic operators (copy, get, put, getinterval, putinterval, */
29 /* length, and forall) are implemented in zgeneric.c. */
30
31 /* <int> array <array> */
32 int
zarray(i_ctx_t * i_ctx_p)33 zarray(i_ctx_t *i_ctx_p)
34 {
35 os_ptr op = osp;
36 uint size;
37 int code;
38
39 check_int_leu(*op, max_array_size);
40 size = op->value.intval;
41 code = ialloc_ref_array((ref *)op, a_all, size, "array");
42 if (code < 0)
43 return code;
44 refset_null(op->value.refs, size);
45 return 0;
46 }
47
48 /* <array> aload <obj_0> ... <obj_n-1> <array> */
49 private int
zaload(i_ctx_t * i_ctx_p)50 zaload(i_ctx_t *i_ctx_p)
51 {
52 os_ptr op = osp;
53 ref aref;
54 uint asize;
55
56 ref_assign(&aref, op);
57 if (!r_is_array(&aref))
58 return_op_typecheck(op);
59 check_read(aref);
60 asize = r_size(&aref);
61 if (asize > ostop - op) { /* Use the slow, general algorithm. */
62 int code = ref_stack_push(&o_stack, asize);
63 uint i;
64 const ref_packed *packed = aref.value.packed;
65
66 if (code < 0)
67 return code;
68 for (i = asize; i > 0; i--, packed = packed_next(packed))
69 packed_get(packed, ref_stack_index(&o_stack, i));
70 *osp = aref;
71 return 0;
72 }
73 if (r_has_type(&aref, t_array))
74 memcpy(op, aref.value.refs, asize * sizeof(ref));
75 else {
76 uint i;
77 const ref_packed *packed = aref.value.packed;
78 os_ptr pdest = op;
79
80 for (i = 0; i < asize; i++, pdest++, packed = packed_next(packed))
81 packed_get(packed, pdest);
82 }
83 push(asize);
84 ref_assign(op, &aref);
85 return 0;
86 }
87
88 /* <obj_0> ... <obj_n-1> <array> astore <array> */
89 private int
zastore(i_ctx_t * i_ctx_p)90 zastore(i_ctx_t *i_ctx_p)
91 {
92 os_ptr op = osp;
93 uint size;
94 int code;
95
96 check_write_type(*op, t_array);
97 size = r_size(op);
98 if (size > op - osbot) {
99 /* The store operation might involve other stack segments. */
100 ref arr;
101
102 if (size >= ref_stack_count(&o_stack))
103 return_error(e_stackunderflow);
104 arr = *op;
105 code = ref_stack_store(&o_stack, &arr, size, 1, 0, true, idmemory,
106 "astore");
107 if (code < 0)
108 return code;
109 ref_stack_pop(&o_stack, size);
110 *ref_stack_index(&o_stack, 0) = arr;
111 } else {
112 code = refcpy_to_old(op, 0, op - size, size, idmemory, "astore");
113 if (code < 0)
114 return code;
115 op[-(int)size] = *op;
116 pop(size);
117 }
118 return 0;
119 }
120
121 /* ------ Initialization procedure ------ */
122
123 const op_def zarray_op_defs[] =
124 {
125 {"1aload", zaload},
126 {"1array", zarray},
127 {"1astore", zastore},
128 op_def_end(0)
129 };
130