// natField.cc - Implementation of java.lang.reflect.Field native methods. /* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004 Free Software Foundation This file is part of libgcj. This software is copyrighted work licensed under the terms of the Libgcj License. Please consult the file "LIBGCJ_LICENSE" for details. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include jint java::lang::reflect::Field::getModifiers () { return _Jv_FromReflectedField (this)->getModifiers (); } jstring java::lang::reflect::Field::getName () { if (name == NULL) name = _Jv_NewStringUtf8Const (_Jv_FromReflectedField (this)->name); return name; } jclass java::lang::reflect::Field::getType () { if (type == NULL) { jfieldID fld = _Jv_FromReflectedField (this); JvSynchronize sync (declaringClass); _Jv_Linker::resolve_field (fld, declaringClass->getClassLoaderInternal ()); type = fld->type; } return type; } static void* getAddr (java::lang::reflect::Field* field, jclass caller, jobject obj, jboolean checkFinal) { // FIXME: we know CALLER is NULL here. At one point we planned to // have the compiler insert the caller as a hidden argument in some // calls. However, we never implemented that, so we have to find // the caller by hand instead. using namespace java::lang::reflect; jfieldID fld = _Jv_FromReflectedField (field); _Jv_ushort flags = fld->getModifiers(); // Setting a final field is usually not allowed. if (checkFinal && field->getModifiers() & java::lang::reflect::Modifier::FINAL) throw new java::lang::IllegalAccessException(JvNewStringUTF ("Field is final")); // Check accessibility, if required. if (! (Modifier::isPublic (flags) || field->isAccessible())) { gnu::gcj::runtime::StackTrace *t = new gnu::gcj::runtime::StackTrace(7); try { // We want to skip all the frames on the stack from this class. for (int i = 1; !caller || caller == &Field::class$; i++) caller = t->classAt (i); } catch (::java::lang::ArrayIndexOutOfBoundsException *e) { } if (! _Jv_CheckAccess (caller, field->getDeclaringClass(), flags)) throw new java::lang::IllegalAccessException; } if (flags & Modifier::STATIC) { jclass fldClass = field->getDeclaringClass (); JvInitClass(fldClass); return fld->u.addr; } else { if (obj == NULL) throw new java::lang::NullPointerException; if (! _Jv_IsInstanceOf (obj, field->getDeclaringClass())) throw new java::lang::IllegalArgumentException; return (void*) ((char*) obj + fld->getOffset ()); } } static jboolean getBoolean (jclass cls, void* addr) { if (cls == JvPrimClass (boolean)) return * (jboolean *) addr; throw new java::lang::IllegalArgumentException; } static jchar getChar (jclass cls, void* addr) { if (cls == JvPrimClass (char)) return * (jchar *) addr; throw new java::lang::IllegalArgumentException; } static jbyte getByte (jclass cls, void* addr) { if (cls == JvPrimClass (byte)) return * (jbyte *) addr; throw new java::lang::IllegalArgumentException; } static jshort getShort (jclass cls, void* addr) { if (cls == JvPrimClass (short)) return * (jshort *) addr; if (cls == JvPrimClass (byte)) return * (jbyte *) addr; throw new java::lang::IllegalArgumentException; } static jint getInt (jclass cls, void* addr) { if (cls == JvPrimClass (int)) return * (jint *) addr; if (cls == JvPrimClass (short)) return * (jshort *) addr; if (cls == JvPrimClass (char)) return * (jchar *) addr; if (cls == JvPrimClass (byte)) return * (jbyte *) addr; throw new java::lang::IllegalArgumentException; } static jlong getLong (jclass cls, void* addr) { if (cls == JvPrimClass (long)) return * (jlong *) addr; return ::getInt(cls, addr); } static jfloat getFloat (jclass cls, void* addr) { if (cls == JvPrimClass (float)) return * (jfloat *) addr; if (cls == JvPrimClass (long)) return * (jlong *) addr; return ::getInt(cls, addr); } static jdouble getDouble (jclass cls, void* addr) { if (cls == JvPrimClass (double)) return * (jdouble *) addr; if (cls == JvPrimClass (float)) return * (jfloat *) addr; if (cls == JvPrimClass (long)) return * (jlong *) addr; return ::getInt(cls, addr); } jboolean java::lang::reflect::Field::getBoolean (jclass caller, jobject obj) { return ::getBoolean (this->getType(), getAddr (this, caller, obj, false)); } jchar java::lang::reflect::Field::getChar (jclass caller, jobject obj) { return ::getChar (this->getType(), getAddr (this, caller, obj, false)); } jbyte java::lang::reflect::Field::getByte (jclass caller, jobject obj) { return ::getByte (this->getType(), getAddr (this, caller, obj, false)); } jshort java::lang::reflect::Field::getShort (jclass caller, jobject obj) { return ::getShort (this->getType(), getAddr (this, caller, obj, false)); } jint java::lang::reflect::Field::getInt (jclass caller, jobject obj) { return ::getInt (this->getType(), getAddr (this, caller, obj, false)); } jlong java::lang::reflect::Field::getLong (jclass caller, jobject obj) { return ::getLong (this->getType(), getAddr (this, caller, obj, false)); } jfloat java::lang::reflect::Field::getFloat (jclass caller, jobject obj) { return ::getFloat (this->getType(), getAddr (this, caller, obj, false)); } jdouble java::lang::reflect::Field::getDouble (jclass caller, jobject obj) { return ::getDouble (this->getType(), getAddr (this, caller, obj, false)); } jobject java::lang::reflect::Field::get (jclass caller, jobject obj) { jclass type = this->getType(); void* addr = getAddr (this, caller, obj, false); if (! type->isPrimitive ()) return * (jobject*) addr; if (type == JvPrimClass (double)) return new java::lang::Double (* (jdouble*) addr); if (type == JvPrimClass (float)) return new java::lang::Float (* (jfloat*) addr); if (type == JvPrimClass (long)) return new java::lang::Long (* (jlong*) addr); if (type == JvPrimClass (int)) return new java::lang::Integer (* (jint*) addr); if (type == JvPrimClass (short)) return new java::lang::Short (* (jshort*) addr); if (type == JvPrimClass (byte)) return new java::lang::Byte (* (jbyte*) addr); if (type == JvPrimClass (char)) return new java::lang::Character (* (jchar*) addr); if (type == JvPrimClass (boolean)) { _Jv_InitClass (&java::lang::Boolean::class$); if (* (jboolean*) addr) return java::lang::Boolean::TRUE; else return java::lang::Boolean::FALSE; } throw new java::lang::IllegalArgumentException; } static void setBoolean (jclass type, void *addr, jboolean value) { if (type == JvPrimClass (boolean)) * (jboolean *) addr = value; else throw new java::lang::IllegalArgumentException; } static void setChar (jclass type, void *addr, jchar value) { if (type == JvPrimClass (char)) * (jchar *) addr = value; else if (type == JvPrimClass (int)) * (jint *) addr = value; else if (type == JvPrimClass (long)) * (jlong *) addr = value; else if (type == JvPrimClass (float)) * (jfloat *) addr = value; else if (type == JvPrimClass (double)) * (jdouble *) addr = value; else throw new java::lang::IllegalArgumentException; } static void setByte (jclass type, void *addr, jbyte value) { if (type == JvPrimClass (byte)) * (jbyte *) addr = value; else if (type == JvPrimClass (short)) * (jshort *) addr = value; else if (type == JvPrimClass (int)) * (jint *) addr = value; else if (type == JvPrimClass (long)) * (jlong *) addr = value; else if (type == JvPrimClass (float)) * (jfloat *) addr = value; else if (type == JvPrimClass (double)) * (jdouble *) addr = value; else throw new java::lang::IllegalArgumentException; } static void setShort (jclass type, void *addr, jshort value) { if (type == JvPrimClass (short)) * (jshort *) addr = value; else if (type == JvPrimClass (int)) * (jint *) addr = value; else if (type == JvPrimClass (long)) * (jlong *) addr = value; else if (type == JvPrimClass (float)) * (jfloat *) addr = value; else if (type == JvPrimClass (double)) * (jdouble *) addr = value; else throw new java::lang::IllegalArgumentException; } static void setInt (jclass type, void *addr, jint value) { if (type == JvPrimClass (int)) * (jint *) addr = value; else if (type == JvPrimClass (long)) * (jlong *) addr = value; else if (type == JvPrimClass (float)) * (jfloat *) addr = value; else if (type == JvPrimClass (double)) * (jdouble *) addr = value; else throw new java::lang::IllegalArgumentException; } static void setLong (jclass type, void *addr, jlong value) { if (type == JvPrimClass (long)) * (jlong *) addr = value; else if (type == JvPrimClass (float)) * (jfloat *) addr = value; else if (type == JvPrimClass (double)) * (jdouble *) addr = value; else throw new java::lang::IllegalArgumentException; } static void setFloat (jclass type, void *addr, jfloat value) { if (type == JvPrimClass (float)) * (jfloat *) addr = value; else if (type == JvPrimClass (double)) * (jdouble *) addr = value; else throw new java::lang::IllegalArgumentException; } static void setDouble (jclass type, void *addr, jdouble value) { if (type == JvPrimClass (double)) * (jdouble *) addr = value; else throw new java::lang::IllegalArgumentException; } void java::lang::reflect::Field::setBoolean (jclass caller, jobject obj, jboolean b, jboolean checkFinal) { ::setBoolean (this->getType(), getAddr (this, caller, obj, checkFinal), b); } void java::lang::reflect::Field::setChar (jclass caller, jobject obj, jchar c, jboolean checkFinal) { ::setChar (this->getType(), getAddr (this, caller, obj, checkFinal), c); } void java::lang::reflect::Field::setByte (jclass caller, jobject obj, jbyte b, jboolean checkFinal) { ::setByte (this->getType(), getAddr (this, caller, obj, checkFinal), b); } void java::lang::reflect::Field::setShort (jclass caller, jobject obj, jshort s, jboolean checkFinal) { ::setShort (this->getType(), getAddr (this, caller, obj, checkFinal), s); } void java::lang::reflect::Field::setInt (jclass caller, jobject obj, jint i, jboolean checkFinal) { ::setInt (this->getType(), getAddr (this, caller, obj, checkFinal), i); } void java::lang::reflect::Field::setLong (jclass caller, jobject obj, jlong l, jboolean checkFinal) { ::setLong (this->getType(), getAddr (this, caller, obj, checkFinal), l); } void java::lang::reflect::Field::setFloat (jclass caller, jobject obj, jfloat f, jboolean checkFinal) { ::setFloat (this->getType(), getAddr (this, caller, obj, checkFinal), f); } void java::lang::reflect::Field::setDouble (jclass caller, jobject obj, jdouble d, jboolean checkFinal) { ::setDouble (this->getType(), getAddr (this, caller, obj, checkFinal), d); } void java::lang::reflect::Field::set (jclass caller, jobject object, jobject value, jclass type, jboolean checkFinal) { void* addr = getAddr (this, caller, object, checkFinal); if (value != NULL && ! _Jv_IsInstanceOf (value, type)) throw new java::lang::IllegalArgumentException; * (jobject*) addr = value; }