6b2fe40162417251abea49b583f560808e6d032c
[cacao.git] / src / native / vm / Field.c
1 /* 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
31    $Id: Field.c 1765 2004-12-15 17:25:04Z jowenn $
32
33 */
34
35
36 #include "native/jni.h"
37 #include "native/native.h"
38 #include "native/include/java_lang_Object.h"
39 #include "native/include/java_lang_Class.h"
40 #include "native/include/java_lang_reflect_Field.h"
41 #include "vm/builtin.h"
42 #include "vm/exceptions.h"
43 #include "vm/loader.h"
44 #include "vm/tables.h"
45 #include "vm/loader.h"
46
47 #undef DEBUG
48
49 /*
50  * Class:     java/lang/reflect/Field
51  * Method:    get
52  * Signature: (Ljava/lang/Object;)Ljava/lang/Object;
53  */
54 JNIEXPORT java_lang_Object* JNICALL Java_java_lang_reflect_Field_get(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj)
55 {
56         jfieldID target_fid;   /* the JNI-fieldid of the wrapping object */
57         jfieldID fid;          /* the JNI-fieldid of the field containing the value */
58         jobject o;               /* the object for wrapping the primitive type */
59         classinfo *c = (classinfo *) this->declaringClass;
60         int st = (this->flag & ACC_STATIC); /* true if field is static */
61
62         /* get the fieldid of the field represented by this Field-object */
63         fid = class_findfield_approx((classinfo *) this->declaringClass,javastring_toutf(this->name, false));
64
65         /* The fieldid is used to retrieve the value, for primitive types a new 
66            object for wrapping the primitive type is created.  */
67         if (st || obj)
68                 switch ((((classinfo *) this->declaringClass)->fields[this->slot]).descriptor->text[0]) {
69                 case 'I':
70                         /* create wrapping class */
71                         c = class_java_lang_Integer;
72                         o = builtin_new(c);
73                         /* get fieldid to store the value */
74                         target_fid = (*env)->GetFieldID(env, c, "value", "I");
75                         if (!target_fid)
76                                 break;
77                                    
78                         if (st)
79                         /* static field */
80                                 SetIntField(env,o,target_fid, (*env)->GetStaticIntField(env, c, fid));
81                         else
82                                 /* instance field */
83                                 SetIntField(env,o,target_fid, (*env)->GetIntField(env,(jobject) obj, fid));
84
85                         /* return the wrapped object */            
86                         return (java_lang_Object *) o;
87
88                 case 'J':
89                         c = class_java_lang_Long;
90                         o = builtin_new(c);
91                         target_fid = (*env)->GetFieldID(env, c, "value", "J");
92                         if (!target_fid)
93                                 break;
94                                    
95                         if (st)
96                                 SetLongField(env,o,target_fid, (*env)->GetStaticLongField(env, c, fid));
97                         else
98                                 SetLongField(env,o,target_fid, (*env)->GetLongField(env,(jobject)  obj, fid));
99
100                         return (java_lang_Object *) o;
101
102                 case 'F':
103                         c = class_java_lang_Float;
104                         o = builtin_new(c);
105                         target_fid = (*env)->GetFieldID(env, c, "value", "F");
106                         if (!target_fid)
107                                 break;
108                                    
109                         if (st)
110                                 SetFloatField(env,o,target_fid, (*env)->GetStaticFloatField(env, c, fid));
111                         else
112                                 SetFloatField(env,o,target_fid, (*env)->GetFloatField(env, (jobject) obj, fid));
113
114                         return (java_lang_Object *) o;
115
116                 case 'D':
117                         c = class_java_lang_Double;
118                         o = builtin_new(c);
119                         target_fid = (*env)->GetFieldID(env, c, "value", "D");
120                         if (!target_fid)
121                                 break;
122                                    
123                         if (st)
124                                 SetDoubleField(env,o,target_fid, (*env)->GetStaticDoubleField(env, c, fid));
125                         else
126                                 SetDoubleField(env,o,target_fid, (*env)->GetDoubleField(env, (jobject) obj, fid));
127
128                         return (java_lang_Object *) o;
129
130                 case 'B':
131                         c = class_java_lang_Byte;
132                         o = builtin_new(c);
133                         target_fid = (*env)->GetFieldID(env, c, "value", "B");
134                         if (!target_fid)
135                                 break;
136                                    
137                         if (st)
138                                 SetByteField(env,o,target_fid, (*env)->GetStaticByteField(env, c, fid));
139                         else
140                                 SetByteField(env,o,target_fid, (*env)->GetByteField(env, (jobject) obj, fid));
141
142                         return (java_lang_Object *) o;
143
144                 case 'C':
145                         c = class_java_lang_Character;
146                         o = builtin_new(c);
147                         target_fid = (*env)->GetFieldID(env, c, "value", "C");
148                         if (!target_fid)
149                                 break;
150                                    
151                         if (st)
152                                 SetCharField(env,o,target_fid, (*env)->GetStaticCharField(env, c, fid));
153                         else
154                                 SetCharField(env,o,target_fid, (*env)->GetCharField(env, (jobject) obj, fid));
155
156                         return (java_lang_Object *) o;
157
158                 case 'S':
159                         c = class_java_lang_Short;
160                         o = builtin_new(c);
161                         target_fid = (*env)->GetFieldID(env, c, "value", "S");
162                         if (!target_fid)
163                                 break;
164                                    
165                         if (st)
166                                 SetShortField(env,o,target_fid, (*env)->GetStaticShortField(env, c, fid));
167                         else
168                                 SetShortField(env,o,target_fid, (*env)->GetShortField(env, (jobject) obj, fid));
169
170                         return (java_lang_Object *) o;
171
172                 case 'Z':
173                         c = class_java_lang_Boolean;
174                         o = builtin_new(c);
175                         target_fid = (*env)->GetFieldID(env, c, "value", "Z");
176                         if (!target_fid)
177                                 break;
178                                    
179                         if (st)
180                                 SetBooleanField(env,o,target_fid, (*env)->GetStaticBooleanField(env, c, fid));
181                         else
182                                 SetBooleanField(env,o,target_fid, (*env)->GetBooleanField(env, (jobject) obj, fid));
183
184                         return (java_lang_Object *) o;
185
186                 case '[':
187                 case 'L':
188                         if (st)
189                         /* static field */
190                                 return (java_lang_Object*) (*env)->GetStaticObjectField(env, c, fid);
191                         else
192                                 /* instance field */
193                                 return (java_lang_Object*) (*env)->GetObjectField(env, (jobject) obj, fid);
194                 }
195
196         *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
197
198         return NULL;
199 }
200
201
202 /*
203  * Class:     java/lang/reflect/Field
204  * Method:    getBoolean
205  * Signature: (Ljava/lang/Object;)Z
206  */
207 JNIEXPORT s4 JNICALL Java_java_lang_reflect_Field_getBoolean(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj)
208 {
209         jfieldID fid;
210
211         if (this->declaringClass && obj) {
212                 /* get the fieldid represented by the field-object */
213                 fid = class_findfield_approx((classinfo *) this->declaringClass,
214                                                                          javastring_toutf(this->name, false));
215
216                 if (fid)
217                         /* call the JNI-function to retrieve the field */ 
218                         return (*env)->GetBooleanField(env, (jobject) obj, fid);
219         }
220
221         /* raise exception */
222         *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
223
224         return 0;
225 }
226
227
228 /*
229  * Class:     java/lang/reflect/Field
230  * Method:    getByte
231  * Signature: (Ljava/lang/Object;)B
232  */
233 JNIEXPORT s4 JNICALL Java_java_lang_reflect_Field_getByte(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj)
234 {
235         jfieldID fid;
236         char *utf_ptr;
237
238 #ifdef DEBUG
239         /* check if the specified slot could be a valid field of this class*/
240         if (this->slot>((classinfo*)this->declaringClass)->fieldscount) throw_cacao_exception_exit(string_java_lang_IncompatibleClassChangeError,
241                                                                           "declaring class: fieldscount mismatch");
242 #endif
243         fid=&((classinfo*)this->declaringClass)->fields[this->slot]; /*get field*/
244 #ifdef DEBUG
245         /* check if the field really has the same name and check if the type descriptor is not empty*/
246         if (fid->name!=javastring_toutf(this->name,false)) throw_cacao_exception_exit(string_java_lang_IncompatibleClassChangeError,
247                                                                           "declaring class: field name mismatch");
248         if (fid->descriptor->blength<1) panic("Type-Descriptor is empty");
249 #endif
250         /* check if obj would be needed (not static field), but is 0)*/
251         if ((!(fid->flags & ACC_STATIC)) && (obj==0)) {
252                 *exceptionptr = new_exception(string_java_lang_NullPointerException);
253                 return 0;
254         }
255         
256         /* if (!(fid->flags & ACC_PUBLIC)) {
257                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
258                 return 0;
259
260         }*/
261
262         if (fid->flags & ACC_STATIC) {
263                 /* initialize class if needed*/
264                 class_init((classinfo*)this->declaringClass);
265                 if (*exceptionptr) return 0;
266                 /*return value*/
267                 utf_ptr = fid->descriptor->text;
268                 switch (*utf_ptr) {
269                         case 'B': return fid->value.i;
270                         default:
271                                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
272                                 return 0;
273                 }
274         } else {
275                 if (!builtin_instanceof((java_objectheader*)obj,(classinfo*)this->declaringClass)) {
276                                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
277                                 return 0;
278                 }
279                 utf_ptr = fid->descriptor->text;
280                 switch (*utf_ptr) {
281                         case 'B':return getField(obj,jbyte,fid);
282                         default:
283                                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
284                                 return 0;
285                 }
286         }
287 }
288
289
290 /*
291  * Class:     java/lang/reflect/Field
292  * Method:    getChar
293  * Signature: (Ljava/lang/Object;)C
294  */
295 JNIEXPORT s4 JNICALL Java_java_lang_reflect_Field_getChar(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj)
296 {
297         jfieldID fid;
298         char *utf_ptr;
299
300 #ifdef DEBUG
301         /* check if the specified slot could be a valid field of this class*/
302         if (this->slot>((classinfo*)this->declaringClass)->fieldscount) throw_cacao_exception_exit(string_java_lang_IncompatibleClassChangeError,
303                                                                           "declaring class: fieldscount mismatch");
304 #endif
305         fid=&((classinfo*)this->declaringClass)->fields[this->slot]; /*get field*/
306 #ifdef DEBUG
307         /* check if the field really has the same name and check if the type descriptor is not empty*/
308         if (fid->name!=javastring_toutf(this->name,false)) throw_cacao_exception_exit(string_java_lang_IncompatibleClassChangeError,
309                                                                           "declaring class: field name mismatch");
310         if (fid->descriptor->blength<1) panic("Type-Descriptor is empty");
311 #endif
312         /* check if obj would be needed (not static field), but is 0)*/
313         if ((!(fid->flags & ACC_STATIC)) && (obj==0)) {
314                 *exceptionptr = new_exception(string_java_lang_NullPointerException);
315                 return 0;
316         }
317         
318         /*if (!(fid->flags & ACC_PUBLIC)) {
319                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
320                 return 0;
321
322         }*/
323
324         if (fid->flags & ACC_STATIC) {
325                 /* initialize class if needed*/
326                 class_init((classinfo*)this->declaringClass);
327                 if (*exceptionptr) return 0;
328                 /*return value*/
329                 utf_ptr = fid->descriptor->text;
330                 switch (*utf_ptr) { 
331                         case 'C': return fid->value.i;
332                         default:
333                                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
334                                 return 0;
335                 }
336         } else {
337                 if (!builtin_instanceof((java_objectheader*)obj,(classinfo*)this->declaringClass)) {
338                                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
339                                 return 0;
340                 }
341                 utf_ptr = fid->descriptor->text;
342                 switch (*utf_ptr) {
343                         case 'C':return getField(obj,jchar,fid);
344                         default:
345                                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
346                                 return 0;
347                 }
348         }
349 }
350
351
352 /*
353  * Class:     java/lang/reflect/Field
354  * Method:    getDouble
355  * Signature: (Ljava/lang/Object;)D
356  */
357 JNIEXPORT double JNICALL Java_java_lang_reflect_Field_getDouble(JNIEnv *env , java_lang_reflect_Field *this, java_lang_Object *obj)
358 {
359         jfieldID fid;
360         char *utf_ptr;
361
362 #ifdef DEBUG
363         /* check if the specified slot could be a valid field of this class*/
364         if (this->slot>((classinfo*)this->declaringClass)->fieldscount) throw_cacao_exception_exit(string_java_lang_IncompatibleClassChangeError,
365                                                                           "declaring class: fieldscount mismatch");
366 #endif
367         fid=&((classinfo*)this->declaringClass)->fields[this->slot]; /*get field*/
368 #ifdef DEBUG
369         /* check if the field really has the same name and check if the type descriptor is not empty*/
370         if (fid->name!=javastring_toutf(this->name,false)) throw_cacao_exception_exit(string_java_lang_IncompatibleClassChangeError,
371                                                                           "declaring class: field name mismatch");
372         if (fid->descriptor->blength<1) panic("Type-Descriptor is empty");
373 #endif
374         /* check if obj would be needed (not static field), but is 0)*/
375         if ((!(fid->flags & ACC_STATIC)) && (obj==0)) {
376                 *exceptionptr = new_exception(string_java_lang_NullPointerException);
377                 return 0;
378         }
379         
380         /*if (!(fid->flags & ACC_PUBLIC)) {
381                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
382                 return 0;
383
384         }*/
385
386         if (fid->flags & ACC_STATIC) {
387                 /* initialize class if needed*/
388                 class_init((classinfo*)this->declaringClass);
389                 if (*exceptionptr) return 0;
390                 /*return value*/
391                 utf_ptr = fid->descriptor->text;
392                 switch (*utf_ptr) {
393                         case 'B':
394                         case 'S': 
395                         case 'C': 
396                         case 'I': return fid->value.i;
397                         case 'F': return fid->value.f;
398                         case 'D': return fid->value.d;
399                         default:
400                                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
401                                 return 0;
402                 }
403         } else {
404                 if (!builtin_instanceof((java_objectheader*)obj,(classinfo*)this->declaringClass)) {
405                                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
406                                 return 0;
407                 }
408                 utf_ptr = fid->descriptor->text;
409                 switch (*utf_ptr) {
410                         case 'B':return getField(obj,jbyte,fid);
411                         case 'S':return getField(obj,jshort,fid);
412                         case 'C':return getField(obj,jchar,fid);
413                         case 'I':return getField(obj,jint,fid);
414                         case 'D':return getField(obj,jdouble,fid);
415                         default:
416                                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
417                                 return 0;
418                 }
419         }
420 }
421
422
423 /*
424  * Class:     java/lang/reflect/Field
425  * Method:    getFloat
426  * Signature: (Ljava/lang/Object;)F
427  */
428 JNIEXPORT float JNICALL Java_java_lang_reflect_Field_getFloat(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj)
429 {
430         jfieldID fid;
431         char *utf_ptr;
432
433 #ifdef DEBUG
434         /* check if the specified slot could be a valid field of this class*/
435         if (this->slot>((classinfo*)this->declaringClass)->fieldscount) throw_cacao_exception_exit(string_java_lang_IncompatibleClassChangeError,
436                                                                           "declaring class: fieldscount mismatch");
437 #endif
438         fid=&((classinfo*)this->declaringClass)->fields[this->slot]; /*get field*/
439 #ifdef DEBUG
440         /* check if the field really has the same name and check if the type descriptor is not empty*/
441         if (fid->name!=javastring_toutf(this->name,false)) throw_cacao_exception_exit(string_java_lang_IncompatibleClassChangeError,
442                                                                           "declaring class: field name mismatch");
443         if (fid->descriptor->blength<1) panic("Type-Descriptor is empty");
444 #endif
445         /* check if obj would be needed (not static field), but is 0)*/
446         if ((!(fid->flags & ACC_STATIC)) && (obj==0)) {
447                 *exceptionptr = new_exception(string_java_lang_NullPointerException);
448                 return 0;
449         }
450         
451         /*if (!(fid->flags & ACC_PUBLIC)) {
452                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
453                 return 0;
454
455         }*/
456
457         if (fid->flags & ACC_STATIC) {
458                 /* initialize class if needed*/
459                 class_init((classinfo*)this->declaringClass);
460                 if (*exceptionptr) return 0;
461                 /*return value*/
462                 utf_ptr = fid->descriptor->text;
463                 switch (*utf_ptr) {
464                         case 'B':
465                         case 'S': 
466                         case 'C': 
467                         case 'I': return fid->value.i;
468                         case 'F': return fid->value.f;
469                         default:
470                                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
471                                 return 0;
472                 }
473         } else {
474                 if (!builtin_instanceof((java_objectheader*)obj,(classinfo*)this->declaringClass)) {
475                                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
476                                 return 0;
477                 }
478                 utf_ptr = fid->descriptor->text;
479                 switch (*utf_ptr) {
480                         case 'B':return getField(obj,jbyte,fid);
481                         case 'S':return getField(obj,jshort,fid);
482                         case 'C':return getField(obj,jchar,fid);
483                         case 'I':return getField(obj,jint,fid);
484                         case 'F':return getField(obj,jfloat,fid);
485                         default:
486                                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
487                                 return 0;
488                 }
489         }
490 }
491
492
493 /*
494  * Class:     java/lang/reflect/Field
495  * Method:    getInt
496  * Signature: (Ljava/lang/Object;)I
497  */
498 JNIEXPORT s4 JNICALL Java_java_lang_reflect_Field_getInt(JNIEnv *env , java_lang_reflect_Field *this, java_lang_Object *obj)
499 {
500         jfieldID fid;
501         char *utf_ptr;
502
503 #ifdef DEBUG
504         /* check if the specified slot could be a valid field of this class*/
505         if (this->slot>((classinfo*)this->declaringClass)->fieldscount) throw_cacao_exception_exit(string_java_lang_IncompatibleClassChangeError,
506                                                                           "declaring class: fieldscount mismatch");
507 #endif
508         fid=&((classinfo*)this->declaringClass)->fields[this->slot]; /*get field*/
509 #ifdef DEBUG
510         /* check if the field really has the same name and check if the type descriptor is not empty*/
511         if (fid->name!=javastring_toutf(this->name,false)) throw_cacao_exception_exit(string_java_lang_IncompatibleClassChangeError,
512                                                                           "declaring class: field name mismatch");
513         if (fid->descriptor->blength<1) panic("Type-Descriptor is empty");
514 #endif
515         /* check if obj would be needed (not static field), but is 0)*/
516         if ((!(fid->flags & ACC_STATIC)) && (obj==0)) {
517                 *exceptionptr = new_exception(string_java_lang_NullPointerException);
518                 return 0;
519         }
520         
521         /*if (!(fid->flags & ACC_PUBLIC)) {
522                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
523                 return 0;
524
525         } */
526
527         if (fid->flags & ACC_STATIC) {
528                 /* initialize class if needed*/
529                 class_init((classinfo*)this->declaringClass);
530                 if (*exceptionptr) return 0;
531                 /*return value*/
532                 utf_ptr = fid->descriptor->text;
533                 switch (*utf_ptr) {
534                         case 'B':
535                         case 'S': 
536                         case 'C': 
537                         case 'I': return fid->value.i;
538                         default:
539                                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
540                                 return 0;
541                 }
542         } else {
543                 if (!builtin_instanceof((java_objectheader*)obj,(classinfo*)this->declaringClass)) {
544                                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
545                                 return 0;
546                 }
547                 utf_ptr = fid->descriptor->text;
548                 switch (*utf_ptr) {
549                         case 'B':return getField(obj,jbyte,fid);
550                         case 'S':return getField(obj,jshort,fid);
551                         case 'C':return getField(obj,jchar,fid);
552                         case 'I':return getField(obj,jint,fid);
553                         default:
554                                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
555                                 return 0;
556                 }
557         }
558 }
559
560
561 /*
562  * Class:     java/lang/reflect/Field
563  * Method:    getLong
564  * Signature: (Ljava/lang/Object;)J
565  */
566 JNIEXPORT s8 JNICALL Java_java_lang_reflect_Field_getLong(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj)
567 {
568         jfieldID fid;
569         char *utf_ptr;
570
571 #ifdef DEBUG
572         /* check if the specified slot could be a valid field of this class*/
573         if (this->slot>((classinfo*)this->declaringClass)->fieldscount) throw_cacao_exception_exit(string_java_lang_IncompatibleClassChangeError,
574                                                                           "declaring class: fieldscount mismatch");
575 #endif
576         fid=&((classinfo*)this->declaringClass)->fields[this->slot]; /*get field*/
577 #ifdef DEBUG
578         /* check if the field really has the same name and check if the type descriptor is not empty*/
579         if (fid->name!=javastring_toutf(this->name,false)) throw_cacao_exception_exit(string_java_lang_IncompatibleClassChangeError,
580                                                                           "declaring class: field name mismatch");
581         if (fid->descriptor->blength<1) panic("Type-Descriptor is empty");
582 #endif
583         /* check if obj would be needed (not static field), but is 0)*/
584         if ((!(fid->flags & ACC_STATIC)) && (obj==0)) {
585                 *exceptionptr = new_exception(string_java_lang_NullPointerException);
586                 return 0;
587         }
588         
589         /*if (!(fid->flags & ACC_PUBLIC)) {
590                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
591                 return 0;
592
593         }*/
594
595         if (fid->flags & ACC_STATIC) {
596                 /* initialize class if needed*/
597                 class_init((classinfo*)this->declaringClass);
598                 if (*exceptionptr) return 0;
599                 /*return value*/
600                 utf_ptr = fid->descriptor->text;
601                 switch (*utf_ptr) {
602                         case 'B':
603                         case 'S': 
604                         case 'C': 
605                         case 'I': return fid->value.i;
606                         case 'J': return fid->value.l;
607                         default:
608                                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
609                                 return 0;
610                 }
611         } else {
612                 if (!builtin_instanceof((java_objectheader*)obj,(classinfo*)this->declaringClass)) {
613                                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
614                                 return 0;
615                 }
616                 utf_ptr = fid->descriptor->text;
617                 switch (*utf_ptr) {
618                         case 'B':return getField(obj,jbyte,fid);
619                         case 'S':return getField(obj,jshort,fid);
620                         case 'C':return getField(obj,jchar,fid);
621                         case 'I':return getField(obj,jint,fid);
622                         case 'J':return getField(obj,jlong,fid);
623                         default:
624                                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
625                                 return 0;
626                 }
627         }
628 }
629
630
631 /*
632  * Class:     java/lang/reflect/Field
633  * Method:    getShort
634  * Signature: (Ljava/lang/Object;)S
635  */
636 JNIEXPORT s4 JNICALL Java_java_lang_reflect_Field_getShort(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj)
637 {
638         jfieldID fid;
639         char *utf_ptr;
640
641 #ifdef DEBUG
642         /* check if the specified slot could be a valid field of this class*/
643         if (this->slot>((classinfo*)this->declaringClass)->fieldscount) throw_cacao_exception_exit(string_java_lang_IncompatibleClassChangeError,
644                                                                           "declaring class: fieldscount mismatch");
645 #endif
646         fid=&((classinfo*)this->declaringClass)->fields[this->slot]; /*get field*/
647 #ifdef DEBUG
648         /* check if the field really has the same name and check if the type descriptor is not empty*/
649         if (fid->name!=javastring_toutf(this->name,false)) throw_cacao_exception_exit(string_java_lang_IncompatibleClassChangeError,
650                                                                           "declaring class: field name mismatch");
651         if (fid->descriptor->blength<1) panic("Type-Descriptor is empty");
652 #endif
653         /* check if obj would be needed (not static field), but is 0)*/
654         if ((!(fid->flags & ACC_STATIC)) && (obj==0)) {
655                 *exceptionptr = new_exception(string_java_lang_NullPointerException);
656                 return 0;
657         }
658         
659         /*if (!(fid->flags & ACC_PUBLIC)) {
660                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
661                 return 0;
662
663         }*/
664
665         if (fid->flags & ACC_STATIC) {
666                 /* initialize class if needed*/
667                 class_init((classinfo*)this->declaringClass);
668                 if (*exceptionptr) return 0;
669                 /*return value*/
670                 utf_ptr = fid->descriptor->text;
671                 switch (*utf_ptr) {
672                         case 'B':
673                         case 'S': return fid->value.i;
674                         default:
675                                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
676                                 return 0;
677                 }
678         } else {
679                 if (!builtin_instanceof((java_objectheader*)obj,(classinfo*)this->declaringClass)) {
680                                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
681                                 return 0;
682                 }
683                 utf_ptr = fid->descriptor->text;
684                 switch (*utf_ptr) {
685                         case 'B':return getField(obj,jbyte,fid);
686                         case 'S':return getField(obj,jshort,fid);
687                         default:
688                                 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
689                                 return 0;
690                 }
691         }
692 }
693
694
695 /*
696  * Class:     java/lang/reflect/Field
697  * Method:    set
698  * Signature: (Ljava/lang/Object;Ljava/lang/Object;)V
699  */
700 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_set(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj, java_lang_Object *val)
701 {
702         jfieldID source_fid;  /* the field containing the value to be written */
703         jfieldID fid;         /* the field to be written */
704         classinfo *c;
705         int st = (this->flag & ACC_STATIC); /* true if the field is static */
706
707         fid = class_findfield_approx((classinfo *) this->declaringClass,
708                                                                  javastring_toutf(this->name, false));
709
710         if (val && (st || obj)) {
711
712                 c = val->header.vftbl->class;
713
714                 /* The fieldid is used to set the new value, for primitive types the value
715                    has to be retrieved from the wrapping object */  
716                 switch ((((classinfo *) this->declaringClass)->fields[this->slot]).descriptor->text[0]) {
717                 case 'I':
718                         /* illegal argument specified */
719                         if (c != class_java_lang_Integer)
720                                 break;
721                         /* determine the field to read the value */
722                         source_fid = (*env)->GetFieldID(env, c, "value", "I");
723                         if (!source_fid)
724                                 break;
725                                    
726                         /* set the new value */
727                         if (st)
728                         /* static field */
729                                 (*env)->SetStaticIntField(env, c, fid, GetIntField(env, (jobject) val, source_fid));
730                         else
731                                 /* instance field */
732                                 (*env)->SetIntField(env, (jobject) obj, fid, GetIntField(env, (jobject) val, source_fid));
733
734                         return;
735
736                 case 'J':
737                         if (c != class_java_lang_Long)
738                                 break;
739                         source_fid = (*env)->GetFieldID(env, c, "value", "J");
740                         if (!source_fid)
741                                 break;
742                                    
743                         if (st)
744                                 (*env)->SetStaticLongField(env, c, fid, GetLongField(env, (jobject) val, source_fid));
745                         else
746                                 (*env)->SetLongField(env, (jobject) obj, fid, GetLongField(env, (jobject) val, source_fid));
747
748                         return;
749
750                 case 'F':
751                         if (c != class_java_lang_Float)
752                                 break;
753                         source_fid = (*env)->GetFieldID(env, c, "value", "F");
754                         if (!source_fid)
755                                 break;
756                                    
757                         if (st)
758                                 (*env)->SetStaticFloatField(env, c, fid, GetFloatField(env, (jobject) val, source_fid));
759                         else
760                                 (*env)->SetFloatField(env, (jobject) obj, fid, GetFloatField(env, (jobject) val, source_fid));
761
762                         return;
763
764                 case 'D':
765                         if (c != class_java_lang_Double)
766                                 break;
767                         source_fid = (*env)->GetFieldID(env, c, "value", "D");
768                         if (!source_fid) break;
769                                    
770                         if (st)
771                                 (*env)->SetStaticDoubleField(env, c, fid, GetDoubleField(env,(jobject) val,source_fid));
772                         else
773                                 (*env)->SetDoubleField(env, (jobject) obj, fid, GetDoubleField(env,(jobject) val,source_fid));
774
775                         return;
776
777                 case 'B':
778                         if (c != class_java_lang_Byte)
779                                 break;
780                         source_fid = (*env)->GetFieldID(env, c, "value", "B");
781                         if (!source_fid)
782                                 break;
783                                    
784                         if (st)
785                                 (*env)->SetStaticByteField(env, c, fid, GetByteField(env, (jobject) val, source_fid));
786                         else
787                                 (*env)->SetByteField(env, (jobject) obj, fid, GetByteField(env, (jobject) val, source_fid));
788
789                         return;
790
791                 case 'C':
792                         if (c != class_java_lang_Character)
793                                 break;
794                         source_fid = (*env)->GetFieldID(env, c, "value", "C");
795                         if (!source_fid)
796                                 break;
797                                    
798                         if (st)
799                                 (*env)->SetStaticCharField(env, c, fid, GetCharField(env, (jobject) val, source_fid));
800                         else
801                                 (*env)->SetCharField(env, (jobject) obj, fid, GetCharField(env, (jobject) val, source_fid));
802
803                         return;
804
805                 case 'S':
806                         if (c != class_java_lang_Short)
807                                 break;
808                         source_fid = (*env)->GetFieldID(env, c, "value", "S");
809                         if (!source_fid)
810                                 break;
811                                    
812                         if (st)
813                                 (*env)->SetStaticShortField(env, c, fid, GetShortField(env, (jobject) val, source_fid));
814                         else
815                                 (*env)->SetShortField(env, (jobject) obj, fid, GetShortField(env, (jobject) val, source_fid));
816
817                         return;
818
819                 case 'Z':
820                         if (c != class_java_lang_Boolean)
821                                 break;
822                         source_fid = (*env)->GetFieldID(env, c, "value", "Z");
823                         if (!source_fid)
824                                 break;
825                                    
826                         if (st)
827                                 (*env)->SetStaticBooleanField(env, c, fid, GetBooleanField(env, (jobject) val, source_fid));
828                         else
829                                 (*env)->SetBooleanField(env, (jobject) obj, fid, GetBooleanField(env, (jobject) val, source_fid));
830
831                         return;
832
833                 case '[':
834                 case 'L':
835                         if (st)
836                                 (*env)->SetStaticObjectField(env, c, fid, (jobject) val);
837                         else
838                                 (*env)->SetObjectField(env, (jobject) obj, fid, (jobject) val);
839
840                         return;
841                 }
842         }
843
844         /* raise exception */
845         *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
846 }
847
848
849 /*
850  * Class:     java/lang/reflect/Field
851  * Method:    setBoolean
852  * Signature: (Ljava/lang/Object;Z)V
853  */
854 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setBoolean(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj, s4 val)
855 {
856         jfieldID fid;
857
858         if (this->declaringClass && obj) {
859                 fid = class_findfield_approx((classinfo *) this->declaringClass,
860                                                                          javastring_toutf(this->name, false));
861
862                 if (fid) {
863                         (*env)->SetBooleanField(env, (jobject) obj, fid, val);
864                         return;
865                 }
866         }
867
868         /* raise exception */
869         *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
870 }
871
872
873 /*
874  * Class:     java/lang/reflect/Field
875  * Method:    setByte
876  * Signature: (Ljava/lang/Object;B)V
877  */
878 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setByte(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj, s4 val)
879 {
880         jfieldID fid;
881
882         if (this->declaringClass && obj) {
883                 fid = class_findfield_approx((classinfo *) this->declaringClass,
884                                                                          javastring_toutf(this->name, false));
885
886                 if (fid) {
887                         (*env)->SetByteField(env, (jobject) obj, fid, val);
888                         return;
889                 }
890         }
891
892         /* raise exception */
893         *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
894 }
895
896
897 /*
898  * Class:     java/lang/reflect/Field
899  * Method:    setChar
900  * Signature: (Ljava/lang/Object;C)V
901  */
902 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setChar(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj, s4 val)
903 {
904         jfieldID fid;
905
906         if (this->declaringClass && obj) {
907                 fid = class_findfield_approx((classinfo *) this->declaringClass,
908                                                                          javastring_toutf(this->name, false));
909
910                 if (fid) {
911                         (*env)->SetCharField(env, (jobject) obj, fid, val);
912                         return;
913                 }
914         }
915
916         /* raise exception */
917         *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
918 }
919
920
921 /*
922  * Class:     java/lang/reflect/Field
923  * Method:    setDouble
924  * Signature: (Ljava/lang/Object;D)V
925  */
926 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setDouble(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj, double val)
927 {
928         jfieldID fid;
929
930         if (this->declaringClass && obj) {
931                 fid = class_findfield_approx((classinfo *) this->declaringClass,
932                                                                          javastring_toutf(this->name, false));
933
934                 if (fid) {
935                         (*env)->SetDoubleField(env, (jobject) obj, fid, val);
936                         return;
937                 } 
938         }
939
940         /* raise exception */
941         *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
942 }
943
944
945 /*
946  * Class:     java/lang/reflect/Field
947  * Method:    setFloat
948  * Signature: (Ljava/lang/Object;F)V
949  */
950 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setFloat(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj, float val)
951 {
952         jfieldID fid;
953
954         if (this->declaringClass && obj) {
955                 fid = class_findfield_approx((classinfo *) this->declaringClass,
956                                                                          javastring_toutf(this->name, false));
957
958                 if (fid) {
959                         (*env)->SetFloatField(env, (jobject) obj, fid, val);
960                         return;
961                 }
962         }
963
964         /* raise exception */
965         *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
966 }
967
968
969 /*
970  * Class:     java/lang/reflect/Field
971  * Method:    setInt
972  * Signature: (Ljava/lang/Object;I)V
973  */
974 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setInt(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj, s4 val)
975 {
976         jfieldID fid;
977
978         if (this->declaringClass && obj) {
979                 fid = class_findfield_approx((classinfo *) this->declaringClass,
980                                                                          javastring_toutf(this->name, false));
981
982                 if (fid) {
983                         (*env)->SetIntField(env, (jobject) obj, fid, val);
984                         return;
985                 }
986         }
987
988         /* raise exception */
989         *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
990 }
991
992
993 /*
994  * Class:     java/lang/reflect/Field
995  * Method:    setLong
996  * Signature: (Ljava/lang/Object;J)V
997  */
998 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setLong(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj, s8 val)
999 {
1000         jfieldID fid;
1001
1002         if (this->declaringClass && obj) {
1003                 fid = class_findfield_approx((classinfo *) this->declaringClass,
1004                                                                          javastring_toutf(this->name, false));
1005
1006                 if (fid) {
1007                         (*env)->SetLongField(env, (jobject) obj, fid, val);
1008                         return;
1009                 }
1010         }
1011
1012         /* raise exception */
1013         *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
1014 }
1015
1016
1017 /*
1018  * Class:     java/lang/reflect/Field
1019  * Method:    setShort
1020  * Signature: (Ljava/lang/Object;S)V
1021  */
1022 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setShort(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj, s4 val)
1023 {
1024         jfieldID fid;
1025
1026         if (this->declaringClass && obj) {
1027                 fid = class_findfield_approx((classinfo *) this->declaringClass,
1028                                                                          javastring_toutf(this->name, false));
1029
1030                 if (fid) {
1031                         (*env)->SetShortField(env, (jobject) obj, fid, val);
1032                         return;
1033                 }
1034         }
1035
1036         /* raise exception */
1037         *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
1038 }
1039
1040
1041 /*
1042  * Class:     java_lang_reflect_Field
1043  * Method:    getType
1044  * Signature: ()Ljava/lang/Class;
1045  */
1046 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_reflect_Field_getType(JNIEnv *env, java_lang_reflect_Field *this)
1047 {
1048         utf *desc = (((classinfo *) this->declaringClass)->fields[this->slot]).descriptor;
1049         java_lang_Class *ret;
1050         if (!desc)
1051                 return NULL;
1052
1053         ret=(java_lang_Class *) class_from_descriptor(desc->text, utf_end(desc), NULL, CLASSLOAD_LOAD);
1054         use_class_as_object(ret);
1055         return ret;
1056 }
1057
1058
1059 /*
1060  * Class:     java_lang_reflect_Field
1061  * Method:    getModifiers
1062  * Signature: ()I
1063  */
1064 JNIEXPORT s4 JNICALL Java_java_lang_reflect_Field_getModifiers(JNIEnv *env, java_lang_reflect_Field *this)
1065 {
1066         return (((classinfo *) this->declaringClass)->fields[this->slot]).flags;
1067 }
1068
1069
1070 /*
1071  * These are local overrides for various environment variables in Emacs.
1072  * Please do not remove this and leave it at the end of the file, where
1073  * Emacs will automagically detect them.
1074  * ---------------------------------------------------------------------
1075  * Local variables:
1076  * mode: c
1077  * indent-tabs-mode: t
1078  * c-basic-offset: 4
1079  * tab-width: 4
1080  * End:
1081  */