Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: java_lang_reflect_Field.c 8305 2007-08-15 13:49:26Z panzi $
-
*/
#include "native/include/java_lang_reflect_Field.h"
#if defined(ENABLE_ANNOTATIONS)
+#include "native/include/java_util_Map.h"
#include "native/include/sun_reflect_ConstantPool.h"
#include "native/vm/reflect.h"
#endif
}
-/* cacao_get_field_address *****************************************************
-
- Return the address of a field of an object.
+/* _field_access_check *********************************************************
- IN:
- this.........the field (a java.lang.reflect.Field object)
- o............the object of which to get the field
+ Checks if the field can be accessed.
RETURN VALUE:
- a pointer to the field, or
- NULL if an exception has been thrown
+ true......field can be accessed, or
+ false.....otherwise (maybe an Exception was thrown).
*******************************************************************************/
-static void *cacao_get_field_address(java_lang_reflect_Field *this,
- java_lang_Object *o)
+static bool _field_access_check(java_lang_reflect_Field *this,
+ fieldinfo *f, classinfo *c, java_handle_t *o)
{
- classinfo *c;
- fieldinfo *f;
- int32_t slot;
- int32_t flag;
-
- LLNI_field_get_cls(this, clazz, c);
- LLNI_field_get_val(this, slot , slot);
- f = &c->fields[slot];
+ int32_t flag;
- /* check field access */
/* check if we should bypass security checks (AccessibleObject) */
LLNI_field_get_val(this, flag, flag);
if (flag == false) {
/* this function is always called like this:
-
java.lang.reflect.Field.xxx (Native Method)
[0] <caller>
*/
if (!access_check_field(f, 0))
- return NULL;
+ return false;
}
- /* get the address of the field */
+ /* some general checks */
if (f->flags & ACC_STATIC) {
/* initialize class if required */
if (!(c->state & CLASS_INITIALIZED))
if (!initialize_class(c))
- return NULL;
+ return false;
- /* return value pointer */
+ /* everything is ok */
- return f->value;
+ return true;
} else {
/* obj is required for not-static fields */
if (o == NULL) {
exceptions_throw_nullpointerexception();
- return NULL;
+ return false;
}
- if (builtin_instanceof((java_handle_t *) o, c))
- return (void *) (((intptr_t) o) + f->offset);
+ if (builtin_instanceof(o, c))
+ return true;
}
/* exception path */
exceptions_throw_illegalargumentexception();
+ return false;
+}
+
+
+/* _field_get_type *************************************************************
+
+ Returns the content of the given field.
+
+*******************************************************************************/
+
+#define _FIELD_GET_TYPE(name, type, uniontype) \
+static inline type _field_get_##name(fieldinfo *f, java_lang_Object *o) \
+{ \
+ type ret; \
+ if (f->flags & ACC_STATIC) { \
+ ret = f->value->uniontype; \
+ } else { \
+ LLNI_CRITICAL_START; \
+ ret = *(type *) (((intptr_t) LLNI_DIRECT(o)) + f->offset); \
+ LLNI_CRITICAL_END; \
+ } \
+ return ret; \
+}
+
+static inline java_handle_t *_field_get_handle(fieldinfo *f, java_lang_Object *o)
+{
+ java_object_t *obj;
+ java_handle_t *hdl;
+
+ LLNI_CRITICAL_START;
+
+ if (f->flags & ACC_STATIC) {
+ obj = f->value->a;
+ } else {
+ obj = *(java_object_t **) (((intptr_t) LLNI_DIRECT(o)) + f->offset);
+ }
+
+ hdl = LLNI_WRAP(obj);
+
+ LLNI_CRITICAL_END;
+
+ return hdl;
+}
+
+_FIELD_GET_TYPE(int, int32_t, i)
+_FIELD_GET_TYPE(long, int64_t, l)
+_FIELD_GET_TYPE(float, float, f)
+_FIELD_GET_TYPE(double, double, d)
+
+
+/* _field_set_type *************************************************************
+
+ Sets the content of the given field to the given value.
+
+*******************************************************************************/
+
+#define _FIELD_SET_TYPE(name, type, uniontype) \
+static inline void _field_set_##name(fieldinfo *f, java_lang_Object *o, type value) \
+{ \
+ if (f->flags & ACC_STATIC) { \
+ f->value->uniontype = value; \
+ } else { \
+ LLNI_CRITICAL_START; \
+ *(type *) (((intptr_t) LLNI_DIRECT(o)) + f->offset) = value; \
+ LLNI_CRITICAL_END; \
+ } \
+}
+
+static inline void _field_set_handle(fieldinfo *f, java_lang_Object *o, java_handle_t *value)
+{
+ LLNI_CRITICAL_START;
+
+ if (f->flags & ACC_STATIC) {
+ f->value->a = LLNI_DIRECT(value);
+ } else {
+ *(java_object_t **) (((intptr_t) LLNI_DIRECT(o)) + f->offset) = LLNI_DIRECT(value);
+ }
- return NULL;
+ LLNI_CRITICAL_END;
}
+_FIELD_SET_TYPE(int, int32_t, i)
+_FIELD_SET_TYPE(long, int64_t, l)
+_FIELD_SET_TYPE(float, float, f)
+_FIELD_SET_TYPE(double, double, d)
+
/*
* Class: java/lang/reflect/Field
if (!resolve_class_from_typedesc(desc, true, false, &ret))
return NULL;
- return (java_lang_Class *) ret;
+ return LLNI_classinfo_wrap(ret);
}
* Method: get
* Signature: (Ljava/lang/Object;)Ljava/lang/Object;
*/
-JNIEXPORT java_lang_Object* JNICALL Java_java_lang_reflect_Field_get(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *object)
+JNIEXPORT java_lang_Object* JNICALL Java_java_lang_reflect_Field_get(JNIEnv *env, java_lang_reflect_Field *this, java_lang_Object *o)
{
classinfo *c;
fieldinfo *f;
- void *addr;
int32_t slot;
imm_union value;
- java_handle_t *o;
+ java_handle_t *object;
LLNI_field_get_cls(this, clazz, c);
LLNI_field_get_val(this, slot , slot);
f = &c->fields[slot];
- /* get address of the source field value */
+ /* check if the field can be accessed */
- if ((addr = cacao_get_field_address(this, object)) == NULL)
+ if (!_field_access_check(this, f, c, (java_handle_t *) o))
return NULL;
switch (f->parseddesc->decltype) {
case PRIMITIVETYPE_CHAR:
case PRIMITIVETYPE_SHORT:
case PRIMITIVETYPE_INT:
- value.i = *((int32_t *) addr);
+ value.i = _field_get_int(f, o);
break;
case PRIMITIVETYPE_LONG:
- value.l = *((int64_t *) addr);
+ value.l = _field_get_long(f, o);
break;
case PRIMITIVETYPE_FLOAT:
- value.f = *((float *) addr);
+ value.f = _field_get_float(f, o);
break;
case PRIMITIVETYPE_DOUBLE:
- value.d = *((double *) addr);
+ value.d = _field_get_double(f, o);
break;
case TYPE_ADR:
-#warning this whole thing needs to be inside a critical section!
- return (java_lang_Object *) *((java_handle_t **) addr);
+ return (java_lang_Object *) _field_get_handle(f, o);
}
/* Now box the primitive types. */
- o = primitive_box(f->parseddesc->decltype, value);
+ object = primitive_box(f->parseddesc->decltype, value);
- return (java_lang_Object *) o;
+ return (java_lang_Object *) object;
}
{
classinfo *c;
fieldinfo *f;
- void *addr;
int32_t slot;
/* get the class and the field */
LLNI_field_get_val(this, slot , slot);
f = &c->fields[slot];
- /* get the address of the field with an internal helper */
+ /* check if the field can be accessed */
- if ((addr = cacao_get_field_address(this, o)) == NULL)
+ if (!_field_access_check(this, f, c, (java_handle_t *) o))
return 0;
/* check the field type and return the value */
switch (f->parseddesc->decltype) {
case PRIMITIVETYPE_BOOLEAN:
- return (int32_t) *((int32_t *) addr);
+ return (int32_t) _field_get_int(f, o);
default:
exceptions_throw_illegalargumentexception();
return 0;
{
classinfo *c;
fieldinfo *f;
- void *addr;
int32_t slot;
/* get the class and the field */
LLNI_field_get_val(this, slot , slot);
f = &c->fields[slot];
- /* get the address of the field with an internal helper */
+ /* check if the field can be accessed */
- if ((addr = cacao_get_field_address(this, o)) == NULL)
+ if (!_field_access_check(this, f, c, (java_handle_t *) o))
return 0;
/* check the field type and return the value */
switch (f->parseddesc->decltype) {
case PRIMITIVETYPE_BYTE:
- return (int32_t) *((int32_t *) addr);
+ return (int32_t) _field_get_int(f, o);
default:
exceptions_throw_illegalargumentexception();
return 0;
{
classinfo *c;
fieldinfo *f;
- void *addr;
int32_t slot;
/* get the class and the field */
LLNI_field_get_val(this, slot , slot);
f = &c->fields[slot];
- /* get the address of the field with an internal helper */
+ /* check if the field can be accessed */
- if ((addr = cacao_get_field_address(this, o)) == NULL)
+ if (!_field_access_check(this, f, c, (java_handle_t *) o))
return 0;
/* check the field type and return the value */
switch (f->parseddesc->decltype) {
case PRIMITIVETYPE_CHAR:
- return (int32_t) *((int32_t *) addr);
+ return (int32_t) _field_get_int(f, o);
default:
exceptions_throw_illegalargumentexception();
return 0;
{
classinfo *c;
fieldinfo *f;
- void *addr;
int32_t slot;
/* get the class and the field */
LLNI_field_get_val(this, slot , slot);
f = &c->fields[slot];
- /* get the address of the field with an internal helper */
+ /* check if the field can be accessed */
- if ((addr = cacao_get_field_address(this, o)) == NULL)
+ if (!_field_access_check(this, f, c, (java_handle_t *) o))
return 0;
/* check the field type and return the value */
switch (f->parseddesc->decltype) {
case PRIMITIVETYPE_BYTE:
case PRIMITIVETYPE_SHORT:
- return (int32_t) *((int32_t *) addr);
+ return (int32_t) _field_get_int(f, o);
default:
exceptions_throw_illegalargumentexception();
return 0;
{
classinfo *c;
fieldinfo *f;
- void *addr;
int32_t slot;
/* get the class and the field */
LLNI_field_get_val(this, slot , slot);
f = &c->fields[slot];
- /* get the address of the field with an internal helper */
+ /* check if the field can be accessed */
- if ((addr = cacao_get_field_address(this, o)) == NULL)
+ if (!_field_access_check(this, f, c, (java_handle_t *) o))
return 0;
/* check the field type and return the value */
case PRIMITIVETYPE_CHAR:
case PRIMITIVETYPE_SHORT:
case PRIMITIVETYPE_INT:
- return (int32_t) *((int32_t *) addr);
+ return (int32_t) _field_get_int(f, o);
default:
exceptions_throw_illegalargumentexception();
return 0;
{
classinfo *c;
fieldinfo *f;
- void *addr;
int32_t slot;
/* get the class and the field */
LLNI_field_get_val(this, slot , slot);
f = &c->fields[slot];
- /* get the address of the field with an internal helper */
+ /* check if the field can be accessed */
- if ((addr = cacao_get_field_address(this, o)) == NULL)
+ if (!_field_access_check(this, f, c, (java_handle_t *) o))
return 0;
/* check the field type and return the value */
case PRIMITIVETYPE_CHAR:
case PRIMITIVETYPE_SHORT:
case PRIMITIVETYPE_INT:
- return (int64_t) *((int32_t *) addr);
+ return (int64_t) _field_get_int(f, o);
case PRIMITIVETYPE_LONG:
- return (int64_t) *((int64_t *) addr);
+ return (int64_t) _field_get_long(f, o);
default:
exceptions_throw_illegalargumentexception();
return 0;
{
classinfo *c;
fieldinfo *f;
- void *addr;
int32_t slot;
/* get the class and the field */
LLNI_field_get_val(this, slot , slot);
f = &c->fields[slot];
- /* get the address of the field with an internal helper */
+ /* check if the field can be accessed */
- if ((addr = cacao_get_field_address(this, o)) == NULL)
+ if (!_field_access_check(this, f, c, (java_handle_t *) o))
return 0;
/* check the field type and return the value */
case PRIMITIVETYPE_CHAR:
case PRIMITIVETYPE_SHORT:
case PRIMITIVETYPE_INT:
- return (float) *((int32_t *) addr);
+ return (float) _field_get_int(f, o);
case PRIMITIVETYPE_LONG:
- return (float) *((int64_t *) addr);
+ return (float) _field_get_long(f, o);
case PRIMITIVETYPE_FLOAT:
- return (float) *((float *) addr);
+ return (float) _field_get_float(f, o);
default:
exceptions_throw_illegalargumentexception();
return 0;
{
classinfo *c;
fieldinfo *f;
- void *addr;
int32_t slot;
/* get the class and the field */
LLNI_field_get_val(this, slot , slot);
f = &c->fields[slot];
- /* get the address of the field with an internal helper */
+ /* check if the field can be accessed */
- if ((addr = cacao_get_field_address(this, o)) == NULL)
+ if (!_field_access_check(this, f, c, (java_handle_t *) o))
return 0;
/* check the field type and return the value */
case PRIMITIVETYPE_CHAR:
case PRIMITIVETYPE_SHORT:
case PRIMITIVETYPE_INT:
- return (double) *((int32_t *) addr);
+ return (double) _field_get_int(f, o);
case PRIMITIVETYPE_LONG:
- return (double) *((int64_t *) addr);
+ return (double) _field_get_long(f, o);
case PRIMITIVETYPE_FLOAT:
- return (double) *((float *) addr);
+ return (double) _field_get_float(f, o);
case PRIMITIVETYPE_DOUBLE:
- return (double) *((double *) addr);
+ return (double) _field_get_double(f, o);
default:
exceptions_throw_illegalargumentexception();
return 0;
classinfo *dc;
fieldinfo *sf;
fieldinfo *df;
- void *faddr;
int32_t slot;
/* get the class and the field */
LLNI_field_get_val(this, slot , slot);
df = &dc->fields[slot];
- /* get the address of the destination field */
+ /* check if the field can be accessed */
- if ((faddr = cacao_get_field_address(this, o)) == NULL)
+ if (!_field_access_check(this, df, dc, (java_handle_t *) o))
return;
/* get the source classinfo from the object */
return;
}
- *((int32_t *) faddr) = val;
+ _field_set_int(df, o, val);
return;
}
return;
}
- *((int32_t *) faddr) = val;
+ _field_set_int(df, o, val);
return;
}
return;
}
- *((int32_t *) faddr) = val;
+ _field_set_int(df, o, val);
return;
}
return;
}
- *((int32_t *) faddr) = val;
+ _field_set_int(df, o, val);
return;
}
return;
}
- *((int32_t *) faddr) = val;
+ _field_set_int(df, o, val);
return;
}
return;
}
- *((int64_t *) faddr) = val;
+ _field_set_long(df, o, val);
return;
}
return;
}
- *((float *) faddr) = val;
+ _field_set_float(df, o, val);
return;
}
return;
}
- *((double *) faddr) = val;
+ _field_set_double(df, o, val);
return;
}
/* if (!builtin_instanceof((java_handle_t *) value, df->class)) */
/* break; */
- *((java_lang_Object **) faddr) = value;
+ _field_set_handle(df, o, (java_handle_t *) value);
return;
}
{
classinfo *c;
fieldinfo *f;
- void *addr;
int32_t slot;
/* get the class and the field */
LLNI_field_get_val(this, slot , slot);
f = &c->fields[slot];
- /* get the address of the field with an internal helper */
+ /* check if the field can be accessed */
- if ((addr = cacao_get_field_address(this, o)) == NULL)
+ if (!_field_access_check(this, f, c, (java_handle_t *) o))
return;
/* check the field type and set the value */
switch (f->parseddesc->decltype) {
case PRIMITIVETYPE_BOOLEAN:
- *((int32_t *) addr) = value;
+ _field_set_int(f, o, value);
break;
default:
exceptions_throw_illegalargumentexception();
{
classinfo *c;
fieldinfo *f;
- void *addr;
int32_t slot;
/* get the class and the field */
LLNI_field_get_val(this, slot , slot);
f = &c->fields[slot];
- /* get the address of the field with an internal helper */
+ /* check if the field can be accessed */
- if ((addr = cacao_get_field_address(this, o)) == NULL)
+ if (!_field_access_check(this, f, c, (java_handle_t *) o))
return;
/* check the field type and set the value */
case PRIMITIVETYPE_BYTE:
case PRIMITIVETYPE_SHORT:
case PRIMITIVETYPE_INT:
- *((int32_t *) addr) = value;
+ _field_set_int(f, o, value);
break;
case PRIMITIVETYPE_LONG:
- *((int64_t *) addr) = value;
+ _field_set_long(f, o, value);
break;
case PRIMITIVETYPE_FLOAT:
- *((float *) addr) = value;
+ _field_set_float(f, o, value);
break;
case PRIMITIVETYPE_DOUBLE:
- *((double *) addr) = value;
+ _field_set_double(f, o, value);
break;
default:
exceptions_throw_illegalargumentexception();
{
classinfo *c;
fieldinfo *f;
- void *addr;
int32_t slot;
/* get the class and the field */
LLNI_field_get_val(this, slot , slot);
f = &c->fields[slot];
- /* get the address of the field with an internal helper */
+ /* check if the field can be accessed */
- if ((addr = cacao_get_field_address(this, o)) == NULL)
+ if (!_field_access_check(this, f, c, (java_handle_t *) o))
return;
/* check the field type and set the value */
switch (f->parseddesc->decltype) {
case PRIMITIVETYPE_CHAR:
case PRIMITIVETYPE_INT:
- *((int32_t *) addr) = value;
+ _field_set_int(f, o, value);
break;
case PRIMITIVETYPE_LONG:
- *((int64_t *) addr) = value;
+ _field_set_long(f, o, value);
break;
case PRIMITIVETYPE_FLOAT:
- *((float *) addr) = value;
+ _field_set_float(f, o, value);
break;
case PRIMITIVETYPE_DOUBLE:
- *((double *) addr) = value;
+ _field_set_double(f, o, value);
break;
default:
exceptions_throw_illegalargumentexception();
{
classinfo *c;
fieldinfo *f;
- void *addr;
int32_t slot;
/* get the class and the field */
LLNI_field_get_val(this, slot , slot);
f = &c->fields[slot];
- /* get the address of the field with an internal helper */
+ /* check if the field can be accessed */
- if ((addr = cacao_get_field_address(this, o)) == NULL)
+ if (!_field_access_check(this, f, c, (java_handle_t *) o))
return;
/* check the field type and set the value */
switch (f->parseddesc->decltype) {
case PRIMITIVETYPE_SHORT:
case PRIMITIVETYPE_INT:
- *((int32_t *) addr) = value;
+ _field_set_int(f, o, value);
break;
case PRIMITIVETYPE_LONG:
- *((int64_t *) addr) = value;
+ _field_set_long(f, o, value);
break;
case PRIMITIVETYPE_FLOAT:
- *((float *) addr) = value;
+ _field_set_float(f, o, value);
break;
case PRIMITIVETYPE_DOUBLE:
- *((double *) addr) = value;
+ _field_set_double(f, o, value);
break;
default:
exceptions_throw_illegalargumentexception();
{
classinfo *c;
fieldinfo *f;
- void *addr;
int32_t slot;
/* get the class and the field */
LLNI_field_get_val(this, slot , slot);
f = &c->fields[slot];
- /* get the address of the field with an internal helper */
+ /* check if the field can be accessed */
- if ((addr = cacao_get_field_address(this, o)) == NULL)
+ if (!_field_access_check(this, f, c, (java_handle_t *) o))
return;
/* check the field type and set the value */
switch (f->parseddesc->decltype) {
case PRIMITIVETYPE_INT:
- *((int32_t *) addr) = value;
+ _field_set_int(f, o, value);
break;
case PRIMITIVETYPE_LONG:
- *((int64_t *) addr) = value;
+ _field_set_long(f, o, value);
break;
case PRIMITIVETYPE_FLOAT:
- *((float *) addr) = value;
+ _field_set_float(f, o, value);
break;
case PRIMITIVETYPE_DOUBLE:
- *((double *) addr) = value;
+ _field_set_double(f, o, value);
break;
default:
exceptions_throw_illegalargumentexception();
{
classinfo *c;
fieldinfo *f;
- void *addr;
int32_t slot;
/* get the class and the field */
LLNI_field_get_val(this, slot , slot);
f = &c->fields[slot];
- /* get the address of the field with an internal helper */
+ /* check if the field can be accessed */
- if ((addr = cacao_get_field_address(this, o)) == NULL)
+ if (!_field_access_check(this, f, c, (java_handle_t *) o))
return;
/* check the field type and set the value */
switch (f->parseddesc->decltype) {
case PRIMITIVETYPE_LONG:
- *((int64_t *) addr) = value;
+ _field_set_long(f, o, value);
break;
case PRIMITIVETYPE_FLOAT:
- *((float *) addr) = value;
+ _field_set_float(f, o, value);
break;
case PRIMITIVETYPE_DOUBLE:
- *((double *) addr) = value;
+ _field_set_double(f, o, value);
break;
default:
exceptions_throw_illegalargumentexception();
{
classinfo *c;
fieldinfo *f;
- void *addr;
int32_t slot;
/* get the class and the field */
LLNI_field_get_val(this, slot , slot);
f = &c->fields[slot];
- /* get the address of the field with an internal helper */
+ /* check if the field can be accessed */
- if ((addr = cacao_get_field_address(this, o)) == NULL)
+ if (!_field_access_check(this, f, c, (java_handle_t *) o))
return;
/* check the field type and set the value */
switch (f->parseddesc->decltype) {
case PRIMITIVETYPE_FLOAT:
- *((float *) addr) = value;
+ _field_set_float(f, o, value);
break;
case PRIMITIVETYPE_DOUBLE:
- *((double *) addr) = value;
+ _field_set_double(f, o, value);
break;
default:
exceptions_throw_illegalargumentexception();
{
classinfo *c;
fieldinfo *f;
- void *addr;
int32_t slot;
/* get the class and the field */
LLNI_field_get_val(this, slot , slot);
f = &c->fields[slot];
- /* get the address of the field with an internal helper */
+ /* check if the field can be accessed */
- if ((addr = cacao_get_field_address(this, o)) == NULL)
+ if (!_field_access_check(this, f, c, (java_handle_t *) o))
return;
/* check the field type and set the value */
switch (f->parseddesc->decltype) {
case PRIMITIVETYPE_DOUBLE:
- *((double *) addr) = value;
+ _field_set_double(f, o, value);
break;
default:
exceptions_throw_illegalargumentexception();
* Method: declaredAnnotations
* Signature: ()Ljava/util/Map;
*/
-JNIEXPORT struct java_util_Map* JNICALL Java_java_lang_reflect_Field_declaredAnnotations(JNIEnv *env, struct java_lang_reflect_Field* this)
+JNIEXPORT struct java_util_Map* JNICALL Java_java_lang_reflect_Field_declaredAnnotations(JNIEnv *env, java_lang_reflect_Field *this)
{
- java_handle_t *o = (java_handle_t*)this;
- struct java_util_Map *declaredAnnotations = NULL;
- java_bytearray *annotations = NULL;
- java_lang_Class *declaringClass = NULL;
-
- if (this == NULL) {
- exceptions_throw_nullpointerexception();
- return NULL;
- }
+ java_util_Map *declaredAnnotations = NULL; /* parsed annotations */
+ java_handle_bytearray_t *annotations = NULL; /* unparsed annotations */
+ java_lang_Class *declaringClass = NULL; /* the constant pool of this class is used */
+ classinfo *referer = NULL; /* class, which calles the annotation parser */
+ /* (for the parameter 'referer' of vm_call_method()) */
LLNI_field_get_ref(this, declaredAnnotations, declaredAnnotations);
+ /* are the annotations parsed yet? */
if (declaredAnnotations == NULL) {
- LLNI_field_get_val(this, annotations, annotations);
+ LLNI_field_get_ref(this, annotations, annotations);
LLNI_field_get_ref(this, clazz, declaringClass);
+ LLNI_class_get(this, referer);
- declaredAnnotations = reflect_get_declaredannotatios(annotations, declaringClass, o->vftbl->class);
+ declaredAnnotations = reflect_get_declaredannotatios(annotations, declaringClass, referer);
LLNI_field_set_ref(this, declaredAnnotations, declaredAnnotations);
}
* c-basic-offset: 4
* tab-width: 4
* End:
+ * vim:noexpandtab:sw=4:ts=4:
*/