This commit is contained in:
jfrijters 2005-07-27 15:57:55 +00:00
Родитель 11608ba623
Коммит 8cddcbc71d
6 изменённых файлов: 82 добавлений и 103 удалений

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

@ -441,4 +441,5 @@ final class VMClassLoader
static final boolean USE_VM_CACHE = true;
static native Class findLoadedClass(ClassLoader cl, String name);
static native void registerInitiatingLoader(ClassLoader cl, Class c);
}

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

@ -192,6 +192,42 @@ namespace IKVM.Internal
}
}
internal TypeWrapper RegisterInitiatingLoader(TypeWrapper tw)
{
if(tw.IsUnloadable || tw.IsPrimitive)
return tw;
lock(types.SyncRoot)
{
object existing = types[tw.Name];
if(existing != tw)
{
if(existing != null)
{
throw new LinkageError("duplicate class definition: " + tw.Name);
}
if(tw.IsArray)
{
TypeWrapper elem = tw;
// TODO there should be a way to get the ultimate element type
// without creating all the intermediate types
while(elem.IsArray)
{
elem = elem.ElementTypeWrapper;
}
RegisterInitiatingLoader(elem);
}
// NOTE if types.ContainsKey(tw.Name) is true (i.e. the value is null),
// we currently have a DefineClass in progress on another thread and we've
// beaten that thread to the punch by loading the class from a parent class
// loader instead. This is ok as DefineClass will throw a LinkageError when
// it is done.
types[tw.Name] = tw;
}
}
return tw;
}
// FXBUG This mangles type names, to enable different class loaders loading classes with the same names.
// We used to support this by using an assembly per class loader instance, but because
// of the CLR TypeResolve bug, we put all types in a single assembly for now.
@ -276,7 +312,7 @@ namespace IKVM.Internal
{
type = type.GetClassLoader().CreateArrayType(name, type, dims);
}
return type;
return RegisterInitiatingLoader(type);
}
if(name.Length != dims + 1)
{
@ -286,21 +322,21 @@ namespace IKVM.Internal
switch(name[dims])
{
case 'B':
return GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.BYTE, dims);
return RegisterInitiatingLoader(GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.BYTE, dims));
case 'C':
return GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.CHAR, dims);
return RegisterInitiatingLoader(GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.CHAR, dims));
case 'D':
return GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.DOUBLE, dims);
return RegisterInitiatingLoader(GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.DOUBLE, dims));
case 'F':
return GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.FLOAT, dims);
return RegisterInitiatingLoader(GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.FLOAT, dims));
case 'I':
return GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.INT, dims);
return RegisterInitiatingLoader(GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.INT, dims));
case 'J':
return GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.LONG, dims);
return RegisterInitiatingLoader(GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.LONG, dims));
case 'S':
return GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.SHORT, dims);
return RegisterInitiatingLoader(GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.SHORT, dims));
case 'Z':
return GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.BOOLEAN, dims);
return RegisterInitiatingLoader(GetBootstrapClassLoader().CreateArrayType(name, PrimitiveTypeWrapper.BOOLEAN, dims));
default:
return null;
}
@ -332,7 +368,7 @@ namespace IKVM.Internal
{
if(t.Module.IsDefined(typeof(JavaModuleAttribute), false))
{
return GetWrapperFromType(t);
return RegisterInitiatingLoader(GetWrapperFromType(t));
}
else
{
@ -350,7 +386,7 @@ namespace IKVM.Internal
Type t = GetBootstrapTypeRaw(name);
if(t != null)
{
return GetWrapperFromBootstrapType(t);
return RegisterInitiatingLoader(GetWrapperFromBootstrapType(t));
}
type = DotNetTypeWrapper.CreateDotNetTypeWrapper(name);
if(type != null)
@ -399,7 +435,7 @@ namespace IKVM.Internal
Profiler.Leave("ClassLoader.loadClass");
}
}
return type;
return RegisterInitiatingLoader(type);
}
finally
{
@ -626,7 +662,7 @@ namespace IKVM.Internal
}
else
{
type = race;
throw new LinkageError("duplicate class definition: " + f.Name);
}
}
return type;

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

@ -70,7 +70,7 @@
/>
<Reference
Name = "System.XML"
AssemblyName = "System.XML"
AssemblyName = "System.Xml"
HintPath = "..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
/>
</References>

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

@ -2168,7 +2168,7 @@ namespace IKVM.Internal
}
if(BaseTypeWrapper.IsFinal)
{
throw new VerifyError("Cannot inherit from final class");
throw new VerifyError("Class " + f.Name + " extends final class " + BaseTypeWrapper.Name);
}
if(BaseTypeWrapper.IsInterface)
{
@ -2283,8 +2283,6 @@ namespace IKVM.Internal
try
{
impl = impl.Finish(forDebugSave);
// call Finish again to get the verify error for doomed types
impl.Finish(forDebugSave);
}
finally
{
@ -3049,7 +3047,6 @@ namespace IKVM.Internal
parent = parent.BaseTypeWrapper;
}
}
string verifyError = null;
bool basehasclinit = wrapper.BaseTypeWrapper != null && wrapper.BaseTypeWrapper.HasStaticInitializer;
bool hasclinit = false;
for(int i = 0; i < classFile.Methods.Length; i++)
@ -3067,7 +3064,7 @@ namespace IKVM.Internal
EmitConstantValueInitialization(ilGenerator);
EmitHelper.RunClassConstructor(ilGenerator, Type.BaseType);
}
Compiler.Compile(wrapper, methods[i], classFile, m, ilGenerator, ref verifyError);
Compiler.Compile(wrapper, methods[i], classFile, m, ilGenerator);
}
else
{
@ -3184,7 +3181,7 @@ namespace IKVM.Internal
continue;
}
bool nonleaf = false;
Compiler.Compile(wrapper, methods[i], classFile, m, ilGenerator, ref verifyError, ref nonleaf);
Compiler.Compile(wrapper, methods[i], classFile, m, ilGenerator, ref nonleaf);
if(nonleaf)
{
mbld.SetImplementationFlags(mbld.GetMethodImplementationFlags() | MethodImplAttributes.NoInlining);
@ -3345,16 +3342,9 @@ namespace IKVM.Internal
Profiler.Leave("TypeBuilder.CreateType");
}
ClassLoaderWrapper.SetWrapperForType(type, wrapper);
if(verifyError != null)
{
return new DoomedTypeImpl(verifyError);
}
else
{
wrapper.FinishGhostStep2();
finishedType = new FinishedTypeImpl(type, innerClassesTypeWrappers, declaringTypeWrapper, this.ReflectiveModifiers);
return finishedType;
}
wrapper.FinishGhostStep2();
finishedType = new FinishedTypeImpl(type, innerClassesTypeWrappers, declaringTypeWrapper, this.ReflectiveModifiers);
return finishedType;
}
catch(Exception x)
{
@ -3921,7 +3911,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 && !m.IsPublic && !m.IsProtected) ||
((baseMethod.IsFamily || baseMethod.IsFamilyOrAssembly) && !m.IsPublic && !m.IsProtected) ||
(!m.IsPublic && !m.IsProtected && !baseMce.DeclaringType.IsInSamePackageAs(wrapper)))
{
attribs &= ~MethodAttributes.MemberAccessMask;
@ -4158,67 +4148,6 @@ namespace IKVM.Internal
}
}
private class DoomedTypeImpl : DynamicImpl
{
private string message;
internal DoomedTypeImpl(string message)
{
this.message = message;
}
internal override TypeWrapper DeclaringTypeWrapper
{
get
{
return null;
}
}
internal override DynamicImpl Finish(bool forDebugSave)
{
if(!forDebugSave)
{
throw new VerifyError(message);
}
return this;
}
internal override TypeWrapper[] InnerClasses
{
get
{
return null;
}
}
internal override FieldInfo LinkField(FieldWrapper fw)
{
return null;
}
internal override MethodBase LinkMethod(MethodWrapper mw)
{
return null;
}
internal override Modifiers ReflectiveModifiers
{
get
{
return (Modifiers)0;
}
}
internal override Type Type
{
get
{
return null;
}
}
}
private class FinishedTypeImpl : DynamicImpl
{
private Type type;

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

@ -648,7 +648,7 @@ namespace IKVM.NativeCode.java
{
rank++;
}
if(name[rank] == 'L')
if(name[rank] == 'L' && name[rank + 1] != '[')
{
wrapper = loader.GetLoadedClass(name.Substring(rank + 1, name.Length - (rank + 2)));
if(wrapper != null)
@ -659,6 +659,23 @@ namespace IKVM.NativeCode.java
}
return null;
}
public static void registerInitiatingLoader(object javaClassLoader, object clazz)
{
ClassLoaderWrapper loader = ClassLoaderWrapper.GetClassLoaderWrapper(javaClassLoader);
TypeWrapper tw = VMClass.getWrapperFromClass(clazz);
if(tw.GetClassLoader() != loader)
{
try
{
loader.RegisterInitiatingLoader(tw);
}
catch(RetargetableJavaException x)
{
throw x.ToJava();
}
}
}
}
public class VMClass

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

