1 // natField.cc - Implementation of java.lang.reflect.Field native methods.
3 /* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
16 #include <java/lang/reflect/Field.h>
17 #include <java/lang/reflect/Modifier.h>
18 #include <java/lang/ArrayIndexOutOfBoundsException.h>
19 #include <java/lang/IllegalArgumentException.h>
20 #include <java/lang/IllegalAccessException.h>
21 #include <java/lang/NullPointerException.h>
22 #include <java/lang/Byte.h>
23 #include <java/lang/Short.h>
24 #include <java/lang/Integer.h>
25 #include <java/lang/Long.h>
26 #include <java/lang/Float.h>
27 #include <java/lang/Double.h>
28 #include <java/lang/Boolean.h>
29 #include <java/lang/Character.h>
32 java::lang::reflect::Field::getModifiers ()
34 return _Jv_FromReflectedField (this)->getModifiers ();
38 java::lang::reflect::Field::getName ()
41 name
= _Jv_NewStringUtf8Const (_Jv_FromReflectedField (this)->name
);
46 java::lang::reflect::Field::getType ()
50 jfieldID fld
= _Jv_FromReflectedField (this);
51 JvSynchronize
sync (declaringClass
);
52 _Jv_Linker::resolve_field (fld
, declaringClass
->getClassLoaderInternal ());
59 getAddr (java::lang::reflect::Field
* field
, jclass caller
, jobject obj
,
62 // FIXME: we know CALLER is NULL here. At one point we planned to
63 // have the compiler insert the caller as a hidden argument in some
64 // calls. However, we never implemented that, so we have to find
65 // the caller by hand instead.
67 using namespace java::lang::reflect
;
69 jfieldID fld
= _Jv_FromReflectedField (field
);
70 _Jv_ushort flags
= fld
->getModifiers();
72 // Setting a final field is usually not allowed.
74 && field
->getModifiers() & java::lang::reflect::Modifier::FINAL
)
75 throw new java::lang::IllegalAccessException(JvNewStringUTF
78 // Check accessibility, if required.
79 if (! (Modifier::isPublic (flags
) || field
->isAccessible()))
81 gnu::gcj::runtime::StackTrace
*t
82 = new gnu::gcj::runtime::StackTrace(7);
85 // We want to skip all the frames on the stack from this class.
86 for (int i
= 1; !caller
|| caller
== &Field::class$
; i
++)
87 caller
= t
->classAt (i
);
89 catch (::java::lang::ArrayIndexOutOfBoundsException
*e
)
93 if (! _Jv_CheckAccess (caller
, field
->getDeclaringClass(), flags
))
94 throw new java::lang::IllegalAccessException
;
97 if (flags
& Modifier::STATIC
)
99 jclass fldClass
= field
->getDeclaringClass ();
100 JvInitClass(fldClass
);
106 throw new java::lang::NullPointerException
;
107 if (! _Jv_IsInstanceOf (obj
, field
->getDeclaringClass()))
108 throw new java::lang::IllegalArgumentException
;
109 return (void*) ((char*) obj
+ fld
->getOffset ());
114 getBoolean (jclass cls
, void* addr
)
116 if (cls
== JvPrimClass (boolean
))
117 return * (jboolean
*) addr
;
118 throw new java::lang::IllegalArgumentException
;
122 getChar (jclass cls
, void* addr
)
124 if (cls
== JvPrimClass (char))
125 return * (jchar
*) addr
;
126 throw new java::lang::IllegalArgumentException
;
130 getByte (jclass cls
, void* addr
)
132 if (cls
== JvPrimClass (byte
))
133 return * (jbyte
*) addr
;
134 throw new java::lang::IllegalArgumentException
;
138 getShort (jclass cls
, void* addr
)
140 if (cls
== JvPrimClass (short))
141 return * (jshort
*) addr
;
142 if (cls
== JvPrimClass (byte
))
143 return * (jbyte
*) addr
;
144 throw new java::lang::IllegalArgumentException
;
148 getInt (jclass cls
, void* addr
)
150 if (cls
== JvPrimClass (int))
151 return * (jint
*) addr
;
152 if (cls
== JvPrimClass (short))
153 return * (jshort
*) addr
;
154 if (cls
== JvPrimClass (char))
155 return * (jchar
*) addr
;
156 if (cls
== JvPrimClass (byte
))
157 return * (jbyte
*) addr
;
158 throw new java::lang::IllegalArgumentException
;
162 getLong (jclass cls
, void* addr
)
164 if (cls
== JvPrimClass (long))
165 return * (jlong
*) addr
;
166 return ::getInt(cls
, addr
);
170 getFloat (jclass cls
, void* addr
)
172 if (cls
== JvPrimClass (float))
173 return * (jfloat
*) addr
;
174 if (cls
== JvPrimClass (long))
175 return * (jlong
*) addr
;
176 return ::getInt(cls
, addr
);
180 getDouble (jclass cls
, void* addr
)
182 if (cls
== JvPrimClass (double))
183 return * (jdouble
*) addr
;
184 if (cls
== JvPrimClass (float))
185 return * (jfloat
*) addr
;
186 if (cls
== JvPrimClass (long))
187 return * (jlong
*) addr
;
188 return ::getInt(cls
, addr
);
192 java::lang::reflect::Field::getBoolean (jclass caller
, jobject obj
)
194 return ::getBoolean (this->getType(), getAddr (this, caller
, obj
, false));
198 java::lang::reflect::Field::getChar (jclass caller
, jobject obj
)
200 return ::getChar (this->getType(), getAddr (this, caller
, obj
, false));
204 java::lang::reflect::Field::getByte (jclass caller
, jobject obj
)
206 return ::getByte (this->getType(), getAddr (this, caller
, obj
, false));
210 java::lang::reflect::Field::getShort (jclass caller
, jobject obj
)
212 return ::getShort (this->getType(), getAddr (this, caller
, obj
, false));
216 java::lang::reflect::Field::getInt (jclass caller
, jobject obj
)
218 return ::getInt (this->getType(), getAddr (this, caller
, obj
, false));
222 java::lang::reflect::Field::getLong (jclass caller
, jobject obj
)
224 return ::getLong (this->getType(), getAddr (this, caller
, obj
, false));
228 java::lang::reflect::Field::getFloat (jclass caller
, jobject obj
)
230 return ::getFloat (this->getType(), getAddr (this, caller
, obj
, false));
234 java::lang::reflect::Field::getDouble (jclass caller
, jobject obj
)
236 return ::getDouble (this->getType(), getAddr (this, caller
, obj
, false));
240 java::lang::reflect::Field::get (jclass caller
, jobject obj
)
242 jclass type
= this->getType();
243 void* addr
= getAddr (this, caller
, obj
, false);
244 if (! type
->isPrimitive ())
245 return * (jobject
*) addr
;
246 if (type
== JvPrimClass (double))
247 return new java::lang::Double (* (jdouble
*) addr
);
248 if (type
== JvPrimClass (float))
249 return new java::lang::Float (* (jfloat
*) addr
);
250 if (type
== JvPrimClass (long))
251 return new java::lang::Long (* (jlong
*) addr
);
252 if (type
== JvPrimClass (int))
253 return new java::lang::Integer (* (jint
*) addr
);
254 if (type
== JvPrimClass (short))
255 return new java::lang::Short (* (jshort
*) addr
);
256 if (type
== JvPrimClass (byte
))
257 return new java::lang::Byte (* (jbyte
*) addr
);
258 if (type
== JvPrimClass (char))
259 return new java::lang::Character (* (jchar
*) addr
);
260 if (type
== JvPrimClass (boolean
))
262 _Jv_InitClass (&java::lang::Boolean::class$
);
263 if (* (jboolean
*) addr
)
264 return java::lang::Boolean::TRUE
;
266 return java::lang::Boolean::FALSE
;
268 throw new java::lang::IllegalArgumentException
;
272 setBoolean (jclass type
, void *addr
, jboolean value
)
274 if (type
== JvPrimClass (boolean
))
275 * (jboolean
*) addr
= value
;
277 throw new java::lang::IllegalArgumentException
;
281 setChar (jclass type
, void *addr
, jchar value
)
283 if (type
== JvPrimClass (char))
284 * (jchar
*) addr
= value
;
285 else if (type
== JvPrimClass (int))
286 * (jint
*) addr
= value
;
287 else if (type
== JvPrimClass (long))
288 * (jlong
*) addr
= value
;
289 else if (type
== JvPrimClass (float))
290 * (jfloat
*) addr
= value
;
291 else if (type
== JvPrimClass (double))
292 * (jdouble
*) addr
= value
;
294 throw new java::lang::IllegalArgumentException
;
298 setByte (jclass type
, void *addr
, jbyte value
)
300 if (type
== JvPrimClass (byte
))
301 * (jbyte
*) addr
= value
;
302 else if (type
== JvPrimClass (short))
303 * (jshort
*) addr
= value
;
304 else if (type
== JvPrimClass (int))
305 * (jint
*) addr
= value
;
306 else if (type
== JvPrimClass (long))
307 * (jlong
*) addr
= value
;
308 else if (type
== JvPrimClass (float))
309 * (jfloat
*) addr
= value
;
310 else if (type
== JvPrimClass (double))
311 * (jdouble
*) addr
= value
;
313 throw new java::lang::IllegalArgumentException
;
317 setShort (jclass type
, void *addr
, jshort value
)
319 if (type
== JvPrimClass (short))
320 * (jshort
*) addr
= value
;
321 else if (type
== JvPrimClass (int))
322 * (jint
*) addr
= value
;
323 else if (type
== JvPrimClass (long))
324 * (jlong
*) addr
= value
;
325 else if (type
== JvPrimClass (float))
326 * (jfloat
*) addr
= value
;
327 else if (type
== JvPrimClass (double))
328 * (jdouble
*) addr
= value
;
330 throw new java::lang::IllegalArgumentException
;
334 setInt (jclass type
, void *addr
, jint value
)
336 if (type
== JvPrimClass (int))
337 * (jint
*) addr
= value
;
338 else if (type
== JvPrimClass (long))
339 * (jlong
*) addr
= value
;
340 else if (type
== JvPrimClass (float))
341 * (jfloat
*) addr
= value
;
342 else if (type
== JvPrimClass (double))
343 * (jdouble
*) addr
= value
;
345 throw new java::lang::IllegalArgumentException
;
349 setLong (jclass type
, void *addr
, jlong value
)
351 if (type
== JvPrimClass (long))
352 * (jlong
*) addr
= value
;
353 else if (type
== JvPrimClass (float))
354 * (jfloat
*) addr
= value
;
355 else if (type
== JvPrimClass (double))
356 * (jdouble
*) addr
= value
;
358 throw new java::lang::IllegalArgumentException
;
362 setFloat (jclass type
, void *addr
, jfloat value
)
364 if (type
== JvPrimClass (float))
365 * (jfloat
*) addr
= value
;
366 else if (type
== JvPrimClass (double))
367 * (jdouble
*) addr
= value
;
369 throw new java::lang::IllegalArgumentException
;
373 setDouble (jclass type
, void *addr
, jdouble value
)
375 if (type
== JvPrimClass (double))
376 * (jdouble
*) addr
= value
;
378 throw new java::lang::IllegalArgumentException
;
382 java::lang::reflect::Field::setBoolean (jclass caller
, jobject obj
, jboolean b
,
385 ::setBoolean (this->getType(), getAddr (this, caller
, obj
, checkFinal
), b
);
389 java::lang::reflect::Field::setChar (jclass caller
, jobject obj
, jchar c
,
392 ::setChar (this->getType(), getAddr (this, caller
, obj
, checkFinal
), c
);
396 java::lang::reflect::Field::setByte (jclass caller
, jobject obj
, jbyte b
,
399 ::setByte (this->getType(), getAddr (this, caller
, obj
, checkFinal
), b
);
403 java::lang::reflect::Field::setShort (jclass caller
, jobject obj
, jshort s
,
406 ::setShort (this->getType(), getAddr (this, caller
, obj
, checkFinal
), s
);
410 java::lang::reflect::Field::setInt (jclass caller
, jobject obj
, jint i
,
413 ::setInt (this->getType(), getAddr (this, caller
, obj
, checkFinal
), i
);
417 java::lang::reflect::Field::setLong (jclass caller
, jobject obj
, jlong l
,
420 ::setLong (this->getType(), getAddr (this, caller
, obj
, checkFinal
), l
);
424 java::lang::reflect::Field::setFloat (jclass caller
, jobject obj
, jfloat f
,
427 ::setFloat (this->getType(), getAddr (this, caller
, obj
, checkFinal
), f
);
431 java::lang::reflect::Field::setDouble (jclass caller
, jobject obj
, jdouble d
,
434 ::setDouble (this->getType(), getAddr (this, caller
, obj
, checkFinal
), d
);
438 java::lang::reflect::Field::set (jclass caller
, jobject object
, jobject value
,
439 jclass type
, jboolean checkFinal
)
441 void* addr
= getAddr (this, caller
, object
, checkFinal
);
442 if (value
!= NULL
&& ! _Jv_IsInstanceOf (value
, type
))
443 throw new java::lang::IllegalArgumentException
;
444 * (jobject
*) addr
= value
;