1 /* native/vm/Field.c - java/lang/reflect/Field
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5 M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6 P. Tomsich, J. Wenninger
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Roman Obermaiser
29 Changes: Joseph Wenninger
31 $Id: Field.c 1621 2004-11-30 13:06:55Z twisti $
36 #include "native/jni.h"
37 #include "native/native.h"
38 #include "native/include/java_lang_Object.h"
39 #include "native/include/java_lang_Class.h"
40 #include "native/include/java_lang_reflect_Field.h"
41 #include "vm/builtin.h"
42 #include "vm/exceptions.h"
43 #include "vm/loader.h"
44 #include "vm/tables.h"
48 * Class: java/lang/reflect/Field
50 * Signature: (Ljava/lang/Object;)Ljava/lang/Object;
52 JNIEXPORT java_lang_Object* JNICALL Java_java_lang_reflect_Field_get(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj)
54 jfieldID target_fid; /* the JNI-fieldid of the wrapping object */
55 jfieldID fid; /* the JNI-fieldid of the field containing the value */
56 jobject o; /* the object for wrapping the primitive type */
57 classinfo *c = (classinfo *) this->declaringClass;
58 int st = (this->flag & ACC_STATIC); /* true if field is static */
60 /* get the fieldid of the field represented by this Field-object */
61 fid = class_findfield_approx((classinfo *) this->declaringClass,javastring_toutf(this->name, false));
63 /* The fieldid is used to retrieve the value, for primitive types a new
64 object for wrapping the primitive type is created. */
66 switch ((((classinfo *) this->declaringClass)->fields[this->slot]).descriptor->text[0]) {
68 /* create wrapping class */
69 c = class_java_lang_Integer;
71 /* get fieldid to store the value */
72 target_fid = (*env)->GetFieldID(env, c, "value", "I");
78 SetIntField(env,o,target_fid, (*env)->GetStaticIntField(env, c, fid));
81 SetIntField(env,o,target_fid, (*env)->GetIntField(env,(jobject) obj, fid));
83 /* return the wrapped object */
84 return (java_lang_Object *) o;
87 c = class_java_lang_Long;
89 target_fid = (*env)->GetFieldID(env, c, "value", "J");
94 SetLongField(env,o,target_fid, (*env)->GetStaticLongField(env, c, fid));
96 SetLongField(env,o,target_fid, (*env)->GetLongField(env,(jobject) obj, fid));
98 return (java_lang_Object *) o;
101 c = class_java_lang_Float;
103 target_fid = (*env)->GetFieldID(env, c, "value", "F");
108 SetFloatField(env,o,target_fid, (*env)->GetStaticFloatField(env, c, fid));
110 SetFloatField(env,o,target_fid, (*env)->GetFloatField(env, (jobject) obj, fid));
112 return (java_lang_Object *) o;
115 c = class_java_lang_Double;
117 target_fid = (*env)->GetFieldID(env, c, "value", "D");
122 SetDoubleField(env,o,target_fid, (*env)->GetStaticDoubleField(env, c, fid));
124 SetDoubleField(env,o,target_fid, (*env)->GetDoubleField(env, (jobject) obj, fid));
126 return (java_lang_Object *) o;
129 c = class_java_lang_Byte;
131 target_fid = (*env)->GetFieldID(env, c, "value", "B");
136 SetByteField(env,o,target_fid, (*env)->GetStaticByteField(env, c, fid));
138 SetByteField(env,o,target_fid, (*env)->GetByteField(env, (jobject) obj, fid));
140 return (java_lang_Object *) o;
143 c = class_java_lang_Character;
145 target_fid = (*env)->GetFieldID(env, c, "value", "C");
150 SetCharField(env,o,target_fid, (*env)->GetStaticCharField(env, c, fid));
152 SetCharField(env,o,target_fid, (*env)->GetCharField(env, (jobject) obj, fid));
154 return (java_lang_Object *) o;
157 c = class_java_lang_Short;
159 target_fid = (*env)->GetFieldID(env, c, "value", "S");
164 SetShortField(env,o,target_fid, (*env)->GetStaticShortField(env, c, fid));
166 SetShortField(env,o,target_fid, (*env)->GetShortField(env, (jobject) obj, fid));
168 return (java_lang_Object *) o;
171 c = class_java_lang_Boolean;
173 target_fid = (*env)->GetFieldID(env, c, "value", "Z");
178 SetBooleanField(env,o,target_fid, (*env)->GetStaticBooleanField(env, c, fid));
180 SetBooleanField(env,o,target_fid, (*env)->GetBooleanField(env, (jobject) obj, fid));
182 return (java_lang_Object *) o;
188 return (java_lang_Object*) (*env)->GetStaticObjectField(env, c, fid);
191 return (java_lang_Object*) (*env)->GetObjectField(env, (jobject) obj, fid);
194 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
201 * Class: java/lang/reflect/Field
203 * Signature: (Ljava/lang/Object;)Z
205 JNIEXPORT s4 JNICALL Java_java_lang_reflect_Field_getBoolean(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj)
209 if (this->declaringClass && obj) {
210 /* get the fieldid represented by the field-object */
211 fid = class_findfield_approx((classinfo *) this->declaringClass,
212 javastring_toutf(this->name, false));
215 /* call the JNI-function to retrieve the field */
216 return (*env)->GetBooleanField(env, (jobject) obj, fid);
219 /* raise exception */
220 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
227 * Class: java/lang/reflect/Field
229 * Signature: (Ljava/lang/Object;)B
231 JNIEXPORT s4 JNICALL Java_java_lang_reflect_Field_getByte(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj)
235 if (this->declaringClass && obj) {
236 fid = class_findfield_approx((classinfo *) this->declaringClass,
237 javastring_toutf(this->name, false));
240 return (*env)->GetByteField(env, (jobject) obj, fid);
243 /* raise exception */
244 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
251 * Class: java/lang/reflect/Field
253 * Signature: (Ljava/lang/Object;)C
255 JNIEXPORT s4 JNICALL Java_java_lang_reflect_Field_getChar(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj)
259 if (this->declaringClass && obj) {
260 fid = class_findfield_approx((classinfo *) this->declaringClass,
261 javastring_toutf(this->name, false));
264 return (*env)->GetCharField (env, (jobject) obj, fid);
267 /* raise exception */
268 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
275 * Class: java/lang/reflect/Field
277 * Signature: (Ljava/lang/Object;)D
279 JNIEXPORT double JNICALL Java_java_lang_reflect_Field_getDouble(JNIEnv *env , java_lang_reflect_Field *this, java_lang_Object *obj)
283 if (this->declaringClass && obj) {
284 fid = class_findfield_approx((classinfo *) this->declaringClass,
285 javastring_toutf(this->name, false));
288 return (*env)->GetDoubleField(env, (jobject) obj, fid);
291 /* raise exception */
292 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
299 * Class: java/lang/reflect/Field
301 * Signature: (Ljava/lang/Object;)F
303 JNIEXPORT float JNICALL Java_java_lang_reflect_Field_getFloat(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj)
307 if (this->declaringClass && obj) {
308 fid = class_findfield_approx((classinfo *) this->declaringClass,
309 javastring_toutf(this->name, false));
312 return (*env)->GetFloatField(env, (jobject) obj, fid);
315 /* raise exception */
316 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
323 * Class: java/lang/reflect/Field
325 * Signature: (Ljava/lang/Object;)I
327 JNIEXPORT s4 JNICALL Java_java_lang_reflect_Field_getInt(JNIEnv *env , java_lang_reflect_Field *this, java_lang_Object *obj)
331 if (this->declaringClass && obj) {
332 fid = class_findfield_approx((classinfo *) this->declaringClass,
333 javastring_toutf(this->name, false));
336 return (*env)->GetIntField(env, (jobject) obj, fid);
339 /* raise exception */
340 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
347 * Class: java/lang/reflect/Field
349 * Signature: (Ljava/lang/Object;)J
351 JNIEXPORT s8 JNICALL Java_java_lang_reflect_Field_getLong(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj)
355 if (this->declaringClass && obj) {
356 fid = class_findfield_approx((classinfo *) this->declaringClass,
357 javastring_toutf(this->name, false));
360 return (*env)->GetLongField(env, (jobject) obj, fid);
363 /* raise exception */
364 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
371 * Class: java/lang/reflect/Field
373 * Signature: (Ljava/lang/Object;)S
375 JNIEXPORT s4 JNICALL Java_java_lang_reflect_Field_getShort(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj)
379 if (this->declaringClass && obj) {
380 fid = class_findfield_approx((classinfo *) this->declaringClass,
381 javastring_toutf(this->name, false));
384 return (*env)->GetShortField(env, (jobject) obj, fid);
387 /* raise exception */
388 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
395 * Class: java/lang/reflect/Field
397 * Signature: (Ljava/lang/Object;Ljava/lang/Object;)V
399 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_set(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj, java_lang_Object *val)
401 jfieldID source_fid; /* the field containing the value to be written */
402 jfieldID fid; /* the field to be written */
404 int st = (this->flag & ACC_STATIC); /* true if the field is static */
406 fid = class_findfield_approx((classinfo *) this->declaringClass,
407 javastring_toutf(this->name, false));
409 if (val && (st || obj)) {
411 c = val->header.vftbl->class;
413 /* The fieldid is used to set the new value, for primitive types the value
414 has to be retrieved from the wrapping object */
415 switch ((((classinfo *) this->declaringClass)->fields[this->slot]).descriptor->text[0]) {
417 /* illegal argument specified */
418 if (c != class_java_lang_Integer)
420 /* determine the field to read the value */
421 source_fid = (*env)->GetFieldID(env, c, "value", "I");
425 /* set the new value */
428 (*env)->SetStaticIntField(env, c, fid, GetIntField(env, (jobject) val, source_fid));
431 (*env)->SetIntField(env, (jobject) obj, fid, GetIntField(env, (jobject) val, source_fid));
436 if (c != class_java_lang_Long)
438 source_fid = (*env)->GetFieldID(env, c, "value", "J");
443 (*env)->SetStaticLongField(env, c, fid, GetLongField(env, (jobject) val, source_fid));
445 (*env)->SetLongField(env, (jobject) obj, fid, GetLongField(env, (jobject) val, source_fid));
450 if (c != class_java_lang_Float)
452 source_fid = (*env)->GetFieldID(env, c, "value", "F");
457 (*env)->SetStaticFloatField(env, c, fid, GetFloatField(env, (jobject) val, source_fid));
459 (*env)->SetFloatField(env, (jobject) obj, fid, GetFloatField(env, (jobject) val, source_fid));
464 if (c != class_java_lang_Double)
466 source_fid = (*env)->GetFieldID(env, c, "value", "D");
467 if (!source_fid) break;
470 (*env)->SetStaticDoubleField(env, c, fid, GetDoubleField(env,(jobject) val,source_fid));
472 (*env)->SetDoubleField(env, (jobject) obj, fid, GetDoubleField(env,(jobject) val,source_fid));
477 if (c != class_java_lang_Byte)
479 source_fid = (*env)->GetFieldID(env, c, "value", "B");
484 (*env)->SetStaticByteField(env, c, fid, GetByteField(env, (jobject) val, source_fid));
486 (*env)->SetByteField(env, (jobject) obj, fid, GetByteField(env, (jobject) val, source_fid));
491 if (c != class_java_lang_Character)
493 source_fid = (*env)->GetFieldID(env, c, "value", "C");
498 (*env)->SetStaticCharField(env, c, fid, GetCharField(env, (jobject) val, source_fid));
500 (*env)->SetCharField(env, (jobject) obj, fid, GetCharField(env, (jobject) val, source_fid));
505 if (c != class_java_lang_Short)
507 source_fid = (*env)->GetFieldID(env, c, "value", "S");
512 (*env)->SetStaticShortField(env, c, fid, GetShortField(env, (jobject) val, source_fid));
514 (*env)->SetShortField(env, (jobject) obj, fid, GetShortField(env, (jobject) val, source_fid));
519 if (c != class_java_lang_Boolean)
521 source_fid = (*env)->GetFieldID(env, c, "value", "Z");
526 (*env)->SetStaticBooleanField(env, c, fid, GetBooleanField(env, (jobject) val, source_fid));
528 (*env)->SetBooleanField(env, (jobject) obj, fid, GetBooleanField(env, (jobject) val, source_fid));
535 (*env)->SetStaticObjectField(env, c, fid, (jobject) val);
537 (*env)->SetObjectField(env, (jobject) obj, fid, (jobject) val);
543 /* raise exception */
544 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
549 * Class: java/lang/reflect/Field
551 * Signature: (Ljava/lang/Object;Z)V
553 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setBoolean(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj, s4 val)
557 if (this->declaringClass && obj) {
558 fid = class_findfield_approx((classinfo *) this->declaringClass,
559 javastring_toutf(this->name, false));
562 (*env)->SetBooleanField(env, (jobject) obj, fid, val);
567 /* raise exception */
568 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
573 * Class: java/lang/reflect/Field
575 * Signature: (Ljava/lang/Object;B)V
577 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setByte(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj, s4 val)
581 if (this->declaringClass && obj) {
582 fid = class_findfield_approx((classinfo *) this->declaringClass,
583 javastring_toutf(this->name, false));
586 (*env)->SetByteField(env, (jobject) obj, fid, val);
591 /* raise exception */
592 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
597 * Class: java/lang/reflect/Field
599 * Signature: (Ljava/lang/Object;C)V
601 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setChar(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj, s4 val)
605 if (this->declaringClass && obj) {
606 fid = class_findfield_approx((classinfo *) this->declaringClass,
607 javastring_toutf(this->name, false));
610 (*env)->SetCharField(env, (jobject) obj, fid, val);
615 /* raise exception */
616 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
621 * Class: java/lang/reflect/Field
623 * Signature: (Ljava/lang/Object;D)V
625 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setDouble(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj, double val)
629 if (this->declaringClass && obj) {
630 fid = class_findfield_approx((classinfo *) this->declaringClass,
631 javastring_toutf(this->name, false));
634 (*env)->SetDoubleField(env, (jobject) obj, fid, val);
639 /* raise exception */
640 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
645 * Class: java/lang/reflect/Field
647 * Signature: (Ljava/lang/Object;F)V
649 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setFloat(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj, float val)
653 if (this->declaringClass && obj) {
654 fid = class_findfield_approx((classinfo *) this->declaringClass,
655 javastring_toutf(this->name, false));
658 (*env)->SetFloatField(env, (jobject) obj, fid, val);
663 /* raise exception */
664 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
669 * Class: java/lang/reflect/Field
671 * Signature: (Ljava/lang/Object;I)V
673 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setInt(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj, s4 val)
677 if (this->declaringClass && obj) {
678 fid = class_findfield_approx((classinfo *) this->declaringClass,
679 javastring_toutf(this->name, false));
682 (*env)->SetIntField(env, (jobject) obj, fid, val);
687 /* raise exception */
688 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
693 * Class: java/lang/reflect/Field
695 * Signature: (Ljava/lang/Object;J)V
697 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setLong(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj, s8 val)
701 if (this->declaringClass && obj) {
702 fid = class_findfield_approx((classinfo *) this->declaringClass,
703 javastring_toutf(this->name, false));
706 (*env)->SetLongField(env, (jobject) obj, fid, val);
711 /* raise exception */
712 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
717 * Class: java/lang/reflect/Field
719 * Signature: (Ljava/lang/Object;S)V
721 JNIEXPORT void JNICALL Java_java_lang_reflect_Field_setShort(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *obj, s4 val)
725 if (this->declaringClass && obj) {
726 fid = class_findfield_approx((classinfo *) this->declaringClass,
727 javastring_toutf(this->name, false));
730 (*env)->SetShortField(env, (jobject) obj, fid, val);
735 /* raise exception */
736 *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
741 * Class: java_lang_reflect_Field
743 * Signature: ()Ljava/lang/Class;
745 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_reflect_Field_getType(JNIEnv *env, java_lang_reflect_Field *this)
747 utf *desc = (((classinfo *) this->declaringClass)->fields[this->slot]).descriptor;
752 return (java_lang_Class *) class_from_descriptor(desc->text, utf_end(desc), NULL, CLASSLOAD_LOAD);
757 * Class: java_lang_reflect_Field
758 * Method: getModifiers
761 JNIEXPORT s4 JNICALL Java_java_lang_reflect_Field_getModifiers(JNIEnv *env, java_lang_reflect_Field *this)
763 return (((classinfo *) this->declaringClass)->fields[this->slot]).flags;
768 * These are local overrides for various environment variables in Emacs.
769 * Please do not remove this and leave it at the end of the file, where
770 * Emacs will automagically detect them.
771 * ---------------------------------------------------------------------
774 * indent-tabs-mode: t