From 29ba470d7889707bc72655b2527360852b3f8b2a Mon Sep 17 00:00:00 2001 From: jfrijters Date: Wed, 26 Jul 2006 14:16:52 +0000 Subject: [PATCH] *** empty log message *** --- ikvmc/AotTypeWrapper.cs | 2 +- ikvmc/Compiler.cs | 21 +++++- ikvmc/CompilerClassLoader.cs | 129 ++++++++++++++++++++++++++++------ runtime/ClassLoaderWrapper.cs | 44 ++++++------ runtime/DynamicClassLoader.cs | 31 +++++--- runtime/MemberWrapper.cs | 13 ++-- runtime/TypeWrapper.cs | 44 +++++------- runtime/compiler.cs | 10 ++- 8 files changed, 198 insertions(+), 96 deletions(-) diff --git a/ikvmc/AotTypeWrapper.cs b/ikvmc/AotTypeWrapper.cs index 7f2cea55..7ce8690d 100644 --- a/ikvmc/AotTypeWrapper.cs +++ b/ikvmc/AotTypeWrapper.cs @@ -979,7 +979,7 @@ namespace IKVM.Internal { typeAttribs &= ~(TypeAttributes.Interface | TypeAttributes.Abstract); typeAttribs |= TypeAttributes.Class | TypeAttributes.Sealed; - TypeBuilder typeBuilder = classLoader.ModuleBuilder.DefineType(mangledTypeName, typeAttribs, typeof(ValueType)); + TypeBuilder typeBuilder = classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(mangledTypeName, typeAttribs, typeof(ValueType)); AttributeHelper.SetGhostInterface(typeBuilder); AttributeHelper.SetModifiers(typeBuilder, Modifiers, IsInternal); ghostRefField = typeBuilder.DefineField("__", typeof(object), FieldAttributes.Public | FieldAttributes.SpecialName); diff --git a/ikvmc/Compiler.cs b/ikvmc/Compiler.cs index 9d2a1b1c..9d0861cf 100644 --- a/ikvmc/Compiler.cs +++ b/ikvmc/Compiler.cs @@ -94,6 +94,7 @@ class IkvmcCompiler Console.Error.WriteLine("usage: ikvmc [-options] ... "); Console.Error.WriteLine(); Console.Error.WriteLine("options:"); + Console.Error.WriteLine(" @ Read more options from file"); Console.Error.WriteLine(" -out: Specify the output filename"); Console.Error.WriteLine(" -assembly: Specify assembly name"); Console.Error.WriteLine(" -target:exe Build a console executable"); @@ -134,6 +135,7 @@ class IkvmcCompiler Console.Error.WriteLine(" of initializer methods"); Console.Error.WriteLine(" -privatepackage: Mark all classes with a package name starting"); Console.Error.WriteLine(" with as internal to the assembly"); + Console.Error.WriteLine(" -nowarn: Suppress specified warnings"); return 1; } foreach(string s in arglist) @@ -289,7 +291,7 @@ class IkvmcCompiler string[] spec = s.Substring(10).Split('='); if(resources.ContainsKey(spec[0])) { - Console.Error.WriteLine("Warning: skipping resource (name clash): " + spec[0]); + StaticCompiler.IssueMessage(Message.DuplicateResourceName, spec[0]); } else { @@ -400,6 +402,19 @@ class IkvmcCompiler options.privatePackages = temp; } } + else if(s.StartsWith("-nowarn:")) + { + foreach(string w in s.Substring(8).Split(',')) + { + string ws = w; + // lame way to chop off the leading zeroes + while(ws.StartsWith("0")) + { + ws = ws.Substring(1); + } + StaticCompiler.SuppressWarning(ws); + } + } else if(s.StartsWith("-runtime:")) { // NOTE this is an undocumented option @@ -475,7 +490,7 @@ class IkvmcCompiler } if(options.mainClass == null && manifestMainClass != null && (options.guessFileKind || options.target != System.Reflection.Emit.PEFileKinds.Dll)) { - Console.Error.WriteLine("Note: using main class {0} based on jar manifest", manifestMainClass); + StaticCompiler.IssueMessage(Message.MainMethodFromManifest, manifestMainClass); options.mainClass = manifestMainClass; } try @@ -541,7 +556,7 @@ class IkvmcCompiler } if(resources.ContainsKey(ze.Name)) { - Console.Error.WriteLine("Warning: skipping resource (name clash): " + ze.Name); + StaticCompiler.IssueMessage(Message.DuplicateResourceName, ze.Name); } else { diff --git a/ikvmc/CompilerClassLoader.cs b/ikvmc/CompilerClassLoader.cs index c5117ca1..3d933ccb 100644 --- a/ikvmc/CompilerClassLoader.cs +++ b/ikvmc/CompilerClassLoader.cs @@ -165,7 +165,7 @@ namespace IKVM.Internal } catch(ClassFormatError x) { - Console.Error.WriteLine("Warning: class format error: {0}", x.Message); + StaticCompiler.IssueMessage(Message.ClassFormatError, x.Message); return null; } if(options.removeUnusedFields) @@ -196,7 +196,7 @@ namespace IKVM.Internal { args = new Type[] { typeof(string[]) }; } - MethodBuilder mainStub = this.ModuleBuilder.DefineGlobalMethod("main", MethodAttributes.Public | MethodAttributes.Static, typeof(int), args); + MethodBuilder mainStub = this.GetTypeWrapperFactory().ModuleBuilder.DefineGlobalMethod("main", MethodAttributes.Public | MethodAttributes.Static, typeof(int), args); if(apartmentAttributeType != null) { mainStub.SetCustomAttribute(new CustomAttributeBuilder(apartmentAttributeType.GetConstructor(Type.EmptyTypes), new object[0])); @@ -255,7 +255,7 @@ namespace IKVM.Internal Tracer.Info(Tracer.Compiler, "CompilerClassLoader.Save..."); DynamicClassLoader.FinishAll(false); - ModuleBuilder.CreateGlobalFunctions(); + GetTypeWrapperFactory().ModuleBuilder.CreateGlobalFunctions(); if(targetIsModule) { @@ -274,7 +274,7 @@ namespace IKVM.Internal internal void AddResources(Hashtable resources, bool compressedResources) { Tracer.Info(Tracer.Compiler, "CompilerClassLoader adding resources..."); - ModuleBuilder moduleBuilder = this.ModuleBuilder; + ModuleBuilder moduleBuilder = this.GetTypeWrapperFactory().ModuleBuilder; foreach(DictionaryEntry d in resources) { byte[] buf = (byte[])d.Value; @@ -419,7 +419,7 @@ namespace IKVM.Internal attrs |= TypeAttributes.Abstract; } string name = c.Name.Replace('/', '.'); - typeBuilder = classLoader.ModuleBuilder.DefineType(name, attrs, baseIsSealed ? typeof(object) : baseType); + typeBuilder = classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(name, attrs, baseIsSealed ? typeof(object) : baseType); if(c.Attributes != null) { foreach(IKVM.Internal.MapXml.Attribute custattr in c.Attributes) @@ -1756,7 +1756,7 @@ namespace IKVM.Internal { foreach(IKVM.Internal.MapXml.Attribute attr in assemblyAttributes) { - AttributeHelper.SetCustomAttribute(((AssemblyBuilder)this.ModuleBuilder.Assembly), attr); + AttributeHelper.SetCustomAttribute(this.GetTypeWrapperFactory().AssemblyBuilder, attr); } } } @@ -1791,6 +1791,25 @@ namespace IKVM.Internal internal string[] privatePackages; } + enum Message + { + // These are the informational messages + MainMethodFound = 1, + OutputFileIs = 2, + AutoAddRef = 3, + MainMethodFromManifest = 4, + // This is were the warnings start + StartWarnings = 100, + ClassNotFound = 100, + ClassFormatError = 101, + DuplicateClassName = 102, + IllegalAccessError = 103, + VerificationError = 104, + NoClassDefFoundError = 105, + GenericUnableToCompileError = 106, + DuplicateResourceName = 107, + } + class StaticCompiler { internal static Assembly runtimeAssembly; @@ -1833,6 +1852,78 @@ namespace IKVM.Internal return null; #endif } + + private static Hashtable suppressWarnings = new Hashtable(); + + internal static void SuppressWarning(string key) + { + suppressWarnings[key] = key; + } + + internal static void IssueMessage(Message msgId, params string[] values) + { + StringBuilder sb = new StringBuilder(); + sb.Append((int)msgId); + foreach(string s in values) + { + sb.Append(':').Append(s); + } + string key = sb.ToString(); + if(suppressWarnings.ContainsKey(key) + || suppressWarnings.ContainsKey(((int)msgId).ToString())) + { + return; + } + suppressWarnings.Add(key, key); + string msg; + switch(msgId) + { + case Message.MainMethodFound: + msg = "found main method in class \"{0}\""; + break; + case Message.OutputFileIs: + msg = "output file is \"{0}\""; + break; + case Message.AutoAddRef: + msg = "automatically adding reference to \"{0}\""; + break; + case Message.MainMethodFromManifest: + msg = "using main class \"{0}\" based on jar manifest"; + break; + case Message.ClassNotFound: + msg = "class \"{0}\" not found"; + break; + case Message.ClassFormatError: + msg = "class format error: \"{0}\""; + break; + case Message.DuplicateClassName: + msg = "duplicate class name: \"{0}\""; + break; + case Message.IllegalAccessError: + msg = "unable to compile class \"{0}\"" + Environment.NewLine + + " (illegal access error \"{1}\")"; + break; + case Message.VerificationError: + msg = "unable to compile class \"{0}\"" + Environment.NewLine + + " (verification error \"{1}\")"; + break; + case Message.NoClassDefFoundError: + msg = "unable to compile class \"{0}\"" + Environment.NewLine + + " (missing class \"{1}\")"; + break; + case Message.GenericUnableToCompileError: + msg = "unable to compile class \"{0}\"" + Environment.NewLine + + " (\"{1}\": \"{2}\")"; + break; + case Message.DuplicateResourceName: + msg = "skipping resource (name clash): \"{0}\""; + break; + default: + throw new InvalidProgramException(); + } + Console.Error.Write("{0} IKVMC{1:D4}: ", msgId < Message.StartWarnings ? "Note" : "Warning", (int)msgId); + Console.Error.WriteLine(msg, values); + } } class AotCompiler @@ -1960,7 +2051,7 @@ namespace IKVM.Internal { if(m.IsPublic && m.IsStatic && m.Name == "main" && m.Signature == "([Ljava.lang.String;)V") { - Console.Error.WriteLine("Note: found main method in class \"{0}\"", f.Name); + StaticCompiler.IssueMessage(Message.MainMethodFound, f.Name); options.mainClass = f.Name; break; } @@ -1992,7 +2083,7 @@ namespace IKVM.Internal } if(h.ContainsKey(name)) { - Console.Error.WriteLine("Warning: duplicate class name: {0}", name); + StaticCompiler.IssueMessage(Message.DuplicateClassName, name); excluded = true; } if(!excluded) @@ -2042,7 +2133,7 @@ namespace IKVM.Internal { options.path = options.assembly + ".exe"; } - Console.Error.WriteLine("Note: output file is \"{0}\"", options.path); + StaticCompiler.IssueMessage(Message.OutputFileIs, options.path); } if(options.targetIsModule) @@ -2097,7 +2188,7 @@ namespace IKVM.Internal return 1; } allReferencesAreStrongNamed &= IsSigned(JVM.CoreAssembly); - Console.Error.WriteLine("Note: automatically adding reference to \"{0}\"", JVM.CoreAssembly.Location); + StaticCompiler.IssueMessage(Message.AutoAddRef, JVM.CoreAssembly.Location); // we need to scan again for remapped types, now that we've loaded the core library ClassLoaderWrapper.LoadRemappedTypes(); } @@ -2156,23 +2247,19 @@ namespace IKVM.Internal } catch(IllegalAccessError x) { - Console.Error.WriteLine("Warning: unable to compile class \"{0}\"", s); - Console.Error.WriteLine(" (illegal access error \"{0}\")", x.Message); + StaticCompiler.IssueMessage(Message.IllegalAccessError, s, x.Message); } catch(VerifyError x) { - Console.Error.WriteLine("Warning: unable to compile class \"{0}\"", s); - Console.Error.WriteLine(" (verification error \"{0}\")", x.Message); + StaticCompiler.IssueMessage(Message.VerificationError, s, x.Message); } catch(NoClassDefFoundError x) { - Console.Error.WriteLine("Warning: unable to compile class \"{0}\"", s); - Console.Error.WriteLine(" (missing class \"{0}\")", x.Message); + StaticCompiler.IssueMessage(Message.NoClassDefFoundError, s, x.Message); } catch(RetargetableJavaException x) { - Console.Error.WriteLine("Warning: unable to compile class \"{0}\"", s); - Console.Error.WriteLine(" ({0}: \"{1}\")", x.GetType().Name, x.Message); + StaticCompiler.IssueMessage(Message.GenericUnableToCompileError, s, x.GetType().Name, x.Message); } } if(options.mainClass != null) @@ -2203,7 +2290,7 @@ namespace IKVM.Internal Console.Error.WriteLine("Error: redirected main method not supported"); return 1; } - if(method.DeclaringType.Assembly != loader.ModuleBuilder.Assembly + if(method.DeclaringType.Assembly != loader.GetTypeWrapperFactory().AssemblyBuilder && (!method.IsPublic || !method.DeclaringType.IsPublic)) { Console.Error.WriteLine("Error: external main method must be public and in a public class"); @@ -2243,9 +2330,9 @@ namespace IKVM.Internal if(options.fileversion != null) { CustomAttributeBuilder filever = new CustomAttributeBuilder(typeof(AssemblyFileVersionAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { options.fileversion }); - ((AssemblyBuilder)loader.ModuleBuilder.Assembly).SetCustomAttribute(filever); + loader.GetTypeWrapperFactory().AssemblyBuilder.SetCustomAttribute(filever); } - ((AssemblyBuilder)loader.ModuleBuilder.Assembly).DefineVersionInfoResource(); + loader.GetTypeWrapperFactory().AssemblyBuilder.DefineVersionInfoResource(); loader.Save(); return 0; } diff --git a/runtime/ClassLoaderWrapper.cs b/runtime/ClassLoaderWrapper.cs index 791fc0f9..c81e88c2 100644 --- a/runtime/ClassLoaderWrapper.cs +++ b/runtime/ClassLoaderWrapper.cs @@ -38,8 +38,10 @@ namespace IKVM.Internal { #if !COMPACT_FRAMEWORK internal abstract ModuleBuilder ModuleBuilder { get; } + internal abstract AssemblyBuilder AssemblyBuilder { get; } #endif internal abstract TypeWrapper DefineClassImpl(Hashtable types, ClassFile f, object protectionDomain); + internal abstract string AllocMangledName(string name); } class ClassLoaderWrapper @@ -200,13 +202,8 @@ namespace IKVM.Internal } return RegisterInitiatingLoader(tw); } - lock(this) - { - if(factory == null) - { - factory = CreateTypeWrapperFactory(); - } - } + // this will create the factory as a side effect + GetTypeWrapperFactory(); lock(factory) { lock(types.SyncRoot) @@ -238,6 +235,18 @@ namespace IKVM.Internal } } + internal TypeWrapperFactory GetTypeWrapperFactory() + { + lock(this) + { + if(factory == null) + { + factory = CreateTypeWrapperFactory(); + } + } + return factory; + } + protected virtual TypeWrapperFactory CreateTypeWrapperFactory() { #if COMPACT_FRAMEWORK @@ -247,23 +256,6 @@ namespace IKVM.Internal #endif } -#if !COMPACT_FRAMEWORK - internal virtual ModuleBuilder ModuleBuilder - { - get - { - lock(this) - { - if(factory == null) - { - factory = CreateTypeWrapperFactory(); - } - } - return factory.ModuleBuilder; - } - } -#endif - internal TypeWrapper LoadClassByDottedName(string name) { TypeWrapper type = LoadClassByDottedNameFastImpl(name, true); @@ -1127,7 +1119,11 @@ namespace IKVM.Internal // HACK we use a ReflectionOnlyClassLoader Java peer for the time being internal GenericClassLoader(ClassLoaderWrapper[] delegates) +#if STATIC_COMPILER + : base(null) +#else : base(JVM.Library.newReflectionOnlyClassLoader()) +#endif { this.delegates = delegates; } diff --git a/runtime/DynamicClassLoader.cs b/runtime/DynamicClassLoader.cs index 0f181010..c0f26aaa 100644 --- a/runtime/DynamicClassLoader.cs +++ b/runtime/DynamicClassLoader.cs @@ -105,14 +105,8 @@ namespace IKVM.Internal return type.TypeAsTBD.Assembly; } - internal override TypeWrapper DefineClassImpl(Hashtable types, ClassFile f, object protectionDomain) + internal override string AllocMangledName(string mangledTypeName) { - DynamicTypeWrapper type = CreateDynamicTypeWrapper(f); - // this step can throw a retargettable exception, if the class is incorrect - bool hasclinit; - type.CreateStep1(out hasclinit); - // now we can allocate the mangledTypeName, because the next step cannot fail - string mangledTypeName = f.Name; lock(dynamicTypes.SyncRoot) { // Ref.Emit doesn't like the "" name for types @@ -153,6 +147,17 @@ namespace IKVM.Internal } dynamicTypes.Add(mangledTypeName, null); } + return mangledTypeName; + } + + internal override TypeWrapper DefineClassImpl(Hashtable types, ClassFile f, object protectionDomain) + { + DynamicTypeWrapper type = CreateDynamicTypeWrapper(f); + // this step can throw a retargettable exception, if the class is incorrect + bool hasclinit; + type.CreateStep1(out hasclinit); + // now we can allocate the mangledTypeName, because the next step cannot fail + string mangledTypeName = AllocMangledName(f.Name); // This step actually creates the TypeBuilder. It is not allowed to throw any exceptions, // if an exception does occur, it is due to a programming error in the IKVM or CLR runtime // and will cause a CriticalFailure and exit the process. @@ -211,7 +216,7 @@ namespace IKVM.Internal ArrayList l = new ArrayList(dynamicTypes.Values); foreach(TypeWrapper tw in l) { - if(!done.ContainsKey(tw)) + if(tw != null && !done.ContainsKey(tw)) { more = true; done.Add(tw, tw); @@ -267,13 +272,21 @@ namespace IKVM.Internal } } + internal override AssemblyBuilder AssemblyBuilder + { + get + { + return (AssemblyBuilder)this.ModuleBuilder.Assembly; + } + } + protected virtual ModuleBuilder CreateModuleBuilder() { #if STATIC_COMPILER // HACK this is required because DelegateInnerClassTypeWrapper currently uses the ModuleBuilder // property to get a ModuleBuilder on the class loader that defined the delegate, // instead of the class loader that is using the delegate (as it probably should) - return ClassLoaderWrapper.GetBootstrapClassLoader().ModuleBuilder; + return ClassLoaderWrapper.GetBootstrapClassLoader().GetTypeWrapperFactory().ModuleBuilder; #else // STATIC_COMPILER AssemblyName name = new AssemblyName(); if(saveDebugImage) diff --git a/runtime/MemberWrapper.cs b/runtime/MemberWrapper.cs index 719510da..1b7278f6 100644 --- a/runtime/MemberWrapper.cs +++ b/runtime/MemberWrapper.cs @@ -1397,11 +1397,6 @@ namespace IKVM.Internal sealed class VolatileLongDoubleFieldWrapper : FieldWrapper { - private static MethodInfo volatileReadDouble = typeof(IKVM.Runtime.ByteCodeHelper).GetMethod("VolatileRead", new Type[] { Type.GetType("System.Double&") }); - private static MethodInfo volatileReadLong = typeof(IKVM.Runtime.ByteCodeHelper).GetMethod("VolatileRead", new Type[] { Type.GetType("System.Int64&") }); - private static MethodInfo volatileWriteDouble = typeof(IKVM.Runtime.ByteCodeHelper).GetMethod("VolatileWrite", new Type[] { Type.GetType("System.Double&"), typeof(double) }); - private static MethodInfo volatileWriteLong = typeof(IKVM.Runtime.ByteCodeHelper).GetMethod("VolatileWrite", new Type[] { Type.GetType("System.Int64&"), typeof(long) }); - internal VolatileLongDoubleFieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string name, string sig, ExModifiers modifiers) : base(declaringType, fieldType, name, sig, modifiers, fi) { @@ -1427,12 +1422,12 @@ namespace IKVM.Internal } if(FieldTypeWrapper == PrimitiveTypeWrapper.DOUBLE) { - ilgen.Emit(OpCodes.Call, volatileReadDouble); + ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.volatileReadDouble); } else { Debug.Assert(FieldTypeWrapper == PrimitiveTypeWrapper.LONG); - ilgen.Emit(OpCodes.Call, volatileReadLong); + ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.volatileReadLong); } } @@ -1456,12 +1451,12 @@ namespace IKVM.Internal ilgen.Emit(OpCodes.Ldloc, temp); if(FieldTypeWrapper == PrimitiveTypeWrapper.DOUBLE) { - ilgen.Emit(OpCodes.Call, volatileWriteDouble); + ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.volatileWriteDouble); } else { Debug.Assert(FieldTypeWrapper == PrimitiveTypeWrapper.LONG); - ilgen.Emit(OpCodes.Call, volatileWriteLong); + ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.volatileWriteLong); } } #endif diff --git a/runtime/TypeWrapper.cs b/runtime/TypeWrapper.cs index a901a9c9..7ac59e07 100644 --- a/runtime/TypeWrapper.cs +++ b/runtime/TypeWrapper.cs @@ -2713,31 +2713,19 @@ namespace IKVM.Internal class UnloadableTypeWrapper : TypeWrapper { -#if STATIC_COMPILER - private static Hashtable warningHashtable; -#endif - internal UnloadableTypeWrapper(string name) : base(TypeWrapper.UnloadableModifiersHack, name, null) { #if STATIC_COMPILER if(name != "") { - if(warningHashtable == null) - { - warningHashtable = new Hashtable(); - } if(name.StartsWith("[")) { int skip = 1; while(name[skip++] == '['); name = name.Substring(skip, name.Length - skip - 1); } - if(!warningHashtable.ContainsKey(name)) - { - warningHashtable.Add(name, name); - Console.Error.WriteLine("Warning: class \"{0}\" not found", name); - } + StaticCompiler.IssueMessage(Message.ClassNotFound, name); } #endif } @@ -3154,7 +3142,7 @@ namespace IKVM.Internal { get { - return classLoader.ModuleBuilder.Assembly; + return classLoader.GetTypeWrapperFactory().AssemblyBuilder; } } @@ -3531,7 +3519,7 @@ namespace IKVM.Internal else #endif // STATIC_COMPILER { - typeBuilder = wrapper.classLoader.ModuleBuilder.DefineType(mangledTypeName, typeAttribs, wrapper.BaseTypeWrapper.TypeAsBaseType); + typeBuilder = wrapper.classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(mangledTypeName, typeAttribs, wrapper.BaseTypeWrapper.TypeAsBaseType); } } #if STATIC_COMPILER @@ -4895,7 +4883,7 @@ namespace IKVM.Internal { typeAttributes |= TypeAttributes.NotPublic; } - attributeTypeBuilder = o.wrapper.classLoader.ModuleBuilder.DefineType(o.classFile.Name + "Attribute", typeAttributes, annotationAttributeBaseType.TypeAsBaseType); + attributeTypeBuilder = o.wrapper.classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(o.classFile.Name + "Attribute", typeAttributes, annotationAttributeBaseType.TypeAsBaseType); } if(o.wrapper.IsPublic) { @@ -6669,7 +6657,7 @@ namespace IKVM.Internal protected virtual TypeBuilder DefineType(string mangledTypeName, TypeAttributes typeAttribs) { - return classLoader.ModuleBuilder.DefineType(mangledTypeName, typeAttribs); + return classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineType(mangledTypeName, typeAttribs); } internal override MethodBase LinkMethod(MethodWrapper mw) @@ -6737,11 +6725,11 @@ namespace IKVM.Internal ConstructorInfo ci = mb as ConstructorInfo; if(ci != null) { - return classLoader.ModuleBuilder.GetConstructorToken(ci).Token; + return classLoader.GetTypeWrapperFactory().ModuleBuilder.GetConstructorToken(ci).Token; } else { - return classLoader.ModuleBuilder.GetMethodToken((MethodInfo)mb).Token; + return classLoader.GetTypeWrapperFactory().ModuleBuilder.GetMethodToken((MethodInfo)mb).Token; } } @@ -8085,9 +8073,6 @@ namespace IKVM.Internal return true; } - // this method returns a new TypeWrapper instance for each invocation (doesn't prevent duplicates) - // the caller is responsible for making sure that only one TypeWrapper with the specified name escapes - // out into the world internal static TypeWrapper CreateDotNetTypeWrapper(ClassLoaderWrapper loader, string name) { Type type = loader.GetType(DemangleTypeName(name)); @@ -8099,7 +8084,7 @@ namespace IKVM.Internal // check the name to make sure that the canonical name was used if(tw.Name == name) { - return tw; + return loader.RegisterInitiatingLoader(tw); } } return null; @@ -8110,7 +8095,7 @@ namespace IKVM.Internal private Type delegateType; private Type type; - internal DelegateInnerClassTypeWrapper(string name, Type delegateType) + internal DelegateInnerClassTypeWrapper(string name, Type delegateType, ClassLoaderWrapper classLoader) : base(Modifiers.Public | Modifiers.Interface | Modifiers.Abstract, name, null) { this.delegateType = delegateType; @@ -8132,11 +8117,13 @@ namespace IKVM.Internal if(!delegateType.Assembly.ReflectionOnly) #endif // WHIDBEY && !STATIC_COMPILER { - // HACK this is an ugly hack to obtain the global ModuleBuilder - ModuleBuilder moduleBuilder = ClassLoaderWrapper.GetBootstrapClassLoader().ModuleBuilder; + // HACK the class loader that defines the delegate is hardly the right one for this inner class, + // but we know that we'll only ever generate one assembly, so this will work. + TypeWrapperFactory factory = classLoader.GetTypeWrapperFactory(); + ModuleBuilder moduleBuilder = factory.ModuleBuilder; // NOTE we chop off the prefix ("cli.") because C++/CLI doesn't like assemblies // that have types in the cli namespace (lame!) - TypeBuilder typeBuilder = moduleBuilder.DefineType(Name.Substring(NamePrefix.Length), TypeAttributes.NotPublic | TypeAttributes.Interface | TypeAttributes.Abstract); + TypeBuilder typeBuilder = moduleBuilder.DefineType(factory.AllocMangledName(Name.Substring(NamePrefix.Length)), TypeAttributes.NotPublic | TypeAttributes.Interface | TypeAttributes.Abstract); #if STATIC_COMPILER AttributeHelper.HideFromJava(typeBuilder); #endif //STATIC_COMPILER @@ -9221,7 +9208,8 @@ namespace IKVM.Internal } if(IsDelegate(type)) { - list.Add(GetClassLoader().RegisterInitiatingLoader(new DelegateInnerClassTypeWrapper(Name + DelegateInterfaceSuffix, type))); + ClassLoaderWrapper classLoader = GetClassLoader(); + list.Add(classLoader.RegisterInitiatingLoader(new DelegateInnerClassTypeWrapper(Name + DelegateInterfaceSuffix, type, classLoader))); } if(IsAttribute(type)) { diff --git a/runtime/compiler.cs b/runtime/compiler.cs index 792868ee..f36a9391 100644 --- a/runtime/compiler.cs +++ b/runtime/compiler.cs @@ -72,6 +72,10 @@ class ByteCodeHelperMethods internal static readonly MethodInfo VerboseCastFailure; internal static readonly MethodInfo SkipFinalizer; internal static readonly MethodInfo DynamicInstanceOf; + internal static readonly MethodInfo volatileReadDouble; + internal static readonly MethodInfo volatileReadLong; + internal static readonly MethodInfo volatileWriteDouble; + internal static readonly MethodInfo volatileWriteLong; static ByteCodeHelperMethods() { @@ -110,6 +114,10 @@ class ByteCodeHelperMethods VerboseCastFailure = typeofByteCodeHelper.GetMethod("VerboseCastFailure"); SkipFinalizer = typeofByteCodeHelper.GetMethod("SkipFinalizer"); DynamicInstanceOf = typeofByteCodeHelper.GetMethod("DynamicInstanceOf"); + volatileReadDouble = typeofByteCodeHelper.GetMethod("VolatileRead", new Type[] { Type.GetType("System.Double&") }); + volatileReadLong = typeofByteCodeHelper.GetMethod("VolatileRead", new Type[] { Type.GetType("System.Int64&") }); + volatileWriteDouble = typeofByteCodeHelper.GetMethod("VolatileWrite", new Type[] { Type.GetType("System.Double&"), typeof(double) }); + volatileWriteLong = typeofByteCodeHelper.GetMethod("VolatileWrite", new Type[] { Type.GetType("System.Int64&"), typeof(long) }); } } @@ -803,7 +811,7 @@ class Compiler package = index == -1 ? "" : package.Substring(0, index).Replace('.', '/'); sourcefile = new System.IO.FileInfo(JVM.SourcePath + "/" + package + "/" + sourcefile).FullName; } - symboldocument = classLoader.ModuleBuilder.DefineDocument(sourcefile, SymLanguageType.Java, Guid.Empty, SymDocumentType.Text); + symboldocument = classLoader.GetTypeWrapperFactory().ModuleBuilder.DefineDocument(sourcefile, SymLanguageType.Java, Guid.Empty, SymDocumentType.Text); // the very first instruction in the method must have an associated line number, to be able // to step into the method in Visual Studio .NET ClassFile.Method.LineNumberTableEntry[] table = m.LineNumberTableAttribute;