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