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