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