1 /* src/vm/array.hpp - Java array functions
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 Copyright (C) 2008 Theobroma Systems Ltd.
7 This file is part of CACAO.
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2, or (at
12 your option) any later version.
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
34 #include "mm/gc.hpp" // XXX Remove me!
36 #include "native/llni.h" // XXX Remove me!
38 #include "vm/class.hpp"
39 #include "vm/exceptions.hpp"
40 #include "vm/global.h"
41 #include "vm/primitive.hpp"
44 /* array types ****************************************************************/
46 /* CAUTION: Don't change the numerical values! These constants (with
47 the exception of ARRAYTYPE_OBJECT) are used as indices in the
48 primitive type table. */
50 #define ARRAYTYPE_INT PRIMITIVETYPE_INT
51 #define ARRAYTYPE_LONG PRIMITIVETYPE_LONG
52 #define ARRAYTYPE_FLOAT PRIMITIVETYPE_FLOAT
53 #define ARRAYTYPE_DOUBLE PRIMITIVETYPE_DOUBLE
54 #define ARRAYTYPE_BYTE PRIMITIVETYPE_BYTE
55 #define ARRAYTYPE_CHAR PRIMITIVETYPE_CHAR
56 #define ARRAYTYPE_SHORT PRIMITIVETYPE_SHORT
57 #define ARRAYTYPE_BOOLEAN PRIMITIVETYPE_BOOLEAN
58 #define ARRAYTYPE_OBJECT PRIMITIVETYPE_VOID /* don't use as index! */
64 * This is a generic accessor class for Java arrays (of unspecified type),
65 * which can be used to safely operate on Java arrays in native code.
69 // Handle of Java array.
70 java_handle_array_t* _handle;
73 // We don't want a Java arrays to be copied.
78 inline Array(java_handle_t* h);
79 inline Array(int32_t length, classinfo* arrayclass);
83 virtual inline java_handle_array_t* get_handle() const { return _handle; }
84 inline int32_t get_length() const;
86 inline bool is_null () const;
87 inline bool is_non_null() const;
89 // Safe element modification functions for primitive values
90 imm_union get_primitive_element(int32_t index);
91 void set_primitive_element(int32_t index, imm_union value);
93 // Safe element modification functions for boxed values
94 java_handle_t* get_boxed_element(int32_t index);
95 void set_boxed_element(int32_t index, java_handle_t *o);
98 inline void* get_raw_data_ptr() { return ((java_objectarray_t*) _handle)->data; }
103 * Constructor checks if passed handle really is a Java array.
105 inline Array::Array(java_handle_t* h)
114 LLNI_class_get(h, c);
115 if (!class_is_array(c)) {
116 printf("Array::Array(): WARNING, passed handle is not an array\n");
117 //exceptions_throw_illegalargumentexception("Argument is not an array");
118 exceptions_throw_illegalargumentexception();
128 * Creates an array of the given array type on the heap.
129 * The handle pointer to the array can be NULL in case of an exception.
131 inline Array::Array(int32_t size, classinfo* arrayclass)
134 assert(class_is_array(arrayclass));
137 exceptions_throw_negativearraysizeexception();
142 arraydescriptor* desc = arrayclass->vftbl->arraydesc;
143 int32_t dataoffset = desc->dataoffset;
144 int32_t componentsize = desc->componentsize;
145 int32_t actualsize = dataoffset + size * componentsize;
147 // Check for overflow.
149 if (((u4) actualsize) < ((u4) size)) {
150 exceptions_throw_outofmemoryerror();
155 java_array_t* a = (java_array_t*) heap_alloc(actualsize, (desc->arraytype == ARRAYTYPE_OBJECT), NULL, true);
162 LLNI_vftbl_direct(a) = arrayclass->vftbl;
164 #if defined(ENABLE_THREADS)
165 a->objheader.lockword.init();
170 _handle = (java_handle_array_t*) a;
173 inline int32_t Array::get_length() const
176 printf("Array::get_length(): WARNING, got null-pointer\n");
177 exceptions_throw_nullpointerexception();
182 int32_t length = ((java_array_t*) _handle)->size;
187 inline bool Array::is_null() const
189 return (_handle == NULL);
192 inline bool Array::is_non_null() const
194 return (_handle != NULL);
199 * This is a template of an accessor class for Java arrays
200 * of a specific type.
202 template<class T> class ArrayTemplate : public Array {
204 ArrayTemplate(int32_t length, classinfo* arrayclass) : Array(length, arrayclass) {}
207 inline ArrayTemplate(java_handle_array_t* h) : Array(h) {}
209 // Safe element modification functions
210 inline T get_element(int32_t index);
211 inline void set_element(int32_t index, T value);
213 // Region copy functions
214 inline void get_region(int32_t offset, int32_t count, T* buffer);
215 inline void set_region(int32_t offset, int32_t count, const T* buffer);
219 template<class T> inline T ArrayTemplate<T>::get_element(int32_t index)
222 exceptions_throw_nullpointerexception();
226 if ((index < 0) || (index >= get_length())) {
227 exceptions_throw_arrayindexoutofboundsexception();
232 T* ptr = (T*) get_raw_data_ptr();
237 template<class T> inline void ArrayTemplate<T>::set_element(int32_t index, T value)
240 exceptions_throw_nullpointerexception();
244 if ((index < 0) || (index >= get_length())) {
245 exceptions_throw_arrayindexoutofboundsexception();
250 T* ptr = (T*) get_raw_data_ptr();
255 template<> inline void ArrayTemplate<java_handle_t*>::set_element(int32_t index, java_handle_t* value)
258 exceptions_throw_nullpointerexception();
263 assert(((java_array_t*) _handle)->objheader.vftbl->arraydesc->arraytype == ARRAYTYPE_OBJECT);
265 // Check if value can be stored
267 if (builtin_canstore(get_handle(), value) == false) {
268 exceptions_throw_illegalargumentexception();
273 if ((index < 0) || (index >= get_length())) {
274 exceptions_throw_arrayindexoutofboundsexception();
279 java_handle_t** ptr = (java_handle_t**) get_raw_data_ptr();
284 template<class T> inline void ArrayTemplate<T>::get_region(int32_t offset, int32_t count, T* buffer)
286 // Copy the array region inside a GC critical section.
287 GCCriticalSection cs;
290 const T* ptr = (T*) get_raw_data_ptr();
292 os::memcpy(buffer, ptr + offset, sizeof(T) * count);
295 template<class T> inline void ArrayTemplate<T>::set_region(int32_t offset, int32_t count, const T* buffer)
297 // Copy the array region inside a GC critical section.
298 GCCriticalSection cs;
301 T* ptr = (T*) get_raw_data_ptr();
303 os::memcpy(ptr + offset, buffer, sizeof(T) * count);
308 * Actual implementations of common Java array access classes.
310 class BooleanArray : public ArrayTemplate<uint8_t> {
312 inline BooleanArray(java_handle_booleanarray_t* h) : ArrayTemplate<uint8_t>(h) {}
313 inline BooleanArray(int32_t length) : ArrayTemplate<uint8_t>(length, primitivetype_table[ARRAYTYPE_BOOLEAN].arrayclass) {}
316 class ByteArray : public ArrayTemplate<int8_t> {
318 inline ByteArray(java_handle_bytearray_t* h) : ArrayTemplate<int8_t>(h) {}
319 inline ByteArray(int32_t length) : ArrayTemplate<int8_t>(length, primitivetype_table[ARRAYTYPE_BYTE].arrayclass) {}
322 class CharArray : public ArrayTemplate<uint16_t> {
324 inline CharArray(java_handle_chararray_t* h) : ArrayTemplate<uint16_t>(h) {}
325 inline CharArray(int32_t length) : ArrayTemplate<uint16_t>(length, primitivetype_table[ARRAYTYPE_CHAR].arrayclass) {}
328 class ShortArray : public ArrayTemplate<int16_t> {
330 inline ShortArray(java_handle_shortarray_t* h) : ArrayTemplate<int16_t>(h) {}
331 inline ShortArray(int32_t length) : ArrayTemplate<int16_t>(length, primitivetype_table[ARRAYTYPE_SHORT].arrayclass) {}
334 class IntArray : public ArrayTemplate<int32_t> {
336 inline IntArray(java_handle_intarray_t* h) : ArrayTemplate<int32_t>(h) {}
337 inline IntArray(int32_t length) : ArrayTemplate<int32_t>(length, primitivetype_table[ARRAYTYPE_INT].arrayclass) {}
340 class LongArray : public ArrayTemplate<int64_t> {
342 inline LongArray(java_handle_longarray_t* h) : ArrayTemplate<int64_t>(h) {}
343 inline LongArray(int32_t length) : ArrayTemplate<int64_t>(length, primitivetype_table[ARRAYTYPE_LONG].arrayclass) {}
346 class FloatArray : public ArrayTemplate<float> {
348 inline FloatArray(java_handle_floatarray_t* h) : ArrayTemplate<float>(h) {}
349 inline FloatArray(int32_t length) : ArrayTemplate<float>(length, primitivetype_table[ARRAYTYPE_FLOAT].arrayclass) {}
352 class DoubleArray : public ArrayTemplate<double> {
354 inline DoubleArray(java_handle_doublearray_t* h) : ArrayTemplate<double>(h) {}
355 inline DoubleArray(int32_t length) : ArrayTemplate<double>(length, primitivetype_table[ARRAYTYPE_DOUBLE].arrayclass) {}
359 * Actual implementation of access class for Java Object arrays.
361 class ObjectArray : public ArrayTemplate<java_handle_t*> {
363 inline ObjectArray(java_handle_objectarray_t* h) : ArrayTemplate<java_handle_t*>(h) {}
364 ObjectArray(int32_t length, classinfo* componentclass);
368 * Actual implementation of access class for java.lang.Class arrays.
370 class ClassArray : public ArrayTemplate<classinfo*> {
372 ClassArray(int32_t length);
377 # warning No legacy C functions for array access classes.
380 #endif // _VM_ARRAY_HPP
384 * These are local overrides for various environment variables in Emacs.
385 * Please do not remove this and leave it at the end of the file, where
386 * Emacs will automagically detect them.
387 * ---------------------------------------------------------------------
390 * indent-tabs-mode: t
394 * vim:noexpandtab:sw=4:ts=4: