clean up Field.get() and Field.set() implementations

This commit is contained in:
Joel Dice 2007-08-18 11:15:03 -06:00
parent 3625a02910
commit d169e4eadf
5 changed files with 296 additions and 170 deletions

View File

@ -27,6 +27,10 @@ public final class Class <T> {
return new String(name, 0, name.length - 1, false);
}
public Object[] staticTable() {
return staticTable;
}
public static Class forName(String name) throws ClassNotFoundException {
return forName
(name, true, Method.getCaller().getDeclaringClass().getClassLoader());

View File

@ -63,8 +63,7 @@ public final class Double extends Number {
return 0.0;
}
public static long doubleToRawLongBits(double value) {
// todo
return 0;
}
public static native long doubleToRawLongBits(double value);
public static native double longBitsToDouble(long bits);
}

View File

@ -53,8 +53,7 @@ public final class Float extends Number {
return (double) value;
}
public static int floatToRawIntBits(float value) {
// todo
return 0;
}
public static native int floatToRawIntBits(float value);
public static native float intBitsToFloat(int bits);
}

View File

@ -1,6 +1,17 @@
package java.lang.reflect;
public class Field<T> extends AccessibleObject {
private static final int VoidField = 0;
private static final int ByteField = 1;
private static final int CharField = 2;
private static final int DoubleField = 3;
private static final int FloatField = 4;
private static final int IntField = 5;
private static final int LongField = 6;
private static final int ShortField = 7;
private static final int BooleanField = 8;
private static final int ObjectField = 9;
private byte vmFlags;
private byte code;
private short flags;
@ -35,8 +46,182 @@ public class Field<T> extends AccessibleObject {
return Class.forCanonicalName(getName());
}
public native Object get(Object instance) throws IllegalAccessException;
public Object get(Object instance) throws IllegalAccessException {
if ((flags & Modifier.STATIC) != 0) {
Object v = class_.staticTable()[offset];
switch (code) {
case ByteField:
return Byte.valueOf((byte) ((Integer) v).intValue());
public native void set(Object instance, Object value)
throws IllegalAccessException;
case BooleanField:
return Boolean.valueOf(((Integer) v) != 0);
case CharField:
return Character.valueOf((char) ((Integer) v).intValue());
case ShortField:
return Short.valueOf((short) ((Integer) v).intValue());
case FloatField:
return Float.valueOf(Float.intBitsToFloat((Integer) v));
case DoubleField:
return Double.valueOf(Double.longBitsToDouble((Long) v));
case IntField:
case LongField:
case ObjectField:
return v;
default:
throw new Error();
}
} else if (class_.isInstance(instance)) {
switch (code) {
case ByteField:
return Byte.valueOf((byte) getPrimitive(instance, code, offset));
case BooleanField:
return Boolean.valueOf(getPrimitive(instance, code, offset) != 0);
case CharField:
return Character.valueOf((char) getPrimitive(instance, code, offset));
case ShortField:
return Short.valueOf((short) getPrimitive(instance, code, offset));
case IntField:
return Integer.valueOf((int) getPrimitive(instance, code, offset));
case LongField:
return Long.valueOf((int) getPrimitive(instance, code, offset));
case FloatField:
return Float.valueOf
(Float.intBitsToFloat((int) getPrimitive(instance, code, offset)));
case DoubleField:
return Double.valueOf
(Double.longBitsToDouble(getPrimitive(instance, code, offset)));
case ObjectField:
return getObject(instance, offset);
default:
throw new Error();
}
} else {
throw new IllegalArgumentException();
}
}
public void set(Object instance, Object value)
throws IllegalAccessException
{
if ((flags & Modifier.STATIC) != 0) {
Object[] a = class_.staticTable();
switch (code) {
case ByteField:
a[offset] = Integer.valueOf((Byte) value);
break;
case BooleanField:
a[offset] = Integer.valueOf(((Boolean) value) ? 1 : 0);
break;
case CharField:
a[offset] = Integer.valueOf((Character) value);
break;
case ShortField:
a[offset] = Integer.valueOf((Short) value);
break;
case FloatField:
a[offset] = Integer.valueOf(Float.floatToRawIntBits((Float) value));
break;
case DoubleField:
a[offset] = Long.valueOf(Double.doubleToRawLongBits((Double) value));
break;
case IntField:
case LongField:
a[offset] = value;
break;
case ObjectField:
if (getType().isInstance(value)) {
a[offset] = value;
} else {
throw new IllegalArgumentException();
}
break;
default:
throw new Error();
}
} else if (class_.isInstance(instance)) {
switch (code) {
case ByteField:
setPrimitive(instance, code, offset, (Byte) value);
break;
case BooleanField:
setPrimitive(instance, code, offset, ((Boolean) value) ? 1 : 0);
break;
case CharField:
setPrimitive(instance, code, offset, (Character) value);
break;
case ShortField:
setPrimitive(instance, code, offset, (Short) value);
break;
case IntField:
setPrimitive(instance, code, offset, (Integer) value);
break;
case LongField:
setPrimitive(instance, code, offset, (Long) value);
break;
case FloatField:
setPrimitive(instance, code, offset,
Float.floatToRawIntBits((Float) value));
break;
case DoubleField:
setPrimitive(instance, code, offset,
Double.doubleToRawLongBits((Double) value));
break;
case ObjectField:
if (getType().isInstance(value)) {
setObject(instance, offset, value);
} else {
throw new IllegalArgumentException();
}
break;
default:
throw new Error();
}
} else {
throw new IllegalArgumentException();
}
}
private static native long getPrimitive
(Object instance, int code, int offset);
private static native Object getObject
(Object instance, int offset);
private static native void setPrimitive
(Object instance, int code, int offset, long value);
private static native void setObject
(Object instance, int offset, Object value);
}

