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