1 /* src/vm/array.hpp - Java array functions
3 Copyright (C) 2007, 2009
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 Array(java_handle_t* h);
79 Array(int32_t length, classinfo* arrayclass);
83 virtual java_handle_array_t* get_handle() const { return _handle; }
84 int32_t get_length() const;
87 bool is_null () const;
88 bool is_non_null() const;
90 // Safe element modification functions for primitive values
91 imm_union get_primitive_element(int32_t index);
92 void set_primitive_element(int32_t index, imm_union value);
94 // Safe element modification functions for boxed values
95 java_handle_t* get_boxed_element(int32_t index);
96 void set_boxed_element(int32_t index, java_handle_t *o);
101 * Constructor checks if passed handle really is a Java array.
103 inline Array::Array(java_handle_t* h)
112 LLNI_class_get(h, c);
113 if (!class_is_array(c)) {
114 printf("Array::Array(): WARNING, passed handle is not an array\n");
115 //exceptions_throw_illegalargumentexception("Argument is not an array");
116 exceptions_throw_illegalargumentexception();
126 * Creates an array of the given array type on the heap.
127 * The handle pointer to the array can be NULL in case of an exception.
129 inline Array::Array(int32_t size, classinfo* arrayclass)
132 assert(class_is_array(arrayclass));
135 exceptions_throw_negativearraysizeexception();
140 arraydescriptor* desc = arrayclass->vftbl->arraydesc;
141 int32_t dataoffset = desc->dataoffset;
142 int32_t componentsize = desc->componentsize;
143 int32_t actualsize = dataoffset + size * componentsize;
145 // Check for overflow.
147 if (((u4) actualsize) < ((u4) size)) {
148 exceptions_throw_outofmemoryerror();
153 java_array_t* a = (java_array_t*) heap_alloc(actualsize, (desc->arraytype == ARRAYTYPE_OBJECT), NULL, true);
160 LLNI_vftbl_direct(a) = arrayclass->vftbl;
162 #if defined(ENABLE_THREADS)
163 a->objheader.lockword.init();
168 _handle = (java_handle_array_t*) a;
171 inline int32_t Array::get_length() const
174 printf("Array::get_length(): WARNING, got null-pointer\n");
175 exceptions_throw_nullpointerexception();
180 int32_t length = ((java_array_t*) _handle)->size;
185 inline bool Array::is_null() const
187 return (_handle == NULL);
190 inline bool Array::is_non_null() const
192 return (_handle != NULL);
197 * This is a template of an accessor class for Java arrays
198 * of a specific type.
200 template<class T> class ArrayTemplate : public Array {
202 ArrayTemplate(int32_t length, classinfo* arrayclass) : Array(length, arrayclass) {}
205 ArrayTemplate(java_handle_array_t* h) : Array(h) {}
207 // XXX This should be protected or private!
208 virtual T* get_raw_data_ptr() = 0;
210 // Safe element modification functions
211 T get_element(int32_t index);
212 void set_element(int32_t index, T value);
214 // Region copy functions
215 void get_region(int32_t offset, int32_t count, T* buffer);
216 void set_region(int32_t offset, int32_t count, const T* buffer);
220 template<class T> inline T ArrayTemplate<T>::get_element(int32_t index)
223 exceptions_throw_nullpointerexception();
227 if ((index < 0) || (index >= get_length())) {
228 exceptions_throw_arrayindexoutofboundsexception();
232 T* ptr = 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();
249 T* ptr = get_raw_data_ptr();
254 template<> inline void ArrayTemplate<java_handle_t*>::set_element(int32_t index, java_handle_t* value)
257 exceptions_throw_nullpointerexception();
262 assert(((java_array_t*) get_handle())->objheader.vftbl->arraydesc->arraytype == ARRAYTYPE_OBJECT);
264 // Check if value can be stored
265 if (!builtin_canstore(get_handle(), value)) {
266 exceptions_throw_illegalargumentexception();
270 if ((index < 0) || (index >= get_length())) {
271 exceptions_throw_arrayindexoutofboundsexception();
275 java_handle_t** ptr = get_raw_data_ptr();
280 template<class T> inline void ArrayTemplate<T>::get_region(int32_t offset, int32_t count, T* buffer)
282 // Copy the array region inside a GC critical section.
283 GCCriticalSection cs;
285 const T* ptr = get_raw_data_ptr();
287 os::memcpy(buffer, ptr + offset, sizeof(T) * count);
290 template<class T> inline void ArrayTemplate<T>::set_region(int32_t offset, int32_t count, const T* buffer)
292 // Copy the array region inside a GC critical section.
293 GCCriticalSection cs;
295 T* ptr = get_raw_data_ptr();
297 os::memcpy(ptr + offset, buffer, sizeof(T) * count);
302 * Actual implementations of common Java array access classes.
304 class BooleanArray : public ArrayTemplate<uint8_t> {
306 BooleanArray(java_handle_booleanarray_t* h) : ArrayTemplate<uint8_t>(h) {}
307 BooleanArray(int32_t length) : ArrayTemplate<uint8_t>(length, primitivetype_table[ARRAYTYPE_BOOLEAN].arrayclass) {}
308 uint8_t* get_raw_data_ptr() { return ((java_booleanarray_t*) get_handle())->data; }
311 class ByteArray : public ArrayTemplate<int8_t> {
313 ByteArray(java_handle_bytearray_t* h) : ArrayTemplate<int8_t>(h) {}
314 ByteArray(int32_t length) : ArrayTemplate<int8_t>(length, primitivetype_table[ARRAYTYPE_BYTE].arrayclass) {}
315 int8_t* get_raw_data_ptr() { return (int8_t*) ((java_bytearray_t*) get_handle())->data; }
318 class CharArray : public ArrayTemplate<uint16_t> {
320 CharArray(java_handle_chararray_t* h) : ArrayTemplate<uint16_t>(h) {}
321 CharArray(int32_t length) : ArrayTemplate<uint16_t>(length, primitivetype_table[ARRAYTYPE_CHAR].arrayclass) {}
322 uint16_t* get_raw_data_ptr() { return ((java_chararray_t*) get_handle())->data; }
325 class ShortArray : public ArrayTemplate<int16_t> {
327 ShortArray(java_handle_shortarray_t* h) : ArrayTemplate<int16_t>(h) {}
328 ShortArray(int32_t length) : ArrayTemplate<int16_t>(length, primitivetype_table[ARRAYTYPE_SHORT].arrayclass) {}
329 int16_t* get_raw_data_ptr() { return ((java_shortarray_t*) get_handle())->data; }
332 class IntArray : public ArrayTemplate<int32_t> {
334 IntArray(java_handle_intarray_t* h) : ArrayTemplate<int32_t>(h) {}
335 IntArray(int32_t length) : ArrayTemplate<int32_t>(length, primitivetype_table[ARRAYTYPE_INT].arrayclass) {}
336 int32_t* get_raw_data_ptr() { return ((java_intarray_t*) get_handle())->data; }
339 class LongArray : public ArrayTemplate<int64_t> {
341 LongArray(java_handle_longarray_t* h) : ArrayTemplate<int64_t>(h) {}
342 LongArray(int32_t length) : ArrayTemplate<int64_t>(length, primitivetype_table[ARRAYTYPE_LONG].arrayclass) {}
343 int64_t* get_raw_data_ptr() { return ((java_longarray_t*) get_handle())->data; }
346 class FloatArray : public ArrayTemplate<float> {
348 FloatArray(java_handle_floatarray_t* h) : ArrayTemplate<float>(h) {}
349 FloatArray(int32_t length) : ArrayTemplate<float>(length, primitivetype_table[ARRAYTYPE_FLOAT].arrayclass) {}
350 float* get_raw_data_ptr() { return ((java_floatarray_t*) get_handle())->data; }
353 class DoubleArray : public ArrayTemplate<double> {
355 DoubleArray(java_handle_doublearray_t* h) : ArrayTemplate<double>(h) {}
356 DoubleArray(int32_t length) : ArrayTemplate<double>(length, primitivetype_table[ARRAYTYPE_DOUBLE].arrayclass) {}
357 double* get_raw_data_ptr() { return ((java_doublearray_t*) get_handle())->data; }
361 * Actual implementation of access class for Java Object arrays.
363 class ObjectArray : public ArrayTemplate<java_handle_t*> {
365 ObjectArray(java_handle_objectarray_t* h) : ArrayTemplate<java_handle_t*>(h) {}
366 ObjectArray(int32_t length, classinfo* componentclass);
367 java_handle_t** get_raw_data_ptr() { return ((java_objectarray_t*) get_handle())->data; }
371 * Actual implementation of access class for java.lang.Class arrays.
373 class ClassArray : public ArrayTemplate<classinfo*> {
375 ClassArray(int32_t length);
376 classinfo** get_raw_data_ptr() { return (classinfo**) ((java_objectarray_t*) get_handle())->data; }
381 # warning No legacy C functions for array access classes.
384 #endif // _VM_ARRAY_HPP
388 * These are local overrides for various environment variables in Emacs.
389 * Please do not remove this and leave it at the end of the file, where
390 * Emacs will automagically detect them.
391 * ---------------------------------------------------------------------
394 * indent-tabs-mode: t
398 * vim:noexpandtab:sw=4:ts=4: