/* src/native/vm/Field.c - java/lang/reflect/Field
- Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
- R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
- C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
- Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+ E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+ J. Wenninger, Institut f. Computersprachen - TU Wien
This file is part of CACAO.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
- Contact: cacao@complang.tuwien.ac.at
+ Contact: cacao@cacaojvm.org
Authors: Roman Obermaiser
Changes: Joseph Wenninger
Christian Thalinger
- $Id: Field.c 3457 2005-10-19 22:11:27Z twisti $
+ $Id: Field.c 4357 2006-01-22 23:33:38Z twisti $
*/
#include "vm/loader.h"
#include "vm/resolve.h"
#include "vm/stringlocal.h"
-#include "vm/tables.h"
#include "vm/utf8.h"
#include "vm/jit/stacktrace.h"
*******************************************************************************/
-static void *cacao_get_field_address(classinfo *c, fieldinfo *f,
+static void *cacao_get_field_address(java_lang_reflect_Field *this,
java_lang_Object *o)
{
- methodinfo *caller;
+ classinfo *c;
+ fieldinfo *f;
+ java_objectarray *oa;
+ classinfo *callerclass;
+
+ c = (classinfo *) this->declaringClass;
+ f = &c->fields[this->slot];
/* check field access */
if (!(f->flags & ACC_PUBLIC)) {
- caller = cacao_callingMethod();
+ /* check if we should bypass security checks (AccessibleObject) */
- if (!access_is_accessible_member(caller->class, c, f->flags)) {
- *exceptionptr =
- new_exception(string_java_lang_IllegalAccessException);
- return NULL;
+ if (this->flag == false) {
+ /* get the calling class */
+
+ oa = cacao_createClassContextArray();
+
+ /* this function is always called like this:
+
+ java.lang.reflect.Field.xxx (Native Method)
+ [0] <caller>
+ */
+
+ callerclass = (classinfo *) oa->data[0];
+
+ if (!access_is_accessible_member(callerclass, c, f->flags)) {
+ *exceptionptr =
+ new_exception(string_java_lang_IllegalAccessException);
+ return NULL;
+ }
}
}
/* obj is required for not-static fields */
if (o == NULL) {
- *exceptionptr = new_nullpointerexception();
+ exceptions_throw_nullpointerexception();
return NULL;
}
/* exception path */
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
return NULL;
}
/* get address of the source field value */
- if ((addr = cacao_get_field_address(c, f, o)) == NULL)
+ if ((addr = cacao_get_field_address(this, o)) == NULL)
return NULL;
switch (f->parseddesc->decltype) {
/* this must not happen */
assert(0);
+
+ /* keep compiler happy */
+
+ return NULL;
}
/* get the address of the field with an internal helper */
- if ((addr = cacao_get_field_address(c, f, o)) == NULL)
+ if ((addr = cacao_get_field_address(this, o)) == NULL)
return 0;
/* check the field type and return the value */
case PRIMITIVETYPE_BOOLEAN:
return (s4) *((s4 *) addr);
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
return 0;
}
}
/* get the address of the field with an internal helper */
- if ((addr = cacao_get_field_address(c, f, o)) == NULL)
+ if ((addr = cacao_get_field_address(this, o)) == NULL)
return 0;
/* check the field type and return the value */
case PRIMITIVETYPE_BYTE:
return (s4) *((s4 *) addr);
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
return 0;
}
}
/* get the address of the field with an internal helper */
- if ((addr = cacao_get_field_address(c, f, o)) == NULL)
+ if ((addr = cacao_get_field_address(this, o)) == NULL)
return 0;
/* check the field type and return the value */
case PRIMITIVETYPE_CHAR:
return (s4) *((s4 *) addr);
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
return 0;
}
}
/* get the address of the field with an internal helper */
- if ((addr = cacao_get_field_address(c, f, o)) == NULL)
+ if ((addr = cacao_get_field_address(this, o)) == NULL)
return 0;
/* check the field type and return the value */
case PRIMITIVETYPE_SHORT:
return (s4) *((s4 *) addr);
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
return 0;
}
}
/* get the address of the field with an internal helper */
- if ((addr = cacao_get_field_address(c, f, o)) == NULL)
+ if ((addr = cacao_get_field_address(this, o)) == NULL)
return 0;
/* check the field type and return the value */
case PRIMITIVETYPE_INT:
return (s4) *((s4 *) addr);
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
return 0;
}
}
/* get the address of the field with an internal helper */
- if ((addr = cacao_get_field_address(c, f, o)) == NULL)
+ if ((addr = cacao_get_field_address(this, o)) == NULL)
return 0;
/* check the field type and return the value */
case PRIMITIVETYPE_LONG:
return (s8) *((s8 *) addr);
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
return 0;
}
}
/* get the address of the field with an internal helper */
- if ((addr = cacao_get_field_address(c, f, o)) == NULL)
+ if ((addr = cacao_get_field_address(this, o)) == NULL)
return 0;
/* check the field type and return the value */
case PRIMITIVETYPE_FLOAT:
return (float) *((float *) addr);
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
return 0;
}
}
/* get the address of the field with an internal helper */
- if ((addr = cacao_get_field_address(c, f, o)) == NULL)
+ if ((addr = cacao_get_field_address(this, o)) == NULL)
return 0;
/* check the field type and return the value */
case PRIMITIVETYPE_DOUBLE:
return (double) *((double *) addr);
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
return 0;
}
}
fieldinfo *sf;
fieldinfo *df;
void *faddr;
- s4 ival;
- s8 lval;
- float fval;
- double dval;
/* get the class and the field */
/* get the address of the destination field */
- if ((faddr = cacao_get_field_address(dc, df, o)) == NULL)
+ if ((faddr = cacao_get_field_address(this, o)) == NULL)
return;
- if (value == NULL) {
- assert(0);
- return;
- }
-
/* get the source classinfo from the object */
- sc = value->header.vftbl->class;
+ if (value == NULL)
+ sc = NULL;
+ else
+ sc = value->header.vftbl->class;
/* The fieldid is used to set the new value, for primitive
types the value has to be retrieved from the wrapping
object */
switch (df->parseddesc->decltype) {
- case PRIMITIVETYPE_BOOLEAN:
+ case PRIMITIVETYPE_BOOLEAN: {
+ s4 val;
+
/* determine the field to read the value */
- if (!(sf = class_findfield(sc, utf_value, utf_Z)))
+ if ((sc == NULL) || !(sf = class_findfield(sc, utf_value, utf_Z)))
break;
switch (sf->parseddesc->decltype) {
case PRIMITIVETYPE_BOOLEAN:
- ival = ((java_lang_Boolean *) value)->value;
+ val = ((java_lang_Boolean *) value)->value;
break;
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
return;
}
- *((s4 *) faddr) = ival;
+ *((s4 *) faddr) = val;
return;
+ }
- case PRIMITIVETYPE_BYTE:
- if (!(sf = class_findfield(sc, utf_value, utf_B)))
+ case PRIMITIVETYPE_BYTE: {
+ s4 val;
+
+ if ((sc == NULL) || !(sf = class_findfield(sc, utf_value, utf_B)))
break;
switch (sf->parseddesc->decltype) {
case PRIMITIVETYPE_BYTE:
- ival = ((java_lang_Byte *) value)->value;
+ val = ((java_lang_Byte *) value)->value;
break;
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
return;
}
- *((s4 *) faddr) = ival;
+ *((s4 *) faddr) = val;
return;
+ }
- case PRIMITIVETYPE_CHAR:
- if (!(sf = class_findfield(sc, utf_value, utf_C)))
+ case PRIMITIVETYPE_CHAR: {
+ s4 val;
+
+ if ((sc == NULL) || !(sf = class_findfield(sc, utf_value, utf_C)))
break;
switch (sf->parseddesc->decltype) {
case PRIMITIVETYPE_CHAR:
- ival = ((java_lang_Character *) value)->value;
+ val = ((java_lang_Character *) value)->value;
break;
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
return;
}
- *((s4 *) faddr) = ival;
+ *((s4 *) faddr) = val;
return;
+ }
+
+ case PRIMITIVETYPE_SHORT: {
+ s4 val;
- case PRIMITIVETYPE_SHORT:
/* get field only by name, it can be one of B, S */
- if (!(sf = class_findfield_by_name(sc, utf_value)))
+ if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
break;
switch (sf->parseddesc->decltype) {
case PRIMITIVETYPE_BYTE:
- ival = ((java_lang_Byte *) value)->value;
+ val = ((java_lang_Byte *) value)->value;
break;
case PRIMITIVETYPE_SHORT:
- ival = ((java_lang_Short *) value)->value;
+ val = ((java_lang_Short *) value)->value;
break;
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
return;
}
- *((s4 *) faddr) = ival;
+ *((s4 *) faddr) = val;
return;
+ }
+
+ case PRIMITIVETYPE_INT: {
+ s4 val;
- case PRIMITIVETYPE_INT:
/* get field only by name, it can be one of B, S, C, I */
- if (!(sf = class_findfield_by_name(sc, utf_value)))
+ if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
break;
switch (sf->parseddesc->decltype) {
case PRIMITIVETYPE_BYTE:
- ival = ((java_lang_Byte *) value)->value;
+ val = ((java_lang_Byte *) value)->value;
break;
case PRIMITIVETYPE_CHAR:
- ival = ((java_lang_Character *) value)->value;
+ val = ((java_lang_Character *) value)->value;
break;
case PRIMITIVETYPE_SHORT:
- ival = ((java_lang_Short *) value)->value;
+ val = ((java_lang_Short *) value)->value;
break;
case PRIMITIVETYPE_INT:
- ival = ((java_lang_Integer *) value)->value;
+ val = ((java_lang_Integer *) value)->value;
break;
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
return;
}
- *((s4 *) faddr) = ival;
+ *((s4 *) faddr) = val;
return;
+ }
+
+ case PRIMITIVETYPE_LONG: {
+ s8 val;
- case PRIMITIVETYPE_LONG:
/* get field only by name, it can be one of B, S, C, I, J */
- if (!(sf = class_findfield_by_name(sc, utf_value)))
+ if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
break;
switch (sf->parseddesc->decltype) {
case PRIMITIVETYPE_BYTE:
- lval = ((java_lang_Byte *) value)->value;
+ val = ((java_lang_Byte *) value)->value;
break;
case PRIMITIVETYPE_CHAR:
- lval = ((java_lang_Character *) value)->value;
+ val = ((java_lang_Character *) value)->value;
break;
case PRIMITIVETYPE_SHORT:
- lval = ((java_lang_Short *) value)->value;
+ val = ((java_lang_Short *) value)->value;
break;
case PRIMITIVETYPE_INT:
- lval = ((java_lang_Integer *) value)->value;
+ val = ((java_lang_Integer *) value)->value;
break;
case PRIMITIVETYPE_LONG:
- lval = ((java_lang_Long *) value)->value;
+ val = ((java_lang_Long *) value)->value;
break;
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
return;
}
- *((s8 *) faddr) = lval;
+ *((s8 *) faddr) = val;
return;
+ }
+
+ case PRIMITIVETYPE_FLOAT: {
+ float val;
- case PRIMITIVETYPE_FLOAT:
/* get field only by name, it can be one of B, S, C, I, J, F */
- if (!(sf = class_findfield_by_name(sc, utf_value)))
+ if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
break;
switch (sf->parseddesc->decltype) {
case PRIMITIVETYPE_BYTE:
- fval = ((java_lang_Byte *) value)->value;
+ val = ((java_lang_Byte *) value)->value;
break;
case PRIMITIVETYPE_CHAR:
- fval = ((java_lang_Character *) value)->value;
+ val = ((java_lang_Character *) value)->value;
break;
case PRIMITIVETYPE_SHORT:
- fval = ((java_lang_Short *) value)->value;
+ val = ((java_lang_Short *) value)->value;
break;
case PRIMITIVETYPE_INT:
- fval = ((java_lang_Integer *) value)->value;
+ val = ((java_lang_Integer *) value)->value;
break;
case PRIMITIVETYPE_LONG:
- fval = ((java_lang_Long *) value)->value;
+ val = ((java_lang_Long *) value)->value;
break;
case PRIMITIVETYPE_FLOAT:
- fval = ((java_lang_Float *) value)->value;
+ val = ((java_lang_Float *) value)->value;
break;
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
return;
}
- *((float *) faddr) = fval;
+ *((float *) faddr) = val;
return;
+ }
+
+ case PRIMITIVETYPE_DOUBLE: {
+ double val;
- case PRIMITIVETYPE_DOUBLE:
/* get field only by name, it can be one of B, S, C, I, J, F, D */
- if (!(sf = class_findfield_by_name(sc, utf_value)))
+ if ((sc == NULL) || !(sf = class_findfield_by_name(sc, utf_value)))
break;
switch (sf->parseddesc->decltype) {
case PRIMITIVETYPE_BYTE:
- dval = ((java_lang_Byte *) value)->value;
+ val = ((java_lang_Byte *) value)->value;
break;
case PRIMITIVETYPE_CHAR:
- dval = ((java_lang_Character *) value)->value;
+ val = ((java_lang_Character *) value)->value;
break;
case PRIMITIVETYPE_SHORT:
- dval = ((java_lang_Short *) value)->value;
+ val = ((java_lang_Short *) value)->value;
break;
case PRIMITIVETYPE_INT:
- dval = ((java_lang_Integer *) value)->value;
+ val = ((java_lang_Integer *) value)->value;
break;
case PRIMITIVETYPE_LONG:
- dval = ((java_lang_Long *) value)->value;
+ val = ((java_lang_Long *) value)->value;
break;
case PRIMITIVETYPE_FLOAT:
- dval = ((java_lang_Float *) value)->value;
+ val = ((java_lang_Float *) value)->value;
break;
case PRIMITIVETYPE_DOUBLE:
- dval = ((java_lang_Double *) value)->value;
+ val = ((java_lang_Double *) value)->value;
break;
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
return;
}
- *((double *) faddr) = dval;
+ *((double *) faddr) = val;
return;
+ }
case TYPE_ADR:
/* check if value is an instance of the destination class */
/* raise exception */
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
}
/* get the address of the field with an internal helper */
- if ((addr = cacao_get_field_address(c, f, o)) == NULL)
+ if ((addr = cacao_get_field_address(this, o)) == NULL)
return;
/* check the field type and set the value */
*((s4 *) addr) = value;
break;
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
}
return;
/* get the address of the field with an internal helper */
- if ((addr = cacao_get_field_address(c, f, o)) == NULL)
+ if ((addr = cacao_get_field_address(this, o)) == NULL)
return;
/* check the field type and set the value */
*((double *) addr) = value;
break;
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
}
return;
/* get the address of the field with an internal helper */
- if ((addr = cacao_get_field_address(c, f, o)) == NULL)
+ if ((addr = cacao_get_field_address(this, o)) == NULL)
return;
/* check the field type and set the value */
*((double *) addr) = value;
break;
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
}
return;
/* get the address of the field with an internal helper */
- if ((addr = cacao_get_field_address(c, f, o)) == NULL)
+ if ((addr = cacao_get_field_address(this, o)) == NULL)
return;
/* check the field type and set the value */
*((double *) addr) = value;
break;
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
}
return;
/* get the address of the field with an internal helper */
- if ((addr = cacao_get_field_address(c, f, o)) == NULL)
+ if ((addr = cacao_get_field_address(this, o)) == NULL)
return;
/* check the field type and set the value */
*((double *) addr) = value;
break;
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
}
return;
/* get the address of the field with an internal helper */
- if ((addr = cacao_get_field_address(c, f, o)) == NULL)
+ if ((addr = cacao_get_field_address(this, o)) == NULL)
return;
/* check the field type and set the value */
*((double *) addr) = value;
break;
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
}
return;
/* get the address of the field with an internal helper */
- if ((addr = cacao_get_field_address(c, f, o)) == NULL)
+ if ((addr = cacao_get_field_address(this, o)) == NULL)
return;
/* check the field type and set the value */
*((double *) addr) = value;
break;
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
}
return;
/* get the address of the field with an internal helper */
- if ((addr = cacao_get_field_address(c, f, o)) == NULL)
+ if ((addr = cacao_get_field_address(this, o)) == NULL)
return;
/* check the field type and set the value */
*((double *) addr) = value;
break;
default:
- *exceptionptr = new_illegalargumentexception();
+ exceptions_throw_illegalargumentexception();
}
return;
if (!resolve_class_from_typedesc(desc, true, false, &ret))
return NULL;
- if (!use_class_as_object(ret))
- return NULL;
-
return (java_lang_Class *) ret;
}