View File

@ -195,169 +195,76 @@ Class_isAssignableFrom(Thread* t, jobject this_, jclass that)
}
}
jobject
Field_get(Thread* t, jobject this_, jobject instancep)
jlong
Field_getPrimitive(Thread* t, jclass, jobject instance, jint code, jint offset)
{
object field = *this_;
if (fieldFlags(t, field) & ACC_STATIC) {
object v = arrayBody(t, classStaticTable(t, fieldClass(t, field)),
fieldOffset(t, field));
switch (fieldCode(t, field)) {
switch (code) {
case ByteField:
return pushReference(t, makeByte(t, intValue(t, v)));
return cast<int8_t>(*instance, offset);
case BooleanField:
return pushReference(t, makeBoolean(t, intValue(t, v)));
return cast<uint8_t>(*instance, offset);
case CharField:
return pushReference(t, makeChar(t, intValue(t, v)));
return cast<uint16_t>(*instance, offset);
case ShortField:
return pushReference(t, makeShort(t, intValue(t, v)));
case FloatField:
return pushReference(t, makeFloat(t, intValue(t, v)));
case DoubleField:
return pushReference(t, makeDouble(t, longValue(t, v)));
return cast<int16_t>(*instance, offset);
case IntField:
return cast<int32_t>(*instance, offset);
case LongField:
case ObjectField:
return pushReference(t, v);
return cast<int64_t>(*instance, offset);
case FloatField:
return cast<uint32_t>(*instance, offset);
case DoubleField:
return cast<uint64_t>(*instance, offset);
default:
abort(t);
}
} else if (instancep) {
object instance = *instancep;
}
if (instanceOf(t, fieldClass(t, this_), instance)) {
switch (fieldCode(t, field)) {
case ByteField:
return pushReference
(t, makeByte(t, cast<int8_t>(instance, fieldOffset(t, field))));
case BooleanField:
return pushReference
(t, makeBoolean(t, cast<uint8_t>(instance, fieldOffset(t, field))));
case CharField:
return pushReference
(t, makeChar(t, cast<uint16_t>(instance, fieldOffset(t, field))));
case ShortField:
return pushReference
(t, makeShort(t, cast<int16_t>(instance, fieldOffset(t, field))));
case FloatField:
return pushReference
(t, makeFloat(t, cast<uint32_t>(instance, fieldOffset(t, field))));
case IntField:
return pushReference
(t, makeInt(t, cast<int32_t>(instance, fieldOffset(t, field))));
case DoubleField:
return pushReference
(t, makeDouble(t, cast<uint64_t>(instance, fieldOffset(t, field))));
case LongField:
return pushReference
(t, makeLong(t, cast<int64_t>(instance, fieldOffset(t, field))));
case ObjectField:
return pushReference
(t, cast<object>(instance, fieldOffset(t, field)));
default:
abort(t);
}
} else {
t->exception = makeIllegalArgumentException(t);
}
} else {
t->exception = makeNullPointerException(t);
}
return 0;
jobject
Field_getObject(Thread* t, jclass, jobject instance, jint offset)
{
return pushReference(t, cast<object>(*instance, offset));
}
void
Field_set(Thread* t, jobject this_, jobject instancep, jobject value)
Field_setPrimitive(Thread* t, jclass, jobject instance, jint code, jint offset,
jlong value)
{
object field = *this_;
object v = (value ? *value : 0);
if (fieldFlags(t, field) & ACC_STATIC) {
object* p = &arrayBody(t, classStaticTable(t, fieldClass(t, field)),
fieldOffset(t, field));
if (fieldCode(t, field) == ObjectField or v) {
switch (fieldCode(t, field)) {
switch (code) {
case ByteField:
set(t, *p, makeInt(t, byteValue(t, v)));
cast<int8_t>(*instance, offset) = static_cast<int8_t>(value);
break;
case BooleanField:
set(t, *p, makeInt(t, booleanValue(t, v)));
cast<uint8_t>(*instance, offset) = static_cast<uint8_t>(value);
break;
case CharField:
set(t, *p, makeInt(t, charValue(t, v)));
cast<uint16_t>(*instance, offset) = static_cast<uint16_t>(value);
break;
case ShortField:
set(t, *p, makeInt(t, shortValue(t, v)));
cast<int16_t>(*instance, offset) = static_cast<int16_t>(value);
break;
case FloatField:
set(t, *p, makeInt(t, floatValue(t, v)));
break;
case DoubleField:
set(t, *p, makeLong(t, longValue(t, v)));
break;
case IntField:
case LongField:
case ObjectField:
set(t, *p, v);
cast<int32_t>(*instance, offset) = static_cast<int32_t>(value);
break;
case LongField:
cast<int64_t>(*instance, offset) = static_cast<int64_t>(value);
break;
case FloatField:
cast<uint32_t>(*instance, offset) = static_cast<uint32_t>(value);
break;
case DoubleField:
cast<uint64_t>(*instance, offset) = static_cast<uint64_t>(value);
break;
default:
abort(t);
}
} else {
t->exception = makeNullPointerException(t);
}
} else if (instancep) {
object instance = *instancep;
}
if (instanceOf(t, fieldClass(t, this_), instance)) {
switch (fieldCode(t, field)) {
case ObjectField:
set(t, cast<object>(instance, fieldOffset(t, field)), v);
break;
default: {
uint8_t* body = &cast<uint8_t>(instance, fieldOffset(t, field));
if (v) {
memcpy(body, &cast<uint8_t>(v, BytesPerWord),
primitiveSize(t, fieldCode(t, field)));
} else {
t->exception = makeNullPointerException(t);
}
} break;
}
} else {
t->exception = makeIllegalArgumentException(t);
}
} else {
t->exception = makeNullPointerException(t);
}
void
Field_setObject(Thread*, jclass, jobject instance, jint offset,
jobject value)
{
cast<object>(*instance, offset) = (value ? *value : 0);
}
jobject
@ -523,6 +430,34 @@ Array_makeObjectArray(Thread* t, jclass, jclass elementType, jint length)
return pushReference(t, makeObjectArray(t, *elementType, length, true));
}
jint
Float_floatToRawIntBits(Thread*, jclass, jfloat v)
{
int32_t r; memcpy(&r, &v, 4);
return r;
}
jfloat
Float_intBitsToFloat(Thread*, jclass, jint v)
{
jfloat r; memcpy(&r, &v, 4);
return r;
}
jlong
Double_doubleToRawLongBits(Thread*, jclass, jdouble v)
{
int64_t r; memcpy(&r, &v, 8);
return r;
}
jdouble
Double_longBitsToDouble(Thread*, jclass, jlong v)
{
jdouble r; memcpy(&r, &v, 8);
return r;
}
jobject
String_intern(Thread* t, jobject this_)
{
@ -841,10 +776,14 @@ populateBuiltinMap(Thread* t, object map)
{ "Java_java_lang_reflect_Constructor_make",
reinterpret_cast<void*>(::Constructor_make) },
{ "Java_java_lang_reflect_Field_get",
reinterpret_cast<void*>(::Field_get) },
{ "Java_java_lang_reflect_Field_set",
reinterpret_cast<void*>(::Field_set) },
{ "Java_java_lang_reflect_Field_getPrimitive",
reinterpret_cast<void*>(::Field_getPrimitive) },
{ "Java_java_lang_reflect_Field_getObject",
reinterpret_cast<void*>(::Field_getObject) },
{ "Java_java_lang_reflect_Field_setPrimitive",
reinterpret_cast<void*>(::Field_setPrimitive) },
{ "Java_java_lang_reflect_Field_setObject",
reinterpret_cast<void*>(::Field_setObject) },
{ "Java_java_lang_reflect_Method_getCaller",
reinterpret_cast<void*>(::Method_getCaller) },