This commit is contained in:
jfrijters 2005-03-23 09:33:18 +00:00
Родитель 36f04bac56
Коммит 446440498b
11 изменённых файлов: 1054 добавлений и 886 удалений

Просмотреть файл

@ -3129,6 +3129,7 @@ gnu/classpath/Configuration.java
gnu/classpath/RawData.java
gnu/classpath/VMStackWalker.java
gnu/classpath/VMSystemProperties.java
gnu/java/lang/reflect/VMField.java
gnu/java/net/PlainDatagramSocketImpl.java
gnu/java/net/PlainSocketImpl.java
gnu/java/net/protocol/ikvmres/Handler.java
@ -3142,6 +3143,7 @@ java/lang/ref/Reference.java
java/lang/reflect/Constructor.java
java/lang/reflect/Field.java
java/lang/reflect/Method.java
java/lang/reflect/VMFieldImpl.java
java/lang/StringHelper.java
java/lang/VMClass.java
java/lang/VMClassLoader.java

Просмотреть файл

@ -0,0 +1,75 @@
/*
Copyright (C) 2005 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jeroen Frijters
jeroen@frijters.net
*/
package gnu.java.lang.reflect;
import java.lang.reflect.Field;
public abstract class VMField
{
// fieldCookie must be package accessible (actually "assembly") to allow map.xml
// implementation of LibraryVMInterfaceImpl.getWrapperFromField() to access it.
protected Object fieldCookie;
protected Class declaringClass;
protected boolean isPublic;
protected int modifiers;
public final boolean needsAccessCheck(boolean accessible)
{
return !accessible & !isPublic;
}
public final Class getDeclaringClass()
{
return declaringClass;
}
public final int getModifiers()
{
return modifiers;
}
public abstract Field newField();
public abstract void checkAccess(Object o, Class caller) throws IllegalAccessException;
public abstract String getName();
public abstract Class getType();
public abstract Object get(Object obj);
public abstract boolean getBoolean(Object obj);
public abstract byte getByte(Object obj);
public abstract char getChar(Object obj);
public abstract short getShort(Object obj);
public abstract int getInt(Object obj);
public abstract float getFloat(Object obj);
public abstract long getLong(Object obj);
public abstract double getDouble(Object obj);
public abstract void set(Object obj, Object val, boolean accessible) throws IllegalAccessException;
public abstract void setBoolean(Object obj, boolean val, boolean accessible) throws IllegalAccessException;
public abstract void setByte(Object obj, byte val, boolean accessible) throws IllegalAccessException;
public abstract void setChar(Object obj, char val, boolean accessible) throws IllegalAccessException;
public abstract void setShort(Object obj, short val, boolean accessible) throws IllegalAccessException;
public abstract void setInt(Object obj, int val, boolean accessible) throws IllegalAccessException;
public abstract void setFloat(Object obj, float val, boolean accessible) throws IllegalAccessException;
public abstract void setLong(Object obj, long val, boolean accessible) throws IllegalAccessException;
public abstract void setDouble(Object obj, double val, boolean accessible) throws IllegalAccessException;
}

Просмотреть файл

