Added support for classes that represent arrays of remapped .NET types and .NET primitives.

This commit is contained in:
jfrijters 2011-11-24 08:35:47 +00:00
Родитель e203aaf1f2
Коммит 917376e242
5 изменённых файлов: 43 добавлений и 3 удалений

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

@ -37,6 +37,9 @@ public final class Util
public static native Class getClassFromTypeHandle(RuntimeTypeHandle handle);
// this is used to create an array of a remapped type (e.g. getClassFromTypeHandle(typeof(object), 1) returns cli.System.Object[])
public static native Class getClassFromTypeHandle(RuntimeTypeHandle handle, int rank);
public static native Class getFriendlyClassFromType(Type type);
public static native Type getInstanceTypeFromClass(Class classObject);

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

@ -2693,7 +2693,7 @@ namespace IKVM.Internal
internal override bool IsFastClassLiteralSafe
{
get { return true; }
get { return type != Types.Void && !type.IsPrimitive && !IsRemapped; }
}
}
}

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

@ -1696,8 +1696,23 @@ namespace IKVM.Internal
// note that this has to be the same check as in LazyInitClass
if (!this.IsFastClassLiteralSafe || IsForbiddenTypeParameterType(type))
{
ilgen.Emit(OpCodes.Ldtoken, type);
Compiler.getClassFromTypeHandle.EmitCall(ilgen);
int rank = 0;
while (ReflectUtil.IsVector(type))
{
rank++;
type = type.GetElementType();
}
if (rank == 0)
{
ilgen.Emit(OpCodes.Ldtoken, type);
Compiler.getClassFromTypeHandle.EmitCall(ilgen);
}
else
{
ilgen.Emit(OpCodes.Ldtoken, type);
ilgen.Emit(OpCodes.Ldc_I4, rank);
Compiler.getClassFromTypeHandle2.EmitCall(ilgen);
}
}
else
{

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

@ -490,6 +490,25 @@ namespace IKVM.NativeCode.ikvm.runtime
return null;
}
public static jlClass getClassFromTypeHandle(RuntimeTypeHandle handle, int rank)
{
Type t = Type.GetTypeFromHandle(handle);
if(t.IsPrimitive || ClassLoaderWrapper.IsRemappedType(t) || t == typeof(void))
{
return DotNetTypeWrapper.GetWrapperFromDotNetType(t).MakeArrayType(rank).ClassObject;
}
if(!IsVisibleAsClass(t))
{
return null;
}
TypeWrapper tw = ClassLoaderWrapper.GetWrapperFromType(t);
if(tw != null)
{
return tw.MakeArrayType(rank).ClassObject;
}
return null;
}
public static jlClass getFriendlyClassFromType(Type type)
{
int rank = 0;

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

@ -387,6 +387,7 @@ sealed class Compiler
private static readonly MethodInfo monitorExitMethod;
private static readonly MethodInfo keepAliveMethod;
internal static readonly MethodWrapper getClassFromTypeHandle;
internal static readonly MethodWrapper getClassFromTypeHandle2;
private static readonly TypeWrapper java_lang_Object;
private static readonly TypeWrapper java_lang_Class;
private static readonly TypeWrapper java_lang_Throwable;
@ -448,6 +449,8 @@ sealed class Compiler
}
getClassFromTypeHandle = ClassLoaderWrapper.LoadClassCritical("ikvm.runtime.Util").GetMethodWrapper("getClassFromTypeHandle", "(Lcli.System.RuntimeTypeHandle;)Ljava.lang.Class;", false);
getClassFromTypeHandle.Link();
getClassFromTypeHandle2 = ClassLoaderWrapper.LoadClassCritical("ikvm.runtime.Util").GetMethodWrapper("getClassFromTypeHandle", "(Lcli.System.RuntimeTypeHandle;I)Ljava.lang.Class;", false);
getClassFromTypeHandle2.Link();
}
private Compiler(DynamicTypeWrapper.FinishContext context, DynamicTypeWrapper clazz, MethodWrapper mw, ClassFile classFile, ClassFile.Method m, CodeEmitter ilGenerator, ClassLoaderWrapper classLoader, Dictionary<MethodKey, MethodInfo> invokespecialstubcache)