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