* src/native/jni.h: Removed.
[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.h"
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.h"
45 #include "vm/builtin.h"
46 #include "vm/exceptions.hpp"
47 #include "vm/global.h"
48 #include "vm/initialize.h"
49 #include "vm/javaobjects.hpp"
50 #include "vm/loader.h"
51 #include "vm/primitive.hpp"
52 #include "vm/resolve.h"
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         java_handle_t* ho = (java_handle_t*) o;
250
251         /* check if the field can be accessed */
252
253         if (!_field_access_check(rvmf, f, ho))
254                 return NULL;
255
256         imm_union value;
257
258         switch (f->parseddesc->primitivetype) {
259         case PRIMITIVETYPE_BOOLEAN:
260         case PRIMITIVETYPE_BYTE:
261         case PRIMITIVETYPE_CHAR:
262         case PRIMITIVETYPE_SHORT:
263         case PRIMITIVETYPE_INT:
264                 value.i = _field_get_int(f, ho);
265                 break;
266
267         case PRIMITIVETYPE_LONG:
268                 value.l = _field_get_long(f, ho);
269                 break;
270
271         case PRIMITIVETYPE_FLOAT:
272                 value.f = _field_get_float(f, ho);
273                 break;
274
275         case PRIMITIVETYPE_DOUBLE:
276                 value.d = _field_get_double(f, ho);
277                 break;
278
279         case TYPE_ADR:
280                 return (jobject) _field_get_handle(f, ho);
281         }
282
283         /* Now box the primitive types. */
284
285         java_handle_t* object = Primitive::box(f->parseddesc->primitivetype, value);
286
287         return (jobject) object;
288 }
289
290
291 /*
292  * Class:     java/lang/reflect/VMField
293  * Method:    getBoolean
294  * Signature: (Ljava/lang/Object;)Z
295  */
296 JNIEXPORT jboolean JNICALL Java_java_lang_reflect_VMField_getBoolean(JNIEnv *env, jobject _this, jobject o)
297 {
298         java_lang_reflect_VMField rvmf(_this);
299         fieldinfo* f = rvmf.get_field();
300
301         java_handle_t* ho = (java_handle_t*) o;
302
303         /* check if the field can be accessed */
304
305         if (!_field_access_check(rvmf, f, ho))
306                 return 0;
307
308         /* check the field type and return the value */
309
310         switch (f->parseddesc->primitivetype) {
311         case PRIMITIVETYPE_BOOLEAN:
312                 return (int32_t) _field_get_int(f, ho);
313         default:
314                 exceptions_throw_illegalargumentexception();
315                 return 0;
316         }
317 }
318
319
320 /*
321  * Class:     java/lang/reflect/VMField
322  * Method:    getByte
323  * Signature: (Ljava/lang/Object;)B
324  */
325 JNIEXPORT jbyte JNICALL Java_java_lang_reflect_VMField_getByte(JNIEnv *env, jobject _this, jobject o)
326 {
327         java_lang_reflect_VMField rvmf(_this);
328         fieldinfo* f = rvmf.get_field();
329
330         java_handle_t* ho = (java_handle_t*) o;
331
332         /* check if the field can be accessed */
333
334         if (!_field_access_check(rvmf, f, ho))
335                 return 0;
336
337         /* check the field type and return the value */
338
339         switch (f->parseddesc->primitivetype) {
340         case PRIMITIVETYPE_BYTE:
341                 return (int32_t) _field_get_int(f, ho);
342         default:
343                 exceptions_throw_illegalargumentexception();
344                 return 0;
345         }
346 }
347
348
349 /*
350  * Class:     java/lang/reflect/VMField
351  * Method:    getChar
352  * Signature: (Ljava/lang/Object;)C
353  */
354 JNIEXPORT jchar JNICALL Java_java_lang_reflect_VMField_getChar(JNIEnv *env, jobject _this, jobject o)
355 {
356         java_lang_reflect_VMField rvmf(_this);
357         fieldinfo* f = rvmf.get_field();
358
359         java_handle_t* ho = (java_handle_t*) o;
360
361         /* check if the field can be accessed */
362
363         if (!_field_access_check(rvmf, f, ho))
364                 return 0;
365
366         /* check the field type and return the value */
367
368         switch (f->parseddesc->primitivetype) {
369         case PRIMITIVETYPE_CHAR:
370                 return (int32_t) _field_get_int(f, ho);
371         default:
372                 exceptions_throw_illegalargumentexception();
373                 return 0;
374         }
375 }
376
377
378 /*
379  * Class:     java/lang/reflect/VMField
380  * Method:    getShort
381  * Signature: (Ljava/lang/Object;)S
382  */
383 JNIEXPORT jshort JNICALL Java_java_lang_reflect_VMField_getShort(JNIEnv *env, jobject _this, jobject o)
384 {
385         java_lang_reflect_VMField rvmf(_this);
386         fieldinfo* f = rvmf.get_field();
387
388         java_handle_t* ho = (java_handle_t*) o;
389
390         /* check if the field can be accessed */
391
392         if (!_field_access_check(rvmf, f, ho))
393                 return 0;
394
395         /* check the field type and return the value */
396
397         switch (f->parseddesc->primitivetype) {
398         case PRIMITIVETYPE_BYTE:
399         case PRIMITIVETYPE_SHORT:
400                 return (int32_t) _field_get_int(f, ho);
401         default:
402                 exceptions_throw_illegalargumentexception();
403                 return 0;
404         }
405 }
406
407
408 /*
409  * Class:     java/lang/reflect/VMField
410  * Method:    getInt
411  * Signature: (Ljava/lang/Object;)I
412  */
413 JNIEXPORT jint JNICALL Java_java_lang_reflect_VMField_getInt(JNIEnv *env , jobject _this, jobject o)
414 {
415         java_lang_reflect_VMField rvmf(_this);
416         fieldinfo* f = rvmf.get_field();
417
418         java_handle_t* ho = (java_handle_t*) o;
419
420         /* check if the field can be accessed */
421
422         if (!_field_access_check(rvmf, f, ho))
423                 return 0;
424
425         /* check the field type and return the value */
426
427         switch (f->parseddesc->primitivetype) {
428         case PRIMITIVETYPE_BYTE:
429         case PRIMITIVETYPE_CHAR:
430         case PRIMITIVETYPE_SHORT:
431         case PRIMITIVETYPE_INT:
432                 return (int32_t) _field_get_int(f, ho);
433         default:
434                 exceptions_throw_illegalargumentexception();
435                 return 0;
436         }
437 }
438
439
440 /*
441  * Class:     java/lang/reflect/VMField
442  * Method:    getLong
443  * Signature: (Ljava/lang/Object;)J
444  */
445 JNIEXPORT jlong JNICALL Java_java_lang_reflect_VMField_getLong(JNIEnv *env, jobject _this, jobject o)
446 {
447         java_lang_reflect_VMField rvmf(_this);
448         fieldinfo* f = rvmf.get_field();
449
450         java_handle_t* ho = (java_handle_t*) o;
451
452         /* check if the field can be accessed */
453
454         if (!_field_access_check(rvmf, f, ho))
455                 return 0;
456
457         /* check the field type and return the value */
458
459         switch (f->parseddesc->primitivetype) {
460         case PRIMITIVETYPE_BYTE:
461         case PRIMITIVETYPE_CHAR:
462         case PRIMITIVETYPE_SHORT:
463         case PRIMITIVETYPE_INT:
464                 return (int64_t) _field_get_int(f, ho);
465         case PRIMITIVETYPE_LONG:
466                 return (int64_t) _field_get_long(f, ho);
467         default:
468                 exceptions_throw_illegalargumentexception();
469                 return 0;
470         }
471 }
472
473
474 /*
475  * Class:     java/lang/reflect/VMField
476  * Method:    getFloat
477  * Signature: (Ljava/lang/Object;)F
478  */
479 JNIEXPORT jfloat JNICALL Java_java_lang_reflect_VMField_getFloat(JNIEnv *env, jobject _this, jobject o)
480 {
481         java_lang_reflect_VMField rvmf(_this);
482         fieldinfo* f = rvmf.get_field();
483
484         java_handle_t* ho = (java_handle_t*) o;
485
486         /* check if the field can be accessed */
487
488         if (!_field_access_check(rvmf, f, ho))
489                 return 0;
490
491         /* check the field type and return the value */
492
493         switch (f->parseddesc->primitivetype) {
494         case PRIMITIVETYPE_BYTE:
495         case PRIMITIVETYPE_CHAR:
496         case PRIMITIVETYPE_SHORT:
497         case PRIMITIVETYPE_INT:
498                 return (float) _field_get_int(f, ho);
499         case PRIMITIVETYPE_LONG:
500                 return (float) _field_get_long(f, ho);
501         case PRIMITIVETYPE_FLOAT:
502                 return (float) _field_get_float(f, ho);
503         default:
504                 exceptions_throw_illegalargumentexception();
505                 return 0;
506         }
507 }
508
509
510 /*
511  * Class:     java/lang/reflect/VMField
512  * Method:    getDouble
513  * Signature: (Ljava/lang/Object;)D
514  */
515 JNIEXPORT jdouble JNICALL Java_java_lang_reflect_VMField_getDouble(JNIEnv *env , jobject _this, jobject o)
516 {
517         java_lang_reflect_VMField rvmf(_this);
518         fieldinfo* f = rvmf.get_field();
519
520         java_handle_t* ho = (java_handle_t*) o;
521
522         /* check if the field can be accessed */
523
524         if (!_field_access_check(rvmf, f, ho))
525                 return 0;
526
527         /* check the field type and return the value */
528
529         switch (f->parseddesc->primitivetype) {
530         case PRIMITIVETYPE_BYTE:
531         case PRIMITIVETYPE_CHAR:
532         case PRIMITIVETYPE_SHORT:
533         case PRIMITIVETYPE_INT:
534                 return (jdouble) _field_get_int(f, ho);
535         case PRIMITIVETYPE_LONG:
536                 return (jdouble) _field_get_long(f, ho);
537         case PRIMITIVETYPE_FLOAT:
538                 return (jdouble) _field_get_float(f, ho);
539         case PRIMITIVETYPE_DOUBLE:
540                 return (jdouble) _field_get_double(f, ho);
541         default:
542                 exceptions_throw_illegalargumentexception();
543                 return 0;
544         }
545 }
546
547
548 /*
549  * Class:     java/lang/reflect/VMField
550  * Method:    set
551  * Signature: (Ljava/lang/Object;Ljava/lang/Object;)V
552  */
553 JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_set(JNIEnv *env, jobject _this, jobject o, jobject value)
554 {
555         java_lang_reflect_VMField rvmf(_this);
556         fieldinfo* df = rvmf.get_field();
557
558         java_handle_t* ho     = (java_handle_t*) o;
559         java_handle_t* hvalue = (java_handle_t*) value;
560
561         classinfo *sc;
562         fieldinfo *sf;
563
564         /* check if the field can be accessed */
565
566         if (!_field_access_check(rvmf, df, ho))
567                 return;
568
569         /* get the source classinfo from the object */
570
571         if (hvalue == NULL)
572                 sc = NULL;
573         else
574                 LLNI_class_get(hvalue, sc);
575
576         /* The fieldid is used to set the new value, for primitive
577            types the value has to be retrieved from the wrapping
578            object */
579
580         switch (df->parseddesc->primitivetype) {
581         case PRIMITIVETYPE_BOOLEAN: {
582                 int32_t val;
583
584                 /* determine the field to read the value */
585
586                 if ((sc == NULL) || !(sf = class_findfield(sc, utf_value, utf_Z)))
587                         break;
588
589                 switch (sf->parseddesc->primitivetype) {
590                 case PRIMITIVETYPE_BOOLEAN:
591                         val = java_lang_Boolean(hvalue).get_value();
592                         break;
593                 default:
594                         exceptions_throw_illegalargumentexception();
595                         return;
596                 }
597
598                 _field_set_int(df, ho, val);
599                 return;
600         }
601
602         case PRIMITIVETYPE_BYTE: {
603                 int32_t val;
604
605                 if ((sc == NULL) || !(sf = class_findfield(sc, utf_value, utf_B)))
606                         break;
607
608                 switch (sf->parseddesc->primitivetype) {
609                 case PRIMITIVETYPE_BYTE:
610                         val = java_lang_Byte(hvalue).get_value();
611                         break;
612                 default:        
613                         exceptions_throw_illegalargumentexception();
614                         return;
615                 }
616
617                 _field_set_int(df, ho, val);
618                 return;
619         }
620
621         case PRIMITIVETYPE_CHAR: {
622                 int32_t val;
623
624                 if ((sc == NULL) || !(sf = class_findfield(sc, utf_value, utf_C)))
625                         break;
626                                    
627                 switch (sf->parseddesc->primitivetype) {
628                 case PRIMITIVETYPE_CHAR:
629                         val = java_lang_Character(hvalue).get_value();
630                         break;
631                 default:
632                         exceptions_throw_illegalargumentexception();
633                         return;
634                 }
635
636                 _field_set_int(df, ho, val);
637                 return;
638         }
639
640         case PRIMITIVETYPE_SHORT: {
641                 int32_t val;
642
643                 /* get field only by name, it can be one of B, S */
644
645                 if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
646                         break;
647                                    
648                 switch (sf->parseddesc->primitivetype) {
649                 case PRIMITIVETYPE_BYTE:
650                         val = java_lang_Byte(hvalue).get_value();
651                         break;
652                 case PRIMITIVETYPE_SHORT:
653                         val = java_lang_Short(hvalue).get_value();
654                         break;
655                 default:
656                         exceptions_throw_illegalargumentexception();
657                         return;
658                 }
659
660                 _field_set_int(df, ho, val);
661                 return;
662         }
663
664         case PRIMITIVETYPE_INT: {
665                 int32_t val;
666
667                 /* get field only by name, it can be one of B, S, C, I */
668
669                 if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
670                         break;
671
672                 switch (sf->parseddesc->primitivetype) {
673                 case PRIMITIVETYPE_BYTE:
674                         val = java_lang_Byte(hvalue).get_value();
675                         break;
676                 case PRIMITIVETYPE_CHAR:
677                         val = java_lang_Character(hvalue).get_value();
678                         break;
679                 case PRIMITIVETYPE_SHORT:
680                         val = java_lang_Short(hvalue).get_value();
681                         break;
682                 case PRIMITIVETYPE_INT:
683                         val = java_lang_Integer(hvalue).get_value();
684                         break;
685                 default:
686                         exceptions_throw_illegalargumentexception();
687                         return;
688                 }
689
690                 _field_set_int(df, ho, val);
691                 return;
692         }
693
694         case PRIMITIVETYPE_LONG: {
695                 int64_t val;
696
697                 /* get field only by name, it can be one of B, S, C, I, J */
698
699                 if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
700                         break;
701
702                 switch (sf->parseddesc->primitivetype) {
703                 case PRIMITIVETYPE_BYTE:
704                         val = java_lang_Byte(hvalue).get_value();
705                         break;
706                 case PRIMITIVETYPE_CHAR:
707                         val = java_lang_Character(hvalue).get_value();
708                         break;
709                 case PRIMITIVETYPE_SHORT:
710                         val = java_lang_Short(hvalue).get_value();
711                         break;
712                 case PRIMITIVETYPE_INT:
713                         val = java_lang_Integer(hvalue).get_value();
714                         break;
715                 case PRIMITIVETYPE_LONG:
716                         val = java_lang_Long(hvalue).get_value();
717                         break;
718                 default:
719                         exceptions_throw_illegalargumentexception();
720                         return;
721                 }
722
723                 _field_set_long(df, ho, val);
724                 return;
725         }
726
727         case PRIMITIVETYPE_FLOAT: {
728                 float val;
729
730                 /* get field only by name, it can be one of B, S, C, I, J, F */
731
732                 if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
733                         break;
734
735                 switch (sf->parseddesc->primitivetype) {
736                 case PRIMITIVETYPE_BYTE:
737                         val = java_lang_Byte(hvalue).get_value();
738                         break;
739                 case PRIMITIVETYPE_CHAR:
740                         val = java_lang_Character(hvalue).get_value();
741                         break;
742                 case PRIMITIVETYPE_SHORT:
743                         val = java_lang_Short(hvalue).get_value();
744                         break;
745                 case PRIMITIVETYPE_INT:
746                         val = java_lang_Integer(hvalue).get_value();
747                         break;
748                 case PRIMITIVETYPE_LONG:
749                         val = java_lang_Long(hvalue).get_value();
750                         break;
751                 case PRIMITIVETYPE_FLOAT:
752                         val = java_lang_Float(hvalue).get_value();
753                         break;
754                 default:
755                         exceptions_throw_illegalargumentexception();
756                         return;
757                 }
758
759                 _field_set_float(df, ho, val);
760                 return;
761         }
762
763         case PRIMITIVETYPE_DOUBLE: {
764                 double val;
765
766                 /* get field only by name, it can be one of B, S, C, I, J, F, D */
767
768                 if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
769                         break;
770
771                 switch (sf->parseddesc->primitivetype) {
772                 case PRIMITIVETYPE_BYTE:
773                         val = java_lang_Byte(hvalue).get_value();
774                         break;
775                 case PRIMITIVETYPE_CHAR:
776                         val = java_lang_Character(hvalue).get_value();
777                         break;
778                 case PRIMITIVETYPE_SHORT:
779                         val = java_lang_Short(hvalue).get_value();
780                         break;
781                 case PRIMITIVETYPE_INT:
782                         val = java_lang_Integer(hvalue).get_value();
783                         break;
784                 case PRIMITIVETYPE_LONG:
785                         val = java_lang_Long(hvalue).get_value();
786                         break;
787                 case PRIMITIVETYPE_FLOAT:
788                         val = java_lang_Float(hvalue).get_value();
789                         break;
790                 case PRIMITIVETYPE_DOUBLE:
791                         val = java_lang_Double(hvalue).get_value();
792                         break;
793                 default:
794                         exceptions_throw_illegalargumentexception();
795                         return;
796                 }
797
798                 _field_set_double(df, ho, val);
799                 return;
800         }
801
802         case TYPE_ADR:
803                 /* check if value is an instance of the destination class */
804
805                 /* XXX TODO */
806                 /*                      if (!builtin_instanceof((java_handle_t *) value, df->class)) */
807                 /*                              break; */
808
809                 _field_set_handle(df, ho, hvalue);
810                 return;
811         }
812
813         /* raise exception */
814
815         exceptions_throw_illegalargumentexception();
816 }
817
818
819 /*
820  * Class:     java/lang/reflect/VMField
821  * Method:    setBoolean
822  * Signature: (Ljava/lang/Object;Z)V
823  */
824 JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setBoolean(JNIEnv *env, jobject _this, jobject o, jboolean value)
825 {
826         java_lang_reflect_VMField rvmf(_this);
827         fieldinfo* f = rvmf.get_field();
828
829         java_handle_t* ho = (java_handle_t*) o;
830
831         /* check if the field can be accessed */
832
833         if (!_field_access_check(rvmf, f, ho))
834                 return;
835
836         /* check the field type and set the value */
837
838         switch (f->parseddesc->primitivetype) {
839         case PRIMITIVETYPE_BOOLEAN:
840                 _field_set_int(f, ho, value);
841                 break;
842         default:
843                 exceptions_throw_illegalargumentexception();
844         }
845 }
846
847
848 /*
849  * Class:     java/lang/reflect/VMField
850  * Method:    setByte
851  * Signature: (Ljava/lang/Object;B)V
852  */
853 JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setByte(JNIEnv *env, jobject _this, jobject o, jbyte value)
854 {
855         java_lang_reflect_VMField rvmf(_this);
856         fieldinfo* f = rvmf.get_field();
857
858         java_handle_t* ho = (java_handle_t*) o;
859
860         /* check if the field can be accessed */
861
862         if (!_field_access_check(rvmf, f, ho))
863                 return;
864
865         /* check the field type and set the value */
866
867         switch (f->parseddesc->primitivetype) {
868         case PRIMITIVETYPE_BYTE:
869         case PRIMITIVETYPE_SHORT:
870         case PRIMITIVETYPE_INT:
871                 _field_set_int(f, ho, value);
872                 break;
873         case PRIMITIVETYPE_LONG:
874                 _field_set_long(f, ho, value);
875                 break;
876         case PRIMITIVETYPE_FLOAT:
877                 _field_set_float(f, ho, value);
878                 break;
879         case PRIMITIVETYPE_DOUBLE:
880                 _field_set_double(f, ho, value);
881                 break;
882         default:
883                 exceptions_throw_illegalargumentexception();
884         }
885 }
886
887
888 /*
889  * Class:     java/lang/reflect/VMField
890  * Method:    setChar
891  * Signature: (Ljava/lang/Object;C)V
892  */
893 JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setChar(JNIEnv *env, jobject _this, jobject o, jchar value)
894 {
895         java_lang_reflect_VMField rvmf(_this);
896         fieldinfo* f = rvmf.get_field();
897
898         java_handle_t* ho = (java_handle_t*) o;
899
900         /* check if the field can be accessed */
901
902         if (!_field_access_check(rvmf, f, ho))
903                 return;
904
905         /* check the field type and set the value */
906
907         switch (f->parseddesc->primitivetype) {
908         case PRIMITIVETYPE_CHAR:
909         case PRIMITIVETYPE_INT:
910                 _field_set_int(f, ho, value);
911                 break;
912         case PRIMITIVETYPE_LONG:
913                 _field_set_long(f, ho, value);
914                 break;
915         case PRIMITIVETYPE_FLOAT:
916                 _field_set_float(f, ho, value);
917                 break;
918         case PRIMITIVETYPE_DOUBLE:
919                 _field_set_double(f, ho, value);
920                 break;
921         default:
922                 exceptions_throw_illegalargumentexception();
923         }
924 }
925
926
927 /*
928  * Class:     java/lang/reflect/VMField
929  * Method:    setShort
930  * Signature: (Ljava/lang/Object;S)V
931  */
932 JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setShort(JNIEnv *env, jobject _this, jobject o, jshort value)
933 {
934         java_lang_reflect_VMField rvmf(_this);
935         fieldinfo* f = rvmf.get_field();
936
937         java_handle_t* ho = (java_handle_t*) o;
938
939         /* check if the field can be accessed */
940
941         if (!_field_access_check(rvmf, f, ho))
942                 return;
943
944         /* check the field type and set the value */
945
946         switch (f->parseddesc->primitivetype) {
947         case PRIMITIVETYPE_SHORT:
948         case PRIMITIVETYPE_INT:
949                 _field_set_int(f, ho, value);
950                 break;
951         case PRIMITIVETYPE_LONG:
952                 _field_set_long(f, ho, value);
953                 break;
954         case PRIMITIVETYPE_FLOAT:
955                 _field_set_float(f, ho, value);
956                 break;
957         case PRIMITIVETYPE_DOUBLE:
958                 _field_set_double(f, ho, value);
959                 break;
960         default:
961                 exceptions_throw_illegalargumentexception();
962         }
963 }
964
965
966 /*
967  * Class:     java/lang/reflect/VMField
968  * Method:    setInt
969  * Signature: (Ljava/lang/Object;I)V
970  */
971 JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setInt(JNIEnv *env, jobject _this, jobject o, jint value)
972 {
973         java_lang_reflect_VMField rvmf(_this);
974         fieldinfo* f = rvmf.get_field();
975
976         java_handle_t* ho = (java_handle_t*) o;
977
978         /* check if the field can be accessed */
979
980         if (!_field_access_check(rvmf, f, ho))
981                 return;
982
983         /* check the field type and set the value */
984
985         switch (f->parseddesc->primitivetype) {
986         case PRIMITIVETYPE_INT:
987                 _field_set_int(f, ho, value);
988                 break;
989         case PRIMITIVETYPE_LONG:
990                 _field_set_long(f, ho, value);
991                 break;
992         case PRIMITIVETYPE_FLOAT:
993                 _field_set_float(f, ho, value);
994                 break;
995         case PRIMITIVETYPE_DOUBLE:
996                 _field_set_double(f, ho, value);
997                 break;
998         default:
999                 exceptions_throw_illegalargumentexception();
1000         }
1001 }
1002
1003
1004 /*
1005  * Class:     java/lang/reflect/VMField
1006  * Method:    setLong
1007  * Signature: (Ljava/lang/Object;J)V
1008  */
1009 JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setLong(JNIEnv *env, jobject _this, jobject o, jlong value)
1010 {
1011         java_lang_reflect_VMField rvmf(_this);
1012         fieldinfo* f = rvmf.get_field();
1013
1014         java_handle_t* ho = (java_handle_t*) o;
1015
1016         /* check if the field can be accessed */
1017
1018         if (!_field_access_check(rvmf, f, ho))
1019                 return;
1020
1021         /* check the field type and set the value */
1022
1023         switch (f->parseddesc->primitivetype) {
1024         case PRIMITIVETYPE_LONG:
1025                 _field_set_long(f, ho, value);
1026                 break;
1027         case PRIMITIVETYPE_FLOAT:
1028                 _field_set_float(f, ho, value);
1029                 break;
1030         case PRIMITIVETYPE_DOUBLE:
1031                 _field_set_double(f, ho, value);
1032                 break;
1033         default:
1034                 exceptions_throw_illegalargumentexception();
1035         }
1036 }
1037
1038
1039 /*
1040  * Class:     java/lang/reflect/VMField
1041  * Method:    setFloat
1042  * Signature: (Ljava/lang/Object;F)V
1043  */
1044 JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setFloat(JNIEnv *env, jobject _this, jobject o, jfloat value)
1045 {
1046         java_lang_reflect_VMField rvmf(_this);
1047         fieldinfo* f = rvmf.get_field();
1048
1049         java_handle_t* ho = (java_handle_t*) o;
1050
1051         /* check if the field can be accessed */
1052
1053         if (!_field_access_check(rvmf, f, ho))
1054                 return;
1055
1056         /* check the field type and set the value */
1057
1058         switch (f->parseddesc->primitivetype) {
1059         case PRIMITIVETYPE_FLOAT:
1060                 _field_set_float(f, ho, value);
1061                 break;
1062         case PRIMITIVETYPE_DOUBLE:
1063                 _field_set_double(f, ho, value);
1064                 break;
1065         default:
1066                 exceptions_throw_illegalargumentexception();
1067         }
1068 }
1069
1070
1071 /*
1072  * Class:     java/lang/reflect/VMField
1073  * Method:    setDouble
1074  * Signature: (Ljava/lang/Object;D)V
1075  */
1076 JNIEXPORT void JNICALL Java_java_lang_reflect_VMField_setDouble(JNIEnv *env, jobject _this, jobject o, jdouble value)
1077 {
1078         java_lang_reflect_VMField rvmf(_this);
1079         fieldinfo* f = rvmf.get_field();
1080
1081         java_handle_t* ho = (java_handle_t*) o;
1082
1083         /* check if the field can be accessed */
1084
1085         if (!_field_access_check(rvmf, f, ho))
1086                 return;
1087
1088         /* check the field type and set the value */
1089
1090         switch (f->parseddesc->primitivetype) {
1091         case PRIMITIVETYPE_DOUBLE:
1092                 _field_set_double(f, ho, value);
1093                 break;
1094         default:
1095                 exceptions_throw_illegalargumentexception();
1096         }
1097 }
1098
1099
1100 /*
1101  * Class:     java/lang/reflect/VMField
1102  * Method:    getSignature
1103  * Signature: ()Ljava/lang/String;
1104  */
1105 JNIEXPORT jstring JNICALL Java_java_lang_reflect_VMField_getSignature(JNIEnv *env, jobject _this)
1106 {
1107         java_lang_reflect_VMField rvmf(_this);
1108         fieldinfo* f = rvmf.get_field();
1109
1110         if (f->signature == NULL)
1111                 return NULL;
1112
1113         java_handle_t* o = javastring_new(f->signature);
1114
1115         /* in error case o is NULL */
1116
1117         return (jstring) o;
1118 }
1119
1120
1121 #if defined(ENABLE_ANNOTATIONS)
1122 /*
1123  * Class:     java/lang/reflect/VMField
1124  * Method:    declaredAnnotations
1125  * Signature: ()Ljava/util/Map;
1126  */
1127 JNIEXPORT jobject JNICALL Java_java_lang_reflect_VMField_declaredAnnotations(JNIEnv *env, jobject _this)
1128 {
1129         java_lang_reflect_VMField rvmf(_this);
1130
1131         java_handle_t* declaredAnnotations = rvmf.get_declaredAnnotations();
1132
1133         // Are the annotations parsed yet?
1134         if (declaredAnnotations == NULL) {
1135                 java_handle_bytearray_t* annotations    = rvmf.get_annotations();
1136                 classinfo*               declaringClass = rvmf.get_clazz();
1137
1138                 classinfo* referer;
1139                 LLNI_class_get(_this, referer);
1140
1141                 declaredAnnotations = Reflection::get_declaredannotations(annotations, declaringClass, referer);
1142
1143                 rvmf.set_declaredAnnotations(declaredAnnotations);
1144         }
1145
1146         return (jobject) declaredAnnotations;
1147 }
1148 #endif
1149
1150 } // extern "C"
1151
1152
1153 /* native methods implemented by this file ************************************/
1154
1155 static const JNINativeMethod methods[] = {
1156         { (char*) "getModifiersInternal", (char*) "()I",                                     (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getModifiersInternal },
1157         { (char*) "getType",              (char*) "()Ljava/lang/Class;",                     (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getType              },
1158         { (char*) "get",                  (char*) "(Ljava/lang/Object;)Ljava/lang/Object;",  (void*) (uintptr_t) &Java_java_lang_reflect_VMField_get                  },
1159         { (char*) "getBoolean",           (char*) "(Ljava/lang/Object;)Z",                   (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getBoolean           },
1160         { (char*) "getByte",              (char*) "(Ljava/lang/Object;)B",                   (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getByte              },
1161         { (char*) "getChar",              (char*) "(Ljava/lang/Object;)C",                   (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getChar              },
1162         { (char*) "getShort",             (char*) "(Ljava/lang/Object;)S",                   (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getShort             },
1163         { (char*) "getInt",               (char*) "(Ljava/lang/Object;)I",                   (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getInt               },
1164         { (char*) "getLong",              (char*) "(Ljava/lang/Object;)J",                   (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getLong              },
1165         { (char*) "getFloat",             (char*) "(Ljava/lang/Object;)F",                   (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getFloat             },
1166         { (char*) "getDouble",            (char*) "(Ljava/lang/Object;)D",                   (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getDouble            },
1167         { (char*) "set",                  (char*) "(Ljava/lang/Object;Ljava/lang/Object;)V", (void*) (uintptr_t) &Java_java_lang_reflect_VMField_set                  },
1168         { (char*) "setBoolean",           (char*) "(Ljava/lang/Object;Z)V",                  (void*) (uintptr_t) &Java_java_lang_reflect_VMField_setBoolean           },
1169         { (char*) "setByte",              (char*) "(Ljava/lang/Object;B)V",                  (void*) (uintptr_t) &Java_java_lang_reflect_VMField_setByte              },
1170         { (char*) "setChar",              (char*) "(Ljava/lang/Object;C)V",                  (void*) (uintptr_t) &Java_java_lang_reflect_VMField_setChar              },
1171         { (char*) "setShort",             (char*) "(Ljava/lang/Object;S)V",                  (void*) (uintptr_t) &Java_java_lang_reflect_VMField_setShort             },
1172         { (char*) "setInt",               (char*) "(Ljava/lang/Object;I)V",                  (void*) (uintptr_t) &Java_java_lang_reflect_VMField_setInt               },
1173         { (char*) "setLong",              (char*) "(Ljava/lang/Object;J)V",                  (void*) (uintptr_t) &Java_java_lang_reflect_VMField_setLong              },
1174         { (char*) "setFloat",             (char*) "(Ljava/lang/Object;F)V",                  (void*) (uintptr_t) &Java_java_lang_reflect_VMField_setFloat             },
1175         { (char*) "setDouble",            (char*) "(Ljava/lang/Object;D)V",                  (void*) (uintptr_t) &Java_java_lang_reflect_VMField_setDouble            },
1176         { (char*) "getSignature",         (char*) "()Ljava/lang/String;",                    (void*) (uintptr_t) &Java_java_lang_reflect_VMField_getSignature         },
1177 #if defined(ENABLE_ANNOTATIONS)
1178         { (char*) "declaredAnnotations",  (char*) "()Ljava/util/Map;",                       (void*) (uintptr_t) &Java_java_lang_reflect_VMField_declaredAnnotations  },
1179 #endif
1180 };
1181
1182
1183 /* _Jv_java_lang_reflect_VMField_init ******************************************
1184
1185    Register native functions.
1186
1187 *******************************************************************************/
1188
1189 // FIXME
1190 extern "C" {
1191 void _Jv_java_lang_reflect_VMField_init(void)
1192 {
1193         utf *u;
1194
1195         u = utf_new_char("java/lang/reflect/VMField");
1196
1197         native_method_register(u, methods, NATIVE_METHODS_COUNT);
1198 }
1199 }
1200
1201
1202 /*
1203  * These are local overrides for various environment variables in Emacs.
1204  * Please do not remove this and leave it at the end of the file, where
1205  * Emacs will automagically detect them.
1206  * ---------------------------------------------------------------------
1207  * Local variables:
1208  * mode: c++
1209  * indent-tabs-mode: t
1210  * c-basic-offset: 4
1211  * tab-width: 4
1212  * End:
1213  * vim:noexpandtab:sw=4:ts=4:
1214  */