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