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