* Removed all Id tags.
[cacao.git] / src / vm / array.c
1 /* src/vm/array.c - array functions
2
3    Copyright (C) 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25 */
26
27
28 #include "config.h"
29
30 #include <stdint.h>
31
32 #include "native/llni.h"
33
34 #include "vm/array.h"
35 #include "vm/exceptions.h"
36 #include "vm/global.h"
37 #include "vm/primitive.h"
38 #include "vm/vm.h"
39
40
41 /* array_element_get ***********************************************************
42
43    Returns a boxed element of the given Java array.
44
45 *******************************************************************************/
46
47 java_handle_t *array_element_get(java_handle_t *a, int32_t index)
48 {
49         vftbl_t       *v;
50         int            type;
51         imm_union      value;
52         java_handle_t *o;
53
54         v = LLNI_vftbl_direct(a);
55
56         type = v->arraydesc->arraytype;
57
58         value = array_element_primitive_get(a, index);
59
60         o = primitive_box(type, value);
61
62         return o;
63 }
64
65
66 /* array_element_set ***********************************************************
67
68    Sets a boxed element in the given Java array.
69
70 *******************************************************************************/
71
72 void array_element_set(java_handle_t *a, int32_t index, java_handle_t *o)
73 {
74         imm_union value;
75
76         value = primitive_unbox(o);
77
78         array_element_primitive_set(a, index, value);
79 }
80
81
82 /* array_element_primitive_get *************************************************
83
84    Returns a primitive element of the given Java array.
85
86 *******************************************************************************/
87
88 imm_union array_element_primitive_get(java_handle_t *a, int32_t index)
89 {
90         vftbl_t  *v;
91         int       type;
92         imm_union value;
93
94         v = LLNI_vftbl_direct(a);
95
96         type = v->arraydesc->arraytype;
97
98         switch (type) {
99         case ARRAYTYPE_BOOLEAN:
100                 value.i = array_booleanarray_element_get((java_handle_booleanarray_t *) a, index);
101                 break;
102         case ARRAYTYPE_BYTE:
103                 value.i = array_bytearray_element_get((java_handle_bytearray_t *) a,
104                                                                                           index);
105                 break;
106         case ARRAYTYPE_CHAR:
107                 value.i = array_chararray_element_get((java_handle_chararray_t *) a,
108                                                                                           index);
109                 break;
110         case ARRAYTYPE_SHORT:
111                 value.i = array_shortarray_element_get((java_handle_shortarray_t *) a,
112                                                                                            index);
113                 break;
114         case ARRAYTYPE_INT:
115                 value.i = array_intarray_element_get((java_handle_intarray_t *) a,
116                                                                                          index);
117                 break;
118         case ARRAYTYPE_LONG:
119                 value.l = array_longarray_element_get((java_handle_longarray_t *) a,
120                                                                                           index);
121                 break;
122         case ARRAYTYPE_FLOAT:
123                 value.f = array_floatarray_element_get((java_handle_floatarray_t *) a,
124                                                                                            index);
125                 break;
126         case ARRAYTYPE_DOUBLE:
127                 value.d = array_doublearray_element_get((java_handle_doublearray_t *) a,
128                                                                                                 index);
129                 break;
130         case ARRAYTYPE_OBJECT:
131                 value.a = array_objectarray_element_get((java_handle_objectarray_t *) a,
132                                                                                                 index);
133                 break;
134         default:
135                 vm_abort("array_element_primitive_get: invalid array element type %d",
136                                  type);
137         }
138
139         return value;
140 }
141
142
143 /* array_element_primitive_set *************************************************
144
145    Sets a primitive element in the given Java array.
146
147 *******************************************************************************/
148
149 void array_element_primitive_set(java_handle_t *a, int32_t index, imm_union value)
150 {
151         vftbl_t *v;
152         int      type;
153
154         v = LLNI_vftbl_direct(a);
155
156         type = v->arraydesc->arraytype;
157
158         switch (type) {
159         case ARRAYTYPE_BOOLEAN:
160                 array_booleanarray_element_set((java_handle_booleanarray_t *) a,
161                                                                            index, value.i);
162                 break;
163         case ARRAYTYPE_BYTE:
164                 array_bytearray_element_set((java_handle_bytearray_t *) a,
165                                                                         index, value.i);
166                 break;
167         case ARRAYTYPE_CHAR:
168                 array_chararray_element_set((java_handle_chararray_t *) a,
169                                                                         index, value.i);
170                 break;
171         case ARRAYTYPE_SHORT:
172                 array_shortarray_element_set((java_handle_shortarray_t *) a,
173                                                                          index, value.i);
174                 break;
175         case ARRAYTYPE_INT:
176                 array_intarray_element_set((java_handle_intarray_t *) a,
177                                                                    index, value.i);
178                 break;
179         case ARRAYTYPE_LONG:
180                 array_longarray_element_set((java_handle_longarray_t *) a,
181                                                                         index, value.l);
182                 break;
183         case ARRAYTYPE_FLOAT:
184                 array_floatarray_element_set((java_handle_floatarray_t *) a,
185                                                                          index, value.f);
186                 break;
187         case ARRAYTYPE_DOUBLE:
188                 array_doublearray_element_set((java_handle_doublearray_t *) a,
189                                                                           index, value.d);
190                 break;
191         case ARRAYTYPE_OBJECT:
192                 array_objectarray_element_set((java_handle_objectarray_t *) a,
193                                                                           index, value.a);
194                 break;
195         default:
196                 vm_abort("array_element_primitive_set: invalid array element type %d",
197                                  type);
198         }
199 }
200
201
202 /* array_xxxarray_element_get **************************************************
203
204    Returns a primitive element of the given Java array.
205
206 *******************************************************************************/
207
208 #define ARRAY_TYPEARRAY_ELEMENT_GET(name, type)                                \
209 type array_##name##array_element_get(java_handle_##name##array_t *a, int32_t index) \
210 {                                                                              \
211         type    value;                                                             \
212         int32_t size;                                                              \
213                                                                                \
214         if (a == NULL) {                                                           \
215                 exceptions_throw_nullpointerexception();                               \
216                 return (type) 0;                                                       \
217         }                                                                          \
218                                                                                \
219         size = LLNI_array_size(a);                                                 \
220                                                                                \
221         if ((index < 0) || (index > size)) {                                       \
222                 exceptions_throw_arrayindexoutofboundsexception();                     \
223                 return (type) 0;                                                       \
224         }                                                                          \
225                                                                                \
226         value = LLNI_array_direct(a, index);                                       \
227                                                                                \
228         return value;                                                              \
229 }
230
231 ARRAY_TYPEARRAY_ELEMENT_GET(boolean, uint8_t)
232 ARRAY_TYPEARRAY_ELEMENT_GET(byte,    int8_t)
233 ARRAY_TYPEARRAY_ELEMENT_GET(char,    uint16_t)
234 ARRAY_TYPEARRAY_ELEMENT_GET(short,   int16_t)
235 ARRAY_TYPEARRAY_ELEMENT_GET(int,     int32_t)
236 ARRAY_TYPEARRAY_ELEMENT_GET(long,    int64_t)
237 ARRAY_TYPEARRAY_ELEMENT_GET(float,   float)
238 ARRAY_TYPEARRAY_ELEMENT_GET(double,  double)
239 ARRAY_TYPEARRAY_ELEMENT_GET(object,  java_handle_t*)
240
241
242 /* array_xxxarray_element_set **************************************************
243
244    Sets a primitive element in the given Java array.
245
246 *******************************************************************************/
247
248 #define ARRAY_TYPEARRAY_ELEMENT_SET(name, type)                                \
249 void array_##name##array_element_set(java_handle_##name##array_t *a, int32_t index, type value) \
250 {                                                                              \
251         int32_t size;                                                              \
252                                                                                \
253         if (a == NULL) {                                                           \
254                 exceptions_throw_nullpointerexception();                               \
255                 return;                                                                \
256         }                                                                          \
257                                                                                \
258         size = LLNI_array_size(a);                                                 \
259                                                                                \
260         if ((index < 0) || (index > size)) {                                       \
261                 exceptions_throw_arrayindexoutofboundsexception();                     \
262                 return;                                                                \
263         }                                                                          \
264                                                                                \
265         LLNI_array_direct(a, index) = value;                                       \
266 }
267
268 ARRAY_TYPEARRAY_ELEMENT_SET(boolean, uint8_t)
269 ARRAY_TYPEARRAY_ELEMENT_SET(byte,    int8_t)
270 ARRAY_TYPEARRAY_ELEMENT_SET(char,    uint16_t)
271 ARRAY_TYPEARRAY_ELEMENT_SET(short,   int16_t)
272 ARRAY_TYPEARRAY_ELEMENT_SET(int,     int32_t)
273 ARRAY_TYPEARRAY_ELEMENT_SET(long,    int64_t)
274 ARRAY_TYPEARRAY_ELEMENT_SET(float,   float)
275 ARRAY_TYPEARRAY_ELEMENT_SET(double,  double)
276 ARRAY_TYPEARRAY_ELEMENT_SET(object,  java_handle_t*)
277
278
279 /* array_length_get ***********************************************************
280
281    Returns a the length of the given Java array.
282
283 *******************************************************************************/
284
285 int32_t array_length_get(java_handle_t *a)
286 {
287         vftbl_t *v;
288         int32_t  size;
289
290         if (a == NULL) {
291                 exceptions_throw_nullpointerexception();
292                 return 0;
293         }
294
295         v = LLNI_vftbl_direct(a);
296
297         if (!class_is_array(v->class)) {
298 /*              exceptions_throw_illegalargumentexception("Argument is not an array"); */
299                 exceptions_throw_illegalargumentexception();
300                 return 0;
301         }
302
303         size = LLNI_array_size(a);
304
305         return size;
306 }
307
308
309 /*
310  * These are local overrides for various environment variables in Emacs.
311  * Please do not remove this and leave it at the end of the file, where
312  * Emacs will automagically detect them.
313  * ---------------------------------------------------------------------
314  * Local variables:
315  * mode: c
316  * indent-tabs-mode: t
317  * c-basic-offset: 4
318  * tab-width: 4
319  * End:
320  * vim:noexpandtab:sw=4:ts=4:
321  */