@ -813,13 +813,13 @@ class Compiler
}
}
internal static void Compile(DynamicTypeWrapper clazz, MethodWrapper mw, ClassFile classFile, ClassFile.Method m, ILGenerator ilGenerator, ref string verifyError)
internal static void Compile(DynamicTypeWrapper clazz, MethodWrapper mw, ClassFile classFile, ClassFile.Method m, ILGenerator ilGenerator)
{
bool nonleaf = false;
Compile(clazz, mw, classFile, m, ilGenerator, ref verifyError, ref nonleaf);
Compile(clazz, mw, classFile, m, ilGenerator, ref nonleaf);
}
internal static void Compile(DynamicTypeWrapper clazz, MethodWrapper mw, ClassFile classFile, ClassFile.Method m, ILGenerator ilGenerator, ref string verifyError, ref bool nonleaf)
internal static void Compile(DynamicTypeWrapper clazz, MethodWrapper mw, ClassFile classFile, ClassFile.Method m, ILGenerator ilGenerator, ref bool nonleaf)
{
ClassLoaderWrapper classLoader = clazz.GetClassLoader();
ISymbolDocumentWriter symboldocument = null;
@ -892,10 +892,6 @@ class Compiler
// because in Java the method is only verified if it is actually called,
// we generate code here to throw the VerificationError
EmitHelper.Throw(ilGenerator, "java.lang.VerifyError", x.Message);
if(verifyError == null)
{
verifyError = x.Message;
}
return;
}
Profiler.Enter("Compile");
@ -1166,7 +1162,7 @@ class Compiler
{
if(cpi.GetFieldType() != fw.FieldTypeWrapper && !fw.FieldTypeWrapper.IsUnloadable)
{
throw new LinkageError("Loader constraints violated: " + fw.Name);
throw new LinkageError("Loader constraints violated: " + fw.DeclaringType.Name + "." + fw.Name);
}
}
@ -1174,7 +1170,7 @@ class Compiler
{
if(cpi.GetRetType() != mw.ReturnType && !mw.ReturnType.IsUnloadable)
{
throw new LinkageError("Loader constraints violated: " + mw.Name + mw.Signature);
throw new LinkageError("Loader constraints violated (return type): " + mw.DeclaringType.Name + "." + mw.Name + mw.Signature);
}
TypeWrapper[] here = cpi.GetArgTypes();
TypeWrapper[] there = mw.GetParameters();
@ -1182,7 +1178,7 @@ class Compiler
{
if(here[i] != there[i] && !there[i].IsUnloadable)
{
throw new LinkageError("Loader constraints violated: " + mw.Name + mw.Signature);
throw new LinkageError("Loader constraints violated (arg " + i + "): " + mw.DeclaringType.Name + "." + mw.Name + mw.Signature);
}
}
}