Files
gcc/libjava/java/lang/reflect/natField.cc
T
Bryce McKinlay f4294557b7 [multiple changes]
2005-02-21  Bryce McKinlay  <mckinlay@redhat.com>

	Merge serialization from GNU Classpath.
	* gcj/method.h: Add missing #includes.
	* java/io/ObjectInputStream.java (readClassDescriptor): Check for
	primitive class IDs on the stream here...
	(resolveClass): ...not here.
	* java/io/ObjectStreamField.java: Use VMObjectStream class calls to set
	fields.
	* java/io/VMObjectStreamClass.java (setDoubleNative, setFloatNative,
	setLongNative, setIntNative, setShortNative, setCharNative,
	setByteNative, setBooleanNative, setObjectNative): New native methods.
	* java/io/natVMObjectStreamClass.java (setDoubleNative, setFloatNative,
	setLongNative, setIntNative, setShortNative, setCharNative,
	setByteNative, setBooleanNative, setObjectNative): Implement them.
	* java/io/natObjectInputStream.cc (allocateObject): Add new parameters
	from Classpath's version. Use _Jv_FromReflectedConstructor(). Call
	the constructor here.
	(callConstructor): Removed.
	(getCallersClassLoader): Removed.
	* java/lang/reflect/Field.java (setByte, setShort, setInt, setLong,
	setFloat, setDouble, setChar, setBoolean): Add 'checkFinal' parameter
	to control whether setting final field values is permitted. Call
	getAddr() with checkFinal parameter instead of setAddr().
	* java/lang/reflect/natField.cc (getType): Lookup and resolve field
	only if not done already.
	(getAddr): Add checkFinal parameter. Do the final field check only if
	checkFinal is set.
	(setAddr): Removed.

2005-02-21  Mark Wielaard  <mark@klomp.org>

	# Fixes bug #11957
	* java/io/ObjectInputStream.java (resolveClass): Don't check "void"
	twice.

2005-02-21  Mark Wielaard  <mark@klomp.org>

	Fixes bug #11618.
	* java/io/ObjectInputStream.java (readClassDescriptor): Handle classes
	without a super class and us ObjectStreamClass.lookupForClassObject().
	(resolveClass): Check for primitive types.
	(lookupClass): Return null when argument is null.

2005-02-21  Jeroen Frijters  <jeroen@frijters.net>

	* java/io/ObjectInputStream.java
	(readObject): Fix to consume TC_ENDBLOCKDATA after readExternal.

2005-02-21  Jeroen Frijters  <jeroen@frijters.net>

	* java/io/ObjectOutputStream.java
	(writeObject, callWriteMethod): Replaced reflection with accessing
	cached info in ObjectStreamClass.
	(getMethod): Removed.
	* java/io/ObjectStreamClass.java
	(findMethod): Added check to make sure the method found has the
	right modifiers.
	(cacheMethods): Added writeReplace and writeObject methods.
	(setFlags): Look at new writeObjectMethod field instead of doing
	reflection again.
	(writeReplaceMethod): New field.
	(writeObjectMethod): New field.

2005-02-21  Guilhem Lavaux  <guilhem@kaffe.org>
	Jeroen Frijters  <jeroen@frijters.net>

	* java/io/ObjectInputStream.java
	(newObject): Changed prototype. Get a constructor reflect object
	directly.
	(callConstructor): Removed.
	(allocateObject): Changed prototype.
	(readClassDescriptor): Build the constructor reflection directly.
	(readObject): Invoke newObject using the new prototype.

	* java/io/ObjectStreamClass.java
	(firstNonSerializableParent): Removed.
	(firstNonSerializableParentConstructor): Added.

From-SVN: r95378
2005-02-22 03:13:35 +00:00

446 lines
12 KiB
C++

// 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 <config.h>
#include <stdlib.h>
#include <jvm.h>
#include <java/lang/reflect/Field.h>
#include <java/lang/reflect/Modifier.h>
#include <java/lang/ArrayIndexOutOfBoundsException.h>
#include <java/lang/IllegalArgumentException.h>
#include <java/lang/IllegalAccessException.h>
#include <java/lang/NullPointerException.h>
#include <java/lang/Byte.h>
#include <java/lang/Short.h>
#include <java/lang/Integer.h>
#include <java/lang/Long.h>
#include <java/lang/Float.h>
#include <java/lang/Double.h>
#include <java/lang/Boolean.h>
#include <java/lang/Character.h>
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;
}