Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / libjava / java / lang / reflect / natField.cc
blob9a8107b795d38c4f48130a8cc8d54e30c957f949
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
9 details. */
11 #include <config.h>
13 #include <stdlib.h>
15 #include <jvm.h>
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>
31 jint
32 java::lang::reflect::Field::getModifiers ()
34 return _Jv_FromReflectedField (this)->getModifiers ();
37 jstring
38 java::lang::reflect::Field::getName ()
40 if (name == NULL)
41 name = _Jv_NewStringUtf8Const (_Jv_FromReflectedField (this)->name);
42 return name;
45 jclass
46 java::lang::reflect::Field::getType ()
48 if (type == NULL)
50 jfieldID fld = _Jv_FromReflectedField (this);
51 JvSynchronize sync (declaringClass);
52 _Jv_Linker::resolve_field (fld, declaringClass->getClassLoaderInternal ());
53 type = fld->type;
55 return type;
58 static void*
59 getAddr (java::lang::reflect::Field* field, jclass caller, jobject obj,
60 jboolean checkFinal)
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.
73 if (checkFinal
74 && field->getModifiers() & java::lang::reflect::Modifier::FINAL)
75 throw new java::lang::IllegalAccessException(JvNewStringUTF
76 ("Field is final"));
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);
83 try
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);
101 return fld->u.addr;
103 else
105 if (obj == NULL)
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 ());
113 static jboolean
114 getBoolean (jclass cls, void* addr)
116 if (cls == JvPrimClass (boolean))
117 return * (jboolean *) addr;
118 throw new java::lang::IllegalArgumentException;
121 static jchar
122 getChar (jclass cls, void* addr)
124 if (cls == JvPrimClass (char))
125 return * (jchar *) addr;
126 throw new java::lang::IllegalArgumentException;
129 static jbyte
130 getByte (jclass cls, void* addr)
132 if (cls == JvPrimClass (byte))
133 return * (jbyte *) addr;
134 throw new java::lang::IllegalArgumentException;
137 static jshort
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;
147 static jint
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;
161 static jlong
162 getLong (jclass cls, void* addr)
164 if (cls == JvPrimClass (long))
165 return * (jlong *) addr;
166 return ::getInt(cls, addr);
169 static jfloat
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);
179 static jdouble
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);
191 jboolean
192 java::lang::reflect::Field::getBoolean (jclass caller, jobject obj)
194 return ::getBoolean (this->getType(), getAddr (this, caller, obj, false));
197 jchar
198 java::lang::reflect::Field::getChar (jclass caller, jobject obj)
200 return ::getChar (this->getType(), getAddr (this, caller, obj, false));
203 jbyte
204 java::lang::reflect::Field::getByte (jclass caller, jobject obj)
206 return ::getByte (this->getType(), getAddr (this, caller, obj, false));
209 jshort
210 java::lang::reflect::Field::getShort (jclass caller, jobject obj)
212 return ::getShort (this->getType(), getAddr (this, caller, obj, false));
215 jint
216 java::lang::reflect::Field::getInt (jclass caller, jobject obj)
218 return ::getInt (this->getType(), getAddr (this, caller, obj, false));
221 jlong
222 java::lang::reflect::Field::getLong (jclass caller, jobject obj)
224 return ::getLong (this->getType(), getAddr (this, caller, obj, false));
227 jfloat
228 java::lang::reflect::Field::getFloat (jclass caller, jobject obj)
230 return ::getFloat (this->getType(), getAddr (this, caller, obj, false));
233 jdouble
234 java::lang::reflect::Field::getDouble (jclass caller, jobject obj)
236 return ::getDouble (this->getType(), getAddr (this, caller, obj, false));
239 jobject
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;
265 else
266 return java::lang::Boolean::FALSE;
268 throw new java::lang::IllegalArgumentException;
271 static void
272 setBoolean (jclass type, void *addr, jboolean value)
274 if (type == JvPrimClass (boolean))
275 * (jboolean *) addr = value;
276 else
277 throw new java::lang::IllegalArgumentException;
280 static void
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;
293 else
294 throw new java::lang::IllegalArgumentException;
297 static void
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;
312 else
313 throw new java::lang::IllegalArgumentException;
316 static void
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;
329 else
330 throw new java::lang::IllegalArgumentException;
333 static void
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;
344 else
345 throw new java::lang::IllegalArgumentException;
348 static void
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;
357 else
358 throw new java::lang::IllegalArgumentException;
361 static void
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;
368 else
369 throw new java::lang::IllegalArgumentException;
372 static void
373 setDouble (jclass type, void *addr, jdouble value)
375 if (type == JvPrimClass (double))
376 * (jdouble *) addr = value;
377 else
378 throw new java::lang::IllegalArgumentException;
381 void
382 java::lang::reflect::Field::setBoolean (jclass caller, jobject obj, jboolean b,
383 jboolean checkFinal)
385 ::setBoolean (this->getType(), getAddr (this, caller, obj, checkFinal), b);
388 void
389 java::lang::reflect::Field::setChar (jclass caller, jobject obj, jchar c,
390 jboolean checkFinal)
392 ::setChar (this->getType(), getAddr (this, caller, obj, checkFinal), c);
395 void
396 java::lang::reflect::Field::setByte (jclass caller, jobject obj, jbyte b,
397 jboolean checkFinal)
399 ::setByte (this->getType(), getAddr (this, caller, obj, checkFinal), b);
402 void
403 java::lang::reflect::Field::setShort (jclass caller, jobject obj, jshort s,
404 jboolean checkFinal)
406 ::setShort (this->getType(), getAddr (this, caller, obj, checkFinal), s);
409 void
410 java::lang::reflect::Field::setInt (jclass caller, jobject obj, jint i,
411 jboolean checkFinal)
413 ::setInt (this->getType(), getAddr (this, caller, obj, checkFinal), i);
416 void
417 java::lang::reflect::Field::setLong (jclass caller, jobject obj, jlong l,
418 jboolean checkFinal)
420 ::setLong (this->getType(), getAddr (this, caller, obj, checkFinal), l);
423 void
424 java::lang::reflect::Field::setFloat (jclass caller, jobject obj, jfloat f,
425 jboolean checkFinal)
427 ::setFloat (this->getType(), getAddr (this, caller, obj, checkFinal), f);
430 void
431 java::lang::reflect::Field::setDouble (jclass caller, jobject obj, jdouble d,
432 jboolean checkFinal)
434 ::setDouble (this->getType(), getAddr (this, caller, obj, checkFinal), d);
437 void
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;