@ -260,7 +260,7 @@ public final class Constructor
InvocationTargetException
{
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
Field.checkAccess(modifiers, null, declaringClass, VMStackWalker.getCallingClass());
VMFieldImpl.checkAccess(modifiers, null, declaringClass, VMStackWalker.getCallingClass());
int mods = declaringClass.getModifiers() | Method.GetRealModifiers(declaringClass);
if(Modifier.isAbstract(mods) || Modifier.isInterface(mods))
{

Просмотреть файл

@ -1,5 +1,5 @@
/* java.lang.reflect.Field - reflection of Java fields
Copyright (C) 1998, 2001 Free Software Foundation, Inc.
Copyright (C) 1998, 2001, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -38,9 +38,8 @@ exception statement from your version. */
package java.lang.reflect;
import cli.System.Diagnostics.StackFrame;
import gnu.classpath.VMStackWalker;
import ikvm.lang.CIL;
import gnu.java.lang.reflect.VMField;
/**
* The Field class represents a member variable of a class. It also allows
@ -66,6 +65,7 @@ import ikvm.lang.CIL;
*
* @author John Keiser
* @author Eric Blake <ebb9@email.byu.edu>
* @author Jeroen Frijters
* @see Member
* @see Class
* @see Class#getField(String)
@ -77,612 +77,16 @@ import ikvm.lang.CIL;
*/
public final class Field extends AccessibleObject implements Member
{
private Class declaringClass;
// package accessible (actually "assembly") to allow map.xml implementation
// of LibraryVMInterfaceImpl.getWrapperFromField() to access it.
Object fieldCookie;
private int modifiers;
private boolean classIsPublic;
private FieldImpl impl;
private static native Object GetValue(Object fieldCookie, Object o);
private static native void SetValue(Object fieldCookie, Object o, Object value, boolean accessible);
abstract static class FieldImpl
{
private Object fieldCookie;
FieldImpl(Object fieldCookie)
{
this.fieldCookie = fieldCookie;
}
final Object getImpl(Object obj)
{
return Field.GetValue(fieldCookie, obj);
}
final void setImpl(Object obj, Object val, boolean accessible)
{
Field.SetValue(fieldCookie, obj, val, accessible);
}
abstract Object get(Object obj);
boolean getBoolean(Object obj)
{
throw new IllegalArgumentException();
}
byte getByte(Object obj)
{
throw new IllegalArgumentException();
}
char getChar(Object obj)
{
throw new IllegalArgumentException();
}
short getShort(Object obj)
{
throw new IllegalArgumentException();
}
int getInt(Object obj)
{
throw new IllegalArgumentException();
}
float getFloat(Object obj)
{
throw new IllegalArgumentException();
}
long getLong(Object obj)
{
throw new IllegalArgumentException();
}
double getDouble(Object obj)
{
throw new IllegalArgumentException();
}
abstract void set(Object obj, Object val, boolean accessible);
void setBoolean(Object obj, boolean val, boolean accessible)
{
throw new IllegalArgumentException();
}
void setByte(Object obj, byte val, boolean accessible)
{
throw new IllegalArgumentException();
}
void setChar(Object obj, char val, boolean accessible)
{
throw new IllegalArgumentException();
}
void setShort(Object obj, short val, boolean accessible)
{
throw new IllegalArgumentException();
}
void setInt(Object obj, int val, boolean accessible)
{
throw new IllegalArgumentException();
}
void setFloat(Object obj, float val, boolean accessible)
{
throw new IllegalArgumentException();
}
void setLong(Object obj, long val, boolean accessible)
{
throw new IllegalArgumentException();
}
void setDouble(Object obj, double val, boolean accessible)
{
throw new IllegalArgumentException();
}
}
final static class ObjectFieldImpl extends FieldImpl
{
ObjectFieldImpl(Object fieldCookie)
{
super(fieldCookie);
}
Object get(Object obj)
{
return getImpl(obj);
}
void set(Object obj, Object val, boolean accessible)
{
setImpl(obj, val, accessible);
}
}
final static class BooleanFieldImpl extends FieldImpl
{
BooleanFieldImpl(Object fieldCookie)
{
super(fieldCookie);
}
Object get(Object obj)
{
return getBoolean(obj) ? Boolean.TRUE : Boolean.FALSE;
}
boolean getBoolean(Object obj)
{
return CIL.unbox_boolean(getImpl(obj));
}
void set(Object obj, Object val, boolean accessible)
{
if(! (val instanceof Boolean))
throw new IllegalArgumentException();
setBoolean(obj, ((Boolean)val).booleanValue(), accessible);
}
void setBoolean(Object obj, boolean val, boolean accessible)
{
setImpl(obj, CIL.box_boolean(val), accessible);
}
}
final static class ByteFieldImpl extends FieldImpl
{
ByteFieldImpl(Object fieldCookie)
{
super(fieldCookie);
}
Object get(Object obj)
{
return new Byte(getByte(obj));
}
byte getByte(Object obj)
{
return CIL.unbox_byte(getImpl(obj));
}
short getShort(Object obj)
{
return getByte(obj);
}
int getInt(Object obj)
{
return getByte(obj);
}
float getFloat(Object obj)
{
return getByte(obj);
}
long getLong(Object obj)
{
return getByte(obj);
}
double getDouble(Object obj)
{
return getByte(obj);
}
void set(Object obj, Object val, boolean accessible)
{
if(! (val instanceof Byte))
throw new IllegalArgumentException();
setByte(obj, ((Byte)val).byteValue(), accessible);
}
void setByte(Object obj, byte val, boolean accessible)
{
setImpl(obj, CIL.box_byte(val), accessible);
}
}
final static class CharFieldImpl extends FieldImpl
{
CharFieldImpl(Object fieldCookie)
{
super(fieldCookie);
}
Object get(Object obj)
{
return new Character(getChar(obj));
}
char getChar(Object obj)
{
return CIL.unbox_char(getImpl(obj));
}
int getInt(Object obj)
{
return getChar(obj);
}
float getFloat(Object obj)
{
return getChar(obj);
}
long getLong(Object obj)
{
return getChar(obj);
}
double getDouble(Object obj)
{
return getChar(obj);
}
void set(Object obj, Object val, boolean accessible)
{
if(! (val instanceof Character))
throw new IllegalArgumentException();
setChar(obj, ((Character)val).charValue(), accessible);
}
void setChar(Object obj, char val, boolean accessible)
{
setImpl(obj, CIL.box_char(val), accessible);
}
}
final static class ShortFieldImpl extends FieldImpl
{
ShortFieldImpl(Object fieldCookie)
{
super(fieldCookie);
}
Object get(Object obj)
{
return new Short(getShort(obj));
}
short getShort(Object obj)
{
return CIL.unbox_short(getImpl(obj));
}
int getInt(Object obj)
{
return getShort(obj);
}
float getFloat(Object obj)
{
return getShort(obj);
}
long getLong(Object obj)
{
return getShort(obj);
}
double getDouble(Object obj)
{
return getShort(obj);
}
void set(Object obj, Object val, boolean accessible)
{
if(! (val instanceof Short
|| val instanceof Byte))
throw new IllegalArgumentException();
setShort(obj, ((Number)val).shortValue(), accessible);
}
void setShort(Object obj, short val, boolean accessible)
{
setImpl(obj, CIL.box_short(val), accessible);
}
void setByte(Object obj, byte val, boolean accessible)
{
setShort(obj, val, accessible);
}
}
final static class IntFieldImpl extends FieldImpl
{
IntFieldImpl(Object fieldCookie)
{
super(fieldCookie);
}
Object get(Object obj)
{
return new Integer(getInt(obj));
}
int getInt(Object obj)
{
return CIL.unbox_int(getImpl(obj));
}
float getFloat(Object obj)
{
return getInt(obj);
}
long getLong(Object obj)
{
return getInt(obj);
}
double getDouble(Object obj)
{
return getInt(obj);
}
void set(Object obj, Object val, boolean accessible)
{
if (val instanceof Integer
|| val instanceof Byte
|| val instanceof Short)
setInt(obj, ((Number)val).intValue(), accessible);
else if (val instanceof Character)
setInt(obj, ((Character)val).charValue(), accessible);
else
throw new IllegalArgumentException();
}
void setInt(Object obj, int val, boolean accessible)
{
setImpl(obj, CIL.box_int(val), accessible);
}
void setByte(Object obj, byte val, boolean accessible)
{
setInt(obj, val, accessible);
}
void setChar(Object obj, char val, boolean accessible)
{
setInt(obj, val, accessible);
}
void setShort(Object obj, short val, boolean accessible)
{
setInt(obj, val, accessible);
}
}
final static class FloatFieldImpl extends FieldImpl
{
FloatFieldImpl(Object fieldCookie)
{
super(fieldCookie);
}
Object get(Object obj)
{
return new Float(getFloat(obj));
}
float getFloat(Object obj)
{
return CIL.unbox_float(getImpl(obj));
}
double getDouble(Object obj)
{
return getFloat(obj);
}
void set(Object obj, Object val, boolean accessible)
{
if (val instanceof Float
|| val instanceof Byte
|| val instanceof Short
|| val instanceof Integer
|| val instanceof Long)
setFloat(obj, ((Number)val).floatValue(), accessible);
else if (val instanceof Character)
setFloat(obj, ((Character)val).charValue(), accessible);
else
throw new IllegalArgumentException();
}
void setFloat(Object obj, float val, boolean accessible)
{
setImpl(obj, CIL.box_float(val), accessible);
}
void setByte(Object obj, byte val, boolean accessible)
{
setFloat(obj, val, accessible);
}
void setChar(Object obj, char val, boolean accessible)
{
setFloat(obj, val, accessible);
}
void setShort(Object obj, short val, boolean accessible)
{
setFloat(obj, val, accessible);
}
void setInt(Object obj, int val, boolean accessible)
{
setFloat(obj, val, accessible);
}
void setLong(Object obj, long val, boolean accessible)
{
setFloat(obj, val, accessible);
}
}
final static class LongFieldImpl extends FieldImpl
{
LongFieldImpl(Object fieldCookie)
{
super(fieldCookie);
}
Object get(Object obj)
{
return new Long(getLong(obj));
}
long getLong(Object obj)
{
return CIL.unbox_long(getImpl(obj));
}
float getFloat(Object obj)
{
return getLong(obj);
}
double getDouble(Object obj)
{
return getLong(obj);
}
void set(Object obj, Object val, boolean accessible)
{
if (val instanceof Long
|| val instanceof Byte
|| val instanceof Short
|| val instanceof Integer)
setLong(obj, ((Number)val).longValue(), accessible);
else if (val instanceof Character)
setLong(obj, ((Character)val).charValue(), accessible);
else
throw new IllegalArgumentException();
}
void setLong(Object obj, long val, boolean accessible)
{
setImpl(obj, CIL.box_long(val), accessible);
}
void setByte(Object obj, byte val, boolean accessible)
{
setLong(obj, val, accessible);
}
void setChar(Object obj, char val, boolean accessible)
{
setLong(obj, val, accessible);
}
void setShort(Object obj, short val, boolean accessible)
{
setLong(obj, val, accessible);
}
void setInt(Object obj, int val, boolean accessible)
{
setLong(obj, val, accessible);
}
}
final static class DoubleFieldImpl extends FieldImpl
{
DoubleFieldImpl(Object fieldCookie)
{
super(fieldCookie);
}
Object get(Object obj)
{
return new Double(getDouble(obj));
}
double getDouble(Object obj)
{
return CIL.unbox_double(getImpl(obj));
}
void set(Object obj, Object val, boolean accessible)
{
if (val instanceof Double
|| val instanceof Byte
|| val instanceof Short
|| val instanceof Integer
|| val instanceof Float
|| val instanceof Long)
setDouble(obj, ((Number)val).doubleValue(), accessible);
else if (val instanceof Character)
setDouble(obj, ((Character)val).charValue(), accessible);
else
throw new IllegalArgumentException();
}
void setDouble(Object obj, double val, boolean accessible)
{
setImpl(obj, CIL.box_double(val), accessible);
}
void setByte(Object obj, byte val, boolean accessible)
{
setDouble(obj, val, accessible);
}
void setChar(Object obj, char val, boolean accessible)
{
setDouble(obj, val, accessible);
}
void setShort(Object obj, short val, boolean accessible)
{
setDouble(obj, val, accessible);
}
void setInt(Object obj, int val, boolean accessible)
{
setDouble(obj, val, accessible);
}
void setFloat(Object obj, float val, boolean accessible)
{
setDouble(obj, val, accessible);
}
void setLong(Object obj, long val, boolean accessible)
{
setDouble(obj, val, accessible);
}
}
// package accessible to allow VM to access it
VMField impl;
/**
* This class is uninstantiable except natively.
*/
Field(Class declaringClass, Object fieldCookie)
Field(VMField impl)
{
this.declaringClass = declaringClass;
this.fieldCookie = fieldCookie;
modifiers = GetModifiers(fieldCookie);
classIsPublic = (Method.GetRealModifiers(declaringClass) & Modifier.PUBLIC) != 0;
Class type = getType();
if (type == Boolean.TYPE)
impl = new BooleanFieldImpl(fieldCookie);
else if (type == Byte.TYPE)
impl = new ByteFieldImpl(fieldCookie);
else if (type == Character.TYPE)
impl = new CharFieldImpl(fieldCookie);
else if (type == Short.TYPE)
impl = new ShortFieldImpl(fieldCookie);
else if (type == Integer.TYPE)
impl = new IntFieldImpl(fieldCookie);
else if (type == Float.TYPE)
impl = new FloatFieldImpl(fieldCookie);
else if (type == Long.TYPE)
impl = new LongFieldImpl(fieldCookie);
else if (type == Double.TYPE)
impl = new DoubleFieldImpl(fieldCookie);
else
impl = new ObjectFieldImpl(fieldCookie);
this.impl = impl;
}
private static native int GetModifiers(Object fieldCookie);
/**
* Gets the class that declared this field, or the class where this field
@ -691,7 +95,7 @@ public final class Field extends AccessibleObject implements Member
*/
public Class getDeclaringClass()
{
return declaringClass;
return impl.getDeclaringClass();
}
/**
@ -700,10 +104,8 @@ public final class Field extends AccessibleObject implements Member
*/
public String getName()
{
return GetName(fieldCookie);
return impl.getName();
}
private static native String GetName(Object fieldCookie);
/**
* Gets the modifiers this field uses. Use the <code>Modifier</code>
@ -716,7 +118,7 @@ public final class Field extends AccessibleObject implements Member
*/
public int getModifiers()
{
return modifiers;
return impl.getModifiers();
}
/**
@ -725,9 +127,8 @@ public final class Field extends AccessibleObject implements Member
*/
public Class getType()
{
return (Class)GetFieldType(fieldCookie);
return impl.getType();
}
private static native Object GetFieldType(Object fieldCookie);
/**
* Compare two objects to see if they are semantically equivalent.
@ -746,7 +147,7 @@ public final class Field extends AccessibleObject implements Member
if(!getName().equals(f.getName()))
return false;
if(declaringClass != f.declaringClass)
if(getDeclaringClass() != f.getDeclaringClass())
return false;
if(getType() != f.getType())
@ -827,10 +228,8 @@ public final class Field extends AccessibleObject implements Member
public Object get(Object o)
throws IllegalAccessException
{
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
if(o != null && !declaringClass.isInstance(o))
throw new IllegalArgumentException();
if(impl.needsAccessCheck(isAccessible()))
impl.checkAccess(o, VMStackWalker.getCallingClass());
return impl.get(o);
}
@ -854,10 +253,8 @@ public final class Field extends AccessibleObject implements Member
public boolean getBoolean(Object o)
throws IllegalAccessException
{
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
if(o != null && !declaringClass.isInstance(o))
throw new IllegalArgumentException();
if(impl.needsAccessCheck(isAccessible()))
impl.checkAccess(o, VMStackWalker.getCallingClass());
return impl.getBoolean(o);
}
@ -881,10 +278,8 @@ public final class Field extends AccessibleObject implements Member
public byte getByte(Object o)
throws IllegalAccessException
{
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
if(o != null && !declaringClass.isInstance(o))
throw new IllegalArgumentException();
if(impl.needsAccessCheck(isAccessible()))
impl.checkAccess(o, VMStackWalker.getCallingClass());
return impl.getByte(o);
}
@ -906,10 +301,8 @@ public final class Field extends AccessibleObject implements Member
public char getChar(Object o)
throws IllegalAccessException
{
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
if(o != null && !declaringClass.isInstance(o))
throw new IllegalArgumentException();
if(impl.needsAccessCheck(isAccessible()))
impl.checkAccess(o, VMStackWalker.getCallingClass());
return impl.getChar(o);
}
@ -933,10 +326,8 @@ public final class Field extends AccessibleObject implements Member
public short getShort(Object o)
throws IllegalAccessException
{
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
if(o != null && !declaringClass.isInstance(o))
throw new IllegalArgumentException();
if(impl.needsAccessCheck(isAccessible()))
impl.checkAccess(o, VMStackWalker.getCallingClass());
return impl.getShort(o);
}
@ -960,10 +351,8 @@ public final class Field extends AccessibleObject implements Member
public int getInt(Object o)
throws IllegalAccessException
{
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
if(o != null && !declaringClass.isInstance(o))
throw new IllegalArgumentException();
if(impl.needsAccessCheck(isAccessible()))
impl.checkAccess(o, VMStackWalker.getCallingClass());
return impl.getInt(o);
}
@ -987,10 +376,8 @@ public final class Field extends AccessibleObject implements Member
public long getLong(Object o)
throws IllegalAccessException
{
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
if(o != null && !declaringClass.isInstance(o))
throw new IllegalArgumentException();
if(impl.needsAccessCheck(isAccessible()))
impl.checkAccess(o, VMStackWalker.getCallingClass());
return impl.getLong(o);
}
@ -1014,10 +401,8 @@ public final class Field extends AccessibleObject implements Member
public float getFloat(Object o)
throws IllegalAccessException
{
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
if(o != null && !declaringClass.isInstance(o))
throw new IllegalArgumentException();
if(impl.needsAccessCheck(isAccessible()))
impl.checkAccess(o, VMStackWalker.getCallingClass());
return impl.getFloat(o);
}
@ -1042,10 +427,8 @@ public final class Field extends AccessibleObject implements Member
public double getDouble(Object o)
throws IllegalAccessException
{
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
if(o != null && !declaringClass.isInstance(o))
throw new IllegalArgumentException();
if(impl.needsAccessCheck(isAccessible()))
impl.checkAccess(o, VMStackWalker.getCallingClass());
return impl.getDouble(o);
}
@ -1097,38 +480,11 @@ public final class Field extends AccessibleObject implements Member
public void set(Object o, Object value)
throws IllegalAccessException
{
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
if(o != null && !declaringClass.isInstance(o))
throw new IllegalArgumentException();
if(impl.needsAccessCheck(isAccessible()))
impl.checkAccess(o, VMStackWalker.getCallingClass());
impl.set(o, value, isAccessible());
}
static void checkAccess(int modifiers, Object o, Class declaringClass, Class caller) throws IllegalAccessException
{
// when we're invoking a constructor, modifiers will not be static, but o will be null.
Class actualClass = Modifier.isStatic(modifiers) || o == null ? declaringClass : o.getClass();
boolean declaringClassIsPublic = (Method.GetRealModifiers(declaringClass) & Modifier.PUBLIC) != 0;
if((!Modifier.isPublic(modifiers) || !declaringClassIsPublic) && declaringClass != caller)
{
// if the caller is a global method, the class returned will be null
if(caller == null)
{
throw new IllegalAccessException();
}
if(Modifier.isProtected(modifiers) && actualClass.isAssignableFrom(caller))
{
}
else if(!isSamePackage(declaringClass, caller) || Modifier.isPrivate(modifiers))
{
throw new IllegalAccessException("Class " + caller.getName() +
" can not access a member of class " + declaringClass.getName() +
" with modifiers \"" + Modifier.toString(modifiers & (Modifier.PRIVATE | Modifier.PROTECTED)) + "\"");
}
}
}
private static native boolean isSamePackage(Class a, Class b);
/**
* Set this boolean Field. If the field is static, <code>o</code> will be
* ignored.
@ -1149,10 +505,8 @@ public final class Field extends AccessibleObject implements Member
public void setBoolean(Object o, boolean value)
throws IllegalAccessException
{
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
if(o != null && !declaringClass.isInstance(o))
throw new IllegalArgumentException();
if(impl.needsAccessCheck(isAccessible()))
impl.checkAccess(o, VMStackWalker.getCallingClass());
impl.setBoolean(o, value, isAccessible());
}
@ -1176,10 +530,8 @@ public final class Field extends AccessibleObject implements Member
public void setByte(Object o, byte value)
throws IllegalAccessException
{
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
if(o != null && !declaringClass.isInstance(o))
throw new IllegalArgumentException();
if(impl.needsAccessCheck(isAccessible()))
impl.checkAccess(o, VMStackWalker.getCallingClass());
impl.setByte(o, value, isAccessible());
}
@ -1203,10 +555,8 @@ public final class Field extends AccessibleObject implements Member
public void setChar(Object o, char value)
throws IllegalAccessException
{
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
if(o != null && !declaringClass.isInstance(o))
throw new IllegalArgumentException();
if(impl.needsAccessCheck(isAccessible()))
impl.checkAccess(o, VMStackWalker.getCallingClass());
impl.setChar(o, value, isAccessible());
}
@ -1230,10 +580,8 @@ public final class Field extends AccessibleObject implements Member
public void setShort(Object o, short value)
throws IllegalAccessException
{
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
if(o != null && !declaringClass.isInstance(o))
throw new IllegalArgumentException();
if(impl.needsAccessCheck(isAccessible()))
impl.checkAccess(o, VMStackWalker.getCallingClass());
impl.setShort(o, value, isAccessible());
}
@ -1257,10 +605,8 @@ public final class Field extends AccessibleObject implements Member
public void setInt(Object o, int value)
throws IllegalAccessException
{
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
if(o != null && !declaringClass.isInstance(o))
throw new IllegalArgumentException();
if(impl.needsAccessCheck(isAccessible()))
impl.checkAccess(o, VMStackWalker.getCallingClass());
impl.setInt(o, value, isAccessible());
}
@ -1284,10 +630,8 @@ public final class Field extends AccessibleObject implements Member
public void setLong(Object o, long value)
throws IllegalAccessException
{
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
if(o != null && !declaringClass.isInstance(o))
throw new IllegalArgumentException();
if(impl.needsAccessCheck(isAccessible()))
impl.checkAccess(o, VMStackWalker.getCallingClass());
impl.setLong(o, value, isAccessible());
}
@ -1311,10 +655,8 @@ public final class Field extends AccessibleObject implements Member
public void setFloat(Object o, float value)
throws IllegalAccessException
{
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
if(o != null && !declaringClass.isInstance(o))
throw new IllegalArgumentException();
if(impl.needsAccessCheck(isAccessible()))
impl.checkAccess(o, VMStackWalker.getCallingClass());
impl.setFloat(o, value, isAccessible());
}
@ -1338,10 +680,8 @@ public final class Field extends AccessibleObject implements Member
public void setDouble(Object o, double value)
throws IllegalAccessException
{
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
if(o != null && !declaringClass.isInstance(o))
throw new IllegalArgumentException();
if(impl.needsAccessCheck(isAccessible()))
impl.checkAccess(o, VMStackWalker.getCallingClass());
impl.setDouble(o, value, isAccessible());
}
}

Просмотреть файл

@ -337,7 +337,7 @@ public final class Method extends AccessibleObject implements Member
throws IllegalAccessException, InvocationTargetException
{
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
Field.checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
VMFieldImpl.checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
if(!Modifier.isStatic(modifiers))
{
if(o == null)

Просмотреть файл

@ -0,0 +1,696 @@
/*
Copyright (C) 2005 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jeroen Frijters
jeroen@frijters.net
*/
package java.lang.reflect;
import cli.System.Diagnostics.StackFrame;
import gnu.java.lang.reflect.VMField;
import ikvm.lang.CIL;
abstract class VMFieldImpl extends VMField
{
private static native Object GetValue(Object fieldCookie, Object o);
private static native void SetValue(Object fieldCookie, Object o, Object value);
private static native int GetModifiers(Object fieldCookie);
private static native String GetName(Object fieldCookie);
private static native Object GetFieldType(Object fieldCookie);
private static native boolean isSamePackage(Class a, Class b);
private static native void RunClassInit(Class clazz);
static void checkAccess(int modifiers, Object o, Class declaringClass, Class caller) throws IllegalAccessException
{
// when we're invoking a constructor, modifiers will not be static, but o will be null.
Class actualClass = Modifier.isStatic(modifiers) || o == null ? declaringClass : o.getClass();
boolean declaringClassIsPublic = (Method.GetRealModifiers(declaringClass) & Modifier.PUBLIC) != 0;
if((!Modifier.isPublic(modifiers) || !declaringClassIsPublic) && declaringClass != caller)
{
// if the caller is a global method, the class returned will be null
if(caller == null)
{
throw new IllegalAccessException();
}
if(Modifier.isProtected(modifiers) && actualClass.isAssignableFrom(caller))
{
}
else if(!isSamePackage(declaringClass, caller) || Modifier.isPrivate(modifiers))
{
throw new IllegalAccessException("Class " + caller.getName() +
" can not access a member of class " + declaringClass.getName() +
" with modifiers \"" + Modifier.toString(modifiers & (Modifier.PRIVATE | Modifier.PROTECTED)) + "\"");
}
}
}
static Field newField(Class declaringClass, Object fieldCookie)
{
Class type = (Class)GetFieldType(fieldCookie);
if (type == Boolean.TYPE)
return new BooleanFieldImpl(declaringClass, fieldCookie).newField();
else if (type == Byte.TYPE)
return new ByteFieldImpl(declaringClass, fieldCookie).newField();
else if (type == Character.TYPE)
return new CharFieldImpl(declaringClass, fieldCookie).newField();
else if (type == Short.TYPE)
return new ShortFieldImpl(declaringClass, fieldCookie).newField();
else if (type == Integer.TYPE)
return new IntFieldImpl(declaringClass, fieldCookie).newField();
else if (type == Float.TYPE)
return new FloatFieldImpl(declaringClass, fieldCookie).newField();
else if (type == Long.TYPE)
return new LongFieldImpl(declaringClass, fieldCookie).newField();
else if (type == Double.TYPE)
return new DoubleFieldImpl(declaringClass, fieldCookie).newField();
else
return new ObjectFieldImpl(declaringClass, fieldCookie).newField();
}
VMFieldImpl(Class declaringClass, Object fieldCookie)
{
this.declaringClass = declaringClass;
this.fieldCookie = fieldCookie;
this.modifiers = GetModifiers(fieldCookie);
isPublic = Modifier.isPublic(modifiers)
&& Modifier.isPublic(Method.GetRealModifiers(declaringClass));
}
public final Field newField()
{
return new Field(this);
}
public final void checkAccess(Object o, Class caller) throws IllegalAccessException
{
checkAccess(modifiers, o, declaringClass, caller);
}
public final String getName()
{
return GetName(fieldCookie);
}
public final Class getType()
{
return (Class)GetFieldType(fieldCookie);
}
final void checkObject(Object obj)
{
if(!Modifier.isStatic(modifiers))
{
if(!declaringClass.isAssignableFrom(obj.getClass()))
{
throw new IllegalArgumentException();
}
}
}
final void checkWrite(boolean accessible) throws IllegalAccessException
{
if(Modifier.isFinal(modifiers))
{
// Starting with JDK 1.5, it is legal to change final instance fields
// (see JSR-133), but they have to be made "accessible".
if(Modifier.isStatic(modifiers) || !accessible)
{
// even though the field access will fail with an IllegalAccessException,
// we run the <clinit> for declaringClass for compatibility with the JDK.
RunClassInit(declaringClass);
throw new IllegalAccessException("Field is final");
}
}
}
final Object getImpl(Object obj)
{
checkObject(obj);
return GetValue(fieldCookie, obj);
}
final void setImpl(Object obj, Object val, boolean accessible) throws IllegalAccessException
{
checkWrite(accessible);
checkObject(obj);
SetValue(fieldCookie, obj, val);
}
public boolean getBoolean(Object obj)
{
throw new IllegalArgumentException();
}
public byte getByte(Object obj)
{
throw new IllegalArgumentException();
}
public char getChar(Object obj)
{
throw new IllegalArgumentException();
}
public short getShort(Object obj)
{
throw new IllegalArgumentException();
}
public int getInt(Object obj)
{
throw new IllegalArgumentException();
}
public float getFloat(Object obj)
{
throw new IllegalArgumentException();
}
public long getLong(Object obj)
{
throw new IllegalArgumentException();
}
public double getDouble(Object obj)
{
throw new IllegalArgumentException();
}
public void setBoolean(Object obj, boolean val, boolean accessible) throws IllegalAccessException
{
throw new IllegalArgumentException();
}
public void setByte(Object obj, byte val, boolean accessible) throws IllegalAccessException
{
throw new IllegalArgumentException();
}
public void setChar(Object obj, char val, boolean accessible) throws IllegalAccessException
{
throw new IllegalArgumentException();
}
public void setShort(Object obj, short val, boolean accessible) throws IllegalAccessException
{
throw new IllegalArgumentException();
}
public void setInt(Object obj, int val, boolean accessible) throws IllegalAccessException
{
throw new IllegalArgumentException();
}
public void setFloat(Object obj, float val, boolean accessible) throws IllegalAccessException
{
throw new IllegalArgumentException();
}
public void setLong(Object obj, long val, boolean accessible) throws IllegalAccessException
{
throw new IllegalArgumentException();
}
public void setDouble(Object obj, double val, boolean accessible) throws IllegalAccessException
{
throw new IllegalArgumentException();
}
}
final class ObjectFieldImpl extends VMFieldImpl
{
ObjectFieldImpl(Class declaringClass, Object fieldCookie)
{
super(declaringClass, fieldCookie);
}
public Object get(Object obj)
{
return getImpl(obj);
}
public void set(Object obj, Object val, boolean accessible) throws IllegalAccessException
{
setImpl(obj, val, accessible);
}
}
final class BooleanFieldImpl extends VMFieldImpl
{
BooleanFieldImpl(Class declaringClass, Object fieldCookie)
{
super(declaringClass, fieldCookie);
}
public Object get(Object obj)
{
return getBoolean(obj) ? Boolean.TRUE : Boolean.FALSE;
}
public boolean getBoolean(Object obj)
{
return CIL.unbox_boolean(getImpl(obj));
}
public void set(Object obj, Object val, boolean accessible) throws IllegalAccessException
{
if(! (val instanceof Boolean))
throw new IllegalArgumentException();
setBoolean(obj, ((Boolean)val).booleanValue(), accessible);
}
public void setBoolean(Object obj, boolean val, boolean accessible) throws IllegalAccessException
{
setImpl(obj, CIL.box_boolean(val), accessible);
}
}
final class ByteFieldImpl extends VMFieldImpl
{
ByteFieldImpl(Class declaringClass, Object fieldCookie)
{
super(declaringClass, fieldCookie);
}
public Object get(Object obj)
{
return new Byte(getByte(obj));
}
public byte getByte(Object obj)
{
return CIL.unbox_byte(getImpl(obj));
}
public short getShort(Object obj)
{
return getByte(obj);
}
public int getInt(Object obj)
{
return getByte(obj);
}
public float getFloat(Object obj)
{
return getByte(obj);
}
public long getLong(Object obj)
{
return getByte(obj);
}
public double getDouble(Object obj)
{
return getByte(obj);
}
public void set(Object obj, Object val, boolean accessible) throws IllegalAccessException
{
if(! (val instanceof Byte))
throw new IllegalArgumentException();
setByte(obj, ((Byte)val).byteValue(), accessible);
}
public void setByte(Object obj, byte val, boolean accessible) throws IllegalAccessException
{
setImpl(obj, CIL.box_byte(val), accessible);
}
}
final class CharFieldImpl extends VMFieldImpl
{
CharFieldImpl(Class declaringClass, Object fieldCookie)
{
super(declaringClass, fieldCookie);
}
public Object get(Object obj)
{
return new Character(getChar(obj));
}
public char getChar(Object obj)
{
return CIL.unbox_char(getImpl(obj));
}
public int getInt(Object obj)
{
return getChar(obj);
}
public float getFloat(Object obj)
{
return getChar(obj);
}
public long getLong(Object obj)
{
return getChar(obj);
}
public double getDouble(Object obj)
{
return getChar(obj);
}
public void set(Object obj, Object val, boolean accessible) throws IllegalAccessException
{
if(! (val instanceof Character))
throw new IllegalArgumentException();
setChar(obj, ((Character)val).charValue(), accessible);
}
public void setChar(Object obj, char val, boolean accessible) throws IllegalAccessException
{
setImpl(obj, CIL.box_char(val), accessible);
}
}
final class ShortFieldImpl extends VMFieldImpl
{
ShortFieldImpl(Class declaringClass, Object fieldCookie)
{
super(declaringClass, fieldCookie);
}
public Object get(Object obj)
{
return new Short(getShort(obj));
}
public short getShort(Object obj)
{
return CIL.unbox_short(getImpl(obj));
}
public int getInt(Object obj)
{
return getShort(obj);
}
public float getFloat(Object obj)
{
return getShort(obj);
}
public long getLong(Object obj)
{
return getShort(obj);
}
public double getDouble(Object obj)
{
return getShort(obj);
}
public void set(Object obj, Object val, boolean accessible) throws IllegalAccessException
{
if(! (val instanceof Short
|| val instanceof Byte))
throw new IllegalArgumentException();
setShort(obj, ((Number)val).shortValue(), accessible);
}
public void setShort(Object obj, short val, boolean accessible) throws IllegalAccessException
{
setImpl(obj, CIL.box_short(val), accessible);
}
public void setByte(Object obj, byte val, boolean accessible) throws IllegalAccessException
{
setShort(obj, val, accessible);
}
}
final class IntFieldImpl extends VMFieldImpl
{
IntFieldImpl(Class declaringClass, Object fieldCookie)
{
super(declaringClass, fieldCookie);
}
public Object get(Object obj)
{
return new Integer(getInt(obj));
}
public int getInt(Object obj)
{
return CIL.unbox_int(getImpl(obj));
}
public float getFloat(Object obj)
{
return getInt(obj);
}
public long getLong(Object obj)
{
return getInt(obj);
}
public double getDouble(Object obj)
{
return getInt(obj);
}
public void set(Object obj, Object val, boolean accessible) throws IllegalAccessException
{
if (val instanceof Integer
|| val instanceof Byte
|| val instanceof Short)
setInt(obj, ((Number)val).intValue(), accessible);
else if (val instanceof Character)
setInt(obj, ((Character)val).charValue(), accessible);
else
throw new IllegalArgumentException();
}
public void setInt(Object obj, int val, boolean accessible) throws IllegalAccessException
{
setImpl(obj, CIL.box_int(val), accessible);
}
public void setByte(Object obj, byte val, boolean accessible) throws IllegalAccessException
{
setInt(obj, val, accessible);
}
public void setChar(Object obj, char val, boolean accessible) throws IllegalAccessException
{
setInt(obj, val, accessible);
}
public void setShort(Object obj, short val, boolean accessible) throws IllegalAccessException
{
setInt(obj, val, accessible);
}
}
final class FloatFieldImpl extends VMFieldImpl
{
FloatFieldImpl(Class declaringClass, Object fieldCookie)
{
super(declaringClass, fieldCookie);
}
public Object get(Object obj)
{
return new Float(getFloat(obj));
}
public float getFloat(Object obj)
{
return CIL.unbox_float(getImpl(obj));
}
public double getDouble(Object obj)
{
return getFloat(obj);
}
public void set(Object obj, Object val, boolean accessible) throws IllegalAccessException
{
if (val instanceof Float
|| val instanceof Byte
|| val instanceof Short
|| val instanceof Integer
|| val instanceof Long)
setFloat(obj, ((Number)val).floatValue(), accessible);
else if (val instanceof Character)
setFloat(obj, ((Character)val).charValue(), accessible);
else
throw new IllegalArgumentException();
}
public void setFloat(Object obj, float val, boolean accessible) throws IllegalAccessException
{
setImpl(obj, CIL.box_float(val), accessible);
}
public void setByte(Object obj, byte val, boolean accessible) throws IllegalAccessException
{
setFloat(obj, val, accessible);
}
public void setChar(Object obj, char val, boolean accessible) throws IllegalAccessException
{
setFloat(obj, val, accessible);
}
public void setShort(Object obj, short val, boolean accessible) throws IllegalAccessException
{
setFloat(obj, val, accessible);
}
public void setInt(Object obj, int val, boolean accessible) throws IllegalAccessException
{
setFloat(obj, val, accessible);
}
public void setLong(Object obj, long val, boolean accessible) throws IllegalAccessException
{
setFloat(obj, val, accessible);
}
}
final class LongFieldImpl extends VMFieldImpl
{
LongFieldImpl(Class declaringClass, Object fieldCookie)
{
super(declaringClass, fieldCookie);
}
public Object get(Object obj)
{
return new Long(getLong(obj));
}
public long getLong(Object obj)
{
return CIL.unbox_long(getImpl(obj));
}
public float getFloat(Object obj)
{
return getLong(obj);
}
public double getDouble(Object obj)
{
return getLong(obj);
}
public void set(Object obj, Object val, boolean accessible) throws IllegalAccessException
{
if (val instanceof Long
|| val instanceof Byte
|| val instanceof Short
|| val instanceof Integer)
setLong(obj, ((Number)val).longValue(), accessible);
else if (val instanceof Character)
setLong(obj, ((Character)val).charValue(), accessible);
else
throw new IllegalArgumentException();
}
public void setLong(Object obj, long val, boolean accessible) throws IllegalAccessException
{
setImpl(obj, CIL.box_long(val), accessible);
}
public void setByte(Object obj, byte val, boolean accessible) throws IllegalAccessException
{
setLong(obj, val, accessible);
}
public void setChar(Object obj, char val, boolean accessible) throws IllegalAccessException
{
setLong(obj, val, accessible);
}
public void setShort(Object obj, short val, boolean accessible) throws IllegalAccessException
{
setLong(obj, val, accessible);
}
public void setInt(Object obj, int val, boolean accessible) throws IllegalAccessException
{
setLong(obj, val, accessible);
}
}
final class DoubleFieldImpl extends VMFieldImpl
{
DoubleFieldImpl(Class declaringClass, Object fieldCookie)
{
super(declaringClass, fieldCookie);
}
public Object get(Object obj)
{
return new Double(getDouble(obj));
}
public double getDouble(Object obj)
{
return CIL.unbox_double(getImpl(obj));
}
public void set(Object obj, Object val, boolean accessible) throws IllegalAccessException
{
if (val instanceof Double
|| val instanceof Byte
|| val instanceof Short
|| val instanceof Integer
|| val instanceof Float
|| val instanceof Long)
setDouble(obj, ((Number)val).doubleValue(), accessible);
else if (val instanceof Character)
setDouble(obj, ((Character)val).charValue(), accessible);
else
throw new IllegalArgumentException();
}
public void setDouble(Object obj, double val, boolean accessible) throws IllegalAccessException
{
setImpl(obj, CIL.box_double(val), accessible);
}
public void setByte(Object obj, byte val, boolean accessible) throws IllegalAccessException
{
setDouble(obj, val, accessible);
}
public void setChar(Object obj, char val, boolean accessible) throws IllegalAccessException
{
setDouble(obj, val, accessible);
}
public void setShort(Object obj, short val, boolean accessible) throws IllegalAccessException
{
setDouble(obj, val, accessible);
}
public void setInt(Object obj, int val, boolean accessible) throws IllegalAccessException
{
setDouble(obj, val, accessible);
}
public void setFloat(Object obj, float val, boolean accessible) throws IllegalAccessException
{
setDouble(obj, val, accessible);
}
public void setLong(Object obj, long val, boolean accessible) throws IllegalAccessException
{
setDouble(obj, val, accessible);
}
}

Просмотреть файл

@ -841,7 +841,7 @@
<body>
<ldarg_0 />
<ldarg_1 />
<newobj class="java.lang.reflect.Field" name="&lt;init&gt;" sig="(Ljava.lang.Class;Ljava.lang.Object;)V" />
<call class="java.lang.reflect.VMFieldImpl" name="newField" sig="(Ljava.lang.Class;Ljava.lang.Object;)Ljava.lang.reflect.Field;" />
<ret />
</body>
</method>
@ -876,7 +876,8 @@
<method name="getWrapperFromField" sig="(Ljava.lang.reflect.Field;)Ljava.lang.Object;">
<body>
<ldarg_0 />
<ldfld class="java.lang.reflect.Field" name="fieldCookie" sig="Ljava.lang.Object;" />
<ldfld class="java.lang.reflect.Field" name="impl" sig="Lgnu.java.lang.reflect.VMField;" />
<ldfld class="gnu.java.lang.reflect.VMField" name="fieldCookie" sig="Ljava.lang.Object;" />
<ret />
</body>
</method>

Просмотреть файл

@ -433,7 +433,7 @@ class ClassLoaderWrapper
{
// since this type was compiled from Java source, we have to look for our
// attributes
wrapper = new CompiledTypeWrapper(name, type);
wrapper = CompiledTypeWrapper.newInstance(name, type);
}
else
{
@ -1012,7 +1012,7 @@ class ClassLoaderWrapper
internal static void PublishLibraryImplementationHelperType(Type type)
{
CompiledTypeWrapper typeWrapper = new CompiledTypeWrapper(type.FullName, type);
CompiledTypeWrapper typeWrapper = CompiledTypeWrapper.newInstance(type.FullName, type);
SetWrapperForType(type, typeWrapper);
GetBootstrapClassLoader().types[type.FullName] = typeWrapper;
}

Просмотреть файл

@ -37,7 +37,8 @@ enum MemberFlags : short
{
None = 0,
HideFromReflection = 1,
ExplicitOverride = 2
ExplicitOverride = 2,
LiteralField = 4
}
class MemberWrapper
@ -47,11 +48,6 @@ class MemberWrapper
private Modifiers modifiers;
private MemberFlags flags;
protected MemberWrapper(TypeWrapper declaringType, Modifiers modifiers, bool hideFromReflection)
: this(declaringType, modifiers, hideFromReflection ? MemberFlags.HideFromReflection : MemberFlags.None)
{
}
protected MemberWrapper(TypeWrapper declaringType, Modifiers modifiers, MemberFlags flags)
{
Debug.Assert(declaringType != null);
@ -121,6 +117,19 @@ class MemberWrapper
}
}
internal bool IsLiteralField
{
get
{
return (flags & MemberFlags.LiteralField) != 0;
}
set
{
flags &= ~MemberFlags.LiteralField;
flags |= value ? MemberFlags.LiteralField : MemberFlags.None;
}
}
internal Modifiers Modifiers
{
get
@ -1049,7 +1058,7 @@ abstract class FieldWrapper : MemberWrapper
private TypeWrapper fieldType;
internal FieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, string name, string sig, Modifiers modifiers, FieldInfo field)
: base(declaringType, modifiers, false)
: base(declaringType, modifiers, field != null && field.IsLiteral ? MemberFlags.LiteralField : MemberFlags.None)
{
Debug.Assert(name != null);
Debug.Assert(sig != null);
@ -1214,6 +1223,7 @@ abstract class FieldWrapper : MemberWrapper
}
// TODO instead of looking up the field by name, we should use the Token to find it.
field = DeclaringType.TypeAsTBD.GetField(name, bindings);
this.IsLiteralField = field.IsLiteral;
Debug.Assert(field != null);
}
@ -1249,10 +1259,13 @@ abstract class FieldWrapper : MemberWrapper
{
LookupField();
}
if(field.IsLiteral)
// FieldInfo.IsLiteral is expensive, so we have our own flag
// TODO we might be able to ensure that we always use ConstantFieldWrapper for literal fields,
// in that case the we could simply remove the check altogether.
if(IsLiteralField)
{
// on a non-broken CLR GetValue on a literal will not trigger type initialization, but on Java it should
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(field.DeclaringType.TypeHandle);
DeclaringType.RunClassInit();
}
object val = field.GetValue(obj);
if(fieldType.IsGhost)

Просмотреть файл

@ -3503,7 +3503,7 @@ sealed class DynamicTypeWrapper : TypeWrapper
// because the ClassLoaderWrapper assumes that all dynamic types are in its hashtable,
// but note that this only registers it for reverse lookup (from Type -> TypeWrapper), this
// is necessary to make stack walking work.
ClassLoaderWrapper.SetWrapperForType(type, new CompiledTypeWrapper(type.FullName, type));
ClassLoaderWrapper.SetWrapperForType(type, CompiledTypeWrapper.newInstance(type.FullName, type));
}
}
@ -4477,14 +4477,188 @@ sealed class DynamicTypeWrapper : TypeWrapper
}
}
sealed class CompiledTypeWrapper : TypeWrapper
class CompiledTypeWrapper : TypeWrapper
{
private readonly Type type;
private TypeWrapper[] interfaces;
private TypeWrapper[] innerclasses;
private FieldInfo ghostRefField;
private Type typeAsBaseType;
private Type remappedType;
internal static CompiledTypeWrapper newInstance(string name, Type type)
{
// TODO since ghost and remapped types can only exist in the core library assembly, we probably
// should be able to remove the Type.IsDefined() tests in most cases
if(type.IsValueType && type.IsDefined(typeof(GhostInterfaceAttribute), false))
{
return new CompiledGhostTypeWrapper(name, type);
}
else if(type.IsDefined(typeof(RemappedTypeAttribute), false))
{
return new CompiledRemappedTypeWrapper(name, type);
}
else
{
return new CompiledTypeWrapper(name, type);
}
}
private sealed class CompiledRemappedTypeWrapper : CompiledTypeWrapper
{
private readonly Type remappedType;
internal CompiledRemappedTypeWrapper(string name, Type type)
: base(name, type)
{
object[] attribs = type.GetCustomAttributes(typeof(RemappedTypeAttribute), false);
if(attribs.Length != 1)
{
throw new InvalidOperationException();
}
remappedType = ((RemappedTypeAttribute)attribs[0]).Type;
}
internal override Type TypeAsTBD
{
get
{
return remappedType;
}
}
internal override bool IsRemapped
{
get
{
return true;
}
}
protected override void LazyPublishMembers()
{
ArrayList methods = new ArrayList();
ArrayList fields = new ArrayList();
MemberInfo[] members = type.GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
foreach(MemberInfo m in members)
{
if(!AttributeHelper.IsHideFromJava(m))
{
MethodBase method = m as MethodBase;
if(method != null &&
(remappedType.IsSealed || !m.Name.StartsWith("instancehelper_")) &&
(!remappedType.IsSealed || method.IsStatic))
{
methods.Add(CreateRemappedMethodWrapper(method));
}
else
{
FieldInfo field = m as FieldInfo;
if(field != null)
{
fields.Add(CreateFieldWrapper(field));
}
}
}
}
// if we're a remapped interface, we need to get the methods from the real interface
if(remappedType.IsInterface)
{
Type nestedHelper = type.GetNestedType("__Helper", BindingFlags.Public | BindingFlags.Static);
foreach(RemappedInterfaceMethodAttribute m in type.GetCustomAttributes(typeof(RemappedInterfaceMethodAttribute), false))
{
MethodInfo method = remappedType.GetMethod(m.MappedTo);
MethodInfo mbHelper = method;
Modifiers modifiers = AttributeHelper.GetModifiers(method, false);
string name;
string sig;
TypeWrapper retType;
TypeWrapper[] paramTypes;
GetNameSigFromMethodBase(method, out name, out sig, out retType, out paramTypes);
if(nestedHelper != null)
{
mbHelper = nestedHelper.GetMethod(m.Name);
if(mbHelper == null)
{
mbHelper = method;
}
}
methods.Add(new CompiledRemappedMethodWrapper(this, m.Name, sig, method, retType, paramTypes, modifiers, false, mbHelper, null));
}
}
SetMethods((MethodWrapper[])methods.ToArray(typeof(MethodWrapper)));
SetFields((FieldWrapper[])fields.ToArray(typeof(FieldWrapper)));
}
private MethodWrapper CreateRemappedMethodWrapper(MethodBase mb)
{
Modifiers modifiers = AttributeHelper.GetModifiers(mb, false);
string name;
string sig;
TypeWrapper retType;
TypeWrapper[] paramTypes;
GetNameSigFromMethodBase(mb, out name, out sig, out retType, out paramTypes);
MethodInfo mbHelper = mb as MethodInfo;
MethodInfo mbNonvirtualHelper = null;
if(!mb.IsStatic && !mb.IsConstructor)
{
ParameterInfo[] parameters = mb.GetParameters();
Type[] argTypes = new Type[parameters.Length + 1];
argTypes[0] = remappedType;
for(int i = 0; i < parameters.Length; i++)
{
argTypes[i + 1] = parameters[i].ParameterType;
}
MethodInfo helper = type.GetMethod("instancehelper_" + mb.Name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, null, argTypes, null);
if(helper != null)
{
mbHelper = helper;
}
mbNonvirtualHelper = type.GetMethod("nonvirtualhelper/" + mb.Name, BindingFlags.NonPublic | BindingFlags.Static, null, argTypes, null);
}
return new CompiledRemappedMethodWrapper(this, name, sig, mb, retType, paramTypes, modifiers, false, mbHelper, mbNonvirtualHelper);
}
}
private sealed class CompiledGhostTypeWrapper : CompiledTypeWrapper
{
private FieldInfo ghostRefField;
private Type typeAsBaseType;
internal CompiledGhostTypeWrapper(string name, Type type)
: base(name, type)
{
}
internal override Type TypeAsBaseType
{
get
{
if(typeAsBaseType == null)
{
typeAsBaseType = type.GetNestedType("__Interface");
}
return typeAsBaseType;
}
}
internal override FieldInfo GhostRefField
{
get
{
if(ghostRefField == null)
{
ghostRefField = type.GetField("__<ref>");
}
return ghostRefField;
}
}
internal override bool IsGhost
{
get
{
return true;
}
}
}
internal static string GetName(Type type)
{
@ -4534,19 +4708,12 @@ sealed class CompiledTypeWrapper : TypeWrapper
return ClassLoaderWrapper.IsCoreAssemblyType(type) ? ClassLoaderWrapper.GetBootstrapClassLoader() : ClassLoaderWrapper.GetSystemClassLoader();
}
internal CompiledTypeWrapper(string name, Type type)
private CompiledTypeWrapper(string name, Type type)
: base(GetModifiers(type), name, GetBaseTypeWrapper(type), GetClassLoader(type), null)
{
Debug.Assert(!(type is TypeBuilder));
Debug.Assert(!type.IsArray);
object[] attribs = type.GetCustomAttributes(typeof(RemappedTypeAttribute), false);
if(attribs.Length == 1)
{
this.typeAsBaseType = type;
this.remappedType = ((RemappedTypeAttribute)attribs[0]).Type;
}
this.type = type;
}
@ -4647,6 +4814,7 @@ sealed class CompiledTypeWrapper : TypeWrapper
{
get
{
// TODO why are we caching this?
if(innerclasses == null)
{
Type[] nestedTypes = type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
@ -4694,30 +4862,7 @@ sealed class CompiledTypeWrapper : TypeWrapper
{
get
{
if(typeAsBaseType == null)
{
if(IsGhost)
{
typeAsBaseType = type.GetNestedType("__Interface");
}
else
{
typeAsBaseType = type;
}
}
return typeAsBaseType;
}
}
internal override FieldInfo GhostRefField
{
get
{
if(ghostRefField == null)
{
ghostRefField = type.GetField("__<ref>");
}
return ghostRefField;
return type;
}
}
@ -4850,81 +4995,29 @@ sealed class CompiledTypeWrapper : TypeWrapper
ArrayList methods = new ArrayList();
ArrayList fields = new ArrayList();
MemberInfo[] members = type.GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
if(remappedType == null)
foreach(MemberInfo m in members)
{
foreach(MemberInfo m in members)
if(!AttributeHelper.IsHideFromJava(m))
{
if(!AttributeHelper.IsHideFromJava(m))
MethodBase method = m as MethodBase;
if(method != null)
{
MethodBase method = m as MethodBase;
if(method != null)
{
string name;
string sig;
TypeWrapper retType;
TypeWrapper[] paramTypes;
GetNameSigFromMethodBase(method, out name, out sig, out retType, out paramTypes);
MethodInfo mi = method as MethodInfo;
bool miranda = mi != null ? AttributeHelper.IsMirandaMethod(mi) : false;
methods.Add(MethodWrapper.Create(this, name, sig, method, retType, paramTypes, AttributeHelper.GetModifiers(method, false), miranda));
}
else
{
FieldInfo field = m as FieldInfo;
if(field != null)
{
fields.Add(CreateFieldWrapper(field));
}
}
}
}
}
else
{
foreach(MemberInfo m in members)
{
if(!AttributeHelper.IsHideFromJava(m))
{
MethodBase method = m as MethodBase;
if(method != null &&
(remappedType.IsSealed || !m.Name.StartsWith("instancehelper_")) &&
(!remappedType.IsSealed || method.IsStatic))
{
methods.Add(CreateRemappedMethodWrapper(method));
}
else
{
FieldInfo field = m as FieldInfo;
if(field != null)
{
fields.Add(CreateFieldWrapper(field));
}
}
}
}
// if we're a remapped interface, we need to get the methods from the real interface
if(remappedType.IsInterface)
{
Type nestedHelper = type.GetNestedType("__Helper", BindingFlags.Public | BindingFlags.Static);
foreach(RemappedInterfaceMethodAttribute m in type.GetCustomAttributes(typeof(RemappedInterfaceMethodAttribute), false))
{
MethodInfo method = remappedType.GetMethod(m.MappedTo);
MethodInfo mbHelper = method;
Modifiers modifiers = AttributeHelper.GetModifiers(method, false);
string name;
string sig;
TypeWrapper retType;
TypeWrapper[] paramTypes;
GetNameSigFromMethodBase(method, out name, out sig, out retType, out paramTypes);
if(nestedHelper != null)
MethodInfo mi = method as MethodInfo;
bool miranda = mi != null ? AttributeHelper.IsMirandaMethod(mi) : false;
methods.Add(MethodWrapper.Create(this, name, sig, method, retType, paramTypes, AttributeHelper.GetModifiers(method, false), miranda));
}
else
{
FieldInfo field = m as FieldInfo;
if(field != null)
{
mbHelper = nestedHelper.GetMethod(m.Name);
if(mbHelper == null)
{
mbHelper = method;
}
fields.Add(CreateFieldWrapper(field));
}
methods.Add(new CompiledRemappedMethodWrapper(this, m.Name, sig, method, retType, paramTypes, modifiers, false, mbHelper, null));
}
}
}
@ -5010,35 +5103,6 @@ sealed class CompiledTypeWrapper : TypeWrapper
}
}
private MethodWrapper CreateRemappedMethodWrapper(MethodBase mb)
{
Modifiers modifiers = AttributeHelper.GetModifiers(mb, false);
string name;
string sig;
TypeWrapper retType;
TypeWrapper[] paramTypes;
GetNameSigFromMethodBase(mb, out name, out sig, out retType, out paramTypes);
MethodInfo mbHelper = mb as MethodInfo;
MethodInfo mbNonvirtualHelper = null;
if(!mb.IsStatic && !mb.IsConstructor)
{
ParameterInfo[] parameters = mb.GetParameters();
Type[] argTypes = new Type[parameters.Length + 1];
argTypes[0] = remappedType;
for(int i = 0; i < parameters.Length; i++)
{
argTypes[i + 1] = parameters[i].ParameterType;
}
MethodInfo helper = type.GetMethod("instancehelper_" + mb.Name, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, null, argTypes, null);
if(helper != null)
{
mbHelper = helper;
}
mbNonvirtualHelper = type.GetMethod("nonvirtualhelper/" + mb.Name, BindingFlags.NonPublic | BindingFlags.Static, null, argTypes, null);
}
return new CompiledRemappedMethodWrapper(this, name, sig, mb, retType, paramTypes, modifiers, false, mbHelper, mbNonvirtualHelper);
}
private FieldWrapper CreateFieldWrapper(FieldInfo field)
{
Modifiers modifiers = AttributeHelper.GetModifiers(field, false);
@ -5071,27 +5135,11 @@ sealed class CompiledTypeWrapper : TypeWrapper
}
}
internal override bool IsGhost
{
get
{
return type.IsDefined(typeof(GhostInterfaceAttribute), false);
}
}
internal override bool IsRemapped
{
get
{
return remappedType != null;
}
}
internal override Type TypeAsTBD
{
get
{
return remappedType != null ? remappedType : type;
return type;
}
}
@ -5250,7 +5298,7 @@ sealed class DotNetTypeWrapper : TypeWrapper
TypeBuilder typeBuilder = moduleBuilder.DefineType(NamePrefix + name, TypeAttributes.Public | TypeAttributes.Interface | TypeAttributes.Abstract);
AttributeHelper.SetInnerClass(typeBuilder, NamePrefix + name, NamePrefix + delegateType.FullName, "Method", Modifiers.Public | Modifiers.Interface | Modifiers.Static | Modifiers.Abstract);
typeBuilder.DefineMethod("Invoke", MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual, CallingConventions.Standard, invoke.ReturnType, args);
return new CompiledTypeWrapper(NamePrefix + name, typeBuilder.CreateType());
return CompiledTypeWrapper.newInstance(NamePrefix + name, typeBuilder.CreateType());
}
}
return null;

