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