Merged?
[cacao.git] / src / native / vm / gnu / java_lang_reflect_Field.c
1 /* src/native/vm/gnu/java_lang_reflect_Field.c
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25 */
26
27
28 #include "config.h"
29
30 #include <assert.h>
31 #include <stdint.h>
32
33 #include "native/jni.h"
34 #include "native/llni.h"
35 #include "native/native.h"
36
37 #include "native/include/java_lang_Boolean.h"
38 #include "native/include/java_lang_Byte.h"
39 #include "native/include/java_lang_Character.h"
40 #include "native/include/java_lang_Short.h"
41 #include "native/include/java_lang_Integer.h"
42 #include "native/include/java_lang_Long.h"
43 #include "native/include/java_lang_Float.h"
44 #include "native/include/java_lang_Double.h"
45 #include "native/include/java_lang_Object.h"
46 #include "native/include/java_lang_Class.h"
47 #include "native/include/java_lang_String.h"
48
49 #include "native/include/java_lang_reflect_Field.h"
50
51 #if defined(ENABLE_ANNOTATIONS)
52 #include "native/include/java_util_Map.h"
53 #include "native/include/sun_reflect_ConstantPool.h"
54 #include "native/vm/reflect.h"
55 #endif
56
57 #include "vm/access.h"
58 #include "vm/builtin.h"
59 #include "vm/exceptions.h"
60 #include "vm/global.h"
61 #include "vm/initialize.h"
62 #include "vm/primitive.h"
63 #include "vm/resolve.h"
64 #include "vm/stringlocal.h"
65
66 #include "vm/jit/stacktrace.h"
67
68 #include "vmcore/loader.h"
69 #include "vmcore/utf8.h"
70
71
72 /* native methods implemented by this file ************************************/
73
74 static JNINativeMethod methods[] = {
75         { "getModifiersInternal", "()I",                                     (void *) (intptr_t) &Java_java_lang_reflect_Field_getModifiersInternal },
76         { "getType",              "()Ljava/lang/Class;",                     (void *) (intptr_t) &Java_java_lang_reflect_Field_getType              },
77         { "get",                  "(Ljava/lang/Object;)Ljava/lang/Object;",  (void *) (intptr_t) &Java_java_lang_reflect_Field_get                  },
78         { "getBoolean",           "(Ljava/lang/Object;)Z",                   (void *) (intptr_t) &Java_java_lang_reflect_Field_getBoolean           },
79         { "getByte",              "(Ljava/lang/Object;)B",                   (void *) (intptr_t) &Java_java_lang_reflect_Field_getByte              },
80         { "getChar",              "(Ljava/lang/Object;)C",                   (void *) (intptr_t) &Java_java_lang_reflect_Field_getChar              },
81         { "getShort",             "(Ljava/lang/Object;)S",                   (void *) (intptr_t) &Java_java_lang_reflect_Field_getShort             },
82         { "getInt",               "(Ljava/lang/Object;)I",                   (void *) (intptr_t) &Java_java_lang_reflect_Field_getInt               },
83         { "getLong",              "(Ljava/lang/Object;)J",                   (void *) (intptr_t) &Java_java_lang_reflect_Field_getLong              },
84         { "getFloat",             "(Ljava/lang/Object;)F",                   (void *) (intptr_t) &Java_java_lang_reflect_Field_getFloat             },
85         { "getDouble",            "(Ljava/lang/Object;)D",                   (void *) (intptr_t) &Java_java_lang_reflect_Field_getDouble            },
86         { "set",                  "(Ljava/lang/Object;Ljava/lang/Object;)V", (void *) (intptr_t) &Java_java_lang_reflect_Field_set                  },
87         { "setBoolean",           "(Ljava/lang/Object;Z)V",                  (void *) (intptr_t) &Java_java_lang_reflect_Field_setBoolean           },
88         { "setByte",              "(Ljava/lang/Object;B)V",                  (void *) (intptr_t) &Java_java_lang_reflect_Field_setByte              },
89         { "setChar",              "(Ljava/lang/Object;C)V",                  (void *) (intptr_t) &Java_java_lang_reflect_Field_setChar              },
90         { "setShort",             "(Ljava/lang/Object;S)V",                  (void *) (intptr_t) &Java_java_lang_reflect_Field_setShort             },
91         { "setInt",               "(Ljava/lang/Object;I)V",                  (void *) (intptr_t) &Java_java_lang_reflect_Field_setInt               },
92         { "setLong",              "(Ljava/lang/Object;J)V",                  (void *) (intptr_t) &Java_java_lang_reflect_Field_setLong              },
93         { "setFloat",             "(Ljava/lang/Object;F)V",                  (void *) (intptr_t) &Java_java_lang_reflect_Field_setFloat             },
94         { "setDouble",            "(Ljava/lang/Object;D)V",                  (void *) (intptr_t) &Java_java_lang_reflect_Field_setDouble            },
95         { "getSignature",         "()Ljava/lang/String;",                    (void *) (intptr_t) &Java_java_lang_reflect_Field_getSignature         },
96 #if defined(ENABLE_ANNOTATIONS)
97         { "declaredAnnotations",  "()Ljava/util/Map;",                       (void *) (intptr_t) &Java_java_lang_reflect_Field_declaredAnnotations  },
98 #endif
99 };
100
101
102 /* _Jv_java_lang_reflect_Field_init ********************************************
103
104    Register native functions.
105
106 *******************************************************************************/
107
108 void _Jv_java_lang_reflect_Field_init(void)
109 {
110         utf *u;
111
112         u = utf_new_char("java/lang/reflect/Field");
113
114         native_method_register(u, methods, NATIVE_METHODS_COUNT);
115 }
116
117
118 /* _field_access_check *********************************************************
119
120    Checks if the field can be accessed.
121
122    RETURN VALUE:
123       true......field can be accessed, or
124       false.....otherwise (maybe an Exception was thrown).
125
126 *******************************************************************************/
127
128 static bool _field_access_check(java_lang_reflect_Field *this,
129                                                                 fieldinfo *f, classinfo *c, java_handle_t *o)
130 {
131         int32_t flag;
132
133         /* check if we should bypass security checks (AccessibleObject) */
134
135         LLNI_field_get_val(this, flag, flag);
136         if (flag == false) {
137                 /* this function is always called like this:
138                            java.lang.reflect.Field.xxx (Native Method)
139                    [0] <caller>
140                 */
141                 if (!access_check_field(f, 0))
142                         return false;
143         }
144
145         /* some general checks */
146
147         if (f->flags & ACC_STATIC) {
148                 /* initialize class if required */
149
150                 if (!(c->state & CLASS_INITIALIZED))
151                         if (!initialize_class(c))
152                                 return false;
153
154                 /* everything is ok */
155
156                 return true;
157
158         } else {
159                 /* obj is required for not-static fields */
160
161                 if (o == NULL) {
162                         exceptions_throw_nullpointerexception();
163                         return false;
164                 }
165         
166                 if (builtin_instanceof(o, c))
167                         return true;
168         }
169
170         /* exception path */
171
172         exceptions_throw_illegalargumentexception();
173         return false;
174 }
175
176
177 /* _field_get_type *************************************************************
178
179    Returns the content of the given field.
180
181 *******************************************************************************/
182
183 #define _FIELD_GET_TYPE(name, type, uniontype) \
184 static inline type _field_get_##name(fieldinfo *f, java_lang_Object *o) \
185 { \
186         type ret; \
187         if (f->flags & ACC_STATIC) { \
188                 ret = f->value->uniontype; \
189         } else { \
190                 LLNI_CRITICAL_START; \
191                 ret = *(type *) (((intptr_t) LLNI_DIRECT(o)) + f->offset); \
192                 LLNI_CRITICAL_END; \
193         } \
194         return ret; \
195 }
196
197 static inline java_handle_t *_field_get_handle(fieldinfo *f, java_lang_Object *o)
198 {
199         java_object_t *obj;
200         java_handle_t *hdl;
201
202         LLNI_CRITICAL_START;
203
204         if (f->flags & ACC_STATIC) {
205                 obj = f->value->a;
206         } else {
207                 obj = *(java_object_t **) (((intptr_t) LLNI_DIRECT(o)) + f->offset);
208         }
209
210         hdl = LLNI_WRAP(obj);
211
212         LLNI_CRITICAL_END;
213
214         return hdl;
215 }
216
217 _FIELD_GET_TYPE(int,    int32_t, i)
218 _FIELD_GET_TYPE(long,   int64_t, l)
219 _FIELD_GET_TYPE(float,  float,   f)
220 _FIELD_GET_TYPE(double, double,  d)
221
222
223 /* _field_set_type *************************************************************
224
225    Sets the content of the given field to the given value.
226
227 *******************************************************************************/
228
229 #define _FIELD_SET_TYPE(name, type, uniontype) \
230 static inline void _field_set_##name(fieldinfo *f, java_lang_Object *o, type value) \
231 { \
232         if (f->flags & ACC_STATIC) { \
233                 f->value->uniontype = value; \
234         } else { \
235                 LLNI_CRITICAL_START; \
236                 *(type *) (((intptr_t) LLNI_DIRECT(o)) + f->offset) = value; \
237                 LLNI_CRITICAL_END; \
238         } \
239 }
240
241 static inline void _field_set_handle(fieldinfo *f, java_lang_Object *o, java_handle_t *value)
242 {
243         LLNI_CRITICAL_START;
244
245         if (f->flags & ACC_STATIC) {
246                 f->value->a = LLNI_DIRECT(value);
247         } else {
248                 *(java_object_t **) (((intptr_t) LLNI_DIRECT(o)) + f->offset) = LLNI_DIRECT(value);
249         }
250
251         LLNI_CRITICAL_END;
252 }
253
254 _FIELD_SET_TYPE(int,    int32_t, i)
255 _FIELD_SET_TYPE(long,   int64_t, l)
256 _FIELD_SET_TYPE(float,  float,   f)
257 _FIELD_SET_TYPE(double, double,  d)
258
259
260 /*
261  * Class:     java/lang/reflect/Field
262  * Method:    getModifiersInternal
263  * Signature: ()I
264  */
265 JNIEXPORT int32_t JNICALL Java_java_lang_reflect_Field_getModifiersInternal(JNIEnv *env, java_lang_reflect_Field *this)
266 {
267         classinfo *c;
268         fieldinfo *f;
269         int32_t    slot;
270
271         LLNI_field_get_cls(this, clazz, c);
272         LLNI_field_get_val(this, slot , slot);
273         f = &(c->fields[slot]);
274
275         return f->flags;
276 }
277
278
279 /*
280  * Class:     java/lang/reflect/Field
281  * Method:    getType
282  * Signature: ()Ljava/lang/Class;
283  */
284 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_reflect_Field_getType(JNIEnv *env, java_lang_reflect_Field *this)
285 {
286         classinfo *c;
287         typedesc  *desc;
288         classinfo *ret;
289         int32_t    slot;
290
291         LLNI_field_get_cls(this, clazz, c);
292         LLNI_field_get_val(this, slot , slot);
293         desc = c->fields[slot].parseddesc;
294
295         if (desc == NULL)
296                 return NULL;
297
298         if (!resolve_class_from_typedesc(desc, true, false, &ret))
299                 return NULL;
300         
301         return LLNI_classinfo_wrap(ret);
302 }
303
304
305 /*
306  * Class:     java/lang/reflect/Field
307  * Method:    get
308  * Signature: (Ljava/lang/Object;)Ljava/lang/Object;
309  */
310 JNIEXPORT java_lang_Object* JNICALL Java_java_lang_reflect_Field_get(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *o)
311 {
312         classinfo *c;
313         fieldinfo *f;
314         int32_t    slot;
315         imm_union  value;
316         java_handle_t *object;
317
318         LLNI_field_get_cls(this, clazz, c);
319         LLNI_field_get_val(this, slot , slot);
320         f = &c->fields[slot];
321
322         /* check if the field can be accessed */
323
324         if (!_field_access_check(this, f, c, (java_handle_t *) o))
325                 return NULL;
326
327         switch (f->parseddesc->decltype) {
328         case PRIMITIVETYPE_BOOLEAN:
329         case PRIMITIVETYPE_BYTE:
330         case PRIMITIVETYPE_CHAR:
331         case PRIMITIVETYPE_SHORT:
332         case PRIMITIVETYPE_INT:
333                 value.i = _field_get_int(f, o);
334                 break;
335
336         case PRIMITIVETYPE_LONG:
337                 value.l = _field_get_long(f, o);
338                 break;
339
340         case PRIMITIVETYPE_FLOAT:
341                 value.f = _field_get_float(f, o);
342                 break;
343
344         case PRIMITIVETYPE_DOUBLE:
345                 value.d = _field_get_double(f, o);
346                 break;
347
348         case TYPE_ADR:
349                 return (java_lang_Object *) _field_get_handle(f, o);
350         }
351
352         /* Now box the primitive types. */
353
354         object = primitive_box(f->parseddesc->decltype, value);
355
356         return (java_lang_Object *) object;
357 }
358
359
360 /*
361  * Class:     java/lang/reflect/Field
362  * Method:    getBoolean
363  * Signature: (Ljava/lang/Object;)Z
364  */
365 JNIEXPORT int32_t JNICALL Java_java_lang_reflect_Field_getBoolean(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *o)
366 {
367         classinfo *c;
368         fieldinfo *f;
369         int32_t    slot;
370
371         /* get the class and the field */
372
373         LLNI_field_get_cls(this, clazz, c);
374         LLNI_field_get_val(this, slot , slot);
375         f = &c->fields[slot];
376
377         /* check if the field can be accessed */
378
379         if (!_field_access_check(this, f, c, (java_handle_t *) o))
380                 return 0;
381
382         /* check the field type and return the value */
383
384         switch (f->parseddesc->decltype) {
385         case PRIMITIVETYPE_BOOLEAN:
386                 return (int32_t) _field_get_int(f, o);
387         default:
388                 exceptions_throw_illegalargumentexception();
389                 return 0;
390         }
391 }
392
393
394 /*
395  * Class:     java/lang/reflect/Field
396  * Method:    getByte
397  * Signature: (Ljava/lang/Object;)B
398  */
399 JNIEXPORT int32_t JNICALL Java_java_lang_reflect_Field_getByte(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *o)
400 {
401         classinfo *c;
402         fieldinfo *f;
403         int32_t    slot;
404
405         /* get the class and the field */
406
407         LLNI_field_get_cls(this, clazz, c);
408         LLNI_field_get_val(this, slot , slot);
409         f = &c->fields[slot];
410
411         /* check if the field can be accessed */
412
413         if (!_field_access_check(this, f, c, (java_handle_t *) o))
414                 return 0;
415
416         /* check the field type and return the value */
417
418         switch (f->parseddesc->decltype) {
419         case PRIMITIVETYPE_BYTE:
420                 return (int32_t) _field_get_int(f, o);
421         default:
422                 exceptions_throw_illegalargumentexception();
423                 return 0;
424         }
425 }
426
427
428 /*
429  * Class:     java/lang/reflect/Field
430  * Method:    getChar
431  * Signature: (Ljava/lang/Object;)C
432  */
433 JNIEXPORT int32_t JNICALL Java_java_lang_reflect_Field_getChar(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *o)
434 {
435         classinfo *c;
436         fieldinfo *f;
437         int32_t    slot;
438
439         /* get the class and the field */
440
441         LLNI_field_get_cls(this, clazz, c);
442         LLNI_field_get_val(this, slot , slot);
443         f = &c->fields[slot];
444
445         /* check if the field can be accessed */
446
447         if (!_field_access_check(this, f, c, (java_handle_t *) o))
448                 return 0;
449
450         /* check the field type and return the value */
451
452         switch (f->parseddesc->decltype) {
453         case PRIMITIVETYPE_CHAR:
454                 return (int32_t) _field_get_int(f, o);
455         default:
456                 exceptions_throw_illegalargumentexception();
457                 return 0;
458         }
459 }
460
461
462 /*
463  * Class:     java/lang/reflect/Field
464  * Method:    getShort
465  * Signature: (Ljava/lang/Object;)S
466  */
467 JNIEXPORT int32_t JNICALL Java_java_lang_reflect_Field_getShort(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *o)
468 {
469         classinfo *c;
470         fieldinfo *f;
471         int32_t    slot;
472
473         /* get the class and the field */
474
475         LLNI_field_get_cls(this, clazz, c);
476         LLNI_field_get_val(this, slot , slot);
477         f = &c->fields[slot];
478
479         /* check if the field can be accessed */
480
481         if (!_field_access_check(this, f, c, (java_handle_t *) o))
482                 return 0;
483
484         /* check the field type and return the value */
485
486         switch (f->parseddesc->decltype) {
487         case PRIMITIVETYPE_BYTE:
488         case PRIMITIVETYPE_SHORT:
489                 return (int32_t) _field_get_int(f, o);
490         default:
491                 exceptions_throw_illegalargumentexception();
492                 return 0;
493         }
494 }
495
496
497 /*
498  * Class:     java/lang/reflect/Field
499  * Method:    getInt
500  * Signature: (Ljava/lang/Object;)I
501  */
502 JNIEXPORT int32_t JNICALL Java_java_lang_reflect_Field_getInt(JNIEnv *env , java_lang_reflect_Field *this, java_lang_Object *o)
503 {
504         classinfo *c;
505         fieldinfo *f;
506         int32_t    slot;
507
508         /* get the class and the field */
509
510         LLNI_field_get_cls(this, clazz, c);
511         LLNI_field_get_val(this, slot , slot);
512         f = &c->fields[slot];
513
514         /* check if the field can be accessed */
515
516         if (!_field_access_check(this, f, c, (java_handle_t *) o))
517                 return 0;
518
519         /* check the field type and return the value */
520
521         switch (f->parseddesc->decltype) {
522         case PRIMITIVETYPE_BYTE:
523         case PRIMITIVETYPE_CHAR:
524         case PRIMITIVETYPE_SHORT:
525         case PRIMITIVETYPE_INT:
526                 return (int32_t) _field_get_int(f, o);
527         default:
528                 exceptions_throw_illegalargumentexception();
529                 return 0;
530         }
531 }
532
533
534 /*
535  * Class:     java/lang/reflect/Field
536  * Method:    getLong
537  * Signature: (Ljava/lang/Object;)J
538  */
539 JNIEXPORT int64_t JNICALL Java_java_lang_reflect_Field_getLong(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *o)
540 {
541         classinfo *c;
542         fieldinfo *f;
543         int32_t    slot;
544
545         /* get the class and the field */
546
547         LLNI_field_get_cls(this, clazz, c);
548         LLNI_field_get_val(this, slot , slot);
549         f = &c->fields[slot];
550
551         /* check if the field can be accessed */
552
553         if (!_field_access_check(this, f, c, (java_handle_t *) o))
554                 return 0;
555
556         /* check the field type and return the value */
557
558         switch (f->parseddesc->decltype) {
559         case PRIMITIVETYPE_BYTE:
560         case PRIMITIVETYPE_CHAR:
561         case PRIMITIVETYPE_SHORT:
562         case PRIMITIVETYPE_INT:
563                 return (int64_t) _field_get_int(f, o);
564         case PRIMITIVETYPE_LONG:
565                 return (int64_t) _field_get_long(f, o);
566         default:
567                 exceptions_throw_illegalargumentexception();
568                 return 0;
569         }
570 }
571
572
573 /*
574  * Class:     java/lang/reflect/Field
575  * Method:    getFloat
576  * Signature: (Ljava/lang/Object;)F
577  */
578 JNIEXPORT float JNICALL Java_java_lang_reflect_Field_getFloat(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *o)
579 {
580         classinfo *c;
581         fieldinfo *f;
582         int32_t    slot;
583
584         /* get the class and the field */
585
586         LLNI_field_get_cls(this, clazz, c);
587         LLNI_field_get_val(this, slot , slot);
588         f = &c->fields[slot];
589
590         /* check if the field can be accessed */
591
592         if (!_field_access_check(this, f, c, (java_handle_t *) o))
593                 return 0;
594
595         /* check the field type and return the value */
596
597         switch (f->parseddesc->decltype) {
598         case PRIMITIVETYPE_BYTE:
599         case PRIMITIVETYPE_CHAR:
600         case PRIMITIVETYPE_SHORT:
601         case PRIMITIVETYPE_INT:
602                 return (float) _field_get_int(f, o);
603         case PRIMITIVETYPE_LONG:
604                 return (float) _field_get_long(f, o);
605         case PRIMITIVETYPE_FLOAT:
606                 return (float) _field_get_float(f, o);
607         default:
608                 exceptions_throw_illegalargumentexception();
609                 return 0;
610         }
611 }
612
613
614 /*
615  * Class:     java/lang/reflect/Field
616  * Method:    getDouble
617  * Signature: (Ljava/lang/Object;)D
618  */
619 JNIEXPORT double JNICALL Java_java_lang_reflect_Field_getDouble(JNIEnv *env , java_lang_reflect_Field *this, java_lang_Object *o)
620 {
621         classinfo *c;
622         fieldinfo *f;
623         int32_t    slot;
624
625         /* get the class and the field */
626
627         LLNI_field_get_cls(this, clazz, c);
628         LLNI_field_get_val(this, slot , slot);
629         f = &c->fields[slot];
630
631         /* check if the field can be accessed */
632
633         if (!_field_access_check(this, f, c, (java_handle_t *) o))
634                 return 0;
635
636         /* check the field type and return the value */
637
638         switch (f->parseddesc->decltype) {
639         case PRIMITIVETYPE_BYTE:
640         case PRIMITIVETYPE_CHAR:
641         case PRIMITIVETYPE_SHORT:
642         case PRIMITIVETYPE_INT:
643                 return (double) _field_get_int(f, o);
644         case PRIMITIVETYPE_LONG:
645                 return (double) _field_get_long(f, o);
646         case PRIMITIVETYPE_FLOAT:
647                 return (double) _field_get_float(f, o);
648         case PRIMITIVETYPE_DOUBLE:
649                 return (double) _field_get_double(f, o);
650         default:
651                 exceptions_throw_illegalargumentexception();
652                 return 0;
653         }
654 }
655
656
657 /*
658  * Class:     java/lang/reflect/Field
659  * Method:    set
660  * Signature: (Ljava/lang/Object;Ljava/lang/Object;)V
661  */
662 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_set(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *o, java_lang_Object *value)
663 {
664         classinfo *sc;
665         classinfo *dc;
666         fieldinfo *sf;
667         fieldinfo *df;
668         int32_t    slot;
669
670         /* get the class and the field */
671
672         LLNI_field_get_cls(this, clazz, dc);
673         LLNI_field_get_val(this, slot , slot);
674         df = &dc->fields[slot];
675
676         /* check if the field can be accessed */
677
678         if (!_field_access_check(this, df, dc, (java_handle_t *) o))
679                 return;
680
681         /* get the source classinfo from the object */
682
683         if (value == NULL)
684                 sc = NULL;
685         else
686                 LLNI_class_get(value, sc);
687
688         /* The fieldid is used to set the new value, for primitive
689            types the value has to be retrieved from the wrapping
690            object */
691
692         switch (df->parseddesc->decltype) {
693         case PRIMITIVETYPE_BOOLEAN: {
694                 int32_t val;
695
696                 /* determine the field to read the value */
697
698                 if ((sc == NULL) || !(sf = class_findfield(sc, utf_value, utf_Z)))
699                         break;
700
701                 switch (sf->parseddesc->decltype) {
702                 case PRIMITIVETYPE_BOOLEAN:
703                         LLNI_field_get_val((java_lang_Boolean *) value, value, val);
704                         break;
705                 default:
706                         exceptions_throw_illegalargumentexception();
707                         return;
708                 }
709
710                 _field_set_int(df, o, val);
711                 return;
712         }
713
714         case PRIMITIVETYPE_BYTE: {
715                 int32_t val;
716
717                 if ((sc == NULL) || !(sf = class_findfield(sc, utf_value, utf_B)))
718                         break;
719
720                 switch (sf->parseddesc->decltype) {
721                 case PRIMITIVETYPE_BYTE:
722                         LLNI_field_get_val((java_lang_Byte *) value, value, val);
723                         break;
724                 default:        
725                         exceptions_throw_illegalargumentexception();
726                         return;
727                 }
728
729                 _field_set_int(df, o, val);
730                 return;
731         }
732
733         case PRIMITIVETYPE_CHAR: {
734                 int32_t val;
735
736                 if ((sc == NULL) || !(sf = class_findfield(sc, utf_value, utf_C)))
737                         break;
738                                    
739                 switch (sf->parseddesc->decltype) {
740                 case PRIMITIVETYPE_CHAR:
741                         LLNI_field_get_val((java_lang_Character *) value, value, val);
742                         break;
743                 default:
744                         exceptions_throw_illegalargumentexception();
745                         return;
746                 }
747
748                 _field_set_int(df, o, val);
749                 return;
750         }
751
752         case PRIMITIVETYPE_SHORT: {
753                 int32_t val;
754
755                 /* get field only by name, it can be one of B, S */
756
757                 if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
758                         break;
759                                    
760                 switch (sf->parseddesc->decltype) {
761                 case PRIMITIVETYPE_BYTE:
762                         LLNI_field_get_val((java_lang_Byte *) value, value, val);
763                         break;
764                 case PRIMITIVETYPE_SHORT:
765                         LLNI_field_get_val((java_lang_Short *) value, value, val);
766                         break;
767                 default:
768                         exceptions_throw_illegalargumentexception();
769                         return;
770                 }
771
772                 _field_set_int(df, o, val);
773                 return;
774         }
775
776         case PRIMITIVETYPE_INT: {
777                 int32_t val;
778
779                 /* get field only by name, it can be one of B, S, C, I */
780
781                 if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
782                         break;
783
784                 switch (sf->parseddesc->decltype) {
785                 case PRIMITIVETYPE_BYTE:
786                         LLNI_field_get_val((java_lang_Byte *) value, value, val);
787                         break;
788                 case PRIMITIVETYPE_CHAR:
789                         LLNI_field_get_val((java_lang_Character *) value, value, val);
790                         break;
791                 case PRIMITIVETYPE_SHORT:
792                         LLNI_field_get_val((java_lang_Short *) value, value, val);
793                         break;
794                 case PRIMITIVETYPE_INT:
795                         LLNI_field_get_val((java_lang_Integer *) value, value, val);
796                         break;
797                 default:
798                         exceptions_throw_illegalargumentexception();
799                         return;
800                 }
801
802                 _field_set_int(df, o, val);
803                 return;
804         }
805
806         case PRIMITIVETYPE_LONG: {
807                 int64_t val;
808
809                 /* get field only by name, it can be one of B, S, C, I, J */
810
811                 if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
812                         break;
813
814                 switch (sf->parseddesc->decltype) {
815                 case PRIMITIVETYPE_BYTE:
816                         LLNI_field_get_val((java_lang_Byte *) value, value, val);
817                         break;
818                 case PRIMITIVETYPE_CHAR:
819                         LLNI_field_get_val((java_lang_Character *) value, value, val);
820                         break;
821                 case PRIMITIVETYPE_SHORT:
822                         LLNI_field_get_val((java_lang_Short *) value, value, val);
823                         break;
824                 case PRIMITIVETYPE_INT:
825                         LLNI_field_get_val((java_lang_Integer *) value, value, val);
826                         break;
827                 case PRIMITIVETYPE_LONG:
828                         LLNI_field_get_val((java_lang_Long *) value, value, val);
829                         break;
830                 default:
831                         exceptions_throw_illegalargumentexception();
832                         return;
833                 }
834
835                 _field_set_long(df, o, val);
836                 return;
837         }
838
839         case PRIMITIVETYPE_FLOAT: {
840                 float val;
841
842                 /* get field only by name, it can be one of B, S, C, I, J, F */
843
844                 if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
845                         break;
846
847                 switch (sf->parseddesc->decltype) {
848                 case PRIMITIVETYPE_BYTE:
849                         LLNI_field_get_val((java_lang_Byte *) value, value, val);
850                         break;
851                 case PRIMITIVETYPE_CHAR:
852                         LLNI_field_get_val((java_lang_Character *) value, value, val);
853                         break;
854                 case PRIMITIVETYPE_SHORT:
855                         LLNI_field_get_val((java_lang_Short *) value, value, val);
856                         break;
857                 case PRIMITIVETYPE_INT:
858                         LLNI_field_get_val((java_lang_Integer *) value, value, val);
859                         break;
860                 case PRIMITIVETYPE_LONG:
861                         LLNI_field_get_val((java_lang_Long *) value, value, val);
862                         break;
863                 case PRIMITIVETYPE_FLOAT:
864                         LLNI_field_get_val((java_lang_Float *) value, value, val);
865                         break;
866                 default:
867                         exceptions_throw_illegalargumentexception();
868                         return;
869                 }
870
871                 _field_set_float(df, o, val);
872                 return;
873         }
874
875         case PRIMITIVETYPE_DOUBLE: {
876                 double val;
877
878                 /* get field only by name, it can be one of B, S, C, I, J, F, D */
879
880                 if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
881                         break;
882
883                 switch (sf->parseddesc->decltype) {
884                 case PRIMITIVETYPE_BYTE:
885                         LLNI_field_get_val((java_lang_Byte *) value, value, val);
886                         break;
887                 case PRIMITIVETYPE_CHAR:
888                         LLNI_field_get_val((java_lang_Character *) value, value, val);
889                         break;
890                 case PRIMITIVETYPE_SHORT:
891                         LLNI_field_get_val((java_lang_Short *) value, value, val);
892                         break;
893                 case PRIMITIVETYPE_INT:
894                         LLNI_field_get_val((java_lang_Integer *) value, value, val);
895                         break;
896                 case PRIMITIVETYPE_LONG:
897                         LLNI_field_get_val((java_lang_Long *) value, value, val);
898                         break;
899                 case PRIMITIVETYPE_FLOAT:
900                         LLNI_field_get_val((java_lang_Float *) value, value, val);
901                         break;
902                 case PRIMITIVETYPE_DOUBLE:
903                         LLNI_field_get_val((java_lang_Double *) value, value, val);
904                         break;
905                 default:
906                         exceptions_throw_illegalargumentexception();
907                         return;
908                 }
909
910                 _field_set_double(df, o, val);
911                 return;
912         }
913
914         case TYPE_ADR:
915                 /* check if value is an instance of the destination class */
916
917                 /* XXX TODO */
918                 /*                      if (!builtin_instanceof((java_handle_t *) value, df->class)) */
919                 /*                              break; */
920
921                 _field_set_handle(df, o, (java_handle_t *) value);
922                 return;
923         }
924
925         /* raise exception */
926
927         exceptions_throw_illegalargumentexception();
928 }
929
930
931 /*
932  * Class:     java/lang/reflect/Field
933  * Method:    setBoolean
934  * Signature: (Ljava/lang/Object;Z)V
935  */
936 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setBoolean(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *o, int32_t value)
937 {
938         classinfo *c;
939         fieldinfo *f;
940         int32_t    slot;
941
942         /* get the class and the field */
943
944         LLNI_field_get_cls(this, clazz, c);
945         LLNI_field_get_val(this, slot , slot);
946         f = &c->fields[slot];
947
948         /* check if the field can be accessed */
949
950         if (!_field_access_check(this, f, c, (java_handle_t *) o))
951                 return;
952
953         /* check the field type and set the value */
954
955         switch (f->parseddesc->decltype) {
956         case PRIMITIVETYPE_BOOLEAN:
957                 _field_set_int(f, o, value);
958                 break;
959         default:
960                 exceptions_throw_illegalargumentexception();
961         }
962
963         return;
964 }
965
966
967 /*
968  * Class:     java/lang/reflect/Field
969  * Method:    setByte
970  * Signature: (Ljava/lang/Object;B)V
971  */
972 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setByte(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *o, int32_t value)
973 {
974         classinfo *c;
975         fieldinfo *f;
976         int32_t    slot;
977
978         /* get the class and the field */
979
980         LLNI_field_get_cls(this, clazz, c);
981         LLNI_field_get_val(this, slot , slot);
982         f = &c->fields[slot];
983
984         /* check if the field can be accessed */
985
986         if (!_field_access_check(this, f, c, (java_handle_t *) o))
987                 return;
988
989         /* check the field type and set the value */
990
991         switch (f->parseddesc->decltype) {
992         case PRIMITIVETYPE_BYTE:
993         case PRIMITIVETYPE_SHORT:
994         case PRIMITIVETYPE_INT:
995                 _field_set_int(f, o, value);
996                 break;
997         case PRIMITIVETYPE_LONG:
998                 _field_set_long(f, o, value);
999                 break;
1000         case PRIMITIVETYPE_FLOAT:
1001                 _field_set_float(f, o, value);
1002                 break;
1003         case PRIMITIVETYPE_DOUBLE:
1004                 _field_set_double(f, o, value);
1005                 break;
1006         default:
1007                 exceptions_throw_illegalargumentexception();
1008         }
1009
1010         return;
1011 }
1012
1013
1014 /*
1015  * Class:     java/lang/reflect/Field
1016  * Method:    setChar
1017  * Signature: (Ljava/lang/Object;C)V
1018  */
1019 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setChar(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *o, int32_t value)
1020 {
1021         classinfo *c;
1022         fieldinfo *f;
1023         int32_t    slot;
1024
1025         /* get the class and the field */
1026
1027         LLNI_field_get_cls(this, clazz, c);
1028         LLNI_field_get_val(this, slot , slot);
1029         f = &c->fields[slot];
1030
1031         /* check if the field can be accessed */
1032
1033         if (!_field_access_check(this, f, c, (java_handle_t *) o))
1034                 return;
1035
1036         /* check the field type and set the value */
1037
1038         switch (f->parseddesc->decltype) {
1039         case PRIMITIVETYPE_CHAR:
1040         case PRIMITIVETYPE_INT:
1041                 _field_set_int(f, o, value);
1042                 break;
1043         case PRIMITIVETYPE_LONG:
1044                 _field_set_long(f, o, value);
1045                 break;
1046         case PRIMITIVETYPE_FLOAT:
1047                 _field_set_float(f, o, value);
1048                 break;
1049         case PRIMITIVETYPE_DOUBLE:
1050                 _field_set_double(f, o, value);
1051                 break;
1052         default:
1053                 exceptions_throw_illegalargumentexception();
1054         }
1055
1056         return;
1057 }
1058
1059
1060 /*
1061  * Class:     java/lang/reflect/Field
1062  * Method:    setShort
1063  * Signature: (Ljava/lang/Object;S)V
1064  */
1065 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setShort(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *o, int32_t value)
1066 {
1067         classinfo *c;
1068         fieldinfo *f;
1069         int32_t    slot;
1070
1071         /* get the class and the field */
1072
1073         LLNI_field_get_cls(this, clazz, c);
1074         LLNI_field_get_val(this, slot , slot);
1075         f = &c->fields[slot];
1076
1077         /* check if the field can be accessed */
1078
1079         if (!_field_access_check(this, f, c, (java_handle_t *) o))
1080                 return;
1081
1082         /* check the field type and set the value */
1083
1084         switch (f->parseddesc->decltype) {
1085         case PRIMITIVETYPE_SHORT:
1086         case PRIMITIVETYPE_INT:
1087                 _field_set_int(f, o, value);
1088                 break;
1089         case PRIMITIVETYPE_LONG:
1090                 _field_set_long(f, o, value);
1091                 break;
1092         case PRIMITIVETYPE_FLOAT:
1093                 _field_set_float(f, o, value);
1094                 break;
1095         case PRIMITIVETYPE_DOUBLE:
1096                 _field_set_double(f, o, value);
1097                 break;
1098         default:
1099                 exceptions_throw_illegalargumentexception();
1100         }
1101
1102         return;
1103 }
1104
1105
1106 /*
1107  * Class:     java/lang/reflect/Field
1108  * Method:    setInt
1109  * Signature: (Ljava/lang/Object;I)V
1110  */
1111 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setInt(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *o, int32_t value)
1112 {
1113         classinfo *c;
1114         fieldinfo *f;
1115         int32_t    slot;
1116
1117         /* get the class and the field */
1118
1119         LLNI_field_get_cls(this, clazz, c);
1120         LLNI_field_get_val(this, slot , slot);
1121         f = &c->fields[slot];
1122
1123         /* check if the field can be accessed */
1124
1125         if (!_field_access_check(this, f, c, (java_handle_t *) o))
1126                 return;
1127
1128         /* check the field type and set the value */
1129
1130         switch (f->parseddesc->decltype) {
1131         case PRIMITIVETYPE_INT:
1132                 _field_set_int(f, o, value);
1133                 break;
1134         case PRIMITIVETYPE_LONG:
1135                 _field_set_long(f, o, value);
1136                 break;
1137         case PRIMITIVETYPE_FLOAT:
1138                 _field_set_float(f, o, value);
1139                 break;
1140         case PRIMITIVETYPE_DOUBLE:
1141                 _field_set_double(f, o, value);
1142                 break;
1143         default:
1144                 exceptions_throw_illegalargumentexception();
1145         }
1146
1147         return;
1148 }
1149
1150
1151 /*
1152  * Class:     java/lang/reflect/Field
1153  * Method:    setLong
1154  * Signature: (Ljava/lang/Object;J)V
1155  */
1156 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setLong(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *o, int64_t value)
1157 {
1158         classinfo *c;
1159         fieldinfo *f;
1160         int32_t    slot;
1161
1162         /* get the class and the field */
1163
1164         LLNI_field_get_cls(this, clazz, c);
1165         LLNI_field_get_val(this, slot , slot);
1166         f = &c->fields[slot];
1167
1168         /* check if the field can be accessed */
1169
1170         if (!_field_access_check(this, f, c, (java_handle_t *) o))
1171                 return;
1172
1173         /* check the field type and set the value */
1174
1175         switch (f->parseddesc->decltype) {
1176         case PRIMITIVETYPE_LONG:
1177                 _field_set_long(f, o, value);
1178                 break;
1179         case PRIMITIVETYPE_FLOAT:
1180                 _field_set_float(f, o, value);
1181                 break;
1182         case PRIMITIVETYPE_DOUBLE:
1183                 _field_set_double(f, o, value);
1184                 break;
1185         default:
1186                 exceptions_throw_illegalargumentexception();
1187         }
1188
1189         return;
1190 }
1191
1192
1193 /*
1194  * Class:     java/lang/reflect/Field
1195  * Method:    setFloat
1196  * Signature: (Ljava/lang/Object;F)V
1197  */
1198 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setFloat(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *o, float value)
1199 {
1200         classinfo *c;
1201         fieldinfo *f;
1202         int32_t    slot;
1203
1204         /* get the class and the field */
1205
1206         LLNI_field_get_cls(this, clazz, c);
1207         LLNI_field_get_val(this, slot , slot);
1208         f = &c->fields[slot];
1209
1210         /* check if the field can be accessed */
1211
1212         if (!_field_access_check(this, f, c, (java_handle_t *) o))
1213                 return;
1214
1215         /* check the field type and set the value */
1216
1217         switch (f->parseddesc->decltype) {
1218         case PRIMITIVETYPE_FLOAT:
1219                 _field_set_float(f, o, value);
1220                 break;
1221         case PRIMITIVETYPE_DOUBLE:
1222                 _field_set_double(f, o, value);
1223                 break;
1224         default:
1225                 exceptions_throw_illegalargumentexception();
1226         }
1227
1228         return;
1229 }
1230
1231
1232 /*
1233  * Class:     java/lang/reflect/Field
1234  * Method:    setDouble
1235  * Signature: (Ljava/lang/Object;D)V
1236  */
1237 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setDouble(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *o, double value)
1238 {
1239         classinfo *c;
1240         fieldinfo *f;
1241         int32_t    slot;
1242
1243         /* get the class and the field */
1244
1245         LLNI_field_get_cls(this, clazz, c);
1246         LLNI_field_get_val(this, slot , slot);
1247         f = &c->fields[slot];
1248
1249         /* check if the field can be accessed */
1250
1251         if (!_field_access_check(this, f, c, (java_handle_t *) o))
1252                 return;
1253
1254         /* check the field type and set the value */
1255
1256         switch (f->parseddesc->decltype) {
1257         case PRIMITIVETYPE_DOUBLE:
1258                 _field_set_double(f, o, value);
1259                 break;
1260         default:
1261                 exceptions_throw_illegalargumentexception();
1262         }
1263
1264         return;
1265 }
1266
1267
1268 /*
1269  * Class:     java/lang/reflect/Field
1270  * Method:    getSignature
1271  * Signature: ()Ljava/lang/String;
1272  */
1273 JNIEXPORT java_lang_String* JNICALL Java_java_lang_reflect_Field_getSignature(JNIEnv *env, java_lang_reflect_Field* this)
1274 {
1275         classinfo     *c;
1276         fieldinfo     *f;
1277         java_handle_t *o;
1278         int32_t        slot;
1279
1280         /* get the class and the field */
1281
1282         LLNI_field_get_cls(this, clazz, c);
1283         LLNI_field_get_val(this, slot , slot);
1284         f = &c->fields[slot];
1285
1286         if (f->signature == NULL)
1287                 return NULL;
1288
1289         o = javastring_new(f->signature);
1290
1291         /* in error case o is NULL */
1292
1293         return (java_lang_String *) o;
1294 }
1295
1296
1297 #if defined(ENABLE_ANNOTATIONS)
1298 /*
1299  * Class:     java/lang/reflect/Field
1300  * Method:    declaredAnnotations
1301  * Signature: ()Ljava/util/Map;
1302  */
1303 JNIEXPORT struct java_util_Map* JNICALL Java_java_lang_reflect_Field_declaredAnnotations(JNIEnv *env, java_lang_reflect_Field *this)
1304 {
1305         java_util_Map           *declaredAnnotations = NULL; /* parsed annotations                                */
1306         java_handle_bytearray_t *annotations         = NULL; /* unparsed annotations                              */
1307         java_lang_Class         *declaringClass      = NULL; /* the constant pool of this class is used           */
1308         classinfo               *referer             = NULL; /* class, which calles the annotation parser         */
1309                                                              /* (for the parameter 'referer' of vm_call_method()) */
1310
1311         LLNI_field_get_ref(this, declaredAnnotations, declaredAnnotations);
1312
1313         /* are the annotations parsed yet? */
1314         if (declaredAnnotations == NULL) {
1315                 LLNI_field_get_ref(this, annotations, annotations);
1316                 LLNI_field_get_ref(this, clazz, declaringClass);
1317                 LLNI_class_get(this, referer);
1318
1319                 declaredAnnotations = reflect_get_declaredannotatios(annotations, declaringClass, referer);
1320
1321                 LLNI_field_set_ref(this, declaredAnnotations, declaredAnnotations);
1322         }
1323
1324         return declaredAnnotations;
1325 }
1326 #endif
1327
1328
1329 /*
1330  * These are local overrides for various environment variables in Emacs.
1331  * Please do not remove this and leave it at the end of the file, where
1332  * Emacs will automagically detect them.
1333  * ---------------------------------------------------------------------
1334  * Local variables:
1335  * mode: c
1336  * indent-tabs-mode: t
1337  * c-basic-offset: 4
1338  * tab-width: 4
1339  * End:
1340  * vim:noexpandtab:sw=4:ts=4:
1341  */