1 // natField.cc - Implementation of java.lang.reflect.Field native methods.
2 
3 /* Copyright (C) 1999, 2000, 2001, 2003  Free Software Foundation
4 
5    This file is part of libgcj.
6 
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10 
11 #include <config.h>
12 
13 #include <stdlib.h>
14 
15 #include <jvm.h>
16 #include <gcj/cni.h>
17 #include <java-stack.h>
18 #include <java/lang/reflect/Array.h>
19 #include <java/lang/ArrayIndexOutOfBoundsException.h>
20 #include <java/lang/IllegalArgumentException.h>
21 #include <java/lang/Byte.h>
22 #include <java/lang/Short.h>
23 #include <java/lang/Integer.h>
24 #include <java/lang/Long.h>
25 #include <java/lang/Float.h>
26 #include <java/lang/Double.h>
27 #include <java/lang/Boolean.h>
28 #include <java/lang/Character.h>
29 
30 jobject
newInstance(jclass componentType,jint length)31 java::lang::reflect::Array::newInstance (jclass componentType, jint length)
32 {
33   if (componentType->isPrimitive())
34     {
35       // We could check for this in _Jv_NewPrimArray, but that seems
36       // like needless overhead when the only real route to this
37       // problem is here.
38       if (componentType == JvPrimClass (void))
39 	throw new java::lang::IllegalArgumentException ();
40       return _Jv_NewPrimArray (componentType, length);
41     }
42   else
43     // FIXME: class loader?
44     return JvNewObjectArray (length, componentType, NULL);
45 }
46 
47 jobject
newInstance(jclass componentType,jintArray dimensions)48 java::lang::reflect::Array::newInstance (jclass componentType,
49 					 jintArray dimensions)
50 {
51   jint ndims = dimensions->length;
52   if (ndims == 0)
53     throw new java::lang::IllegalArgumentException ();
54   jint* dims = elements (dimensions);
55   if (ndims == 1)
56     return newInstance (componentType, dims[0]);
57 
58   Class *caller = _Jv_StackTrace::GetCallingClass (&Array::class$);
59   ClassLoader *caller_loader = NULL;
60   if (caller)
61     caller_loader = caller->getClassLoaderInternal();
62 
63   jclass arrayType = componentType;
64   for (int i = 0;  i < ndims;  i++)
65     arrayType = _Jv_GetArrayClass (arrayType, caller_loader);
66 
67   return _Jv_NewMultiArray (arrayType, ndims, dims);
68 }
69 
70 jint
getLength(jobject array)71 java::lang::reflect::Array::getLength (jobject array)
72 {
73   jclass arrayType = array->getClass();
74   if (! arrayType->isArray ())
75     throw new java::lang::IllegalArgumentException;
76   return ((__JArray*) array)->length;
77 }
78 
79 jclass
getElementType(jobject array,jint index)80 java::lang::reflect::Array::getElementType (jobject array, jint index)
81 {
82   jclass arrayType = array->getClass();
83   if (! arrayType->isArray ())
84     throw new java::lang::IllegalArgumentException;
85   jint length = ((__JArray*) array)->length;
86   if ((_Jv_uint) index >= (_Jv_uint) length)
87     _Jv_ThrowBadArrayIndex(index);
88   return arrayType->getComponentType ();
89 }
90 
91 jboolean
getBoolean(jobject array,jint index)92 java::lang::reflect::Array::getBoolean (jobject array, jint index)
93 {
94   jclass elementType = getElementType (array, index);
95   if (elementType == JvPrimClass (boolean))
96     return elements ((jbooleanArray) array) [index];
97   throw new java::lang::IllegalArgumentException;
98 }
99 
100 jchar
getChar(jobject array,jint index)101 java::lang::reflect::Array::getChar (jobject array, jint index)
102 {
103   jclass elementType = getElementType (array, index);
104   if (elementType == JvPrimClass (char))
105     return elements ((jcharArray) array) [index];
106   throw new java::lang::IllegalArgumentException;
107 }
108 
109 jbyte
getByte(jobject array,jint index)110 java::lang::reflect::Array::getByte (jobject array, jint index)
111 {
112   jclass elementType = getElementType (array, index);
113   if (elementType == JvPrimClass (byte))
114     return elements ((jbyteArray) array) [index];
115   throw new java::lang::IllegalArgumentException;
116 }
117 
118 jshort
getShort(jobject array,jint index)119 java::lang::reflect::Array::getShort (jobject array, jint index)
120 {
121   jclass elementType = getElementType (array, index);
122   if (elementType == JvPrimClass (short))
123     return elements ((jshortArray) array) [index];
124   if (elementType == JvPrimClass (byte))
125     return elements ((jbyteArray) array) [index];
126   throw new java::lang::IllegalArgumentException;
127 }
128 
129 jint
getInt(jobject array,jint index)130 java::lang::reflect::Array::getInt (jobject array, jint index)
131 {
132   jclass elementType = getElementType (array, index);
133   if (elementType == JvPrimClass (int))
134     return elements ((jintArray) array) [index];
135   if (elementType == JvPrimClass (short))
136     return elements ((jshortArray) array) [index];
137   if (elementType == JvPrimClass (byte))
138     return elements ((jbyteArray) array) [index];
139   if (elementType == JvPrimClass (char))
140     return elements ((jcharArray) array) [index];
141   throw new java::lang::IllegalArgumentException;
142 }
143 
144 jlong
getLong(jobject array,jint index)145 java::lang::reflect::Array::getLong (jobject array, jint index)
146 {
147   jclass elementType = getElementType (array, index);
148   if (elementType == JvPrimClass (long))
149     return elements ((jlongArray) array) [index];
150   if (elementType == JvPrimClass (int))
151     return elements ((jintArray) array) [index];
152   if (elementType == JvPrimClass (short))
153     return elements ((jshortArray) array) [index];
154   if (elementType == JvPrimClass (byte))
155     return elements ((jbyteArray) array) [index];
156   if (elementType == JvPrimClass (char))
157     return elements ((jcharArray) array) [index];
158   throw new java::lang::IllegalArgumentException;
159 }
160 
161 jfloat
getFloat(jobject array,jint index)162 java::lang::reflect::Array::getFloat (jobject array, jint index)
163 {
164   jclass elementType = getElementType (array, index);
165   if (elementType == JvPrimClass (float))
166     return elements ((jfloatArray) array) [index];
167   if (elementType == JvPrimClass (long))
168     return elements ((jlongArray) array) [index];
169   if (elementType == JvPrimClass (int))
170     return elements ((jintArray) array) [index];
171   if (elementType == JvPrimClass (short))
172     return elements ((jshortArray) array) [index];
173   if (elementType == JvPrimClass (byte))
174     return elements ((jbyteArray) array) [index];
175   if (elementType == JvPrimClass (char))
176     return elements ((jcharArray) array) [index];
177   throw new java::lang::IllegalArgumentException;
178 }
179 
180 jdouble
getDouble(jobject array,jint index)181 java::lang::reflect::Array::getDouble (jobject array, jint index)
182 {
183   jclass elementType = getElementType (array, index);
184   if (elementType == JvPrimClass (double))
185     return elements ((jdoubleArray) array) [index];
186   if (elementType == JvPrimClass (float))
187     return elements ((jfloatArray) array) [index];
188   if (elementType == JvPrimClass (long))
189     return elements ((jlongArray) array) [index];
190   if (elementType == JvPrimClass (int))
191     return elements ((jintArray) array) [index];
192   if (elementType == JvPrimClass (short))
193     return elements ((jshortArray) array) [index];
194   if (elementType == JvPrimClass (byte))
195     return elements ((jbyteArray) array) [index];
196   if (elementType == JvPrimClass (char))
197     return elements ((jcharArray) array) [index];
198   throw new java::lang::IllegalArgumentException;
199 }
200 
201 jobject
get(jobject array,jint index)202 java::lang::reflect::Array::get (jobject array, jint index)
203 {
204   jclass elementType = getElementType (array, index);
205   if (! elementType->isPrimitive ())
206     return elements ((jobjectArray) array) [index];
207   if (elementType == JvPrimClass (double))
208     return new java::lang::Double (elements ((jdoubleArray) array) [index]);
209   if (elementType == JvPrimClass (float))
210     return new java::lang::Float (elements ((jfloatArray) array) [index]);
211   if (elementType == JvPrimClass (long))
212     return new java::lang::Long (elements ((jlongArray) array) [index]);
213   if (elementType == JvPrimClass (int))
214     return new java::lang::Integer (elements ((jintArray) array) [index]);
215   if (elementType == JvPrimClass (short))
216     return new java::lang::Short (elements ((jshortArray) array) [index]);
217   if (elementType == JvPrimClass (byte))
218     return new java::lang::Byte (elements ((jbyteArray) array) [index]);
219   if (elementType == JvPrimClass (char))
220     return new java::lang::Character (elements ((jcharArray) array) [index]);
221   if (elementType == JvPrimClass (boolean))
222     {
223       _Jv_InitClass (&java::lang::Boolean::class$);
224       if (elements ((jbooleanArray) array) [index])
225 	return java::lang::Boolean::TRUE;
226       else
227 	return java::lang::Boolean::FALSE;
228     }
229   throw new java::lang::IllegalArgumentException;
230 }
231 
232 void
setChar(jobject array,jint index,jchar value)233 java::lang::reflect::Array::setChar (jobject array, jint index, jchar value)
234 {
235   jclass elementType = getElementType (array, index);
236   if (elementType == JvPrimClass (char))
237     elements ((jcharArray) array) [index] = value;
238   else if (elementType == JvPrimClass (int))
239     elements ((jintArray) array) [index] = value;
240   else if (elementType == JvPrimClass (long))
241     elements ((jlongArray) array) [index] = value;
242   else if (elementType == JvPrimClass (float))
243     elements ((jfloatArray) array) [index] = value;
244   else if (elementType == JvPrimClass (double))
245     elements ((jdoubleArray) array) [index] = value;
246   else
247     throw new java::lang::IllegalArgumentException;
248 }
249 
250 void
setByte(jobject array,jint index,jbyte value)251 java::lang::reflect::Array::setByte (jobject array, jint index, jbyte value)
252 {
253   jclass elementType = getElementType (array, index);
254   if (elementType == JvPrimClass (byte))
255     elements ((jbyteArray) array) [index] = value;
256   else if (elementType == JvPrimClass (short))
257     elements ((jshortArray) array) [index] = value;
258   else if (elementType == JvPrimClass (int))
259     elements ((jintArray) array) [index] = value;
260   else if (elementType == JvPrimClass (long))
261     elements ((jlongArray) array) [index] = value;
262   else if (elementType == JvPrimClass (float))
263     elements ((jfloatArray) array) [index] = value;
264   else if (elementType == JvPrimClass (double))
265     elements ((jdoubleArray) array) [index] = value;
266   else
267     throw new java::lang::IllegalArgumentException;
268 }
269 
270 void
setShort(jobject array,jint index,jshort value)271 java::lang::reflect::Array::setShort (jobject array, jint index, jshort value)
272 {
273   jclass elementType = getElementType (array, index);
274   if (elementType == JvPrimClass (short))
275     elements ((jshortArray) array) [index] = value;
276   else if (elementType == JvPrimClass (int))
277     elements ((jintArray) array) [index] = value;
278   else if (elementType == JvPrimClass (long))
279     elements ((jlongArray) array) [index] = value;
280   else if (elementType == JvPrimClass (float))
281     elements ((jfloatArray) array) [index] = value;
282   else if (elementType == JvPrimClass (double))
283     elements ((jdoubleArray) array) [index] = value;
284   else
285     throw new java::lang::IllegalArgumentException;
286 }
287 
288 void
setInt(jobject array,jint index,jint value)289 java::lang::reflect::Array::setInt (jobject array, jint index, jint value)
290 {
291   jclass elementType = getElementType (array, index);
292   if (elementType == JvPrimClass (int))
293     elements ((jintArray) array) [index] = value;
294   else if (elementType == JvPrimClass (long))
295     elements ((jlongArray) array) [index] = value;
296   else if (elementType == JvPrimClass (float))
297     elements ((jfloatArray) array) [index] = value;
298   else if (elementType == JvPrimClass (double))
299     elements ((jdoubleArray) array) [index] = value;
300   else
301     throw new java::lang::IllegalArgumentException;
302 }
303 
304 void
setLong(jobject array,jint index,jlong value)305 java::lang::reflect::Array::setLong (jobject array, jint index, jlong value)
306 {
307   jclass elementType = getElementType (array, index);
308   if (elementType == JvPrimClass (long))
309     elements ((jlongArray) array) [index] = value;
310   else if (elementType == JvPrimClass (float))
311     elements ((jfloatArray) array) [index] = value;
312   else if (elementType == JvPrimClass (double))
313     elements ((jdoubleArray) array) [index] = value;
314   else
315     throw new java::lang::IllegalArgumentException;
316 }
317 
318 void
setFloat(jobject array,jint index,jfloat value)319 java::lang::reflect::Array::setFloat (jobject array, jint index, jfloat value)
320 {
321   jclass elementType = getElementType (array, index);
322   if (elementType == JvPrimClass (float))
323     elements ((jfloatArray) array) [index] = value;
324   else if (elementType == JvPrimClass (double))
325     elements ((jdoubleArray) array) [index] = value;
326   else
327     throw new java::lang::IllegalArgumentException;
328 }
329 
330 void
setDouble(jobject array,jint index,jdouble value)331 java::lang::reflect::Array::setDouble (jobject array, jint index, jdouble value)
332 {
333   jclass elementType = getElementType (array, index);
334   if (elementType == JvPrimClass (double))
335     elements ((jdoubleArray) array) [index] = value;
336   else
337     throw new java::lang::IllegalArgumentException;
338 }
339 
340 void
setBoolean(jobject array,jint index,jboolean value)341 java::lang::reflect::Array::setBoolean (jobject array,
342 					jint index, jboolean value)
343 {
344   jclass elementType = getElementType (array, index);
345   if (elementType == JvPrimClass (boolean))
346     elements ((jbooleanArray) array) [index] = value;
347   else
348     throw new java::lang::IllegalArgumentException;
349 }
350 
351 void
set(jobject array,jint index,jobject value,jclass elType)352 java::lang::reflect::Array::set (jobject array, jint index,
353 				 jobject value, jclass elType)
354 {
355   // We don't have to call getElementType here, or check INDEX,
356   // because it was already done in the Java wrapper.
357   if (value != NULL && ! _Jv_IsInstanceOf (value, elType))
358     throw new java::lang::IllegalArgumentException;
359   elements ((jobjectArray) array) [index] = value;
360 }
361