зеркало из https://github.com/mono/ikvm-fork.git
*** empty log message ***
This commit is contained in:
Родитель
36f04bac56
Коммит
446440498b
|
@ -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="<init>" 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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче