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