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