Fix mysterious unremovable file part 2 ?
[cacao.git] / src / native / vm / gnuclasspath / java_lang_reflect_VMField.c
1 /* src/native/vm/gnu/java_lang_reflect_VMField.c
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <assert.h>
29 #include <stdint.h>
30
31 #include "native/jni.h"
32 #include "native/llni.h"
33 #include "native/native.h"
34
35 #include "native/include/java_lang_Boolean.h"
36 #include "native/include/java_lang_Byte.h"
37 #include "native/include/java_lang_Character.h"
38 #include "native/include/java_lang_Short.h"
39 #include "native/include/java_lang_Integer.h"
40 #include "native/include/java_lang_Long.h"
41 #include "native/include/java_lang_Float.h"
42 #include "native/include/java_lang_Double.h"
43 #include "native/include/java_lang_Object.h"
44 #include "native/include/java_lang_Class.h"
45 #include "native/include/java_lang_String.h"
46
47 #include "native/include/java_lang_reflect_Field.h"
48 #include "native/include/java_lang_reflect_VMField.h"
49
50 #if defined(ENABLE_ANNOTATIONS)
51 #include "native/include/java_util_Map.h"
52 #include "native/include/sun_reflect_ConstantPool.h"
53 #include "native/vm/reflect.h"
54 #endif
55
56 #include "vm/access.h"
57 #include "vm/builtin.h"
58 #include "vm/exceptions.h"
59 #include "vm/global.h"
60 #include "vm/initialize.h"
61 #include "vm/primitive.h"
62 #include "vm/resolve.h"
63 #include "vm/stringlocal.h"
64
65 #include "vm/jit/stacktrace.h"
66
67 #include "vmcore/loader.h"
68 #include "vmcore/utf8.h"
69
70
71 /* native methods implemented by this file ************************************/
72
73 static JNINativeMethod methods[] = {
74         { "getModifiersInternal", "()I",                                     (void *) (intptr_t) &Java_java_lang_reflect_VMField_getModifiersInternal },
75         { "getType",              "()Ljava/lang/Class;",                     (void *) (intptr_t) &Java_java_lang_reflect_VMField_getType              },
76         { "get",                  "(Ljava/lang/Object;)Ljava/lang/Object;",  (void *) (intptr_t) &Java_java_lang_reflect_VMField_get                  },
77         { "getBoolean",           "(Ljava/lang/Object;)Z",                   (void *) (intptr_t) &Java_java_lang_reflect_VMField_getBoolean           },
78         { "getByte",              "(Ljava/lang/Object;)B",                   (void *) (intptr_t) &Java_java_lang_reflect_VMField_getByte              },
79         { "getChar",              "(Ljava/lang/Object;)C",                   (void *) (intptr_t) &Java_java_lang_reflect_VMField_getChar              },
80         { "getShort",             "(Ljava/lang/Object;)S",                   (void *) (intptr_t) &Java_java_lang_reflect_VMField_getShort             },
81         { "getInt",               "(Ljava/lang/Object;)I",                   (void *) (intptr_t) &Java_java_lang_reflect_VMField_getInt               },
82         { "getLong",              "(Ljava/lang/Object;)J",                   (void *) (intptr_t) &Java_java_lang_reflect_VMField_getLong              },
83         { "getFloat",             "(Ljava/lang/Object;)F",                   (void *) (intptr_t) &Java_java_lang_reflect_VMField_getFloat             },
84         { "getDouble",            "(Ljava/lang/Object;)D",                   (void *) (intptr_t) &Java_java_lang_reflect_VMField_getDouble            },
85         { "set",                  "(Ljava/lang/Object;Ljava/lang/Object;)V", (void *) (intptr_t) &Java_java_lang_reflect_VMField_set                  },
86         { "setBoolean",           "(Ljava/lang/Object;Z)V",                  (void *) (intptr_t) &Java_java_lang_reflect_VMField_setBoolean           },
87         { "setByte",              "(Ljava/lang/Object;B)V",                  (void *) (intptr_t) &Java_java_lang_reflect_VMField_setByte              },
88         { "setChar",              "(Ljava/lang/Object;C)V",                  (void *) (intptr_t) &Java_java_lang_reflect_VMField_setChar              },
89         { "setShort",             "(Ljava/lang/Object;S)V",                  (void *) (intptr_t) &Java_java_lang_reflect_VMField_setShort             },
90         { "setInt",               "(Ljava/lang/Object;I)V",                  (void *) (intptr_t) &Java_java_lang_reflect_VMField_setInt               },
91         { "setLong",              "(Ljava/lang/Object;J)V",                  (void *) (intptr_t) &Java_java_lang_reflect_VMField_setLong              },
92         { "setFloat",             "(Ljava/lang/Object;F)V",                  (void *) (intptr_t) &Java_java_lang_reflect_VMField_setFloat             },
93         { "setDouble",            "(Ljava/lang/Object;D)V",                  (void *) (intptr_t) &Java_java_lang_reflect_VMField_setDouble            },
94         { "getSignature",         "()Ljava/lang/String;",                    (void *) (intptr_t) &Java_java_lang_reflect_VMField_getSignature         },
95 #if defined(ENABLE_ANNOTATIONS)
96         { "declaredAnnotations",  "()Ljava/util/Map;",                       (void *) (intptr_t) &Java_java_lang_reflect_VMField_declaredAnnotations  },
97 #endif
98 };
99
100
101 /* _Jv_java_lang_reflect_VMField_init ******************************************
102
103    Register native functions.
104
105 *******************************************************************************/
106
107 void _Jv_java_lang_reflect_VMField_init(void)
108 {
109         utf *u;
110
111         u = utf_new_char("java/lang/reflect/VMField");
112
113         native_method_register(u, methods, NATIVE_METHODS_COUNT);
114 }
115
116
117 /* _field_access_check *********************************************************
118
119    Checks if the field can be accessed.
120
121    RETURN VALUE:
122       true......field can be accessed, or
123       false.....otherwise (maybe an Exception was thrown).
124
125 *******************************************************************************/
126
127 static bool _field_access_check(java_lang_reflect_VMField *this,
128                                                                 fieldinfo *f, classinfo *c, java_handle_t *o)
129 {
130         java_lang_reflect_Field *rf;
131         int32_t                  flag;
132
133         /* check if we should bypass security checks (AccessibleObject) */
134
135         LLNI_field_get_ref(this, f, rf);
136         LLNI_field_get_val(rf, flag, flag);
137
138         if (flag == false) {
139                 /* This function is always called like this:
140                        [0] java.lang.reflect.VMField.xxx (Native Method)
141                        [1] java.lang.reflect.Field.xxx
142                        [2] <caller>
143                 */
144
145                 if (!access_check_field(f, 2))
146                         return false;
147         }
148
149         /* some general checks */
150
151         if (f->flags & ACC_STATIC) {
152                 /* initialize class if required */
153
154                 if (!(c->state & CLASS_INITIALIZED))
155                         if (!initialize_class(c))
156                                 return false;
157
158                 /* everything is ok */
159
160                 return true;
161         }
162         else {
163                 /* obj is required for not-static fields */
164
165                 if (o == NULL) {
166                         exceptions_throw_nullpointerexception();
167                         return false;
168                 }
169         
170                 if (builtin_instanceof(o, c))
171                         return true;
172         }
173
174         /* exception path */
175
176         exceptions_throw_illegalargumentexception();
177         return false;
178 }
179
180
181 /* _field_get_type *************************************************************
182
183    Returns the content of the given field.
184
185 *******************************************************************************/
186
187 #define _FIELD_GET_TYPE(name, type, uniontype) \
188 static inline type _field_get_##name(fieldinfo *f, java_lang_Object *o) \
189 { \
190         type ret; \
191         if (f->flags & ACC_STATIC) { \
192                 ret = f->value->uniontype; \
193         } else { \
194                 LLNI_CRITICAL_START; \
195                 ret = *(type *) (((intptr_t) LLNI_DIRECT(o)) + f->offset); \
196                 LLNI_CRITICAL_END; \
197         } \
198         return ret; \
199 }
200
201 static inline java_handle_t *_field_get_handle(fieldinfo *f, java_lang_Object *o)
202 {
203         java_object_t *obj;
204         java_handle_t *hdl;
205
206         LLNI_CRITICAL_START;
207
208         if (f->flags & ACC_STATIC) {
209                 obj = f->value->a;
210         } else {
211                 obj = *(java_object_t **) (((intptr_t) LLNI_DIRECT(o)) + f->offset);
212         }
213
214         hdl = LLNI_WRAP(obj);
215
216         LLNI_CRITICAL_END;
217
218         return hdl;
219 }
220
221 _FIELD_GET_TYPE(int,    int32_t, i)
222 _FIELD_GET_TYPE(long,   int64_t, l)
223 _FIELD_GET_TYPE(float,  float,   f)
224 _FIELD_GET_TYPE(double, double,  d)
225
226
227 /* _field_set_type *************************************************************
228
229    Sets the content of the given field to the given value.
230
231 *******************************************************************************/
232
233 #define _FIELD_SET_TYPE(name, type, uniontype) \
234 static inline void _field_set_##name(fieldinfo *f, java_lang_Object *o, type value) \
235 { \
236         if (f->flags & ACC_STATIC) { \
237                 f->value->uniontype = value; \
238         } else { \
239                 LLNI_CRITICAL_START; \
240                 *(type *) (((intptr_t) LLNI_DIRECT(o)) + f->offset) = value; \
241                 LLNI_CRITICAL_END; \
242         } \
243 }
244
245 static inline void _field_set_handle(fieldinfo *f, java_lang_Object *o, java_handle_t *value)
246 {
247         LLNI_CRITICAL_START;
248
249         if (f->flags & ACC_STATIC) {
250                 f->value->a = LLNI_DIRECT(value);
251         } else {
252                 *(java_object_t **) (((intptr_t) LLNI_DIRECT(o)) + f->offset) = LLNI_DIRECT(value);
253         }
254
255         LLNI_CRITICAL_END;
256 }
257
258 _FIELD_SET_TYPE(int,    int32_t, i)
259 _FIELD_SET_TYPE(long,   int64_t, l)
260 _FIELD_SET_TYPE(float,  float,   f)
261 _FIELD_SET_TYPE(double, double,  d)
262
263
264 /*
265  * Class:     java/lang/reflect/VMField
266  * Method:    getModifiersInternal
267  * Signature: ()I
268  */
269 JNIEXPORT int32_t JNICALL Java_java_lang_reflect_VMField_getModifiersInternal(JNIEnv *env, java_lang_reflect_VMField *this)
270 {
271         classinfo *c;
272         fieldinfo *f;
273         int32_t    slot;
274
275         LLNI_field_get_cls(this, clazz, c);
276         LLNI_field_get_val(this, slot , slot);
277         f = &(c->fields[slot]);
278
279         return f->flags;
280 }
281
282
283 /*
284  * Class:     java/lang/reflect/VMField
285  * Method:    getType
286  * Signature: ()Ljava/lang/Class;
287  */
288 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_reflect_VMField_getType(JNIEnv *env, java_lang_reflect_VMField *this)
289 {
290         classinfo *c;
291         typedesc  *desc;
292         classinfo *ret;
293         int32_t    slot;
294
295         LLNI_field_get_cls(this, clazz, c);
296         LLNI_field_get_val(this, slot , slot);
297         desc = c->fields[slot].parseddesc;
298
299         if (desc == NULL)
300                 return NULL;
301
302         if (!resolve_class_from_typedesc(desc, true, false, &ret))
303                 return NULL;
304         
305         return LLNI_classinfo_wrap(ret);
306 }
307
308
309 /*
310  * Class:     java/lang/reflect/VMField
311  * Method:    get
312  * Signature: (Ljava/lang/Object;)Ljava/lang/Object;
313  */
314 JNIEXPORT java_lang_Object* JNICALL Java_java_lang_reflect_VMField_get(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o)
315 {
316         classinfo *c;
317         fieldinfo *f;
318         int32_t    slot;
319         imm_union  value;
320         java_handle_t *object;
321
322         LLNI_field_get_cls(this, clazz, c);
323         LLNI_field_get_val(this, slot , slot);
324         f = &c->fields[slot];
325
326         /* check if the field can be accessed */
327
328         if (!_field_access_check(this, f, c, (java_handle_t *) o))
329                 return NULL;
330
331         switch (f->parseddesc->decltype) {
332         case PRIMITIVETYPE_BOOLEAN:
333         case PRIMITIVETYPE_BYTE:
334         case PRIMITIVETYPE_CHAR:
335         case PRIMITIVETYPE_SHORT:
336         case PRIMITIVETYPE_INT:
337                 value.i = _field_get_int(f, o);
338                 break;
339
340         case PRIMITIVETYPE_LONG:
341                 value.l = _field_get_long(f, o);
342                 break;
343
344         case PRIMITIVETYPE_FLOAT:
345                 value.f = _field_get_float(f, o);
346                 break;
347
348         case PRIMITIVETYPE_DOUBLE:
349                 value.d = _field_get_double(f, o);
350                 break;
351
352         case TYPE_ADR:
353                 return (java_lang_Object *) _field_get_handle(f, o);
354         }
355
356         /* Now box the primitive types. */
357
358         object = primitive_box(f->parseddesc->decltype, value);
359
360         return (java_lang_Object *) object;
361 }
362
363
364 /*
365  * Class:     java/lang/reflect/VMField
366  * Method:    getBoolean
367  * Signature: (Ljava/lang/Object;)Z
368  */
369 JNIEXPORT int32_t JNICALL Java_java_lang_reflect_VMField_getBoolean(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o)
370 {
371         classinfo *c;
372         fieldinfo *f;
373         int32_t    slot;
374
375         /* get the class and the field */
376
377         LLNI_field_get_cls(this, clazz, c);
378         LLNI_field_get_val(this, slot , slot);
379         f = &c->fields[slot];
380
381         /* check if the field can be accessed */
382
383         if (!_field_access_check(this, f, c, (java_handle_t *) o))
384                 return 0;
385
386         /* check the field type and return the value */
387
388         switch (f->parseddesc->decltype) {
389         case PRIMITIVETYPE_BOOLEAN:
390                 return (int32_t) _field_get_int(f, o);
391         default:
392                 exceptions_throw_illegalargumentexception();
393                 return 0;
394         }
395 }
396
397
398 /*
399  * Class:     java/lang/reflect/VMField
400  * Method:    getByte
401  * Signature: (Ljava/lang/Object;)B
402  */
403 JNIEXPORT int32_t JNICALL Java_java_lang_reflect_VMField_getByte(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o)
404 {
405         classinfo *c;
406         fieldinfo *f;
407         int32_t    slot;
408
409         /* get the class and the field */
410
411         LLNI_field_get_cls(this, clazz, c);
412         LLNI_field_get_val(this, slot , slot);
413         f = &c->fields[slot];
414
415         /* check if the field can be accessed */
416
417         if (!_field_access_check(this, f, c, (java_handle_t *) o))
418                 return 0;
419
420         /* check the field type and return the value */
421
422         switch (f->parseddesc->decltype) {
423         case PRIMITIVETYPE_BYTE:
424                 return (int32_t) _field_get_int(f, o);
425         default:
426                 exceptions_throw_illegalargumentexception();
427                 return 0;
428         }
429 }
430
431
432 /*
433  * Class:     java/lang/reflect/VMField
434  * Method:    getChar
435  * Signature: (Ljava/lang/Object;)C
436  */
437 JNIEXPORT int32_t JNICALL Java_java_lang_reflect_VMField_getChar(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o)
438 {
439         classinfo *c;
440         fieldinfo *f;
441         int32_t    slot;
442
443         /* get the class and the field */
444
445         LLNI_field_get_cls(this, clazz, c);
446         LLNI_field_get_val(this, slot , slot);
447         f = &c->fields[slot];
448
449         /* check if the field can be accessed */
450
451         if (!_field_access_check(this, f, c, (java_handle_t *) o))
452                 return 0;
453
454         /* check the field type and return the value */
455
456         switch (f->parseddesc->decltype) {
457         case PRIMITIVETYPE_CHAR:
458                 return (int32_t) _field_get_int(f, o);
459         default:
460                 exceptions_throw_illegalargumentexception();
461                 return 0;
462         }
463 }
464
465
466 /*
467  * Class:     java/lang/reflect/VMField
468  * Method:    getShort
469  * Signature: (Ljava/lang/Object;)S
470  */
471 JNIEXPORT int32_t JNICALL Java_java_lang_reflect_VMField_getShort(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o)
472 {
473         classinfo *c;
474         fieldinfo *f;
475         int32_t    slot;
476
477         /* get the class and the field */
478
479         LLNI_field_get_cls(this, clazz, c);
480         LLNI_field_get_val(this, slot , slot);
481         f = &c->fields[slot];
482
483         /* check if the field can be accessed */
484
485         if (!_field_access_check(this, f, c, (java_handle_t *) o))
486                 return 0;
487
488         /* check the field type and return the value */
489
490         switch (f->parseddesc->decltype) {
491         case PRIMITIVETYPE_BYTE:
492         case PRIMITIVETYPE_SHORT:
493                 return (int32_t) _field_get_int(f, o);
494         default:
495                 exceptions_throw_illegalargumentexception();
496                 return 0;
497         }
498 }
499
500
501 /*
502  * Class:     java/lang/reflect/VMField
503  * Method:    getInt
504  * Signature: (Ljava/lang/Object;)I
505  */
506 JNIEXPORT int32_t JNICALL Java_java_lang_reflect_VMField_getInt(JNIEnv *env , java_lang_reflect_VMField *this, java_lang_Object *o)
507 {
508         classinfo *c;
509         fieldinfo *f;
510         int32_t    slot;
511
512         /* get the class and the field */
513
514         LLNI_field_get_cls(this, clazz, c);
515         LLNI_field_get_val(this, slot , slot);
516         f = &c->fields[slot];
517
518         /* check if the field can be accessed */
519
520         if (!_field_access_check(this, f, c, (java_handle_t *) o))
521                 return 0;
522
523         /* check the field type and return the value */
524
525         switch (f->parseddesc->decltype) {
526         case PRIMITIVETYPE_BYTE:
527         case PRIMITIVETYPE_CHAR:
528         case PRIMITIVETYPE_SHORT:
529         case PRIMITIVETYPE_INT:
530                 return (int32_t) _field_get_int(f, o);
531         default:
532                 exceptions_throw_illegalargumentexception();
533                 return 0;
534         }
535 }
536
537
538 /*
539  * Class:     java/lang/reflect/VMField
540  * Method:    getLong
541  * Signature: (Ljava/lang/Object;)J
542  */
543 JNIEXPORT int64_t JNICALL Java_java_lang_reflect_VMField_getLong(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o)
544 {
545         classinfo *c;
546         fieldinfo *f;
547         int32_t    slot;
548
549         /* get the class and the field */
550
551         LLNI_field_get_cls(this, clazz, c);
552         LLNI_field_get_val(this, slot , slot);
553         f = &c->fields[slot];
554
555         /* check if the field can be accessed */
556
557         if (!_field_access_check(this, f, c, (java_handle_t *) o))
558                 return 0;
559
560         /* check the field type and return the value */
561
562         switch (f->parseddesc->decltype) {
563         case PRIMITIVETYPE_BYTE:
564         case PRIMITIVETYPE_CHAR:
565         case PRIMITIVETYPE_SHORT:
566         case PRIMITIVETYPE_INT:
567                 return (int64_t) _field_get_int(f, o);
568         case PRIMITIVETYPE_LONG:
569                 return (int64_t) _field_get_long(f, o);
570         default:
571                 exceptions_throw_illegalargumentexception();
572                 return 0;
573         }
574 }
575
576
577 /*
578  * Class:     java/lang/reflect/VMField
579  * Method:    getFloat
580  * Signature: (Ljava/lang/Object;)F
581  */
582 JNIEXPORT float JNICALL Java_java_lang_reflect_VMField_getFloat(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o)
583 {
584         classinfo *c;
585         fieldinfo *f;
586         int32_t    slot;
587
588         /* get the class and the field */
589
590         LLNI_field_get_cls(this, clazz, c);
591         LLNI_field_get_val(this, slot , slot);
592         f = &c->fields[slot];
593
594         /* check if the field can be accessed */
595
596         if (!_field_access_check(this, f, c, (java_handle_t *) o))
597                 return 0;
598
599         /* check the field type and return the value */
600
601         switch (f->parseddesc->decltype) {
602         case PRIMITIVETYPE_BYTE:
603         case PRIMITIVETYPE_CHAR:
604         case PRIMITIVETYPE_SHORT:
605         case PRIMITIVETYPE_INT:
606                 return (float) _field_get_int(f, o);
607         case PRIMITIVETYPE_LONG:
608                 return (float) _field_get_long(f, o);
609         case PRIMITIVETYPE_FLOAT:
610                 return (float) _field_get_float(f, o);
611         default:
612                 exceptions_throw_illegalargumentexception();
613                 return 0;
614         }
615 }
616
617
618 /*
619  * Class:     java/lang/reflect/VMField
620  * Method:    getDouble
621  * Signature: (Ljava/lang/Object;)D
622  */
623 JNIEXPORT double JNICALL Java_java_lang_reflect_VMField_getDouble(JNIEnv *env , java_lang_reflect_VMField *this, java_lang_Object *o)
624 {
625         classinfo *c;
626         fieldinfo *f;
627         int32_t    slot;
628
629         /* get the class and the field */
630
631         LLNI_field_get_cls(this, clazz, c);
632         LLNI_field_get_val(this, slot , slot);
633         f = &c->fields[slot];
634
635         /* check if the field can be accessed */
636
637         if (!_field_access_check(this, f, c, (java_handle_t *) o))
638                 return 0;
639
640         /* check the field type and return the value */
641
642         switch (f->parseddesc->decltype) {
643         case PRIMITIVETYPE_BYTE:
644         case PRIMITIVETYPE_CHAR:
645         case PRIMITIVETYPE_SHORT:
646         case PRIMITIVETYPE_INT:
647                 return (double) _field_get_int(f, o);
648         case PRIMITIVETYPE_LONG:
649                 return (double) _field_get_long(f, o);
650         case PRIMITIVETYPE_FLOAT:
651                 return (double) _field_get_float(f, o);
652         case PRIMITIVETYPE_DOUBLE:
653                 return (double) _field_get_double(f, o);
654         default:
655                 exceptions_throw_illegalargumentexception();
656                 return 0;
657         }
658 }
659
660
661 /*
662  * Class:     java/lang/reflect/VMField
663  * Method:    set
664  * Signature: (Ljava/lang/Object;Ljava/lang/Object;)V
665  */
666 JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_set(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o, java_lang_Object *value)
667 {
668         classinfo *sc;
669         classinfo *dc;
670         fieldinfo *sf;
671         fieldinfo *df;
672         int32_t    slot;
673
674         /* get the class and the field */
675
676         LLNI_field_get_cls(this, clazz, dc);
677         LLNI_field_get_val(this, slot , slot);
678         df = &dc->fields[slot];
679
680         /* check if the field can be accessed */
681
682         if (!_field_access_check(this, df, dc, (java_handle_t *) o))
683                 return;
684
685         /* get the source classinfo from the object */
686
687         if (value == NULL)
688                 sc = NULL;
689         else
690                 LLNI_class_get(value, sc);
691
692         /* The fieldid is used to set the new value, for primitive
693            types the value has to be retrieved from the wrapping
694            object */
695
696         switch (df->parseddesc->decltype) {
697         case PRIMITIVETYPE_BOOLEAN: {
698                 int32_t val;
699
700                 /* determine the field to read the value */
701
702                 if ((sc == NULL) || !(sf = class_findfield(sc, utf_value, utf_Z)))
703                         break;
704
705                 switch (sf->parseddesc->decltype) {
706                 case PRIMITIVETYPE_BOOLEAN:
707                         LLNI_field_get_val((java_lang_Boolean *) value, value, val);
708                         break;
709                 default:
710                         exceptions_throw_illegalargumentexception();
711                         return;
712                 }
713
714                 _field_set_int(df, o, val);
715                 return;
716         }
717
718         case PRIMITIVETYPE_BYTE: {
719                 int32_t val;
720
721                 if ((sc == NULL) || !(sf = class_findfield(sc, utf_value, utf_B)))
722                         break;
723
724                 switch (sf->parseddesc->decltype) {
725                 case PRIMITIVETYPE_BYTE:
726                         LLNI_field_get_val((java_lang_Byte *) value, value, val);
727                         break;
728                 default:        
729                         exceptions_throw_illegalargumentexception();
730                         return;
731                 }
732
733                 _field_set_int(df, o, val);
734                 return;
735         }
736
737         case PRIMITIVETYPE_CHAR: {
738                 int32_t val;
739
740                 if ((sc == NULL) || !(sf = class_findfield(sc, utf_value, utf_C)))
741                         break;
742                                    
743                 switch (sf->parseddesc->decltype) {
744                 case PRIMITIVETYPE_CHAR:
745                         LLNI_field_get_val((java_lang_Character *) value, value, val);
746                         break;
747                 default:
748                         exceptions_throw_illegalargumentexception();
749                         return;
750                 }
751
752                 _field_set_int(df, o, val);
753                 return;
754         }
755
756         case PRIMITIVETYPE_SHORT: {
757                 int32_t val;
758
759                 /* get field only by name, it can be one of B, S */
760
761                 if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
762                         break;
763                                    
764                 switch (sf->parseddesc->decltype) {
765                 case PRIMITIVETYPE_BYTE:
766                         LLNI_field_get_val((java_lang_Byte *) value, value, val);
767                         break;
768                 case PRIMITIVETYPE_SHORT:
769                         LLNI_field_get_val((java_lang_Short *) value, value, val);
770                         break;
771                 default:
772                         exceptions_throw_illegalargumentexception();
773                         return;
774                 }
775
776                 _field_set_int(df, o, val);
777                 return;
778         }
779
780         case PRIMITIVETYPE_INT: {
781                 int32_t val;
782
783                 /* get field only by name, it can be one of B, S, C, I */
784
785                 if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
786                         break;
787
788                 switch (sf->parseddesc->decltype) {
789                 case PRIMITIVETYPE_BYTE:
790                         LLNI_field_get_val((java_lang_Byte *) value, value, val);
791                         break;
792                 case PRIMITIVETYPE_CHAR:
793                         LLNI_field_get_val((java_lang_Character *) value, value, val);
794                         break;
795                 case PRIMITIVETYPE_SHORT:
796                         LLNI_field_get_val((java_lang_Short *) value, value, val);
797                         break;
798                 case PRIMITIVETYPE_INT:
799                         LLNI_field_get_val((java_lang_Integer *) value, value, val);
800                         break;
801                 default:
802                         exceptions_throw_illegalargumentexception();
803                         return;
804                 }
805
806                 _field_set_int(df, o, val);
807                 return;
808         }
809
810         case PRIMITIVETYPE_LONG: {
811                 int64_t val;
812
813                 /* get field only by name, it can be one of B, S, C, I, J */
814
815                 if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
816                         break;
817
818                 switch (sf->parseddesc->decltype) {
819                 case PRIMITIVETYPE_BYTE:
820                         LLNI_field_get_val((java_lang_Byte *) value, value, val);
821                         break;
822                 case PRIMITIVETYPE_CHAR:
823                         LLNI_field_get_val((java_lang_Character *) value, value, val);
824                         break;
825                 case PRIMITIVETYPE_SHORT:
826                         LLNI_field_get_val((java_lang_Short *) value, value, val);
827                         break;
828                 case PRIMITIVETYPE_INT:
829                         LLNI_field_get_val((java_lang_Integer *) value, value, val);
830                         break;
831                 case PRIMITIVETYPE_LONG:
832                         LLNI_field_get_val((java_lang_Long *) value, value, val);
833                         break;
834                 default:
835                         exceptions_throw_illegalargumentexception();
836                         return;
837                 }
838
839                 _field_set_long(df, o, val);
840                 return;
841         }
842
843         case PRIMITIVETYPE_FLOAT: {
844                 float val;
845
846                 /* get field only by name, it can be one of B, S, C, I, J, F */
847
848                 if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
849                         break;
850
851                 switch (sf->parseddesc->decltype) {
852                 case PRIMITIVETYPE_BYTE:
853                         LLNI_field_get_val((java_lang_Byte *) value, value, val);
854                         break;
855                 case PRIMITIVETYPE_CHAR:
856                         LLNI_field_get_val((java_lang_Character *) value, value, val);
857                         break;
858                 case PRIMITIVETYPE_SHORT:
859                         LLNI_field_get_val((java_lang_Short *) value, value, val);
860                         break;
861                 case PRIMITIVETYPE_INT:
862                         LLNI_field_get_val((java_lang_Integer *) value, value, val);
863                         break;
864                 case PRIMITIVETYPE_LONG:
865                         LLNI_field_get_val((java_lang_Long *) value, value, val);
866                         break;
867                 case PRIMITIVETYPE_FLOAT:
868                         LLNI_field_get_val((java_lang_Float *) value, value, val);
869                         break;
870                 default:
871                         exceptions_throw_illegalargumentexception();
872                         return;
873                 }
874
875                 _field_set_float(df, o, val);
876                 return;
877         }
878
879         case PRIMITIVETYPE_DOUBLE: {
880                 double val;
881
882                 /* get field only by name, it can be one of B, S, C, I, J, F, D */
883
884                 if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
885                         break;
886
887                 switch (sf->parseddesc->decltype) {
888                 case PRIMITIVETYPE_BYTE:
889                         LLNI_field_get_val((java_lang_Byte *) value, value, val);
890                         break;
891                 case PRIMITIVETYPE_CHAR:
892                         LLNI_field_get_val((java_lang_Character *) value, value, val);
893                         break;
894                 case PRIMITIVETYPE_SHORT:
895                         LLNI_field_get_val((java_lang_Short *) value, value, val);
896                         break;
897                 case PRIMITIVETYPE_INT:
898                         LLNI_field_get_val((java_lang_Integer *) value, value, val);
899                         break;
900                 case PRIMITIVETYPE_LONG:
901                         LLNI_field_get_val((java_lang_Long *) value, value, val);
902                         break;
903                 case PRIMITIVETYPE_FLOAT:
904                         LLNI_field_get_val((java_lang_Float *) value, value, val);
905                         break;
906                 case PRIMITIVETYPE_DOUBLE:
907                         LLNI_field_get_val((java_lang_Double *) value, value, val);
908                         break;
909                 default:
910                         exceptions_throw_illegalargumentexception();
911                         return;
912                 }
913
914                 _field_set_double(df, o, val);
915                 return;
916         }
917
918         case TYPE_ADR:
919                 /* check if value is an instance of the destination class */
920
921                 /* XXX TODO */
922                 /*                      if (!builtin_instanceof((java_handle_t *) value, df->class)) */
923                 /*                              break; */
924
925                 _field_set_handle(df, o, (java_handle_t *) value);
926                 return;
927         }
928
929         /* raise exception */
930
931         exceptions_throw_illegalargumentexception();
932 }
933
934
935 /*
936  * Class:     java/lang/reflect/VMField
937  * Method:    setBoolean
938  * Signature: (Ljava/lang/Object;Z)V
939  */
940 JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setBoolean(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o, int32_t value)
941 {
942         classinfo *c;
943         fieldinfo *f;
944         int32_t    slot;
945
946         /* get the class and the field */
947
948         LLNI_field_get_cls(this, clazz, c);
949         LLNI_field_get_val(this, slot , slot);
950         f = &c->fields[slot];
951
952         /* check if the field can be accessed */
953
954         if (!_field_access_check(this, f, c, (java_handle_t *) o))
955                 return;
956
957         /* check the field type and set the value */
958
959         switch (f->parseddesc->decltype) {
960         case PRIMITIVETYPE_BOOLEAN:
961                 _field_set_int(f, o, value);
962                 break;
963         default:
964                 exceptions_throw_illegalargumentexception();
965         }
966
967         return;
968 }
969
970
971 /*
972  * Class:     java/lang/reflect/VMField
973  * Method:    setByte
974  * Signature: (Ljava/lang/Object;B)V
975  */
976 JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setByte(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o, int32_t value)
977 {
978         classinfo *c;
979         fieldinfo *f;
980         int32_t    slot;
981
982         /* get the class and the field */
983
984         LLNI_field_get_cls(this, clazz, c);
985         LLNI_field_get_val(this, slot , slot);
986         f = &c->fields[slot];
987
988         /* check if the field can be accessed */
989
990         if (!_field_access_check(this, f, c, (java_handle_t *) o))
991                 return;
992
993         /* check the field type and set the value */
994
995         switch (f->parseddesc->decltype) {
996         case PRIMITIVETYPE_BYTE:
997         case PRIMITIVETYPE_SHORT:
998         case PRIMITIVETYPE_INT:
999                 _field_set_int(f, o, value);
1000                 break;
1001         case PRIMITIVETYPE_LONG:
1002                 _field_set_long(f, o, value);
1003                 break;
1004         case PRIMITIVETYPE_FLOAT:
1005                 _field_set_float(f, o, value);
1006                 break;
1007         case PRIMITIVETYPE_DOUBLE:
1008                 _field_set_double(f, o, value);
1009                 break;
1010         default:
1011                 exceptions_throw_illegalargumentexception();
1012         }
1013
1014         return;
1015 }
1016
1017
1018 /*
1019  * Class:     java/lang/reflect/VMField
1020  * Method:    setChar
1021  * Signature: (Ljava/lang/Object;C)V
1022  */
1023 JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setChar(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o, int32_t value)
1024 {
1025         classinfo *c;
1026         fieldinfo *f;
1027         int32_t    slot;
1028
1029         /* get the class and the field */
1030
1031         LLNI_field_get_cls(this, clazz, c);
1032         LLNI_field_get_val(this, slot , slot);
1033         f = &c->fields[slot];
1034
1035         /* check if the field can be accessed */
1036
1037         if (!_field_access_check(this, f, c, (java_handle_t *) o))
1038                 return;
1039
1040         /* check the field type and set the value */
1041
1042         switch (f->parseddesc->decltype) {
1043         case PRIMITIVETYPE_CHAR:
1044         case PRIMITIVETYPE_INT:
1045                 _field_set_int(f, o, value);
1046                 break;
1047         case PRIMITIVETYPE_LONG:
1048                 _field_set_long(f, o, value);
1049                 break;
1050         case PRIMITIVETYPE_FLOAT:
1051                 _field_set_float(f, o, value);
1052                 break;
1053         case PRIMITIVETYPE_DOUBLE:
1054                 _field_set_double(f, o, value);
1055                 break;
1056         default:
1057                 exceptions_throw_illegalargumentexception();
1058         }
1059
1060         return;
1061 }
1062
1063
1064 /*
1065  * Class:     java/lang/reflect/VMField
1066  * Method:    setShort
1067  * Signature: (Ljava/lang/Object;S)V
1068  */
1069 JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setShort(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o, int32_t value)
1070 {
1071         classinfo *c;
1072         fieldinfo *f;
1073         int32_t    slot;
1074
1075         /* get the class and the field */
1076
1077         LLNI_field_get_cls(this, clazz, c);
1078         LLNI_field_get_val(this, slot , slot);
1079         f = &c->fields[slot];
1080
1081         /* check if the field can be accessed */
1082
1083         if (!_field_access_check(this, f, c, (java_handle_t *) o))
1084                 return;
1085
1086         /* check the field type and set the value */
1087
1088         switch (f->parseddesc->decltype) {
1089         case PRIMITIVETYPE_SHORT:
1090         case PRIMITIVETYPE_INT:
1091                 _field_set_int(f, o, value);
1092                 break;
1093         case PRIMITIVETYPE_LONG:
1094                 _field_set_long(f, o, value);
1095                 break;
1096         case PRIMITIVETYPE_FLOAT:
1097                 _field_set_float(f, o, value);
1098                 break;
1099         case PRIMITIVETYPE_DOUBLE:
1100                 _field_set_double(f, o, value);
1101                 break;
1102         default:
1103                 exceptions_throw_illegalargumentexception();
1104         }
1105
1106         return;
1107 }
1108
1109
1110 /*
1111  * Class:     java/lang/reflect/VMField
1112  * Method:    setInt
1113  * Signature: (Ljava/lang/Object;I)V
1114  */
1115 JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setInt(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o, int32_t value)
1116 {
1117         classinfo *c;
1118         fieldinfo *f;
1119         int32_t    slot;
1120
1121         /* get the class and the field */
1122
1123         LLNI_field_get_cls(this, clazz, c);
1124         LLNI_field_get_val(this, slot , slot);
1125         f = &c->fields[slot];
1126
1127         /* check if the field can be accessed */
1128
1129         if (!_field_access_check(this, f, c, (java_handle_t *) o))
1130                 return;
1131
1132         /* check the field type and set the value */
1133
1134         switch (f->parseddesc->decltype) {
1135         case PRIMITIVETYPE_INT:
1136                 _field_set_int(f, o, value);
1137                 break;
1138         case PRIMITIVETYPE_LONG:
1139                 _field_set_long(f, o, value);
1140                 break;
1141         case PRIMITIVETYPE_FLOAT:
1142                 _field_set_float(f, o, value);
1143                 break;
1144         case PRIMITIVETYPE_DOUBLE:
1145                 _field_set_double(f, o, value);
1146                 break;
1147         default:
1148                 exceptions_throw_illegalargumentexception();
1149         }
1150
1151         return;
1152 }
1153
1154
1155 /*
1156  * Class:     java/lang/reflect/VMField
1157  * Method:    setLong
1158  * Signature: (Ljava/lang/Object;J)V
1159  */
1160 JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setLong(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o, int64_t value)
1161 {
1162         classinfo *c;
1163         fieldinfo *f;
1164         int32_t    slot;
1165
1166         /* get the class and the field */
1167
1168         LLNI_field_get_cls(this, clazz, c);
1169         LLNI_field_get_val(this, slot , slot);
1170         f = &c->fields[slot];
1171
1172         /* check if the field can be accessed */
1173
1174         if (!_field_access_check(this, f, c, (java_handle_t *) o))
1175                 return;
1176
1177         /* check the field type and set the value */
1178
1179         switch (f->parseddesc->decltype) {
1180         case PRIMITIVETYPE_LONG:
1181                 _field_set_long(f, o, value);
1182                 break;
1183         case PRIMITIVETYPE_FLOAT:
1184                 _field_set_float(f, o, value);
1185                 break;
1186         case PRIMITIVETYPE_DOUBLE:
1187                 _field_set_double(f, o, value);
1188                 break;
1189         default:
1190                 exceptions_throw_illegalargumentexception();
1191         }
1192
1193         return;
1194 }
1195
1196
1197 /*
1198  * Class:     java/lang/reflect/VMField
1199  * Method:    setFloat
1200  * Signature: (Ljava/lang/Object;F)V
1201  */
1202 JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setFloat(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o, float value)
1203 {
1204         classinfo *c;
1205         fieldinfo *f;
1206         int32_t    slot;
1207
1208         /* get the class and the field */
1209
1210         LLNI_field_get_cls(this, clazz, c);
1211         LLNI_field_get_val(this, slot , slot);
1212         f = &c->fields[slot];
1213
1214         /* check if the field can be accessed */
1215
1216         if (!_field_access_check(this, f, c, (java_handle_t *) o))
1217                 return;
1218
1219         /* check the field type and set the value */
1220
1221         switch (f->parseddesc->decltype) {
1222         case PRIMITIVETYPE_FLOAT:
1223                 _field_set_float(f, o, value);
1224                 break;
1225         case PRIMITIVETYPE_DOUBLE:
1226                 _field_set_double(f, o, value);
1227                 break;
1228         default:
1229                 exceptions_throw_illegalargumentexception();
1230         }
1231
1232         return;
1233 }
1234
1235
1236 /*
1237  * Class:     java/lang/reflect/VMField
1238  * Method:    setDouble
1239  * Signature: (Ljava/lang/Object;D)V
1240  */
1241 JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setDouble(JNIEnv *env, java_lang_reflect_VMField *this, java_lang_Object *o, double value)
1242 {
1243         classinfo *c;
1244         fieldinfo *f;
1245         int32_t    slot;
1246
1247         /* get the class and the field */
1248
1249         LLNI_field_get_cls(this, clazz, c);
1250         LLNI_field_get_val(this, slot , slot);
1251         f = &c->fields[slot];
1252
1253         /* check if the field can be accessed */
1254
1255         if (!_field_access_check(this, f, c, (java_handle_t *) o))
1256                 return;
1257
1258         /* check the field type and set the value */
1259
1260         switch (f->parseddesc->decltype) {
1261         case PRIMITIVETYPE_DOUBLE:
1262                 _field_set_double(f, o, value);
1263                 break;
1264         default:
1265                 exceptions_throw_illegalargumentexception();
1266         }
1267
1268         return;
1269 }
1270
1271
1272 /*
1273  * Class:     java/lang/reflect/VMField
1274  * Method:    getSignature
1275  * Signature: ()Ljava/lang/String;
1276  */
1277 JNIEXPORT java_lang_String* JNICALL Java_java_lang_reflect_VMField_getSignature(JNIEnv *env, java_lang_reflect_VMField* this)
1278 {
1279         classinfo     *c;
1280         fieldinfo     *f;
1281         java_handle_t *o;
1282         int32_t        slot;
1283
1284         /* get the class and the field */
1285
1286         LLNI_field_get_cls(this, clazz, c);
1287         LLNI_field_get_val(this, slot , slot);
1288         f = &c->fields[slot];
1289
1290         if (f->signature == NULL)
1291                 return NULL;
1292
1293         o = javastring_new(f->signature);
1294
1295         /* in error case o is NULL */
1296
1297         return (java_lang_String *) o;
1298 }
1299
1300
1301 #if defined(ENABLE_ANNOTATIONS)
1302 /*
1303  * Class:     java/lang/reflect/VMField
1304  * Method:    declaredAnnotations
1305  * Signature: ()Ljava/util/Map;
1306  */
1307 JNIEXPORT struct java_util_Map* JNICALL Java_java_lang_reflect_VMField_declaredAnnotations(JNIEnv *env, java_lang_reflect_VMField *this)
1308 {
1309         java_util_Map           *declaredAnnotations = NULL; /* parsed annotations                                */
1310         java_handle_bytearray_t *annotations         = NULL; /* unparsed annotations                              */
1311         java_lang_Class         *declaringClass      = NULL; /* the constant pool of this class is used           */
1312         classinfo               *referer             = NULL; /* class, which calles the annotation parser         */
1313                                                              /* (for the parameter 'referer' of vm_call_method()) */
1314
1315         LLNI_field_get_ref(this, declaredAnnotations, declaredAnnotations);
1316
1317         /* are the annotations parsed yet? */
1318         if (declaredAnnotations == NULL) {
1319                 LLNI_field_get_ref(this, annotations, annotations);
1320                 LLNI_field_get_ref(this, clazz, declaringClass);
1321                 LLNI_class_get(this, referer);
1322
1323                 declaredAnnotations = reflect_get_declaredannotatios(annotations, declaringClass, referer);
1324
1325                 LLNI_field_set_ref(this, declaredAnnotations, declaredAnnotations);
1326         }
1327
1328         return declaredAnnotations;
1329 }
1330 #endif
1331
1332
1333 /*
1334  * These are local overrides for various environment variables in Emacs.
1335  * Please do not remove this and leave it at the end of the file, where
1336  * Emacs will automagically detect them.
1337  * ---------------------------------------------------------------------
1338  * Local variables:
1339  * mode: c
1340  * indent-tabs-mode: t
1341  * c-basic-offset: 4
1342  * tab-width: 4
1343  * End:
1344  * vim:noexpandtab:sw=4:ts=4:
1345  */