1 /* src/vm/array.c - Java array functions
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
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.
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.
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
30 #include "native/llni.h"
33 #include "vm/exceptions.h"
34 #include "vm/global.h"
35 #include "vm/primitive.h"
39 /* array_element_get ***********************************************************
41 Returns a boxed element of the given Java array.
43 *******************************************************************************/
45 java_handle_t *array_element_get(java_handle_t *a, int32_t index)
53 exceptions_throw_nullpointerexception();
57 v = LLNI_vftbl_direct(a);
59 type = v->arraydesc->arraytype;
61 value = array_element_primitive_get(a, index);
63 o = primitive_box(type, value);
69 /* array_element_set ***********************************************************
71 Sets a boxed element in the given Java array.
73 *******************************************************************************/
75 void array_element_set(java_handle_t *a, int32_t index, java_handle_t *o)
79 value = primitive_unbox(o);
81 array_element_primitive_set(a, index, value);
85 /* array_element_primitive_get *************************************************
87 Returns a primitive element of the given Java array.
89 *******************************************************************************/
91 imm_union array_element_primitive_get(java_handle_t *a, int32_t index)
98 exceptions_throw_nullpointerexception();
103 v = LLNI_vftbl_direct(a);
105 type = v->arraydesc->arraytype;
108 case ARRAYTYPE_BOOLEAN:
109 value.i = array_booleanarray_element_get((java_handle_booleanarray_t *) a, index);
112 value.i = array_bytearray_element_get((java_handle_bytearray_t *) a,
116 value.i = array_chararray_element_get((java_handle_chararray_t *) a,
119 case ARRAYTYPE_SHORT:
120 value.i = array_shortarray_element_get((java_handle_shortarray_t *) a,
124 value.i = array_intarray_element_get((java_handle_intarray_t *) a,
128 value.l = array_longarray_element_get((java_handle_longarray_t *) a,
131 case ARRAYTYPE_FLOAT:
132 value.f = array_floatarray_element_get((java_handle_floatarray_t *) a,
135 case ARRAYTYPE_DOUBLE:
136 value.d = array_doublearray_element_get((java_handle_doublearray_t *) a,
139 case ARRAYTYPE_OBJECT:
140 value.a = array_objectarray_element_get((java_handle_objectarray_t *) a,
144 vm_abort("array_element_primitive_get: invalid array element type %d",
152 /* array_element_primitive_set *************************************************
154 Sets a primitive element in the given Java array.
156 *******************************************************************************/
158 void array_element_primitive_set(java_handle_t *a, int32_t index, imm_union value)
164 exceptions_throw_nullpointerexception();
168 v = LLNI_vftbl_direct(a);
170 type = v->arraydesc->arraytype;
173 case ARRAYTYPE_BOOLEAN:
174 array_booleanarray_element_set((java_handle_booleanarray_t *) a,
178 array_bytearray_element_set((java_handle_bytearray_t *) a,
182 array_chararray_element_set((java_handle_chararray_t *) a,
185 case ARRAYTYPE_SHORT:
186 array_shortarray_element_set((java_handle_shortarray_t *) a,
190 array_intarray_element_set((java_handle_intarray_t *) a,
194 array_longarray_element_set((java_handle_longarray_t *) a,
197 case ARRAYTYPE_FLOAT:
198 array_floatarray_element_set((java_handle_floatarray_t *) a,
201 case ARRAYTYPE_DOUBLE:
202 array_doublearray_element_set((java_handle_doublearray_t *) a,
205 case ARRAYTYPE_OBJECT:
206 array_objectarray_element_set((java_handle_objectarray_t *) a,
210 vm_abort("array_element_primitive_set: invalid array element type %d",
216 /* array_xxxarray_element_get **************************************************
218 Returns a primitive element of the given Java array.
220 *******************************************************************************/
222 #define ARRAY_TYPEARRAY_ELEMENT_GET(name, type) \
223 type array_##name##array_element_get(java_handle_##name##array_t *a, int32_t index) \
229 exceptions_throw_nullpointerexception(); \
233 size = LLNI_array_size(a); \
235 if ((index < 0) || (index >= size)) { \
236 exceptions_throw_arrayindexoutofboundsexception(); \
240 value = LLNI_array_direct(a, index); \
245 java_handle_t *array_objectarray_element_get(java_handle_objectarray_t *a, int32_t index)
247 java_handle_t *value;
251 exceptions_throw_nullpointerexception();
255 size = LLNI_array_size(a);
257 if ((index < 0) || (index >= size)) {
258 exceptions_throw_arrayindexoutofboundsexception();
263 value = LLNI_WRAP(LLNI_array_direct(a, index));
269 ARRAY_TYPEARRAY_ELEMENT_GET(boolean, uint8_t)
270 ARRAY_TYPEARRAY_ELEMENT_GET(byte, int8_t)
271 ARRAY_TYPEARRAY_ELEMENT_GET(char, uint16_t)
272 ARRAY_TYPEARRAY_ELEMENT_GET(short, int16_t)
273 ARRAY_TYPEARRAY_ELEMENT_GET(int, int32_t)
274 ARRAY_TYPEARRAY_ELEMENT_GET(long, int64_t)
275 ARRAY_TYPEARRAY_ELEMENT_GET(float, float)
276 ARRAY_TYPEARRAY_ELEMENT_GET(double, double)
279 /* array_xxxarray_element_set **************************************************
281 Sets a primitive element in the given Java array.
283 *******************************************************************************/
285 #define ARRAY_TYPEARRAY_ELEMENT_SET(name, type) \
286 void array_##name##array_element_set(java_handle_##name##array_t *a, int32_t index, type value) \
291 exceptions_throw_nullpointerexception(); \
295 size = LLNI_array_size(a); \
297 if ((index < 0) || (index >= size)) { \
298 exceptions_throw_arrayindexoutofboundsexception(); \
302 LLNI_array_direct(a, index) = value; \
305 void array_objectarray_element_set(java_handle_objectarray_t *a, int32_t index, java_handle_t *value)
312 exceptions_throw_nullpointerexception();
316 /* TODO Write inline functions for that and use LLNI. */
320 ad = a->header.objheader.vftbl->arraydesc;
321 cc = ad->componentvftbl->class;
325 if (ad->arraytype == ARRAYTYPE_OBJECT) {
327 if (builtin_instanceof(value, cc) == false) {
328 exceptions_throw_illegalargumentexception();
334 size = LLNI_array_size(a);
336 if ((index < 0) || (index >= size)) {
337 exceptions_throw_arrayindexoutofboundsexception();
342 LLNI_array_direct(a, index) = LLNI_UNWRAP(value);
346 ARRAY_TYPEARRAY_ELEMENT_SET(boolean, uint8_t)
347 ARRAY_TYPEARRAY_ELEMENT_SET(byte, int8_t)
348 ARRAY_TYPEARRAY_ELEMENT_SET(char, uint16_t)
349 ARRAY_TYPEARRAY_ELEMENT_SET(short, int16_t)
350 ARRAY_TYPEARRAY_ELEMENT_SET(int, int32_t)
351 ARRAY_TYPEARRAY_ELEMENT_SET(long, int64_t)
352 ARRAY_TYPEARRAY_ELEMENT_SET(float, float)
353 ARRAY_TYPEARRAY_ELEMENT_SET(double, double)
356 /* array_length_get ***********************************************************
358 Returns a the length of the given Java array.
364 0 ... exception thrown
365 >0 ... length of the Java array
367 *******************************************************************************/
369 int32_t array_length_get(java_handle_t *a)
375 exceptions_throw_nullpointerexception();
379 LLNI_class_get(a, c);
381 if (!class_is_array(c)) {
382 /* exceptions_throw_illegalargumentexception("Argument is not an array"); */
383 exceptions_throw_illegalargumentexception();
387 size = LLNI_array_size(a);
389 if ((size <= 0) || (size > /* MAX_DIM */ 255)) {
390 exceptions_throw_illegalargumentexception();
399 * These are local overrides for various environment variables in Emacs.
400 * Please do not remove this and leave it at the end of the file, where
401 * Emacs will automagically detect them.
402 * ---------------------------------------------------------------------
405 * indent-tabs-mode: t
409 * vim:noexpandtab:sw=4:ts=4: