Line data Source code
1 : /* src/vm/array.cpp - Java array functions
2 :
3 : Copyright (C) 2007-2013
4 : CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 : Copyright (C) 2008 Theobroma Systems Ltd.
6 :
7 : This file is part of CACAO.
8 :
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.
13 :
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.
18 :
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
22 : 02110-1301, USA.
23 :
24 : */
25 :
26 :
27 : #include "config.h"
28 :
29 : #include <stdint.h>
30 :
31 : #include "native/llni.hpp"
32 :
33 : #include "vm/array.hpp"
34 : #include "vm/exceptions.hpp"
35 : #include "vm/global.hpp"
36 : #include "vm/globals.hpp"
37 : #include "vm/primitive.hpp"
38 : #include "vm/vm.hpp"
39 :
40 :
41 : /**
42 : * Returns a boxed element of the given Java array.
43 : */
44 0 : java_handle_t* Array::get_boxed_element(int32_t index)
45 : {
46 : vftbl_t *v;
47 : int type;
48 : imm_union value;
49 : java_handle_t *o;
50 :
51 0 : if (is_null()) {
52 0 : exceptions_throw_nullpointerexception();
53 0 : return NULL;
54 : }
55 :
56 0 : v = LLNI_vftbl_direct(_handle);
57 :
58 0 : type = v->arraydesc->arraytype;
59 :
60 0 : value = get_primitive_element(index);
61 :
62 0 : o = Primitive::box(type, value);
63 :
64 0 : return o;
65 : }
66 :
67 :
68 : /**
69 : * Sets a boxed element in the given Java array.
70 : */
71 0 : void Array::set_boxed_element(int32_t index, java_handle_t *o)
72 : {
73 : vftbl_t *v;
74 : int type;
75 : imm_union value;
76 :
77 0 : if (is_null()) {
78 0 : exceptions_throw_nullpointerexception();
79 0 : return;
80 : }
81 :
82 0 : v = LLNI_vftbl_direct(_handle);
83 :
84 0 : type = v->arraydesc->arraytype;
85 :
86 : // Special handling for object arrays.
87 0 : if (type == ARRAYTYPE_OBJECT) {
88 0 : ObjectArray array(_handle);
89 0 : array.set_element(index, o);
90 0 : return;
91 : }
92 :
93 : // Check if primitive type can be stored.
94 0 : if (!Primitive::unbox_typed(o, type, &value)) {
95 : /* exceptions_throw_illegalargumentexception("argument type mismatch"); */
96 0 : exceptions_throw_illegalargumentexception();
97 0 : return;
98 : }
99 :
100 0 : set_primitive_element(index, value);
101 : }
102 :
103 :
104 : /**
105 : * Returns a primitive element of the given Java array.
106 : */
107 0 : imm_union Array::get_primitive_element(int32_t index)
108 : {
109 : vftbl_t *v;
110 : int type;
111 : imm_union value;
112 :
113 0 : if (is_null()) {
114 0 : exceptions_throw_nullpointerexception();
115 0 : value.a = NULL;
116 0 : return value;
117 : }
118 :
119 0 : java_handle_array_t* a = _handle;
120 :
121 0 : v = LLNI_vftbl_direct(a);
122 :
123 0 : type = v->arraydesc->arraytype;
124 :
125 0 : switch (type) {
126 : case ARRAYTYPE_BOOLEAN:
127 : {
128 0 : BooleanArray array(a);
129 0 : value.i = array.get_element(index);
130 : }
131 0 : break;
132 : case ARRAYTYPE_BYTE:
133 : {
134 0 : ByteArray array(a);
135 0 : value.i = array.get_element(index);
136 : }
137 0 : break;
138 : case ARRAYTYPE_CHAR:
139 : {
140 0 : CharArray array(a);
141 0 : value.i = array.get_element(index);
142 : }
143 0 : break;
144 : case ARRAYTYPE_SHORT:
145 : {
146 0 : ShortArray array(a);
147 0 : value.i = array.get_element(index);
148 : }
149 0 : break;
150 : case ARRAYTYPE_INT:
151 : {
152 0 : IntArray array(a);
153 0 : value.i = array.get_element(index);
154 : }
155 0 : break;
156 : case ARRAYTYPE_LONG:
157 : {
158 0 : LongArray array(a);
159 0 : value.l = array.get_element(index);
160 : }
161 0 : break;
162 : case ARRAYTYPE_FLOAT:
163 : {
164 0 : FloatArray array(a);
165 0 : value.f = array.get_element(index);
166 : }
167 0 : break;
168 : case ARRAYTYPE_DOUBLE:
169 : {
170 0 : DoubleArray array(a);
171 0 : value.d = array.get_element(index);
172 : }
173 0 : break;
174 : case ARRAYTYPE_OBJECT:
175 : {
176 0 : ObjectArray array(a);
177 0 : value.a = array.get_element(index);
178 : }
179 0 : break;
180 : default:
181 : vm_abort("Array::primitive_element_get: invalid array element type %d",
182 0 : type);
183 : }
184 :
185 0 : return value;
186 : }
187 :
188 :
189 : /**
190 : * Sets a primitive element in the given Java array.
191 : */
192 0 : void Array::set_primitive_element(int32_t index, imm_union value)
193 : {
194 : vftbl_t *v;
195 : int type;
196 :
197 0 : if (is_null()) {
198 0 : exceptions_throw_nullpointerexception();
199 0 : return;
200 : }
201 :
202 0 : java_handle_array_t* a = _handle;
203 :
204 0 : v = LLNI_vftbl_direct(a);
205 :
206 0 : type = v->arraydesc->arraytype;
207 :
208 0 : switch (type) {
209 : case ARRAYTYPE_BOOLEAN:
210 : {
211 0 : BooleanArray array(a);
212 0 : array.set_element(index, value.i);
213 : }
214 0 : break;
215 : case ARRAYTYPE_BYTE:
216 : {
217 0 : ByteArray array(a);
218 0 : array.set_element(index, value.i);
219 : }
220 0 : break;
221 : case ARRAYTYPE_CHAR:
222 : {
223 0 : CharArray array(a);
224 0 : array.set_element(index, value.i);
225 : }
226 0 : break;
227 : case ARRAYTYPE_SHORT:
228 : {
229 0 : ShortArray array(a);
230 0 : array.set_element(index, value.i);
231 : }
232 0 : break;
233 : case ARRAYTYPE_INT:
234 : {
235 0 : IntArray array(a);
236 0 : array.set_element(index, value.i);
237 : }
238 0 : break;
239 : case ARRAYTYPE_LONG:
240 : {
241 0 : LongArray array(a);
242 0 : array.set_element(index, value.l);
243 : }
244 0 : break;
245 : case ARRAYTYPE_FLOAT:
246 : {
247 0 : FloatArray array(a);
248 0 : array.set_element(index, value.f);
249 : }
250 0 : break;
251 : case ARRAYTYPE_DOUBLE:
252 : {
253 0 : DoubleArray array(a);
254 0 : array.set_element(index, value.d);
255 : }
256 0 : break;
257 : case ARRAYTYPE_OBJECT:
258 : {
259 0 : ObjectArray array(a);
260 0 : array.set_element(index, static_cast<java_handle_t*>(value.a));
261 : }
262 0 : break;
263 : default:
264 : vm_abort("array_element_primitive_set: invalid array element type %d",
265 0 : type);
266 : }
267 : }
268 :
269 :
270 : /**
271 : * Creates an array of references to the given class type on the heap.
272 : * The handle pointer to the array can be NULL in case of an exception.
273 : */
274 312069 : ObjectArray::ObjectArray(int32_t length, classinfo* componentclass)
275 312069 : : ArrayTemplate<java_handle_t*>(NULL)
276 : {
277 : // Is class loaded?
278 312069 : assert(componentclass->state & CLASS_LOADED);
279 :
280 : // Is class linked?
281 312069 : if (!(componentclass->state & CLASS_LINKED))
282 0 : if (!link_class(componentclass)) {
283 0 : _handle = NULL;
284 0 : return;
285 : }
286 :
287 312069 : classinfo* arrayclass = class_array_of(componentclass, true);
288 :
289 312069 : if (arrayclass == NULL) {
290 1 : _handle = NULL;
291 1 : return;
292 : }
293 :
294 : // Delegate allocation to generic array class
295 312068 : Array a(length, arrayclass);
296 :
297 312068 : _handle = a.get_handle();
298 0 : }
299 :
300 :
301 : /**
302 : * Creates an array of references to classinfos on the heap.
303 : * The handle pointer to the array can be NULL in case of an exception.
304 : */
305 1899 : ClassArray::ClassArray(int32_t length)
306 1899 : : ArrayTemplate<classinfo*>(NULL)
307 : {
308 : // Delegate allocation to object array class
309 1899 : ObjectArray oa(length, class_java_lang_Class);
310 :
311 1899 : _handle = oa.get_handle();
312 0 : }
313 :
314 :
315 : /*
316 : * These are local overrides for various environment variables in Emacs.
317 : * Please do not remove this and leave it at the end of the file, where
318 : * Emacs will automagically detect them.
319 : * ---------------------------------------------------------------------
320 : * Local variables:
321 : * mode: c++
322 : * indent-tabs-mode: t
323 : * c-basic-offset: 4
324 : * tab-width: 4
325 : * End:
326 : * vim:noexpandtab:sw=4:ts=4:
327 : */
|