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