From 8cddcbc71df6ee80c7d7921f24b82136827162ab Mon Sep 17 00:00:00 2001 From: jfrijters Date: Wed, 27 Jul 2005 15:57:55 +0000 Subject: [PATCH] *** empty log message *** --- classpath/java/lang/VMClassLoader.java | 1 + runtime/ClassLoaderWrapper.cs | 62 +++++++++++++++---- runtime/IKVM.Runtime.csproj | 2 +- runtime/TypeWrapper.cs | 85 +++----------------------- runtime/classpath.cs | 19 +++++- runtime/compiler.cs | 16 ++--- 6 files changed, 82 insertions(+), 103 deletions(-) diff --git a/classpath/java/lang/VMClassLoader.java b/classpath/java/lang/VMClassLoader.java index 5adb712e..412a4264 100644 --- a/classpath/java/lang/VMClassLoader.java +++ b/classpath/java/lang/VMClassLoader.java @@ -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); } diff --git a/runtime/ClassLoaderWrapper.cs b/runtime/ClassLoaderWrapper.cs index 469b03db..f96ce663 100644 --- a/runtime/ClassLoaderWrapper.cs +++ b/runtime/ClassLoaderWrapper.cs @@ -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; diff --git a/runtime/IKVM.Runtime.csproj b/runtime/IKVM.Runtime.csproj index 608f5198..bcec3729 100644 --- a/runtime/IKVM.Runtime.csproj +++ b/runtime/IKVM.Runtime.csproj @@ -70,7 +70,7 @@ /> diff --git a/runtime/TypeWrapper.cs b/runtime/TypeWrapper.cs index 1635e876..c7481ed7 100644 --- a/runtime/TypeWrapper.cs +++ b/runtime/TypeWrapper.cs @@ -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; diff --git a/runtime/classpath.cs b/runtime/classpath.cs index 703deca6..272c3244 100644 --- a/runtime/classpath.cs +++ b/runtime/classpath.cs @@ -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 diff --git a/runtime/compiler.cs b/runtime/compiler.cs index e8f6b40c..010b2e2a 100644 --- a/runtime/compiler.cs +++ b/runtime/compiler.cs @@ -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); } } }