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