This commit is contained in:
jfrijters 2006-04-05 08:18:58 +00:00
Родитель 0ad640b8c6
Коммит cb926ea086
21 изменённых файлов: 684 добавлений и 178 удалений

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

@ -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)