зеркало из https://github.com/mono/ikvm-fork.git
*** empty log message ***
This commit is contained in:
Родитель
0ad640b8c6
Коммит
cb926ea086
|
@ -630,6 +630,7 @@
|
|||
../../classpath/gnu/java/rmi/registry/RegistryImpl_Stub.java
|
||||
../../classpath/gnu/java/rmi/RMIMarshalledObjectInputStream.java
|
||||
../../classpath/gnu/java/rmi/RMIMarshalledObjectOutputStream.java
|
||||
../../classpath/gnu/java/rmi/server/ActivatableRef.java
|
||||
../../classpath/gnu/java/rmi/server/ActivatableServerRef.java
|
||||
../../classpath/gnu/java/rmi/server/CombinedClassLoader.java
|
||||
../../classpath/gnu/java/rmi/server/ConnectionRunnerPool.java
|
||||
|
@ -2884,6 +2885,7 @@
|
|||
../../classpath/javax/imageio/metadata/IIOMetadataNode.java
|
||||
../../classpath/javax/imageio/plugins/bmp/BMPImageWriteParam.java
|
||||
../../classpath/javax/imageio/plugins/jpeg/JPEGHuffmanTable.java
|
||||
../../classpath/javax/imageio/plugins/jpeg/JPEGQTable.java
|
||||
../../classpath/javax/imageio/spi/IIORegistry.java
|
||||
../../classpath/javax/imageio/spi/IIOServiceProvider.java
|
||||
../../classpath/javax/imageio/spi/ImageInputStreamSpi.java
|
||||
|
@ -3866,6 +3868,7 @@
|
|||
../../classpath/javax/xml/transform/URIResolver.java
|
||||
../../classpath/javax/xml/validation/Schema.java
|
||||
../../classpath/javax/xml/validation/SchemaFactory.java
|
||||
../../classpath/javax/xml/validation/SchemaFactoryLoader.java
|
||||
../../classpath/javax/xml/validation/TypeInfoProvider.java
|
||||
../../classpath/javax/xml/validation/Validator.java
|
||||
../../classpath/javax/xml/validation/ValidatorHandler.java
|
||||
|
@ -4449,6 +4452,7 @@ gnu/java/nio/VMPipe.java
|
|||
ikvm/internal/AnnotationAttributeBase.java
|
||||
ikvm/internal/Library.java
|
||||
ikvm/internal/LibraryVMInterface.java
|
||||
ikvm/internal/WeakIdentityMap.java
|
||||
ikvm/io/InputStreamWrapper.java
|
||||
ikvm/lang/CIL.java
|
||||
ikvm/lang/Internal.java
|
||||
|
|
|
@ -58,7 +58,6 @@ public abstract class VMField
|
|||
}
|
||||
|
||||
public abstract Field newField();
|
||||
public abstract void checkAccess(Object o, Class caller) throws IllegalAccessException;
|
||||
public abstract String getName();
|
||||
public abstract Class getType();
|
||||
public abstract String getSignature();
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
Copyright (C) 2006 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 ikvm.internal;
|
||||
|
||||
import cli.System.GC;
|
||||
import cli.System.WeakReference;
|
||||
|
||||
@ikvm.lang.Internal
|
||||
public final class WeakIdentityMap
|
||||
{
|
||||
private WeakReference[] keys = new WeakReference[16];
|
||||
private Object[] values = new Object[keys.length];
|
||||
|
||||
public WeakIdentityMap()
|
||||
{
|
||||
for (int i = 0; i < keys.length; i++)
|
||||
{
|
||||
keys[i] = new WeakReference(null, true);
|
||||
// NOTE we suppress finalization, to make sure the WeakReference continues to work
|
||||
// while the AppDomain is finalizing for unload
|
||||
GC.SuppressFinalize(keys[i]);
|
||||
}
|
||||
}
|
||||
|
||||
protected void finalize()
|
||||
{
|
||||
for (int i = 0; i < keys.length; i++)
|
||||
{
|
||||
if (keys[i] != null)
|
||||
{
|
||||
GC.ReRegisterForFinalize(keys[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note that null values are supported, null keys are not
|
||||
public synchronized void put(Object key, Object value)
|
||||
{
|
||||
if (key == null)
|
||||
throw new NullPointerException();
|
||||
int emptySlot = -1;
|
||||
int keySlot = -1;
|
||||
for (int i = 0; i < keys.length; i++)
|
||||
{
|
||||
Object k = keys[i].get_Target();
|
||||
if (k == null)
|
||||
{
|
||||
emptySlot = i;
|
||||
values[i] = null;
|
||||
}
|
||||
else if (k == key)
|
||||
{
|
||||
keySlot = i;
|
||||
}
|
||||
}
|
||||
if (keySlot != -1)
|
||||
{
|
||||
values[keySlot] = value;
|
||||
}
|
||||
else if (emptySlot != -1)
|
||||
{
|
||||
keys[emptySlot].set_Target(key);
|
||||
values[emptySlot] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
int len = keys.length;
|
||||
WeakReference[] newkeys = new WeakReference[len * 2];
|
||||
Object[] newvalues = new Object[newkeys.length];
|
||||
cli.System.Array.Copy((cli.System.Array)(Object)keys, (cli.System.Array)(Object)newkeys, len);
|
||||
cli.System.Array.Copy((cli.System.Array)(Object)values, (cli.System.Array)(Object)newvalues, len);
|
||||
keys = newkeys;
|
||||
values = newvalues;
|
||||
for (int i = len; i < keys.length; i++)
|
||||
{
|
||||
keys[i] = new WeakReference(null, true);
|
||||
GC.SuppressFinalize(keys[i]);
|
||||
}
|
||||
keys[len].set_Target(key);
|
||||
values[len] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized Object get(Object key)
|
||||
{
|
||||
for (int i = 0; i < keys.length; i++)
|
||||
{
|
||||
if (keys[i].get_Target() == key)
|
||||
{
|
||||
return values[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public synchronized boolean containsKey(Object key)
|
||||
{
|
||||
for (int i = 0; i < keys.length; i++)
|
||||
{
|
||||
if (keys[i].get_Target() == key)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2003, 2004, 2005 Jeroen Frijters
|
||||
Copyright (C) 2003, 2004, 2005, 2006 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
|
||||
|
@ -33,7 +33,7 @@ final class ExceptionHelper
|
|||
// it will return that text as the Message property), but it *must* be a copy, because we need to be
|
||||
// able to distinguish it from a user specified blank string
|
||||
private static final String NULL_STRING = new String();
|
||||
private static final java.util.WeakHashMap exceptions = new java.util.WeakHashMap();
|
||||
private static final ikvm.internal.WeakIdentityMap exceptions = new ikvm.internal.WeakIdentityMap();
|
||||
private static final boolean cleanStackTrace = SafeGetEnvironmentVariable("IKVM_DISABLE_STACKTRACE_CLEANING") == null;
|
||||
private static cli.System.Type System_Reflection_MethodBase = cli.System.Type.GetType("System.Reflection.MethodBase, mscorlib");
|
||||
private static cli.System.Type System_Exception = cli.System.Type.GetType("System.Exception, mscorlib");
|
||||
|
@ -245,6 +245,7 @@ final class ExceptionHelper
|
|||
|| className.equals("cli.System.RuntimeMethodHandle")
|
||||
|| className.equals("java.lang.LibraryVMInterfaceImpl")
|
||||
|| (className.equals("java.lang.Throwable") && m.get_Name().equals("instancehelper_fillInStackTrace"))
|
||||
|| methodName.startsWith("__<")
|
||||
|| IsHideFromJava(m)
|
||||
|| IsPrivateScope(m))) // NOTE we assume that privatescope methods are always stubs that we should exclude
|
||||
{
|
||||
|
|
|
@ -27,15 +27,66 @@ import java.lang.annotation.Annotation;
|
|||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.VMFieldImpl;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import cli.System.Type;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
abstract class VMClass
|
||||
@ikvm.lang.Internal
|
||||
public abstract class VMClass
|
||||
{
|
||||
private VMClass() {}
|
||||
|
||||
public static Object getWrapper(Class c)
|
||||
{
|
||||
return c.vmdata;
|
||||
}
|
||||
|
||||
// this method is used by the map.xml implementation of Class.newInstance
|
||||
static boolean isPublic(Constructor c)
|
||||
{
|
||||
return Modifier.isPublic(c.getModifiers())
|
||||
&& Modifier.isPublic(GetModifiers(c.getDeclaringClass().vmdata, true));
|
||||
}
|
||||
|
||||
// this method is used by the map.xml implementation of Class.newInstance
|
||||
static void checkAccess(Constructor c, Class caller) throws IllegalAccessException
|
||||
{
|
||||
VMFieldImpl.checkAccess(c.methodCookie, null, caller);
|
||||
}
|
||||
|
||||
// this method is used by the map.xml implementation of Class.newInstance
|
||||
static Constructor getConstructor(Class c) throws InstantiationException
|
||||
{
|
||||
Constructor constructor = null;
|
||||
Constructor[] constructors = getDeclaredConstructors(c, false);
|
||||
for (int i = 0; i < constructors.length; i++)
|
||||
{
|
||||
if (constructors[i].getParameterTypes().length == 0)
|
||||
{
|
||||
constructor = constructors[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (constructor == null)
|
||||
throw new InstantiationException(c.getName());
|
||||
if (!Modifier.isPublic(constructor.getModifiers())
|
||||
|| !Modifier.isPublic(GetModifiers(c.vmdata, true)))
|
||||
{
|
||||
final Constructor finalConstructor = constructor;
|
||||
AccessController.doPrivileged(new PrivilegedAction()
|
||||
{
|
||||
public Object run()
|
||||
{
|
||||
finalConstructor.setAccessible(true);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
return constructor;
|
||||
}
|
||||
|
||||
static boolean isInstance(Class clazz, Object o)
|
||||
{
|
||||
return o != null && clazz.isAssignableFrom(o.getClass());
|
||||
|
|
|
@ -246,7 +246,9 @@ public final class Constructor
|
|||
{
|
||||
// 128 is a reasonable buffer initial size for constructor
|
||||
StringBuffer sb = new StringBuffer(128);
|
||||
Modifier.toString(getModifiers(), sb).append(' ');
|
||||
Modifier.toString(getModifiers(), sb);
|
||||
if (sb.length() > 0)
|
||||
sb.append(' ');
|
||||
sb.append(getDeclaringClass().getName()).append('(');
|
||||
Class[] c = getParameterTypes();
|
||||
if (c.length > 0)
|
||||
|
@ -301,7 +303,7 @@ public final class Constructor
|
|||
InvocationTargetException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
VMFieldImpl.checkAccess(modifiers, null, clazz, VMStackWalker.getCallingClass());
|
||||
VMFieldImpl.checkAccess(methodCookie, null, VMStackWalker.getCallingClass());
|
||||
int mods = clazz.getModifiers() | Method.GetRealModifiers(clazz);
|
||||
if(Modifier.isAbstract(mods) || Modifier.isInterface(mods))
|
||||
{
|
||||
|
|
|
@ -215,7 +215,9 @@ public final class Field
|
|||
{
|
||||
// 64 is a reasonable buffer initial size for field
|
||||
StringBuffer sb = new StringBuffer(64);
|
||||
Modifier.toString(getModifiers(), sb).append(' ');
|
||||
Modifier.toString(getModifiers(), sb);
|
||||
if (sb.length() > 0)
|
||||
sb.append(' ');
|
||||
sb.append(ClassHelper.getUserName(getType())).append(' ');
|
||||
sb.append(getDeclaringClass().getName()).append('.');
|
||||
sb.append(getName());
|
||||
|
@ -266,7 +268,7 @@ public final class Field
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(impl.needsAccessCheck(isAccessible()))
|
||||
impl.checkAccess(o, VMStackWalker.getCallingClass());
|
||||
VMFieldImpl.checkAccess(impl.fieldCookie, o, VMStackWalker.getCallingClass());
|
||||
return impl.get(o);
|
||||
}
|
||||
|
||||
|
@ -291,7 +293,7 @@ public final class Field
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(impl.needsAccessCheck(isAccessible()))
|
||||
impl.checkAccess(o, VMStackWalker.getCallingClass());
|
||||
VMFieldImpl.checkAccess(impl.fieldCookie, o, VMStackWalker.getCallingClass());
|
||||
return impl.getBoolean(o);
|
||||
}
|
||||
|
||||
|
@ -316,7 +318,7 @@ public final class Field
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(impl.needsAccessCheck(isAccessible()))
|
||||
impl.checkAccess(o, VMStackWalker.getCallingClass());
|
||||
VMFieldImpl.checkAccess(impl.fieldCookie, o, VMStackWalker.getCallingClass());
|
||||
return impl.getByte(o);
|
||||
}
|
||||
|
||||
|
@ -339,7 +341,7 @@ public final class Field
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(impl.needsAccessCheck(isAccessible()))
|
||||
impl.checkAccess(o, VMStackWalker.getCallingClass());
|
||||
VMFieldImpl.checkAccess(impl.fieldCookie, o, VMStackWalker.getCallingClass());
|
||||
return impl.getChar(o);
|
||||
}
|
||||
|
||||
|
@ -364,7 +366,7 @@ public final class Field
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(impl.needsAccessCheck(isAccessible()))
|
||||
impl.checkAccess(o, VMStackWalker.getCallingClass());
|
||||
VMFieldImpl.checkAccess(impl.fieldCookie, o, VMStackWalker.getCallingClass());
|
||||
return impl.getShort(o);
|
||||
}
|
||||
|
||||
|
@ -389,7 +391,7 @@ public final class Field
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(impl.needsAccessCheck(isAccessible()))
|
||||
impl.checkAccess(o, VMStackWalker.getCallingClass());
|
||||
VMFieldImpl.checkAccess(impl.fieldCookie, o, VMStackWalker.getCallingClass());
|
||||
return impl.getInt(o);
|
||||
}
|
||||
|
||||
|
@ -414,7 +416,7 @@ public final class Field
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(impl.needsAccessCheck(isAccessible()))
|
||||
impl.checkAccess(o, VMStackWalker.getCallingClass());
|
||||
VMFieldImpl.checkAccess(impl.fieldCookie, o, VMStackWalker.getCallingClass());
|
||||
return impl.getLong(o);
|
||||
}
|
||||
|
||||
|
@ -439,7 +441,7 @@ public final class Field
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(impl.needsAccessCheck(isAccessible()))
|
||||
impl.checkAccess(o, VMStackWalker.getCallingClass());
|
||||
VMFieldImpl.checkAccess(impl.fieldCookie, o, VMStackWalker.getCallingClass());
|
||||
return impl.getFloat(o);
|
||||
}
|
||||
|
||||
|
@ -465,7 +467,7 @@ public final class Field
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(impl.needsAccessCheck(isAccessible()))
|
||||
impl.checkAccess(o, VMStackWalker.getCallingClass());
|
||||
VMFieldImpl.checkAccess(impl.fieldCookie, o, VMStackWalker.getCallingClass());
|
||||
return impl.getDouble(o);
|
||||
}
|
||||
|
||||
|
@ -518,7 +520,7 @@ public final class Field
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(impl.needsAccessCheck(isAccessible()))
|
||||
impl.checkAccess(o, VMStackWalker.getCallingClass());
|
||||
VMFieldImpl.checkAccess(impl.fieldCookie, o, VMStackWalker.getCallingClass());
|
||||
impl.set(o, value, isAccessible());
|
||||
}
|
||||
|
||||
|
@ -543,7 +545,7 @@ public final class Field
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(impl.needsAccessCheck(isAccessible()))
|
||||
impl.checkAccess(o, VMStackWalker.getCallingClass());
|
||||
VMFieldImpl.checkAccess(impl.fieldCookie, o, VMStackWalker.getCallingClass());
|
||||
impl.setBoolean(o, value, isAccessible());
|
||||
}
|
||||
|
||||
|
@ -568,7 +570,7 @@ public final class Field
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(impl.needsAccessCheck(isAccessible()))
|
||||
impl.checkAccess(o, VMStackWalker.getCallingClass());
|
||||
VMFieldImpl.checkAccess(impl.fieldCookie, o, VMStackWalker.getCallingClass());
|
||||
impl.setByte(o, value, isAccessible());
|
||||
}
|
||||
|
||||
|
@ -593,7 +595,7 @@ public final class Field
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(impl.needsAccessCheck(isAccessible()))
|
||||
impl.checkAccess(o, VMStackWalker.getCallingClass());
|
||||
VMFieldImpl.checkAccess(impl.fieldCookie, o, VMStackWalker.getCallingClass());
|
||||
impl.setChar(o, value, isAccessible());
|
||||
}
|
||||
|
||||
|
@ -618,7 +620,7 @@ public final class Field
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(impl.needsAccessCheck(isAccessible()))
|
||||
impl.checkAccess(o, VMStackWalker.getCallingClass());
|
||||
VMFieldImpl.checkAccess(impl.fieldCookie, o, VMStackWalker.getCallingClass());
|
||||
impl.setShort(o, value, isAccessible());
|
||||
}
|
||||
|
||||
|
@ -643,7 +645,7 @@ public final class Field
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(impl.needsAccessCheck(isAccessible()))
|
||||
impl.checkAccess(o, VMStackWalker.getCallingClass());
|
||||
VMFieldImpl.checkAccess(impl.fieldCookie, o, VMStackWalker.getCallingClass());
|
||||
impl.setInt(o, value, isAccessible());
|
||||
}
|
||||
|
||||
|
@ -668,7 +670,7 @@ public final class Field
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(impl.needsAccessCheck(isAccessible()))
|
||||
impl.checkAccess(o, VMStackWalker.getCallingClass());
|
||||
VMFieldImpl.checkAccess(impl.fieldCookie, o, VMStackWalker.getCallingClass());
|
||||
impl.setLong(o, value, isAccessible());
|
||||
}
|
||||
|
||||
|
@ -693,7 +695,7 @@ public final class Field
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(impl.needsAccessCheck(isAccessible()))
|
||||
impl.checkAccess(o, VMStackWalker.getCallingClass());
|
||||
VMFieldImpl.checkAccess(impl.fieldCookie, o, VMStackWalker.getCallingClass());
|
||||
impl.setFloat(o, value, isAccessible());
|
||||
}
|
||||
|
||||
|
@ -718,7 +720,7 @@ public final class Field
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(impl.needsAccessCheck(isAccessible()))
|
||||
impl.checkAccess(o, VMStackWalker.getCallingClass());
|
||||
VMFieldImpl.checkAccess(impl.fieldCookie, o, VMStackWalker.getCallingClass());
|
||||
impl.setDouble(o, value, isAccessible());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -313,7 +313,9 @@ public final class Method
|
|||
{
|
||||
// 128 is a reasonable buffer initial size for constructor
|
||||
StringBuffer sb = new StringBuffer(128);
|
||||
Modifier.toString(getModifiers(), sb).append(' ');
|
||||
Modifier.toString(getModifiers(), sb);
|
||||
if (sb.length() > 0)
|
||||
sb.append(' ');
|
||||
sb.append(ClassHelper.getUserName(getReturnType())).append(' ');
|
||||
sb.append(getDeclaringClass().getName()).append('.');
|
||||
sb.append(getName()).append('(');
|
||||
|
@ -380,7 +382,7 @@ public final class Method
|
|||
throws IllegalAccessException, InvocationTargetException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
VMFieldImpl.checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||
VMFieldImpl.checkAccess(methodCookie, o, VMStackWalker.getCallingClass());
|
||||
if(!Modifier.isStatic(modifiers))
|
||||
{
|
||||
if(o == null)
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
*/
|
||||
package java.lang.reflect;
|
||||
|
||||
import cli.System.Diagnostics.StackFrame;
|
||||
import gnu.java.lang.reflect.VMField;
|
||||
import ikvm.lang.CIL;
|
||||
|
||||
|
@ -32,33 +31,22 @@ public 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 int GetModifiers(Object memberCookie);
|
||||
private static native Object GetDeclaringClass(Object memberCookie);
|
||||
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);
|
||||
private static native boolean CheckAccess(Object memberCookie, Object obj, Object callerTypeWrapper);
|
||||
|
||||
static void checkAccess(int modifiers, Object o, Class declaringClass, Class caller) throws IllegalAccessException
|
||||
public static void checkAccess(Object memberCookie, Object o, 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(!CheckAccess(memberCookie, o, caller == null ? null : VMClass.getWrapper(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() +
|
||||
Class declaringClass = (Class)GetDeclaringClass(memberCookie);
|
||||
int modifiers = GetModifiers(memberCookie);
|
||||
throw new IllegalAccessException((caller == null ? "Global or JNI function" : "Class " + caller.getName()) +
|
||||
" can not access a member of class " + declaringClass.getName() +
|
||||
" with modifiers \"" + Modifier.toString(modifiers & (Modifier.PRIVATE | Modifier.PROTECTED)) + "\"");
|
||||
}
|
||||
" with modifiers \"" + Modifier.toString(modifiers & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED)) + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,11 +87,6 @@ public abstract class VMFieldImpl extends VMField
|
|||
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);
|
||||
|
|
|
@ -968,6 +968,50 @@
|
|||
<ret />
|
||||
</body>
|
||||
</method>
|
||||
<method name="newInstance" sig="()Ljava.lang.Object;">
|
||||
<body>
|
||||
<ldarg_0 />
|
||||
<ldc_i4_0 />
|
||||
<call class="java.lang.Class" name="memberAccessCheck" sig="(I)V" />
|
||||
<ldarg_0 />
|
||||
<volatile />
|
||||
<ldfld class="java.lang.Class" name="constructor" sig="Ljava.lang.reflect.Constructor;" />
|
||||
<dup />
|
||||
<brtrue name="ok" />
|
||||
<pop />
|
||||
<ldarg_0 />
|
||||
<ldarg_0 />
|
||||
<call class="java.lang.VMClass" name="getConstructor" sig="(Ljava.lang.Class;)Ljava.lang.reflect.Constructor;" />
|
||||
<dup />
|
||||
<stloc name="constructor" class="java.lang.reflect.Constructor" />
|
||||
<volatile />
|
||||
<stfld class="java.lang.Class" name="constructor" sig="Ljava.lang.reflect.Constructor;" />
|
||||
<ldloc name="constructor" />
|
||||
<label name="ok" />
|
||||
<dup />
|
||||
<stloc name="constructor" class="java.lang.reflect.Constructor" />
|
||||
<call class="java.lang.VMClass" name="isPublic" sig="(Ljava.lang.reflect.Constructor;)Z" />
|
||||
<brtrue name="doit" />
|
||||
<ldloc name="constructor" />
|
||||
<call class="gnu.classpath.VMStackWalker" name="getCallingClass" sig="()Ljava.lang.Class;" />
|
||||
<call class="java.lang.VMClass" name="checkAccess" sig="(Ljava.lang.reflect.Constructor;Ljava.lang.Class;)V" />
|
||||
<label name="doit" />
|
||||
<exceptionBlock>
|
||||
<try>
|
||||
<ldloc name="constructor" />
|
||||
<ldnull />
|
||||
<callvirt class="java.lang.reflect.Constructor" name="newInstance" sig="([Ljava.lang.Object;)Ljava.lang.Object;" />
|
||||
<stloc name="retval" class="java.lang.Object" />
|
||||
</try>
|
||||
<catch class="java.lang.reflect.InvocationTargetException">
|
||||
<callvirt class="java.lang.reflect.InvocationTargetException" name="getTargetException" sig="()Ljava.lang.Throwable;" />
|
||||
<throw />
|
||||
</catch>
|
||||
</exceptionBlock>
|
||||
<ldloc name="retval" />
|
||||
<ret />
|
||||
</body>
|
||||
</method>
|
||||
</class>
|
||||
<!-- This is where the "native" helper methods start -->
|
||||
<class name="ikvm.lang.CIL">
|
||||
|
|
|
@ -24,6 +24,7 @@ gnu/java/nio/VMPipe.java
|
|||
ikvm/internal/AnnotationAttributeBase.java
|
||||
ikvm/internal/Library.java
|
||||
ikvm/internal/LibraryVMInterface.java
|
||||
ikvm/internal/WeakIdentityMap.java
|
||||
ikvm/io/InputStreamWrapper.java
|
||||
ikvm/lang/CIL.java
|
||||
ikvm/lang/Internal.java
|
||||
|
|
|
@ -132,6 +132,8 @@ class Compiler
|
|||
Console.Error.WriteLine(" -compressresources Compress resources");
|
||||
Console.Error.WriteLine(" -strictfinalfieldsemantics Don't allow final fields to be modified outside");
|
||||
Console.Error.WriteLine(" of initializer methods");
|
||||
Console.Error.WriteLine(" -privatepackage:<prefix> Mark all classes with a package name starting");
|
||||
Console.Error.WriteLine(" with <prefix> as internal to the assembly");
|
||||
return 1;
|
||||
}
|
||||
foreach(string s in arglist)
|
||||
|
@ -384,6 +386,21 @@ class Compiler
|
|||
{
|
||||
options.strictFinalFieldSemantics = true;
|
||||
}
|
||||
else if(s.StartsWith("-privatepackage:"))
|
||||
{
|
||||
string prefix = s.Substring(16);
|
||||
if(options.privatePackages == null)
|
||||
{
|
||||
options.privatePackages = new string[] { prefix };
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] temp = new string[options.privatePackages.Length + 1];
|
||||
Array.Copy(options.privatePackages, 0, temp, 0, options.privatePackages.Length);
|
||||
temp[temp.Length - 1] = prefix;
|
||||
options.privatePackages = temp;
|
||||
}
|
||||
}
|
||||
else if(s.StartsWith("-runtime:"))
|
||||
{
|
||||
// NOTE this is an undocumented option
|
||||
|
|
|
@ -429,6 +429,7 @@ namespace IKVM.Internal
|
|||
{
|
||||
if(annot[1].Equals("Likvm/lang/Internal;"))
|
||||
{
|
||||
this.access_flags &= ~Modifiers.AccessMask;
|
||||
flags |= FLAG_MASK_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
@ -994,6 +995,13 @@ namespace IKVM.Internal
|
|||
}
|
||||
}
|
||||
|
||||
// for use by ikvmc (to implement the -privatepackage option)
|
||||
internal void SetInternal()
|
||||
{
|
||||
access_flags &= ~Modifiers.AccessMask;
|
||||
flags |= FLAG_MASK_INTERNAL;
|
||||
}
|
||||
|
||||
internal struct InnerClass
|
||||
{
|
||||
internal ushort innerClass; // ConstantPoolItemClass
|
||||
|
@ -1961,6 +1969,7 @@ namespace IKVM.Internal
|
|||
{
|
||||
if(annot[1].Equals("Likvm/lang/Internal;"))
|
||||
{
|
||||
this.access_flags &= ~Modifiers.AccessMask;
|
||||
flags |= FLAG_MASK_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
@ -2102,6 +2111,7 @@ namespace IKVM.Internal
|
|||
{
|
||||
if(annot[1].Equals("Likvm/lang/Internal;"))
|
||||
{
|
||||
this.access_flags &= ~Modifiers.AccessMask;
|
||||
flags |= FLAG_MASK_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -166,6 +166,17 @@ namespace IKVM.Internal
|
|||
{
|
||||
f.RemoveUnusedFields();
|
||||
}
|
||||
if(f.IsPublic && options.privatePackages != null)
|
||||
{
|
||||
foreach(string p in options.privatePackages)
|
||||
{
|
||||
if(f.Name.StartsWith(p))
|
||||
{
|
||||
f.SetInternal();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
type = DefineClass(f, null);
|
||||
}
|
||||
}
|
||||
|
@ -421,7 +432,7 @@ namespace IKVM.Internal
|
|||
|
||||
if(baseIsSealed)
|
||||
{
|
||||
AttributeHelper.SetModifiers(typeBuilder, (Modifiers)c.Modifiers);
|
||||
AttributeHelper.SetModifiers(typeBuilder, (Modifiers)c.Modifiers, false);
|
||||
}
|
||||
|
||||
if(c.scope == IKVM.Internal.MapXml.Scope.Public)
|
||||
|
@ -459,16 +470,42 @@ namespace IKVM.Internal
|
|||
|
||||
if(c.Methods != null)
|
||||
{
|
||||
// TODO we should also add methods from our super classes (e.g. Throwable should have Object's methods)
|
||||
foreach(IKVM.Internal.MapXml.Method m in c.Methods)
|
||||
{
|
||||
methods.Add(new RemappedMethodWrapper(this, m, map));
|
||||
methods.Add(new RemappedMethodWrapper(this, m, map, false));
|
||||
}
|
||||
}
|
||||
// add methods from our super classes (e.g. Throwable should have Object's methods)
|
||||
if(!this.IsFinal && !this.IsInterface && this.BaseTypeWrapper != null)
|
||||
{
|
||||
foreach(MethodWrapper mw in BaseTypeWrapper.GetMethods())
|
||||
{
|
||||
RemappedMethodWrapper rmw = mw as RemappedMethodWrapper;
|
||||
if(rmw != null && (rmw.IsPublic || rmw.IsProtected))
|
||||
{
|
||||
if(!FindMethod(methods, rmw.Name, rmw.Signature))
|
||||
{
|
||||
methods.Add(new RemappedMethodWrapper(this, rmw.XmlMethod, map, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetMethods((MethodWrapper[])methods.ToArray(typeof(MethodWrapper)));
|
||||
}
|
||||
|
||||
private static bool FindMethod(ArrayList methods, string name, string sig)
|
||||
{
|
||||
foreach(MethodWrapper mw in methods)
|
||||
{
|
||||
if(mw.Name == name && mw.Signature == sig)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
abstract class RemappedMethodBaseWrapper : MethodWrapper
|
||||
{
|
||||
internal RemappedMethodBaseWrapper(RemapperTypeWrapper typeWrapper, string name, string sig, Modifiers modifiers)
|
||||
|
@ -541,7 +578,7 @@ namespace IKVM.Internal
|
|||
}
|
||||
}
|
||||
SetParameters(mbHelper, m.Params);
|
||||
AttributeHelper.SetModifiers(mbHelper, (Modifiers)m.Modifiers);
|
||||
AttributeHelper.SetModifiers(mbHelper, (Modifiers)m.Modifiers, false);
|
||||
AttributeHelper.SetNameSig(mbHelper, "<init>", m.Sig);
|
||||
AddDeclaredExceptions(mbHelper, m.throws);
|
||||
}
|
||||
|
@ -678,12 +715,22 @@ namespace IKVM.Internal
|
|||
private IKVM.Internal.MapXml.Root map;
|
||||
private MethodBuilder mbHelper;
|
||||
private ArrayList overriders = new ArrayList();
|
||||
private bool inherited;
|
||||
|
||||
internal RemappedMethodWrapper(RemapperTypeWrapper typeWrapper, IKVM.Internal.MapXml.Method m, IKVM.Internal.MapXml.Root map)
|
||||
internal RemappedMethodWrapper(RemapperTypeWrapper typeWrapper, IKVM.Internal.MapXml.Method m, IKVM.Internal.MapXml.Root map, bool inherited)
|
||||
: base(typeWrapper, m.Name, m.Sig, (Modifiers)m.Modifiers)
|
||||
{
|
||||
this.m = m;
|
||||
this.map = map;
|
||||
this.inherited = inherited;
|
||||
}
|
||||
|
||||
internal IKVM.Internal.MapXml.Method XmlMethod
|
||||
{
|
||||
get
|
||||
{
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
internal override void EmitCall(ILGenerator ilgen)
|
||||
|
@ -858,10 +905,14 @@ namespace IKVM.Internal
|
|||
}
|
||||
}
|
||||
SetParameters(mbCore, m.Params);
|
||||
if(overrideMethod != null)
|
||||
if(overrideMethod != null && !inherited)
|
||||
{
|
||||
typeWrapper.typeBuilder.DefineMethodOverride(mbCore, overrideMethod);
|
||||
}
|
||||
if(inherited)
|
||||
{
|
||||
AttributeHelper.HideFromReflection(mbCore);
|
||||
}
|
||||
AddDeclaredExceptions(mbCore, m.throws);
|
||||
}
|
||||
|
||||
|
@ -906,7 +957,7 @@ namespace IKVM.Internal
|
|||
{
|
||||
AttributeHelper.SetEditorBrowsableNever(mbHelper);
|
||||
}
|
||||
AttributeHelper.SetModifiers(mbHelper, (Modifiers)m.Modifiers);
|
||||
AttributeHelper.SetModifiers(mbHelper, (Modifiers)m.Modifiers, false);
|
||||
AttributeHelper.SetNameSig(mbHelper, m.Name, m.Sig);
|
||||
AddDeclaredExceptions(mbHelper, m.throws);
|
||||
}
|
||||
|
@ -1268,7 +1319,7 @@ namespace IKVM.Internal
|
|||
}
|
||||
// TODO emit an static helper method that enables access to the field at runtime
|
||||
method.Link();
|
||||
fields.Add(new GetterFieldWrapper(this, GetClassLoader().FieldTypeWrapperFromSig(f.Sig), null, f.Name, f.Sig, (Modifiers)f.Modifiers, (MethodInfo)method.GetMethod()));
|
||||
fields.Add(new GetterFieldWrapper(this, GetClassLoader().FieldTypeWrapperFromSig(f.Sig), null, f.Name, f.Sig, new ExModifiers((Modifiers)f.Modifiers, false), (MethodInfo)method.GetMethod()));
|
||||
}
|
||||
else if((f.Modifiers & IKVM.Internal.MapXml.MapModifiers.Static) != 0)
|
||||
{
|
||||
|
@ -1306,7 +1357,7 @@ namespace IKVM.Internal
|
|||
}
|
||||
else
|
||||
{
|
||||
fields.Add(FieldWrapper.Create(this, GetClassLoader().FieldTypeWrapperFromSig(f.Sig), fb, f.Name, f.Sig, (Modifiers)f.Modifiers));
|
||||
fields.Add(FieldWrapper.Create(this, GetClassLoader().FieldTypeWrapperFromSig(f.Sig), fb, f.Name, f.Sig, new ExModifiers((Modifiers)f.Modifiers, false)));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1731,6 +1782,7 @@ namespace IKVM.Internal
|
|||
public bool compressedResources;
|
||||
public bool strictFinalFieldSemantics;
|
||||
public string runtimeAssembly;
|
||||
public string[] privatePackages;
|
||||
}
|
||||
|
||||
public class AotCompiler
|
||||
|
|
|
@ -42,7 +42,8 @@ namespace IKVM.Internal
|
|||
ExplicitOverride = 2,
|
||||
LiteralField = 4,
|
||||
MirandaMethod = 8,
|
||||
AccessStub = 16
|
||||
AccessStub = 16,
|
||||
InternalAccess = 32 // member has "internal" access (@ikvm.lang.Internal)
|
||||
}
|
||||
|
||||
class MemberWrapper
|
||||
|
@ -135,6 +136,7 @@ namespace IKVM.Internal
|
|||
return IsPublic ||
|
||||
caller == DeclaringType ||
|
||||
(IsProtected && caller.IsSubTypeOf(DeclaringType) && (IsStatic || instance.IsSubTypeOf(caller))) ||
|
||||
(IsInternal && caller.Assembly == DeclaringType.Assembly) ||
|
||||
(!IsPrivate && caller.IsInSamePackageAs(DeclaringType));
|
||||
}
|
||||
return false;
|
||||
|
@ -201,6 +203,14 @@ namespace IKVM.Internal
|
|||
}
|
||||
}
|
||||
|
||||
internal bool IsInternal
|
||||
{
|
||||
get
|
||||
{
|
||||
return (flags & MemberFlags.InternalAccess) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsPublic
|
||||
{
|
||||
get
|
||||
|
@ -1110,8 +1120,9 @@ namespace IKVM.Internal
|
|||
this.field = field;
|
||||
}
|
||||
|
||||
internal FieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, string name, string sig, Modifiers modifiers, FieldInfo field)
|
||||
: this(declaringType, fieldType, name, sig, modifiers, field, field != null && field.IsLiteral ? MemberFlags.LiteralField : MemberFlags.None)
|
||||
internal FieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, string name, string sig, ExModifiers modifiers, FieldInfo field)
|
||||
: this(declaringType, fieldType, name, sig, modifiers.Modifiers, field,
|
||||
(modifiers.IsInternal ? MemberFlags.InternalAccess : MemberFlags.None) | (field != null && field.IsLiteral ? MemberFlags.LiteralField : MemberFlags.None))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1241,10 +1252,10 @@ namespace IKVM.Internal
|
|||
}
|
||||
}
|
||||
|
||||
internal static FieldWrapper Create(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string name, string sig, Modifiers modifiers)
|
||||
internal static FieldWrapper Create(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string name, string sig, ExModifiers modifiers)
|
||||
{
|
||||
// volatile long & double field accesses must be made atomic
|
||||
if((modifiers & Modifiers.Volatile) != 0 && (sig == "J" || sig == "D"))
|
||||
if((modifiers.Modifiers & Modifiers.Volatile) != 0 && (sig == "J" || sig == "D"))
|
||||
{
|
||||
return new VolatileLongDoubleFieldWrapper(declaringType, fieldType, fi, name, sig, modifiers);
|
||||
}
|
||||
|
@ -1319,7 +1330,7 @@ namespace IKVM.Internal
|
|||
|
||||
sealed class SimpleFieldWrapper : FieldWrapper
|
||||
{
|
||||
internal SimpleFieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string name, string sig, Modifiers modifiers)
|
||||
internal SimpleFieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string name, string sig, ExModifiers modifiers)
|
||||
: base(declaringType, fieldType, name, sig, modifiers, fi)
|
||||
{
|
||||
Debug.Assert(!(fieldType == PrimitiveTypeWrapper.DOUBLE || fieldType == PrimitiveTypeWrapper.LONG) || !IsVolatile);
|
||||
|
@ -1365,7 +1376,7 @@ namespace IKVM.Internal
|
|||
private static MethodInfo volatileWriteDouble = typeof(System.Threading.Thread).GetMethod("VolatileWrite", new Type[] { Type.GetType("System.Double&"), typeof(double) });
|
||||
private static MethodInfo volatileWriteLong = typeof(System.Threading.Thread).GetMethod("VolatileWrite", new Type[] { Type.GetType("System.Int64&"), typeof(long) });
|
||||
|
||||
internal VolatileLongDoubleFieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string name, string sig, Modifiers modifiers)
|
||||
internal VolatileLongDoubleFieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string name, string sig, ExModifiers modifiers)
|
||||
: base(declaringType, fieldType, name, sig, modifiers, fi)
|
||||
{
|
||||
Debug.Assert(IsVolatile);
|
||||
|
@ -1435,7 +1446,7 @@ namespace IKVM.Internal
|
|||
private MethodInfo getter;
|
||||
|
||||
// NOTE fi may be null!
|
||||
internal GetterFieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string name, string sig, Modifiers modifiers, MethodInfo getter)
|
||||
internal GetterFieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string name, string sig, ExModifiers modifiers, MethodInfo getter)
|
||||
: base(declaringType, fieldType, name, sig, modifiers, fi)
|
||||
{
|
||||
Debug.Assert(!IsVolatile);
|
||||
|
|
|
@ -41,6 +41,18 @@ using IKVM.Attributes;
|
|||
|
||||
namespace IKVM.Internal
|
||||
{
|
||||
struct ExModifiers
|
||||
{
|
||||
internal readonly Modifiers Modifiers;
|
||||
internal readonly bool IsInternal;
|
||||
|
||||
internal ExModifiers(Modifiers modifiers, bool isInternal)
|
||||
{
|
||||
this.Modifiers = modifiers;
|
||||
this.IsInternal = isInternal;
|
||||
}
|
||||
}
|
||||
|
||||
#if !COMPACT_FRAMEWORK
|
||||
class EmitHelper
|
||||
{
|
||||
|
@ -730,6 +742,10 @@ namespace IKVM.Internal
|
|||
if(cad.Constructor.DeclaringType == typeofModifiersAttribute)
|
||||
{
|
||||
IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
|
||||
if(args.Count == 2)
|
||||
{
|
||||
return new ModifiersAttribute((Modifiers)args[0].Value, (bool)args[1].Value);
|
||||
}
|
||||
return new ModifiersAttribute((Modifiers)args[0].Value);
|
||||
}
|
||||
}
|
||||
|
@ -737,10 +753,10 @@ namespace IKVM.Internal
|
|||
}
|
||||
#endif
|
||||
object[] attr = type.GetCustomAttributes(typeof(ModifiersAttribute), false);
|
||||
return attr.Length == 1 ? new ModifiersAttribute(((ModifiersAttribute)attr[0]).Modifiers) : null;
|
||||
return attr.Length == 1 ? (ModifiersAttribute)attr[0] : null;
|
||||
}
|
||||
|
||||
internal static Modifiers GetModifiers(MethodBase mb, bool assemblyIsPrivate)
|
||||
internal static ExModifiers GetModifiers(MethodBase mb, bool assemblyIsPrivate)
|
||||
{
|
||||
#if WHIDBEY
|
||||
if(JVM.IsStaticCompiler || JVM.IsIkvmStub)
|
||||
|
@ -750,7 +766,11 @@ namespace IKVM.Internal
|
|||
if(cad.Constructor.DeclaringType == typeofModifiersAttribute)
|
||||
{
|
||||
IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
|
||||
return (Modifiers)args[0].Value;
|
||||
if(args.Count == 2)
|
||||
{
|
||||
return new ExModifiers((Modifiers)args[0].Value, (bool)args[1].Value);
|
||||
}
|
||||
return new ExModifiers((Modifiers)args[0].Value, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -760,7 +780,8 @@ namespace IKVM.Internal
|
|||
object[] customAttribute = mb.GetCustomAttributes(typeof(ModifiersAttribute), false);
|
||||
if(customAttribute.Length == 1)
|
||||
{
|
||||
return ((ModifiersAttribute)customAttribute[0]).Modifiers;
|
||||
ModifiersAttribute mod = (ModifiersAttribute)customAttribute[0];
|
||||
return new ExModifiers(mod.Modifiers, mod.IsInternal);
|
||||
}
|
||||
}
|
||||
Modifiers modifiers = 0;
|
||||
|
@ -813,10 +834,10 @@ namespace IKVM.Internal
|
|||
{
|
||||
modifiers |= Modifiers.VarArgs;
|
||||
}
|
||||
return modifiers;
|
||||
return new ExModifiers(modifiers, false);
|
||||
}
|
||||
|
||||
internal static Modifiers GetModifiers(FieldInfo fi, bool assemblyIsPrivate)
|
||||
internal static ExModifiers GetModifiers(FieldInfo fi, bool assemblyIsPrivate)
|
||||
{
|
||||
#if WHIDBEY
|
||||
if(JVM.IsStaticCompiler || JVM.IsIkvmStub)
|
||||
|
@ -826,7 +847,11 @@ namespace IKVM.Internal
|
|||
if(cad.Constructor.DeclaringType == typeofModifiersAttribute)
|
||||
{
|
||||
IList<CustomAttributeTypedArgument> args = cad.ConstructorArguments;
|
||||
return (Modifiers)args[0].Value;
|
||||
if(args.Count == 2)
|
||||
{
|
||||
return new ExModifiers((Modifiers)args[0].Value, (bool)args[1].Value);
|
||||
}
|
||||
return new ExModifiers((Modifiers)args[0].Value, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -836,7 +861,8 @@ namespace IKVM.Internal
|
|||
object[] customAttribute = fi.GetCustomAttributes(typeof(ModifiersAttribute), false);
|
||||
if(customAttribute.Length == 1)
|
||||
{
|
||||
return ((ModifiersAttribute)customAttribute[0]).Modifiers;
|
||||
ModifiersAttribute mod = (ModifiersAttribute)customAttribute[0];
|
||||
return new ExModifiers(mod.Modifiers, mod.IsInternal);
|
||||
}
|
||||
}
|
||||
Modifiers modifiers = 0;
|
||||
|
@ -869,31 +895,63 @@ namespace IKVM.Internal
|
|||
modifiers |= Modifiers.Static;
|
||||
}
|
||||
// TODO reflection doesn't support volatile
|
||||
return modifiers;
|
||||
return new ExModifiers(modifiers, false);
|
||||
}
|
||||
|
||||
#if !COMPACT_FRAMEWORK
|
||||
internal static void SetModifiers(MethodBuilder mb, Modifiers modifiers)
|
||||
internal static void SetModifiers(MethodBuilder mb, Modifiers modifiers, bool isInternal)
|
||||
{
|
||||
CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers }), new object[] { modifiers });
|
||||
CustomAttributeBuilder customAttributeBuilder;
|
||||
if (isInternal)
|
||||
{
|
||||
customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers, typeof(bool) }), new object[] { modifiers, isInternal });
|
||||
}
|
||||
else
|
||||
{
|
||||
customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers }), new object[] { modifiers });
|
||||
}
|
||||
mb.SetCustomAttribute(customAttributeBuilder);
|
||||
}
|
||||
|
||||
internal static void SetModifiers(ConstructorBuilder cb, Modifiers modifiers)
|
||||
internal static void SetModifiers(ConstructorBuilder cb, Modifiers modifiers, bool isInternal)
|
||||
{
|
||||
CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers }), new object[] { modifiers });
|
||||
CustomAttributeBuilder customAttributeBuilder;
|
||||
if (isInternal)
|
||||
{
|
||||
customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers, typeof(bool) }), new object[] { modifiers, isInternal });
|
||||
}
|
||||
else
|
||||
{
|
||||
customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers }), new object[] { modifiers });
|
||||
}
|
||||
cb.SetCustomAttribute(customAttributeBuilder);
|
||||
}
|
||||
|
||||
internal static void SetModifiers(FieldBuilder fb, Modifiers modifiers)
|
||||
internal static void SetModifiers(FieldBuilder fb, Modifiers modifiers, bool isInternal)
|
||||
{
|
||||
CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers }), new object[] { modifiers });
|
||||
CustomAttributeBuilder customAttributeBuilder;
|
||||
if (isInternal)
|
||||
{
|
||||
customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers, typeof(bool) }), new object[] { modifiers, isInternal });
|
||||
}
|
||||
else
|
||||
{
|
||||
customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers }), new object[] { modifiers });
|
||||
}
|
||||
fb.SetCustomAttribute(customAttributeBuilder);
|
||||
}
|
||||
|
||||
internal static void SetModifiers(TypeBuilder tb, Modifiers modifiers)
|
||||
internal static void SetModifiers(TypeBuilder tb, Modifiers modifiers, bool isInternal)
|
||||
{
|
||||
CustomAttributeBuilder customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers }), new object[] { modifiers });
|
||||
CustomAttributeBuilder customAttributeBuilder;
|
||||
if (isInternal)
|
||||
{
|
||||
customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers, typeof(bool) }), new object[] { modifiers, isInternal });
|
||||
}
|
||||
else
|
||||
{
|
||||
customAttributeBuilder = new CustomAttributeBuilder(typeofModifiersAttribute.GetConstructor(new Type[] { typeofModifiers }), new object[] { modifiers });
|
||||
}
|
||||
tb.SetCustomAttribute(customAttributeBuilder);
|
||||
}
|
||||
|
||||
|
@ -1348,15 +1406,23 @@ namespace IKVM.Internal
|
|||
}
|
||||
#endif
|
||||
|
||||
[Flags]
|
||||
enum TypeFlags : ushort
|
||||
{
|
||||
HasIncompleteInterfaceImplementation = 1,
|
||||
InternalAccess = 2,
|
||||
HasStaticInitializer = 4
|
||||
}
|
||||
|
||||
public abstract class TypeWrapper
|
||||
{
|
||||
private readonly string name; // java name (e.g. java.lang.Object)
|
||||
private readonly Modifiers modifiers;
|
||||
private TypeFlags flags;
|
||||
private MethodWrapper[] methods;
|
||||
private FieldWrapper[] fields;
|
||||
private readonly TypeWrapper baseWrapper;
|
||||
private object classObject;
|
||||
private bool hasIncompleteInterfaceImplementation;
|
||||
internal static readonly TypeWrapper[] EmptyArray = new TypeWrapper[0];
|
||||
internal const Modifiers UnloadableModifiersHack = Modifiers.Final | Modifiers.Interface | Modifiers.Private;
|
||||
internal const Modifiers VerifierTypeModifiersHack = Modifiers.Final | Modifiers.Interface;
|
||||
|
@ -1417,11 +1483,19 @@ namespace IKVM.Internal
|
|||
{
|
||||
get
|
||||
{
|
||||
return hasIncompleteInterfaceImplementation || (baseWrapper != null && baseWrapper.HasIncompleteInterfaceImplementation);
|
||||
return (flags & TypeFlags.HasIncompleteInterfaceImplementation) != 0 || (baseWrapper != null && baseWrapper.HasIncompleteInterfaceImplementation);
|
||||
}
|
||||
set
|
||||
{
|
||||
hasIncompleteInterfaceImplementation = value;
|
||||
// TODO do we need locking here?
|
||||
if(value)
|
||||
{
|
||||
flags |= TypeFlags.HasIncompleteInterfaceImplementation;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags &= ~TypeFlags.HasIncompleteInterfaceImplementation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1429,7 +1503,19 @@ namespace IKVM.Internal
|
|||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
return (flags & TypeFlags.HasStaticInitializer) != 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
// TODO do we need locking here?
|
||||
if(value)
|
||||
{
|
||||
flags |= TypeFlags.HasStaticInitializer;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags &= ~TypeFlags.HasStaticInitializer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1575,6 +1661,26 @@ namespace IKVM.Internal
|
|||
}
|
||||
}
|
||||
|
||||
internal bool IsInternal
|
||||
{
|
||||
get
|
||||
{
|
||||
return (flags & TypeFlags.InternalAccess) != 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
// TODO do we need locking here?
|
||||
if(value)
|
||||
{
|
||||
flags |= TypeFlags.InternalAccess;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags &= ~TypeFlags.InternalAccess;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsPublic
|
||||
{
|
||||
get
|
||||
|
@ -1755,7 +1861,9 @@ namespace IKVM.Internal
|
|||
// returns true iff wrapper is allowed to access us
|
||||
internal bool IsAccessibleFrom(TypeWrapper wrapper)
|
||||
{
|
||||
return IsPublic || IsInSamePackageAs(wrapper);
|
||||
return IsPublic
|
||||
|| (IsInternal && this.Assembly == wrapper.Assembly)
|
||||
|| IsInSamePackageAs(wrapper);
|
||||
}
|
||||
|
||||
internal bool IsInSamePackageAs(TypeWrapper wrapper)
|
||||
|
@ -2837,7 +2945,6 @@ namespace IKVM.Internal
|
|||
protected readonly DynamicClassLoader classLoader;
|
||||
private volatile DynamicImpl impl;
|
||||
private TypeWrapper[] interfaces;
|
||||
private bool hasStaticInitializer;
|
||||
|
||||
private static TypeWrapper LoadTypeWrapper(ClassLoaderWrapper classLoader, string name)
|
||||
{
|
||||
|
@ -2854,6 +2961,7 @@ namespace IKVM.Internal
|
|||
{
|
||||
Profiler.Count("DynamicTypeWrapper");
|
||||
this.classLoader = classLoader;
|
||||
this.IsInternal = f.IsInternal;
|
||||
if(BaseTypeWrapper != null)
|
||||
{
|
||||
if(!BaseTypeWrapper.IsAccessibleFrom(this))
|
||||
|
@ -2918,14 +3026,6 @@ namespace IKVM.Internal
|
|||
return classLoader;
|
||||
}
|
||||
|
||||
internal override bool HasStaticInitializer
|
||||
{
|
||||
get
|
||||
{
|
||||
return hasStaticInitializer;
|
||||
}
|
||||
}
|
||||
|
||||
internal override Assembly Assembly
|
||||
{
|
||||
get
|
||||
|
@ -3068,25 +3168,34 @@ namespace IKVM.Internal
|
|||
hasclinit = true;
|
||||
}
|
||||
}
|
||||
MemberFlags flags = MemberFlags.None;
|
||||
if(m.IsInternal)
|
||||
{
|
||||
flags |= MemberFlags.InternalAccess;
|
||||
}
|
||||
if(wrapper.IsGhost)
|
||||
{
|
||||
methods[i] = new MethodWrapper.GhostMethodWrapper(wrapper, m.Name, m.Signature, null, null, null, m.Modifiers, MemberFlags.None);
|
||||
methods[i] = new MethodWrapper.GhostMethodWrapper(wrapper, m.Name, m.Signature, null, null, null, m.Modifiers, flags);
|
||||
}
|
||||
else if(m.Name == "<init>")
|
||||
{
|
||||
methods[i] = new SmartConstructorMethodWrapper(wrapper, m.Name, m.Signature, null, null, m.Modifiers, MemberFlags.None);
|
||||
methods[i] = new SmartConstructorMethodWrapper(wrapper, m.Name, m.Signature, null, null, m.Modifiers, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool explicitOverride = false;
|
||||
if(!classFile.IsInterface && !m.IsStatic && !m.IsPrivate)
|
||||
{
|
||||
bool explicitOverride = false;
|
||||
baseMethods[i] = FindBaseMethod(m.Name, m.Signature, out explicitOverride);
|
||||
}
|
||||
methods[i] = new SmartCallMethodWrapper(wrapper, m.Name, m.Signature, null, null, null, m.Modifiers, explicitOverride ? MemberFlags.ExplicitOverride : MemberFlags.None, SimpleOpCode.Call, SimpleOpCode.Callvirt);
|
||||
if(explicitOverride)
|
||||
{
|
||||
flags |= MemberFlags.ExplicitOverride;
|
||||
}
|
||||
}
|
||||
wrapper.hasStaticInitializer = hasclinit;
|
||||
methods[i] = new SmartCallMethodWrapper(wrapper, m.Name, m.Signature, null, null, null, m.Modifiers, flags, SimpleOpCode.Call, SimpleOpCode.Callvirt);
|
||||
}
|
||||
}
|
||||
wrapper.HasStaticInitializer = hasclinit;
|
||||
if(!wrapper.IsInterface)
|
||||
{
|
||||
ArrayList methodsArray = null;
|
||||
|
@ -3130,11 +3239,11 @@ namespace IKVM.Internal
|
|||
else if(fld.IsFinal && (JVM.IsStaticCompiler && (fld.IsPublic || fld.IsProtected))
|
||||
&& !wrapper.IsInterface && (!JVM.StrictFinalFieldSemantics || wrapper.Name == "java.lang.System"))
|
||||
{
|
||||
fields[i] = new GetterFieldWrapper(wrapper, null, null, fld.Name, fld.Signature, fld.Modifiers, null);
|
||||
fields[i] = new GetterFieldWrapper(wrapper, null, null, fld.Name, fld.Signature, new ExModifiers(fld.Modifiers, fld.IsInternal), null);
|
||||
}
|
||||
else
|
||||
{
|
||||
fields[i] = FieldWrapper.Create(wrapper, null, null, fld.Name, fld.Signature, fld.Modifiers);
|
||||
fields[i] = FieldWrapper.Create(wrapper, null, null, fld.Name, fld.Signature, new ExModifiers(fld.Modifiers, fld.IsInternal));
|
||||
}
|
||||
}
|
||||
if(!wrapper.IsInterface && wrapper.IsPublic && JVM.IsStaticCompiler)
|
||||
|
@ -3235,7 +3344,7 @@ namespace IKVM.Internal
|
|||
}
|
||||
}
|
||||
}
|
||||
if(f.IsPublic && !f.IsInternal)
|
||||
if(f.IsPublic)
|
||||
{
|
||||
if(outer != null)
|
||||
{
|
||||
|
@ -3760,7 +3869,7 @@ namespace IKVM.Internal
|
|||
attribs |= FieldAttributes.FamORAssem;
|
||||
methodAttribs |= MethodAttributes.FamORAssem;
|
||||
}
|
||||
else if(fld.IsPublic && !fld.IsInternal)
|
||||
else if(fld.IsPublic)
|
||||
{
|
||||
attribs |= FieldAttributes.Public;
|
||||
methodAttribs |= MethodAttributes.Public;
|
||||
|
@ -3853,14 +3962,9 @@ namespace IKVM.Internal
|
|||
{
|
||||
// if the Java modifiers cannot be expressed in .NET, we emit the Modifiers attribute to store
|
||||
// the Java modifiers
|
||||
if(setModifiers || (fld.Modifiers & (Modifiers.Synthetic | Modifiers.Enum)) != 0)
|
||||
if(setModifiers || fld.IsInternal || (fld.Modifiers & (Modifiers.Synthetic | Modifiers.Enum)) != 0)
|
||||
{
|
||||
Modifiers mods = fld.Modifiers;
|
||||
if(fld.IsPublic && fld.IsInternal)
|
||||
{
|
||||
mods &= ~Modifiers.Public;
|
||||
}
|
||||
AttributeHelper.SetModifiers(field, mods);
|
||||
AttributeHelper.SetModifiers(field, fld.Modifiers, fld.IsInternal);
|
||||
}
|
||||
if(setNameSig)
|
||||
{
|
||||
|
@ -4275,14 +4379,9 @@ namespace IKVM.Internal
|
|||
if(JVM.IsStaticCompiler || DynamicClassLoader.IsSaveDebugImage)
|
||||
{
|
||||
// NOTE in Whidbey we can (and should) use CompilerGeneratedAttribute to mark Synthetic types
|
||||
if((classFile.Modifiers & (Modifiers.Synthetic | Modifiers.Annotation | Modifiers.Enum)) != 0)
|
||||
if(classFile.IsInternal || (classFile.Modifiers & (Modifiers.Synthetic | Modifiers.Annotation | Modifiers.Enum)) != 0)
|
||||
{
|
||||
Modifiers mods = classFile.Modifiers;
|
||||
if(classFile.IsPublic && classFile.IsInternal)
|
||||
{
|
||||
mods &= ~Modifiers.Public;
|
||||
}
|
||||
AttributeHelper.SetModifiers(typeBuilder, mods);
|
||||
AttributeHelper.SetModifiers(typeBuilder, classFile.Modifiers, classFile.IsInternal);
|
||||
}
|
||||
|
||||
// // For Java 5 Enum types, we generate a nested .NET enum
|
||||
|
@ -4477,7 +4576,7 @@ namespace IKVM.Internal
|
|||
if(o.wrapper.IsPublic)
|
||||
{
|
||||
// In the Java world, the class appears as a non-public proxy class
|
||||
AttributeHelper.SetModifiers(attributeTypeBuilder, Modifiers.Final);
|
||||
AttributeHelper.SetModifiers(attributeTypeBuilder, Modifiers.Final, false);
|
||||
}
|
||||
// NOTE we "abuse" the InnerClassAttribute to add a custom attribute to name the class "$Proxy[Annotation]" in the Java world
|
||||
int dotindex = o.classFile.Name.LastIndexOf('.') + 1;
|
||||
|
@ -4942,7 +5041,6 @@ namespace IKVM.Internal
|
|||
TypeWrapper tw = wrapper.BaseTypeWrapper;
|
||||
while(tw != null)
|
||||
{
|
||||
// TODO we need to handle static methods (duh!)
|
||||
MethodWrapper baseMethod = tw.GetMethodWrapper(name, sig, true);
|
||||
if(baseMethod == null)
|
||||
{
|
||||
|
@ -4950,13 +5048,20 @@ namespace IKVM.Internal
|
|||
}
|
||||
// here are the complex rules for determining whether this method overrides the method we found
|
||||
// RULE 1: final methods may not be overridden
|
||||
if(baseMethod.IsFinal && !baseMethod.IsPrivate)
|
||||
// (note that we intentionally not check IsStatic here!)
|
||||
if(baseMethod.IsFinal
|
||||
&& !baseMethod.IsPrivate
|
||||
&& (baseMethod.IsPublic || baseMethod.IsProtected || baseMethod.DeclaringType.IsInSamePackageAs(wrapper)))
|
||||
{
|
||||
throw new VerifyError("final method " + baseMethod.Name + baseMethod.Signature + " in " + baseMethod.DeclaringType.Name + " is overriden in " + wrapper.Name);
|
||||
}
|
||||
// RULE 1a: static methods are ignored (other than the RULE 1 check)
|
||||
if(baseMethod.IsStatic)
|
||||
{
|
||||
}
|
||||
// RULE 2: public & protected methods can be overridden (package methods are handled by RULE 4)
|
||||
// (by public, protected & *package* methods [even if they are in a different package])
|
||||
if(baseMethod.IsPublic || baseMethod.IsProtected)
|
||||
else if(baseMethod.IsPublic || baseMethod.IsProtected)
|
||||
{
|
||||
// if we already encountered a package method, we cannot override the base method of
|
||||
// that package method
|
||||
|
@ -4967,11 +5072,12 @@ namespace IKVM.Internal
|
|||
}
|
||||
return baseMethod;
|
||||
}
|
||||
// RULE 3: private methods are ignored
|
||||
if(!baseMethod.IsPrivate)
|
||||
// RULE 3: private and static methods are ignored
|
||||
else if(!baseMethod.IsPrivate)
|
||||
{
|
||||
// RULE 4: package methods can only be overridden in the same package
|
||||
if(baseMethod.DeclaringType.IsInSamePackageAs(wrapper))
|
||||
if(baseMethod.DeclaringType.IsInSamePackageAs(wrapper)
|
||||
|| (baseMethod.IsInternal && baseMethod.DeclaringType.Assembly == wrapper.Assembly))
|
||||
{
|
||||
return baseMethod;
|
||||
}
|
||||
|
@ -5107,7 +5213,7 @@ namespace IKVM.Internal
|
|||
{
|
||||
attribs |= MethodAttributes.FamORAssem;
|
||||
}
|
||||
else if(m.IsPublic && !m.IsInternal)
|
||||
else if(m.IsPublic)
|
||||
{
|
||||
attribs |= MethodAttributes.Public;
|
||||
}
|
||||
|
@ -5198,7 +5304,7 @@ namespace IKVM.Internal
|
|||
// method more accessible, because otherwise the CLR will complain that we're reducing access
|
||||
MethodBase baseMethod = baseMce.GetMethod();
|
||||
if((baseMethod.IsPublic && !m.IsPublic) ||
|
||||
((baseMethod.IsFamily || baseMethod.IsFamilyOrAssembly) && (!m.IsPublic || m.IsInternal) && !m.IsProtected) ||
|
||||
((baseMethod.IsFamily || baseMethod.IsFamilyOrAssembly) && !m.IsPublic && !m.IsProtected) ||
|
||||
(!m.IsPublic && !m.IsProtected && !baseMce.DeclaringType.IsInSamePackageAs(wrapper)))
|
||||
{
|
||||
attribs &= ~MethodAttributes.MemberAccessMask;
|
||||
|
@ -5339,20 +5445,15 @@ namespace IKVM.Internal
|
|||
if(JVM.IsStaticCompiler || DynamicClassLoader.IsSaveDebugImage)
|
||||
{
|
||||
AttributeHelper.SetThrowsAttribute(method, exceptions);
|
||||
if(setModifiers || (m.Modifiers & (Modifiers.Synthetic | Modifiers.Bridge)) != 0)
|
||||
if(setModifiers || m.IsInternal || (m.Modifiers & (Modifiers.Synthetic | Modifiers.Bridge)) != 0)
|
||||
{
|
||||
Modifiers mods = m.Modifiers;
|
||||
if(m.IsPublic && m.IsInternal)
|
||||
{
|
||||
mods &= ~Modifiers.Public;
|
||||
}
|
||||
if(method is ConstructorBuilder)
|
||||
{
|
||||
AttributeHelper.SetModifiers((ConstructorBuilder)method, mods);
|
||||
AttributeHelper.SetModifiers((ConstructorBuilder)method, m.Modifiers, m.IsInternal);
|
||||
}
|
||||
else
|
||||
{
|
||||
AttributeHelper.SetModifiers((MethodBuilder)method, mods);
|
||||
AttributeHelper.SetModifiers((MethodBuilder)method, m.Modifiers, m.IsInternal);
|
||||
}
|
||||
}
|
||||
if(m.DeprecatedAttribute)
|
||||
|
@ -6773,7 +6874,7 @@ namespace IKVM.Internal
|
|||
MethodBuilder mb = typeBuilder.DefineMethod(method.Name, attribs, returnType, parameterTypes);
|
||||
if(setmodifiers)
|
||||
{
|
||||
AttributeHelper.SetModifiers(mb, modifiers);
|
||||
AttributeHelper.SetModifiers(mb, modifiers, false);
|
||||
}
|
||||
ILGenerator ilgen = mb.GetILGenerator();
|
||||
method.body.Emit(ilgen);
|
||||
|
@ -6836,7 +6937,7 @@ namespace IKVM.Internal
|
|||
TypeWrapper[] args = methods[i].GetParameters();
|
||||
MethodBuilder stub = typeBuilder.DefineMethod(methods[i].Name, MethodAttributes.Public, methods[i].ReturnTypeForDefineMethod, methods[i].GetParametersForDefineMethod());
|
||||
AddParameterNames(stub, methods[i]);
|
||||
AttributeHelper.SetModifiers(stub, methods[i].Modifiers);
|
||||
AttributeHelper.SetModifiers(stub, methods[i].Modifiers, methods[i].IsInternal);
|
||||
ILGenerator ilgen = stub.GetILGenerator();
|
||||
Label end = ilgen.DefineLabel();
|
||||
TypeWrapper[] implementers = GetGhostImplementers(this);
|
||||
|
@ -7038,7 +7139,7 @@ namespace IKVM.Internal
|
|||
typeAttribs |= TypeAttributes.Class | TypeAttributes.Sealed;
|
||||
TypeBuilder typeBuilder = classLoader.ModuleBuilder.DefineType(classLoader.MangleTypeName(Name), typeAttribs, typeof(ValueType));
|
||||
AttributeHelper.SetGhostInterface(typeBuilder);
|
||||
AttributeHelper.SetModifiers(typeBuilder, Modifiers);
|
||||
AttributeHelper.SetModifiers(typeBuilder, Modifiers, IsInternal);
|
||||
ghostRefField = typeBuilder.DefineField("__<ref>", typeof(object), FieldAttributes.Public | FieldAttributes.SpecialName);
|
||||
typeBuilderGhostInterface = typeBuilder.DefineNestedType("__Interface", TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.NestedPublic);
|
||||
AttributeHelper.HideFromJava(typeBuilderGhostInterface);
|
||||
|
@ -7189,6 +7290,7 @@ namespace IKVM.Internal
|
|||
(remappedType.IsSealed || !m.Name.StartsWith("instancehelper_")) &&
|
||||
(!remappedType.IsSealed || method.IsStatic))
|
||||
{
|
||||
// FXBUG on .NET 1.1 Throwable.toString() shows up twice
|
||||
methods.Add(CreateRemappedMethodWrapper(method));
|
||||
}
|
||||
else
|
||||
|
@ -7209,7 +7311,7 @@ namespace IKVM.Internal
|
|||
{
|
||||
MethodInfo method = remappedType.GetMethod(m.MappedTo);
|
||||
MethodInfo mbHelper = method;
|
||||
Modifiers modifiers = AttributeHelper.GetModifiers(method, false);
|
||||
ExModifiers modifiers = AttributeHelper.GetModifiers(method, false);
|
||||
string name;
|
||||
string sig;
|
||||
TypeWrapper retType;
|
||||
|
@ -7232,13 +7334,14 @@ namespace IKVM.Internal
|
|||
|
||||
private MethodWrapper CreateRemappedMethodWrapper(MethodBase mb)
|
||||
{
|
||||
Modifiers modifiers = AttributeHelper.GetModifiers(mb, false);
|
||||
ExModifiers 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;
|
||||
bool hideFromReflection = mbHelper != null && AttributeHelper.IsHideFromReflection(mbHelper);
|
||||
MethodInfo mbNonvirtualHelper = null;
|
||||
if(!mb.IsStatic && !mb.IsConstructor)
|
||||
{
|
||||
|
@ -7256,7 +7359,7 @@ namespace IKVM.Internal
|
|||
}
|
||||
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);
|
||||
return new CompiledRemappedMethodWrapper(this, name, sig, mb, retType, paramTypes, modifiers, hideFromReflection, mbHelper, mbNonvirtualHelper);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7358,8 +7461,14 @@ namespace IKVM.Internal
|
|||
return ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedNameFast(new String('[', rank) + this.SigName);
|
||||
}
|
||||
|
||||
private CompiledTypeWrapper(ExModifiers exmod, string name, TypeWrapper baseTypeWrapper)
|
||||
: base(exmod.Modifiers, name, baseTypeWrapper)
|
||||
{
|
||||
this.IsInternal = exmod.IsInternal;
|
||||
}
|
||||
|
||||
private CompiledTypeWrapper(string name, Type type)
|
||||
: base(GetModifiers(type), name, GetBaseTypeWrapper(type))
|
||||
: this(GetModifiers(type), name, GetBaseTypeWrapper(type))
|
||||
{
|
||||
Debug.Assert(!(type is TypeBuilder));
|
||||
Debug.Assert(!type.IsArray);
|
||||
|
@ -7372,12 +7481,12 @@ namespace IKVM.Internal
|
|||
return JVM.IsStaticCompiler || ClassLoaderWrapper.IsCoreAssemblyType(type) ? ClassLoaderWrapper.GetBootstrapClassLoader() : ClassLoaderWrapper.GetSystemClassLoader();
|
||||
}
|
||||
|
||||
private static Modifiers GetModifiers(Type type)
|
||||
private static ExModifiers GetModifiers(Type type)
|
||||
{
|
||||
ModifiersAttribute attr = AttributeHelper.GetModifiersAttribute(type);
|
||||
if(attr != null)
|
||||
{
|
||||
return attr.Modifiers;
|
||||
return new ExModifiers(attr.Modifiers, attr.IsInternal);
|
||||
}
|
||||
// only returns public, protected, private, final, static, abstract and interface (as per
|
||||
// the documentation of Class.getModifiers())
|
||||
|
@ -7416,7 +7525,7 @@ namespace IKVM.Internal
|
|||
{
|
||||
modifiers |= Modifiers.Interface;
|
||||
}
|
||||
return modifiers;
|
||||
return new ExModifiers(modifiers, false);
|
||||
}
|
||||
|
||||
internal override bool HasStaticInitializer
|
||||
|
@ -7675,7 +7784,12 @@ namespace IKVM.Internal
|
|||
MethodInfo mi = method as MethodInfo;
|
||||
bool hideFromReflection = mi != null ? AttributeHelper.IsHideFromReflection(mi) : false;
|
||||
MemberFlags flags = hideFromReflection ? MemberFlags.HideFromReflection : MemberFlags.None;
|
||||
methods.Add(MethodWrapper.Create(this, name, sig, method, retType, paramTypes, AttributeHelper.GetModifiers(method, false), flags));
|
||||
ExModifiers mods = AttributeHelper.GetModifiers(method, false);
|
||||
if(mods.IsInternal)
|
||||
{
|
||||
flags |= MemberFlags.InternalAccess;
|
||||
}
|
||||
methods.Add(MethodWrapper.Create(this, name, sig, method, retType, paramTypes, mods.Modifiers, flags));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -7717,8 +7831,9 @@ namespace IKVM.Internal
|
|||
private MethodInfo mbHelper;
|
||||
private MethodInfo mbNonvirtualHelper;
|
||||
|
||||
internal CompiledRemappedMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodBase method, TypeWrapper returnType, TypeWrapper[] parameterTypes, Modifiers modifiers, bool hideFromReflection, MethodInfo mbHelper, MethodInfo mbNonvirtualHelper)
|
||||
: base(declaringType, name, sig, method, returnType, parameterTypes, modifiers, hideFromReflection ? MemberFlags.HideFromReflection : MemberFlags.None)
|
||||
internal CompiledRemappedMethodWrapper(TypeWrapper declaringType, string name, string sig, MethodBase method, TypeWrapper returnType, TypeWrapper[] parameterTypes, ExModifiers modifiers, bool hideFromReflection, MethodInfo mbHelper, MethodInfo mbNonvirtualHelper)
|
||||
: base(declaringType, name, sig, method, returnType, parameterTypes, modifiers.Modifiers,
|
||||
(modifiers.IsInternal ? MemberFlags.InternalAccess : MemberFlags.None) | (hideFromReflection ? MemberFlags.HideFromReflection : MemberFlags.None))
|
||||
{
|
||||
this.mbHelper = mbHelper;
|
||||
this.mbNonvirtualHelper = mbNonvirtualHelper;
|
||||
|
@ -7805,7 +7920,7 @@ namespace IKVM.Internal
|
|||
|
||||
private FieldWrapper CreateFieldWrapper(FieldInfo field)
|
||||
{
|
||||
Modifiers modifiers = AttributeHelper.GetModifiers(field, false);
|
||||
ExModifiers modifiers = AttributeHelper.GetModifiers(field, false);
|
||||
string name = field.Name;
|
||||
TypeWrapper type = ClassLoaderWrapper.GetWrapperFromType(field.FieldType);
|
||||
NameSigAttribute attr = AttributeHelper.GetNameSig(field);
|
||||
|
@ -7817,7 +7932,7 @@ namespace IKVM.Internal
|
|||
|
||||
// If the backing field is private, but the modifiers aren't, we've got a final field that
|
||||
// has a property accessor method.
|
||||
if(field.IsPrivate && ((modifiers & Modifiers.Private) == 0))
|
||||
if(field.IsPrivate && ((modifiers.Modifiers & Modifiers.Private) == 0))
|
||||
{
|
||||
BindingFlags bindingFlags = BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Public;
|
||||
bindingFlags |= field.IsStatic ? BindingFlags.Static : BindingFlags.Instance;
|
||||
|
@ -7832,7 +7947,11 @@ namespace IKVM.Internal
|
|||
{
|
||||
flags |= MemberFlags.HideFromReflection;
|
||||
}
|
||||
return new ConstantFieldWrapper(this, type, name, type.SigName, modifiers, field, null, flags);
|
||||
if(modifiers.IsInternal)
|
||||
{
|
||||
flags |= MemberFlags.InternalAccess;
|
||||
}
|
||||
return new ConstantFieldWrapper(this, type, name, type.SigName, modifiers.Modifiers, field, null, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -8222,7 +8341,7 @@ namespace IKVM.Internal
|
|||
ModuleBuilder moduleBuilder = new DynamicClassLoader(null).ModuleBuilder;
|
||||
TypeBuilder typeBuilder = moduleBuilder.DefineType(origname.Substring(NamePrefix.Length), TypeAttributes.NotPublic | TypeAttributes.Interface | TypeAttributes.Abstract);
|
||||
AttributeHelper.HideFromJava(typeBuilder);
|
||||
AttributeHelper.SetModifiers(typeBuilder, Modifiers.Public | Modifiers.Interface | Modifiers.Abstract);
|
||||
AttributeHelper.SetModifiers(typeBuilder, Modifiers.Public | Modifiers.Interface | Modifiers.Abstract, false);
|
||||
typeBuilder.DefineMethod("Invoke", MethodAttributes.Public | MethodAttributes.Abstract | MethodAttributes.Virtual, CallingConventions.Standard, invoke.ReturnType, args);
|
||||
return CompiledTypeWrapper.newInstance(origname, typeBuilder.CreateType());
|
||||
}
|
||||
|
@ -8553,7 +8672,7 @@ namespace IKVM.Internal
|
|||
{
|
||||
// NOTE if the reference on the stack is null, we *want* the NullReferenceException, so we don't use TypeWrapper.EmitUnbox
|
||||
internal EnumValueFieldWrapper(DotNetTypeWrapper tw, TypeWrapper fieldType)
|
||||
: base(tw, fieldType, "Value", fieldType.SigName, Modifiers.Public | Modifiers.Final, null)
|
||||
: base(tw, fieldType, "Value", fieldType.SigName, new ExModifiers(Modifiers.Public | Modifiers.Final, false), null)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -8744,7 +8863,7 @@ namespace IKVM.Internal
|
|||
else
|
||||
{
|
||||
// TODO handle name/signature clash
|
||||
fieldsList.Add(CreateFieldWrapperDotNet(AttributeHelper.GetModifiers(fields[i], true), fields[i].Name, fields[i].FieldType, fields[i]));
|
||||
fieldsList.Add(CreateFieldWrapperDotNet(AttributeHelper.GetModifiers(fields[i], true).Modifiers, fields[i].Name, fields[i].FieldType, fields[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9116,13 +9235,14 @@ namespace IKVM.Internal
|
|||
}
|
||||
else
|
||||
{
|
||||
return FieldWrapper.Create(this, type, field, name, type.SigName, modifiers);
|
||||
return FieldWrapper.Create(this, type, field, name, type.SigName, new ExModifiers(modifiers, false));
|
||||
}
|
||||
}
|
||||
|
||||
private MethodWrapper CreateMethodWrapper(string name, string sig, MethodBase mb, bool privateInterfaceImplHack)
|
||||
{
|
||||
Modifiers mods = AttributeHelper.GetModifiers(mb, true);
|
||||
ExModifiers exmods = AttributeHelper.GetModifiers(mb, true);
|
||||
Modifiers mods = exmods.Modifiers;
|
||||
if(name == "Finalize" && sig == "()V" && !mb.IsStatic &&
|
||||
TypeAsBaseType.IsSubclassOf(CoreClasses.java.lang.Object.Wrapper.TypeAsBaseType))
|
||||
{
|
||||
|
|
|
@ -404,12 +404,27 @@ namespace IKVM.Attributes
|
|||
public sealed class ModifiersAttribute : Attribute
|
||||
{
|
||||
private Modifiers modifiers;
|
||||
private bool isInternal;
|
||||
|
||||
public ModifiersAttribute(Modifiers modifiers)
|
||||
{
|
||||
this.modifiers = modifiers;
|
||||
}
|
||||
|
||||
public ModifiersAttribute(Modifiers modifiers, bool isInternal)
|
||||
{
|
||||
this.modifiers = modifiers;
|
||||
this.isInternal = isInternal;
|
||||
}
|
||||
|
||||
public bool IsInternal
|
||||
{
|
||||
get
|
||||
{
|
||||
return isInternal;
|
||||
}
|
||||
}
|
||||
|
||||
public Modifiers Modifiers
|
||||
{
|
||||
get
|
||||
|
|
|
@ -195,12 +195,18 @@ namespace IKVM.NativeCode.java
|
|||
return wrapper.Name;
|
||||
}
|
||||
|
||||
public static int GetModifiers(object fieldCookie)
|
||||
public static int GetModifiers(object memberCookie)
|
||||
{
|
||||
FieldWrapper wrapper = (FieldWrapper)fieldCookie;
|
||||
MemberWrapper wrapper = (MemberWrapper)memberCookie;
|
||||
return (int)wrapper.Modifiers;
|
||||
}
|
||||
|
||||
public static object GetDeclaringClass(object memberCookie)
|
||||
{
|
||||
MemberWrapper wrapper = (MemberWrapper)memberCookie;
|
||||
return wrapper.DeclaringType.ClassObject;
|
||||
}
|
||||
|
||||
public static object GetFieldType(object fieldCookie)
|
||||
{
|
||||
FieldWrapper wrapper = (FieldWrapper)fieldCookie;
|
||||
|
@ -215,16 +221,33 @@ namespace IKVM.NativeCode.java
|
|||
return wrapper.DeclaringType.GetGenericFieldSignature(wrapper);
|
||||
}
|
||||
|
||||
public static bool isSamePackage(object a, object b)
|
||||
{
|
||||
return TypeWrapper.FromClass(a).IsInSamePackageAs(TypeWrapper.FromClass(b));
|
||||
}
|
||||
|
||||
public static void RunClassInit(object clazz)
|
||||
{
|
||||
TypeWrapper.FromClass(clazz).RunClassInit();
|
||||
}
|
||||
|
||||
public static bool CheckAccess(object memberCookie, object instance, object callerTypeWrapper)
|
||||
{
|
||||
MemberWrapper member = (MemberWrapper)memberCookie;
|
||||
if(callerTypeWrapper != null)
|
||||
{
|
||||
TypeWrapper instanceTypeWrapper;
|
||||
if(member.IsStatic || instance == null)
|
||||
{
|
||||
instanceTypeWrapper = member.DeclaringType;
|
||||
}
|
||||
else
|
||||
{
|
||||
instanceTypeWrapper = IKVM.Runtime.Util.GetTypeWrapperFromObject(instance);
|
||||
}
|
||||
return member.IsAccessibleFrom(member.DeclaringType, (TypeWrapper)callerTypeWrapper, instanceTypeWrapper);
|
||||
}
|
||||
else
|
||||
{
|
||||
return member.IsPublic && member.DeclaringType.IsPublic;
|
||||
}
|
||||
}
|
||||
|
||||
public static object GetValue(object fieldCookie, object o)
|
||||
{
|
||||
Profiler.Enter("Field.GetValue");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2002, 2003, 2004, 2005 Jeroen Frijters
|
||||
Copyright (C) 2002, 2003, 2004, 2005, 2006 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
|
||||
|
@ -1790,9 +1790,25 @@ class Compiler
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE this check is written somewhat pessimistically, because we need to
|
||||
// take remapped types into account. For example, Throwable.getClass() "overrides"
|
||||
// the final Object.getClass() method and we don't want to call Object.getClass()
|
||||
// on a Throwable instance, because that would yield unverifiable code (java.lang.Throwable
|
||||
// extends System.Exception instead of java.lang.Object in the .NET type system).
|
||||
if(VerifierTypeWrapper.IsThis(type)
|
||||
&& (method.IsFinal || clazz.IsFinal)
|
||||
&& clazz.GetMethodWrapper(method.Name, method.Signature, true) == method)
|
||||
{
|
||||
// we're calling a method on our own instance that can't possibly be overriden,
|
||||
// so we don't need to use callvirt
|
||||
method.EmitCall(ilGenerator);
|
||||
}
|
||||
else
|
||||
{
|
||||
method.EmitCallvirt(ilGenerator);
|
||||
}
|
||||
}
|
||||
method.ReturnType.EmitConvSignatureTypeToStackType(ilGenerator);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -921,7 +921,16 @@ namespace IKVM.Internal.MapXml
|
|||
@try.Generate(context, ilgen);
|
||||
if(@catch != null)
|
||||
{
|
||||
ilgen.BeginCatchBlock(JVM.LoadType(Type.GetType(@catch.type, true)));
|
||||
Type type;
|
||||
if(@catch.type != null)
|
||||
{
|
||||
type = JVM.LoadType(Type.GetType(@catch.type, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
type = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(@catch.Class).TypeAsExceptionType;
|
||||
}
|
||||
ilgen.BeginCatchBlock(type);
|
||||
@catch.Generate(context, ilgen);
|
||||
}
|
||||
if(@finally != null)
|
||||
|
@ -937,6 +946,8 @@ namespace IKVM.Internal.MapXml
|
|||
{
|
||||
[XmlAttribute("type")]
|
||||
public string type;
|
||||
[XmlAttribute("class")]
|
||||
public string Class;
|
||||
}
|
||||
|
||||
[XmlType("conditional")]
|
||||
|
@ -955,6 +966,14 @@ namespace IKVM.Internal.MapXml
|
|||
}
|
||||
}
|
||||
|
||||
[XmlType("volatile")]
|
||||
public sealed class Volatile : Simple
|
||||
{
|
||||
public Volatile() : base(OpCodes.Volatile)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class InstructionList : CodeEmitter
|
||||
{
|
||||
[XmlElement(typeof(Ldstr))]
|
||||
|
@ -1019,6 +1038,7 @@ namespace IKVM.Internal.MapXml
|
|||
[XmlElement(typeof(Cpblk))]
|
||||
[XmlElement(typeof(Ceq))]
|
||||
[XmlElement(typeof(ConditionalInstruction))]
|
||||
[XmlElement(typeof(Volatile))]
|
||||
public Instruction[] invoke;
|
||||
|
||||
internal void Generate(Hashtable context, ILGenerator ilgen)
|
||||
|
|
|
@ -195,13 +195,18 @@ namespace IKVM.Runtime
|
|||
}
|
||||
|
||||
public static object GetClassFromObject(object o)
|
||||
{
|
||||
return GetTypeWrapperFromObject(o).ClassObject;
|
||||
}
|
||||
|
||||
internal static TypeWrapper GetTypeWrapperFromObject(object o)
|
||||
{
|
||||
Type t = o.GetType();
|
||||
if(t.IsPrimitive || (ClassLoaderWrapper.IsRemappedType(t) && !t.IsSealed))
|
||||
{
|
||||
return DotNetTypeWrapper.GetWrapperFromDotNetType(t).ClassObject;
|
||||
return DotNetTypeWrapper.GetWrapperFromDotNetType(t);
|
||||
}
|
||||
return ClassLoaderWrapper.GetWrapperFromType(t).ClassObject;
|
||||
return ClassLoaderWrapper.GetWrapperFromType(t);
|
||||
}
|
||||
|
||||
public static object GetClassFromTypeHandle(RuntimeTypeHandle handle)
|
||||
|
|
Загрузка…
Ссылка в новой задаче