Просмотреть файл

@ -188,7 +188,7 @@ namespace IKVM.NativeCode.java
}
}
public class Field
public class VMFieldImpl
{
public static string GetName(object fieldCookie)
{
@ -215,6 +215,11 @@ namespace IKVM.NativeCode.java
return VMClass.getWrapperFromClass(a).IsInSamePackageAs(VMClass.getWrapperFromClass(b));
}
public static void RunClassInit(object clazz)
{
VMClass.getWrapperFromClass(clazz).RunClassInit();
}
public static object GetValue(object fieldCookie, object o)
{
Profiler.Enter("Field.GetValue");
@ -235,24 +240,12 @@ namespace IKVM.NativeCode.java
}
}
public static void SetValue(object fieldCookie, object o, object v, bool accessible)
public static void SetValue(object fieldCookie, object o, object v)
{
Profiler.Enter("Field.SetValue");
try
{
FieldWrapper wrapper = (FieldWrapper)fieldCookie;
if(wrapper.IsFinal)
{
// NOTE Java runs the class initializer when trying to set a final field
wrapper.DeclaringType.RunClassInit();
// Starting with JDK 1.5, it is legal to change final instance fields
// (see JSR-133)
if(wrapper.IsStatic || !accessible)
{
// NOTE even if the caller is the class itself, it still isn't legal
throw JavaException.IllegalAccessException("Field is final");
}
}
// if the field is an interface field, we must explicitly run <clinit>,
// because .NET reflection doesn't
if(wrapper.DeclaringType.IsInterface)