OSDN Git Service

Merged gcj-eclipse branch to trunk.
[pf3gnuchains/gcc-fork.git] / libjava / java / lang / reflect / natField.cc
1 // natField.cc - Implementation of java.lang.reflect.Field native methods.
2
3 /* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006  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 <java-stack.h>
17 #include <java/lang/reflect/Field.h>
18 #include <java/lang/reflect/Modifier.h>
19 #include <java/lang/ArrayIndexOutOfBoundsException.h>
20 #include <java/lang/IllegalArgumentException.h>
21 #include <java/lang/IllegalAccessException.h>
22 #include <java/lang/NullPointerException.h>
23 #include <java/lang/Byte.h>
24 #include <java/lang/Short.h>
25 #include <java/lang/Integer.h>
26 #include <java/lang/Long.h>
27 #include <java/lang/Float.h>
28 #include <java/lang/Double.h>
29 #include <java/lang/Boolean.h>
30 #include <java/lang/Character.h>
31
32 typedef JArray< ::java::lang::annotation::Annotation * > * anno_a_t;
33
34 jint
35 java::lang::reflect::Field::getModifiersInternal ()
36 {
37   return _Jv_FromReflectedField (this)->flags;
38 }
39
40 jstring
41 java::lang::reflect::Field::getSignature()
42 {
43   return declaringClass->getReflectionSignature (this);
44 }
45
46 anno_a_t
47 java::lang::reflect::Field::getDeclaredAnnotationsInternal()
48 {
49   return (anno_a_t) declaringClass->getDeclaredAnnotations(this);
50 }
51
52 jstring
53 java::lang::reflect::Field::getName ()
54 {
55   if (name == NULL)
56     name = _Jv_NewStringUtf8Const (_Jv_FromReflectedField (this)->name);
57   return name;
58 }
59
60 jclass
61 java::lang::reflect::Field::getType ()
62 {
63   if (type == NULL)
64     {
65       jfieldID fld = _Jv_FromReflectedField (this);
66       JvSynchronize sync (declaringClass);
67       _Jv_Linker::resolve_field (fld, declaringClass->getClassLoaderInternal ());
68       type = fld->type;
69     }
70   return type;
71 }
72
73 static void*
74 getAddr (java::lang::reflect::Field* field, jclass caller, jobject obj,
75          jboolean checkFinal)
76 {
77   // FIXME: we know CALLER is NULL here.  At one point we planned to
78   // have the compiler insert the caller as a hidden argument in some
79   // calls.  However, we never implemented that, so we have to find
80   // the caller by hand instead.
81   
82   using namespace java::lang::reflect;
83   
84   jfieldID fld = _Jv_FromReflectedField (field);
85   _Jv_ushort flags = fld->getModifiers();
86
87   // Setting a final field is usually not allowed.
88   if (checkFinal
89       // As of 1.5, you can set a non-static final field if it is
90       // accessible.
91       && (! field->isAccessible()
92           || (field->getModifiers() & java::lang::reflect::Modifier::STATIC))
93       && (field->getModifiers() & java::lang::reflect::Modifier::FINAL))
94     throw new java::lang::IllegalAccessException(JvNewStringUTF 
95       ("Field is final"));
96   
97   // Check accessibility, if required.
98   if (! (Modifier::isPublic (flags) || field->isAccessible()))
99     {
100       caller = _Jv_StackTrace::GetCallingClass (&Field::class$);
101       if (! _Jv_CheckAccess (caller, field->getDeclaringClass(), flags))
102         throw new java::lang::IllegalAccessException;
103     }
104
105   if (flags & Modifier::STATIC)
106     {
107       jclass fldClass = field->getDeclaringClass ();
108       JvInitClass(fldClass);
109       return fld->u.addr;
110     }
111   else
112     {
113       if (obj == NULL)
114         throw new java::lang::NullPointerException;
115       if (! _Jv_IsInstanceOf (obj, field->getDeclaringClass()))
116         throw new java::lang::IllegalArgumentException;
117       return (void*) ((char*) obj + fld->getOffset ());
118     }
119 }
120
121 static jboolean
122 getBoolean (jclass cls, void* addr)
123 {
124   if (cls == JvPrimClass (boolean))
125     return * (jboolean *) addr;
126   throw new java::lang::IllegalArgumentException;
127 }
128
129 static jchar
130 getChar (jclass cls, void* addr)
131 {
132   if (cls == JvPrimClass (char))
133     return * (jchar *) addr;
134   throw new java::lang::IllegalArgumentException;
135 }
136
137 static jbyte
138 getByte (jclass cls, void* addr)
139 {
140   if (cls == JvPrimClass (byte))
141     return * (jbyte *) addr;
142   throw new java::lang::IllegalArgumentException;
143 }
144
145 static jshort
146 getShort (jclass cls, void* addr)
147 {
148   if (cls == JvPrimClass (short))
149     return * (jshort *) addr;
150   if (cls == JvPrimClass (byte))
151     return * (jbyte *) addr;
152   throw new java::lang::IllegalArgumentException;
153 }
154
155 static jint
156 getInt (jclass cls, void* addr)
157 {
158   if (cls == JvPrimClass (int))
159     return * (jint *) addr;
160   if (cls == JvPrimClass (short))
161     return * (jshort *) addr;
162   if (cls == JvPrimClass (char))
163     return * (jchar *) addr;
164   if (cls == JvPrimClass (byte))
165     return * (jbyte *) addr;
166   throw new java::lang::IllegalArgumentException;
167 }
168
169 static jlong
170 getLong (jclass cls, void* addr)
171 {
172   if (cls == JvPrimClass (long))
173     return * (jlong *) addr;
174   return ::getInt(cls, addr);
175 }
176
177 static jfloat
178 getFloat (jclass cls, void* addr)
179 {
180   if (cls == JvPrimClass (float))
181     return * (jfloat *) addr;
182   if (cls == JvPrimClass (long))
183     return * (jlong *) addr;
184   return ::getInt(cls, addr);
185 }
186
187 static jdouble
188 getDouble (jclass cls, void* addr)
189 {
190   if (cls == JvPrimClass (double))
191     return * (jdouble *) addr;
192   if (cls == JvPrimClass (float))
193     return * (jfloat *) addr;
194   if (cls == JvPrimClass (long))
195     return * (jlong *) addr;
196   return ::getInt(cls, addr);
197 }
198
199 jboolean
200 java::lang::reflect::Field::getBoolean (jclass caller, jobject obj)
201 {
202   return ::getBoolean (this->getType(), getAddr (this, caller, obj, false));
203 }
204
205 jchar
206 java::lang::reflect::Field::getChar (jclass caller, jobject obj)
207 {
208   return ::getChar (this->getType(), getAddr (this, caller, obj, false));
209 }
210
211 jbyte
212 java::lang::reflect::Field::getByte (jclass caller, jobject obj)
213 {
214   return ::getByte (this->getType(), getAddr (this, caller, obj, false));
215 }
216
217 jshort
218 java::lang::reflect::Field::getShort (jclass caller, jobject obj)
219 {
220   return ::getShort (this->getType(), getAddr (this, caller, obj, false));
221 }
222
223 jint
224 java::lang::reflect::Field::getInt (jclass caller, jobject obj)
225 {
226   return ::getInt (this->getType(), getAddr (this, caller, obj, false));
227 }
228
229 jlong
230 java::lang::reflect::Field::getLong (jclass caller, jobject obj)
231 {
232   return ::getLong (this->getType(), getAddr (this, caller, obj, false));
233 }
234
235 jfloat
236 java::lang::reflect::Field::getFloat (jclass caller, jobject obj)
237 {
238   return ::getFloat (this->getType(), getAddr (this, caller, obj, false));
239 }
240
241 jdouble
242 java::lang::reflect::Field::getDouble (jclass caller, jobject obj)
243 {
244   return ::getDouble (this->getType(), getAddr (this, caller, obj, false));
245 }
246
247 jobject
248 java::lang::reflect::Field::get (jclass caller, jobject obj)
249 {
250   jclass type = this->getType();
251   void* addr = getAddr (this, caller, obj, false);
252   if (! type->isPrimitive ())
253     return * (jobject*) addr;
254   if (type == JvPrimClass (double))
255     return new java::lang::Double (* (jdouble*) addr);
256   if (type == JvPrimClass (float))
257     return new java::lang::Float (* (jfloat*) addr);
258   if (type == JvPrimClass (long))
259     return new java::lang::Long (* (jlong*) addr);
260   if (type == JvPrimClass (int))
261     return new java::lang::Integer (* (jint*) addr);
262   if (type == JvPrimClass (short))
263     return new java::lang::Short (* (jshort*) addr);
264   if (type == JvPrimClass (byte))
265     return new java::lang::Byte (* (jbyte*) addr);
266   if (type == JvPrimClass (char))
267     return new java::lang::Character (* (jchar*) addr);
268   if (type == JvPrimClass (boolean))
269     {
270       _Jv_InitClass (&java::lang::Boolean::class$);
271       if (* (jboolean*) addr)
272         return java::lang::Boolean::TRUE;
273       else
274         return java::lang::Boolean::FALSE;
275     }
276   throw new java::lang::IllegalArgumentException;
277 }
278
279 static void
280 setBoolean (jclass type, void *addr, jboolean value)
281 {
282   if (type == JvPrimClass (boolean))
283     * (jboolean *) addr = value;
284   else
285     throw new java::lang::IllegalArgumentException;
286 }
287
288 static void
289 setChar (jclass type, void *addr, jchar value)
290 {
291   if (type == JvPrimClass (char))
292     * (jchar *) addr = value;
293   else if (type == JvPrimClass (int))
294     * (jint *) addr = value;
295   else if (type == JvPrimClass (long))
296     * (jlong *) addr = value;
297   else if (type == JvPrimClass (float))
298     * (jfloat *) addr = value;
299   else if (type == JvPrimClass (double))
300     * (jdouble *) addr = value;
301   else
302     throw new java::lang::IllegalArgumentException;
303 }
304
305 static void
306 setByte (jclass type, void *addr, jbyte value)
307 {
308   if (type == JvPrimClass (byte))
309     * (jbyte *) addr = value;
310   else if (type == JvPrimClass (short))
311     * (jshort *) addr = value;
312   else if (type == JvPrimClass (int))
313     * (jint *) addr = value;
314   else if (type == JvPrimClass (long))
315     * (jlong *) addr = value;
316   else if (type == JvPrimClass (float))
317     * (jfloat *) addr = value;
318   else if (type == JvPrimClass (double))
319     * (jdouble *) addr = value;
320   else
321     throw new java::lang::IllegalArgumentException;
322 }
323
324 static void
325 setShort (jclass type, void *addr, jshort value)
326 {
327   if (type == JvPrimClass (short))
328     * (jshort *) addr = value;
329   else if (type == JvPrimClass (int))
330     * (jint *) addr = value;
331   else if (type == JvPrimClass (long))
332     * (jlong *) addr = value;
333   else if (type == JvPrimClass (float))
334     * (jfloat *) addr = value;
335   else if (type == JvPrimClass (double))
336     * (jdouble *) addr = value;
337   else
338     throw new java::lang::IllegalArgumentException;
339 }
340
341 static void
342 setInt (jclass type, void *addr, jint value)
343 {
344   if (type == JvPrimClass (int))
345     * (jint *) addr = value;
346   else if (type == JvPrimClass (long))
347     * (jlong *) addr = value;
348   else if (type == JvPrimClass (float))
349     * (jfloat *) addr = value;
350   else if (type == JvPrimClass (double))
351     * (jdouble *) addr = value;
352   else
353     throw new java::lang::IllegalArgumentException;
354 }
355
356 static void
357 setLong (jclass type, void *addr, jlong value)
358 {
359   if (type == JvPrimClass (long))
360     * (jlong *) addr = value;
361   else if (type == JvPrimClass (float))
362     * (jfloat *) addr = value;
363   else if (type == JvPrimClass (double))
364     * (jdouble *) addr = value;
365   else
366     throw new java::lang::IllegalArgumentException;
367 }
368
369 static void
370 setFloat (jclass type, void *addr, jfloat value)
371 {
372   if (type == JvPrimClass (float))
373     * (jfloat *) addr = value;
374   else if (type == JvPrimClass (double))
375     * (jdouble *) addr = value;
376   else
377     throw new java::lang::IllegalArgumentException;
378 }
379
380 static void
381 setDouble (jclass type, void *addr, jdouble value)
382 {
383   if (type == JvPrimClass (double))
384     * (jdouble *) addr = value;
385   else
386     throw new java::lang::IllegalArgumentException;
387 }
388
389 void
390 java::lang::reflect::Field::setBoolean (jclass caller, jobject obj, jboolean b,
391                                         jboolean checkFinal)
392 {
393   ::setBoolean (this->getType(), getAddr (this, caller, obj, checkFinal), b);
394 }
395
396 void
397 java::lang::reflect::Field::setChar (jclass caller, jobject obj, jchar c,
398                                      jboolean checkFinal)
399 {
400   ::setChar (this->getType(), getAddr (this, caller, obj, checkFinal), c);
401 }
402
403 void
404 java::lang::reflect::Field::setByte (jclass caller, jobject obj, jbyte b,
405                                      jboolean checkFinal)
406 {
407   ::setByte (this->getType(), getAddr (this, caller, obj, checkFinal), b);
408 }
409
410 void
411 java::lang::reflect::Field::setShort (jclass caller, jobject obj, jshort s,
412                                       jboolean checkFinal)
413 {
414   ::setShort (this->getType(), getAddr (this, caller, obj, checkFinal), s);
415 }
416
417 void
418 java::lang::reflect::Field::setInt (jclass caller, jobject obj, jint i,
419                                     jboolean checkFinal)
420 {
421   ::setInt (this->getType(), getAddr (this, caller, obj, checkFinal), i);
422 }
423
424 void
425 java::lang::reflect::Field::setLong (jclass caller, jobject obj, jlong l,
426                                      jboolean checkFinal)
427 {
428   ::setLong (this->getType(), getAddr (this, caller, obj, checkFinal), l);
429 }
430
431 void
432 java::lang::reflect::Field::setFloat (jclass caller, jobject obj, jfloat f,
433                                       jboolean checkFinal)
434 {
435   ::setFloat (this->getType(), getAddr (this, caller, obj, checkFinal), f);
436 }
437
438 void
439 java::lang::reflect::Field::setDouble (jclass caller, jobject obj, jdouble d,
440                                        jboolean checkFinal)
441 {
442   ::setDouble (this->getType(), getAddr (this, caller, obj, checkFinal), d);
443 }
444
445 void
446 java::lang::reflect::Field::set (jclass caller, jobject object, jobject value,
447                                  jclass type, jboolean checkFinal)
448 {
449   void* addr = getAddr (this, caller, object, checkFinal);
450   if (value != NULL && ! _Jv_IsInstanceOf (value, type))
451     throw new java::lang::IllegalArgumentException;
452   * (jobject*) addr = value;
453 }