This commit is contained in:
jfrijters 2006-07-26 14:16:52 +00:00
Родитель 12e330ed91
Коммит 29ba470d78
8 изменённых файлов: 198 добавлений и 96 удалений

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

@ -979,7 +979,7 @@ namespace IKVM.Internal
{ {
typeAttribs &= ~(TypeAttributes.Interface | TypeAttributes.Abstract); typeAttribs &= ~(TypeAttributes.Interface | TypeAttributes.Abstract);
typeAttribs |= TypeAttributes.Class | TypeAttributes.Sealed; 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.SetGhostInterface(typeBuilder);
AttributeHelper.SetModifiers(typeBuilder, Modifiers, IsInternal); AttributeHelper.SetModifiers(typeBuilder, Modifiers, IsInternal);
ghostRefField = typeBuilder.DefineField("__<ref>", typeof(object), FieldAttributes.Public | FieldAttributes.SpecialName); ghostRefField = typeBuilder.DefineField("__<ref>", typeof(object), FieldAttributes.Public | FieldAttributes.SpecialName);

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

@ -94,6 +94,7 @@ class IkvmcCompiler
Console.Error.WriteLine("usage: ikvmc [-options] <classOrJar1> ... <classOrJarN>"); Console.Error.WriteLine("usage: ikvmc [-options] <classOrJar1> ... <classOrJarN>");
Console.Error.WriteLine(); Console.Error.WriteLine();
Console.Error.WriteLine("options:"); Console.Error.WriteLine("options:");
Console.Error.WriteLine(" @<filename> Read more options from file");
Console.Error.WriteLine(" -out:<outputfile> Specify the output filename"); Console.Error.WriteLine(" -out:<outputfile> Specify the output filename");
Console.Error.WriteLine(" -assembly:<name> Specify assembly name"); Console.Error.WriteLine(" -assembly:<name> Specify assembly name");
Console.Error.WriteLine(" -target:exe Build a console executable"); Console.Error.WriteLine(" -target:exe Build a console executable");
@ -134,6 +135,7 @@ class IkvmcCompiler
Console.Error.WriteLine(" of initializer methods"); Console.Error.WriteLine(" of initializer methods");
Console.Error.WriteLine(" -privatepackage:<prefix> Mark all classes with a package name starting"); Console.Error.WriteLine(" -privatepackage:<prefix> Mark all classes with a package name starting");
Console.Error.WriteLine(" with <prefix> as internal to the assembly"); Console.Error.WriteLine(" with <prefix> as internal to the assembly");
Console.Error.WriteLine(" -nowarn:<warning[:key]> Suppress specified warnings");
return 1; return 1;
} }
foreach(string s in arglist) foreach(string s in arglist)
@ -289,7 +291,7 @@ class IkvmcCompiler
string[] spec = s.Substring(10).Split('='); string[] spec = s.Substring(10).Split('=');
if(resources.ContainsKey(spec[0])) if(resources.ContainsKey(spec[0]))
{ {
Console.Error.WriteLine("Warning: skipping resource (name clash): " + spec[0]); StaticCompiler.IssueMessage(Message.DuplicateResourceName, spec[0]);
} }
else else
{ {
@ -400,6 +402,19 @@ class IkvmcCompiler
options.privatePackages = temp; 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:")) else if(s.StartsWith("-runtime:"))
{ {
// NOTE this is an undocumented option // 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)) 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; options.mainClass = manifestMainClass;
} }
try try
@ -541,7 +556,7 @@ class IkvmcCompiler
} }
if(resources.ContainsKey(ze.Name)) if(resources.ContainsKey(ze.Name))
{ {
Console.Error.WriteLine("Warning: skipping resource (name clash): " + ze.Name); StaticCompiler.IssueMessage(Message.DuplicateResourceName, ze.Name);
} }
else else
{ {

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

@ -165,7 +165,7 @@ namespace IKVM.Internal
} }
catch(ClassFormatError x) catch(ClassFormatError x)
{ {
Console.Error.WriteLine("Warning: class format error: {0}", x.Message); StaticCompiler.IssueMessage(Message.ClassFormatError, x.Message);
return null; return null;
} }
if(options.removeUnusedFields) if(options.removeUnusedFields)
@ -196,7 +196,7 @@ namespace IKVM.Internal
{ {
args = new Type[] { typeof(string[]) }; 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) if(apartmentAttributeType != null)
{ {
mainStub.SetCustomAttribute(new CustomAttributeBuilder(apartmentAttributeType.GetConstructor(Type.EmptyTypes), new object[0])); mainStub.SetCustomAttribute(new CustomAttributeBuilder(apartmentAttributeType.GetConstructor(Type.EmptyTypes), new object[0]));
@ -255,7 +255,7 @@ namespace IKVM.Internal
Tracer.Info(Tracer.Compiler, "CompilerClassLoader.Save..."); Tracer.Info(Tracer.Compiler, "CompilerClassLoader.Save...");
DynamicClassLoader.FinishAll(false); DynamicClassLoader.FinishAll(false);
ModuleBuilder.CreateGlobalFunctions(); GetTypeWrapperFactory().ModuleBuilder.CreateGlobalFunctions();
if(targetIsModule) if(targetIsModule)
{ {
@ -274,7 +274,7 @@ namespace IKVM.Internal
internal void AddResources(Hashtable resources, bool compressedResources) internal void AddResources(Hashtable resources, bool compressedResources)
{ {
Tracer.Info(Tracer.Compiler, "CompilerClassLoader adding resources..."); Tracer.Info(Tracer.Compiler, "CompilerClassLoader adding resources...");
ModuleBuilder moduleBuilder = this.ModuleBuilder; ModuleBuilder moduleBuilder = this.GetTypeWrapperFactory().ModuleBuilder;
foreach(DictionaryEntry d in resources) foreach(DictionaryEntry d in resources)
{ {
byte[] buf = (byte[])d.Value; byte[] buf = (byte[])d.Value;
@ -419,7 +419,7 @@ namespace IKVM.Internal
attrs |= TypeAttributes.Abstract; attrs |= TypeAttributes.Abstract;
} }
string name = c.Name.Replace('/', '.'); 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) if(c.Attributes != null)
{ {
foreach(IKVM.Internal.MapXml.Attribute custattr in c.Attributes) foreach(IKVM.Internal.MapXml.Attribute custattr in c.Attributes)
@ -1756,7 +1756,7 @@ namespace IKVM.Internal
{ {
foreach(IKVM.Internal.MapXml.Attribute attr in assemblyAttributes) 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; 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 class StaticCompiler
{ {
internal static Assembly runtimeAssembly; internal static Assembly runtimeAssembly;
@ -1833,6 +1852,78 @@ namespace IKVM.Internal
return null; return null;
#endif #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 class AotCompiler
@ -1960,7 +2051,7 @@ namespace IKVM.Internal
{ {
if(m.IsPublic && m.IsStatic && m.Name == "main" && m.Signature == "([Ljava.lang.String;)V") 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; options.mainClass = f.Name;
break; break;
} }
@ -1992,7 +2083,7 @@ namespace IKVM.Internal
} }
if(h.ContainsKey(name)) if(h.ContainsKey(name))
{ {
Console.Error.WriteLine("Warning: duplicate class name: {0}", name); StaticCompiler.IssueMessage(Message.DuplicateClassName, name);
excluded = true; excluded = true;
} }
if(!excluded) if(!excluded)
@ -2042,7 +2133,7 @@ namespace IKVM.Internal
{ {
options.path = options.assembly + ".exe"; options.path = options.assembly + ".exe";
} }
Console.Error.WriteLine("Note: output file is \"{0}\"", options.path); StaticCompiler.IssueMessage(Message.OutputFileIs, options.path);
} }
if(options.targetIsModule) if(options.targetIsModule)
@ -2097,7 +2188,7 @@ namespace IKVM.Internal
return 1; return 1;
} }
allReferencesAreStrongNamed &= IsSigned(JVM.CoreAssembly); 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 // we need to scan again for remapped types, now that we've loaded the core library
ClassLoaderWrapper.LoadRemappedTypes(); ClassLoaderWrapper.LoadRemappedTypes();
} }
@ -2156,23 +2247,19 @@ namespace IKVM.Internal
} }
catch(IllegalAccessError x) catch(IllegalAccessError x)
{ {
Console.Error.WriteLine("Warning: unable to compile class \"{0}\"", s); StaticCompiler.IssueMessage(Message.IllegalAccessError, s, x.Message);
Console.Error.WriteLine(" (illegal access error \"{0}\")", x.Message);
} }
catch(VerifyError x) catch(VerifyError x)
{ {
Console.Error.WriteLine("Warning: unable to compile class \"{0}\"", s); StaticCompiler.IssueMessage(Message.VerificationError, s, x.Message);
Console.Error.WriteLine(" (verification error \"{0}\")", x.Message);
} }
catch(NoClassDefFoundError x) catch(NoClassDefFoundError x)
{ {
Console.Error.WriteLine("Warning: unable to compile class \"{0}\"", s); StaticCompiler.IssueMessage(Message.NoClassDefFoundError, s, x.Message);
Console.Error.WriteLine(" (missing class \"{0}\")", x.Message);
} }
catch(RetargetableJavaException x) catch(RetargetableJavaException x)
{ {
Console.Error.WriteLine("Warning: unable to compile class \"{0}\"", s); StaticCompiler.IssueMessage(Message.GenericUnableToCompileError, s, x.GetType().Name, x.Message);
Console.Error.WriteLine(" ({0}: \"{1}\")", x.GetType().Name, x.Message);
} }
} }
if(options.mainClass != null) if(options.mainClass != null)
@ -2203,7 +2290,7 @@ namespace IKVM.Internal
Console.Error.WriteLine("Error: redirected main method not supported"); Console.Error.WriteLine("Error: redirected main method not supported");
return 1; return 1;
} }
if(method.DeclaringType.Assembly != loader.ModuleBuilder.Assembly if(method.DeclaringType.Assembly != loader.GetTypeWrapperFactory().AssemblyBuilder
&& (!method.IsPublic || !method.DeclaringType.IsPublic)) && (!method.IsPublic || !method.DeclaringType.IsPublic))
{ {
Console.Error.WriteLine("Error: external main method must be public and in a public class"); 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) if(options.fileversion != null)
{ {
CustomAttributeBuilder filever = new CustomAttributeBuilder(typeof(AssemblyFileVersionAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { options.fileversion }); 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(); loader.Save();
return 0; return 0;
} }

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

@ -38,8 +38,10 @@ namespace IKVM.Internal
{ {
#if !COMPACT_FRAMEWORK #if !COMPACT_FRAMEWORK
internal abstract ModuleBuilder ModuleBuilder { get; } internal abstract ModuleBuilder ModuleBuilder { get; }
internal abstract AssemblyBuilder AssemblyBuilder { get; }
#endif #endif
internal abstract TypeWrapper DefineClassImpl(Hashtable types, ClassFile f, object protectionDomain); internal abstract TypeWrapper DefineClassImpl(Hashtable types, ClassFile f, object protectionDomain);
internal abstract string AllocMangledName(string name);
} }
class ClassLoaderWrapper class ClassLoaderWrapper
@ -200,13 +202,8 @@ namespace IKVM.Internal
} }
return RegisterInitiatingLoader(tw); return RegisterInitiatingLoader(tw);
} }
lock(this) // this will create the factory as a side effect
{ GetTypeWrapperFactory();
if(factory == null)
{
factory = CreateTypeWrapperFactory();
}
}
lock(factory) lock(factory)
{ {
lock(types.SyncRoot) lock(types.SyncRoot)
@ -238,19 +235,7 @@ namespace IKVM.Internal
} }
} }
protected virtual TypeWrapperFactory CreateTypeWrapperFactory() internal TypeWrapperFactory GetTypeWrapperFactory()
{
#if COMPACT_FRAMEWORK
throw new NoClassDefFoundError("Class loading is not supported on the Compact Framework");
#else
return new DynamicClassLoader(this);
#endif
}
#if !COMPACT_FRAMEWORK
internal virtual ModuleBuilder ModuleBuilder
{
get
{ {
lock(this) lock(this)
{ {
@ -259,10 +244,17 @@ namespace IKVM.Internal
factory = CreateTypeWrapperFactory(); factory = CreateTypeWrapperFactory();
} }
} }
return factory.ModuleBuilder; return factory;
}
} }
protected virtual TypeWrapperFactory CreateTypeWrapperFactory()
{
#if COMPACT_FRAMEWORK
throw new NoClassDefFoundError("Class loading is not supported on the Compact Framework");
#else
return new DynamicClassLoader(this);
#endif #endif
}
internal TypeWrapper LoadClassByDottedName(string name) internal TypeWrapper LoadClassByDottedName(string name)
{ {
@ -1127,7 +1119,11 @@ namespace IKVM.Internal
// HACK we use a ReflectionOnlyClassLoader Java peer for the time being // HACK we use a ReflectionOnlyClassLoader Java peer for the time being
internal GenericClassLoader(ClassLoaderWrapper[] delegates) internal GenericClassLoader(ClassLoaderWrapper[] delegates)
#if STATIC_COMPILER
: base(null)
#else
: base(JVM.Library.newReflectionOnlyClassLoader()) : base(JVM.Library.newReflectionOnlyClassLoader())
#endif
{ {
this.delegates = delegates; this.delegates = delegates;
} }

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

@ -105,14 +105,8 @@ namespace IKVM.Internal
return type.TypeAsTBD.Assembly; 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) lock(dynamicTypes.SyncRoot)
{ {
// Ref.Emit doesn't like the "<Module>" name for types // Ref.Emit doesn't like the "<Module>" name for types
@ -153,6 +147,17 @@ namespace IKVM.Internal
} }
dynamicTypes.Add(mangledTypeName, null); 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, // 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 // 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. // and will cause a CriticalFailure and exit the process.
@ -211,7 +216,7 @@ namespace IKVM.Internal
ArrayList l = new ArrayList(dynamicTypes.Values); ArrayList l = new ArrayList(dynamicTypes.Values);
foreach(TypeWrapper tw in l) foreach(TypeWrapper tw in l)
{ {
if(!done.ContainsKey(tw)) if(tw != null && !done.ContainsKey(tw))
{ {
more = true; more = true;
done.Add(tw, tw); 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() protected virtual ModuleBuilder CreateModuleBuilder()
{ {
#if STATIC_COMPILER #if STATIC_COMPILER
// HACK this is required because DelegateInnerClassTypeWrapper currently uses the ModuleBuilder // HACK this is required because DelegateInnerClassTypeWrapper currently uses the ModuleBuilder
// property to get a ModuleBuilder on the class loader that defined the delegate, // 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) // 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 #else // STATIC_COMPILER
AssemblyName name = new AssemblyName(); AssemblyName name = new AssemblyName();
if(saveDebugImage) if(saveDebugImage)

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

@ -1397,11 +1397,6 @@ namespace IKVM.Internal
sealed class VolatileLongDoubleFieldWrapper : FieldWrapper 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) internal VolatileLongDoubleFieldWrapper(TypeWrapper declaringType, TypeWrapper fieldType, FieldInfo fi, string name, string sig, ExModifiers modifiers)
: base(declaringType, fieldType, name, sig, modifiers, fi) : base(declaringType, fieldType, name, sig, modifiers, fi)
{ {
@ -1427,12 +1422,12 @@ namespace IKVM.Internal
} }
if(FieldTypeWrapper == PrimitiveTypeWrapper.DOUBLE) if(FieldTypeWrapper == PrimitiveTypeWrapper.DOUBLE)
{ {
ilgen.Emit(OpCodes.Call, volatileReadDouble); ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.volatileReadDouble);
} }
else else
{ {
Debug.Assert(FieldTypeWrapper == PrimitiveTypeWrapper.LONG); 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); ilgen.Emit(OpCodes.Ldloc, temp);
if(FieldTypeWrapper == PrimitiveTypeWrapper.DOUBLE) if(FieldTypeWrapper == PrimitiveTypeWrapper.DOUBLE)
{ {
ilgen.Emit(OpCodes.Call, volatileWriteDouble); ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.volatileWriteDouble);
} }
else else
{ {
Debug.Assert(FieldTypeWrapper == PrimitiveTypeWrapper.LONG); Debug.Assert(FieldTypeWrapper == PrimitiveTypeWrapper.LONG);
ilgen.Emit(OpCodes.Call, volatileWriteLong); ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.volatileWriteLong);
} }
} }
#endif #endif

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

@ -2713,31 +2713,19 @@ namespace IKVM.Internal
class UnloadableTypeWrapper : TypeWrapper class UnloadableTypeWrapper : TypeWrapper
{ {
#if STATIC_COMPILER
private static Hashtable warningHashtable;
#endif
internal UnloadableTypeWrapper(string name) internal UnloadableTypeWrapper(string name)
: base(TypeWrapper.UnloadableModifiersHack, name, null) : base(TypeWrapper.UnloadableModifiersHack, name, null)
{ {
#if STATIC_COMPILER #if STATIC_COMPILER
if(name != "<verifier>") if(name != "<verifier>")
{ {
if(warningHashtable == null)
{
warningHashtable = new Hashtable();
}
if(name.StartsWith("[")) if(name.StartsWith("["))
{ {
int skip = 1; int skip = 1;
while(name[skip++] == '['); while(name[skip++] == '[');
name = name.Substring(skip, name.Length - skip - 1); name = name.Substring(skip, name.Length - skip - 1);
} }
if(!warningHashtable.ContainsKey(name)) StaticCompiler.IssueMessage(Message.ClassNotFound, name);
{
warningHashtable.Add(name, name);
Console.Error.WriteLine("Warning: class \"{0}\" not found", name);
}
} }
#endif #endif
} }
@ -3154,7 +3142,7 @@ namespace IKVM.Internal
{ {
get get
{ {
return classLoader.ModuleBuilder.Assembly; return classLoader.GetTypeWrapperFactory().AssemblyBuilder;
} }
} }
@ -3531,7 +3519,7 @@ namespace IKVM.Internal
else else
#endif // STATIC_COMPILER #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 #if STATIC_COMPILER
@ -4895,7 +4883,7 @@ namespace IKVM.Internal
{ {
typeAttributes |= TypeAttributes.NotPublic; 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) if(o.wrapper.IsPublic)
{ {
@ -6669,7 +6657,7 @@ namespace IKVM.Internal
protected virtual TypeBuilder DefineType(string mangledTypeName, TypeAttributes typeAttribs) 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) internal override MethodBase LinkMethod(MethodWrapper mw)
@ -6737,11 +6725,11 @@ namespace IKVM.Internal
ConstructorInfo ci = mb as ConstructorInfo; ConstructorInfo ci = mb as ConstructorInfo;
if(ci != null) if(ci != null)
{ {
return classLoader.ModuleBuilder.GetConstructorToken(ci).Token; return classLoader.GetTypeWrapperFactory().ModuleBuilder.GetConstructorToken(ci).Token;
} }
else 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; 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) internal static TypeWrapper CreateDotNetTypeWrapper(ClassLoaderWrapper loader, string name)
{ {
Type type = loader.GetType(DemangleTypeName(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 // check the name to make sure that the canonical name was used
if(tw.Name == name) if(tw.Name == name)
{ {
return tw; return loader.RegisterInitiatingLoader(tw);
} }
} }
return null; return null;
@ -8110,7 +8095,7 @@ namespace IKVM.Internal
private Type delegateType; private Type delegateType;
private Type type; 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) : base(Modifiers.Public | Modifiers.Interface | Modifiers.Abstract, name, null)
{ {
this.delegateType = delegateType; this.delegateType = delegateType;
@ -8132,11 +8117,13 @@ namespace IKVM.Internal
if(!delegateType.Assembly.ReflectionOnly) if(!delegateType.Assembly.ReflectionOnly)
#endif // WHIDBEY && !STATIC_COMPILER #endif // WHIDBEY && !STATIC_COMPILER
{ {
// HACK this is an ugly hack to obtain the global ModuleBuilder // HACK the class loader that defines the delegate is hardly the right one for this inner class,
ModuleBuilder moduleBuilder = ClassLoaderWrapper.GetBootstrapClassLoader().ModuleBuilder; // 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 // NOTE we chop off the prefix ("cli.") because C++/CLI doesn't like assemblies
// that have types in the cli namespace (lame!) // 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 #if STATIC_COMPILER
AttributeHelper.HideFromJava(typeBuilder); AttributeHelper.HideFromJava(typeBuilder);
#endif //STATIC_COMPILER #endif //STATIC_COMPILER
@ -9221,7 +9208,8 @@ namespace IKVM.Internal
} }
if(IsDelegate(type)) 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)) if(IsAttribute(type))
{ {

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

@ -72,6 +72,10 @@ class ByteCodeHelperMethods
internal static readonly MethodInfo VerboseCastFailure; internal static readonly MethodInfo VerboseCastFailure;
internal static readonly MethodInfo SkipFinalizer; internal static readonly MethodInfo SkipFinalizer;
internal static readonly MethodInfo DynamicInstanceOf; 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() static ByteCodeHelperMethods()
{ {
@ -110,6 +114,10 @@ class ByteCodeHelperMethods
VerboseCastFailure = typeofByteCodeHelper.GetMethod("VerboseCastFailure"); VerboseCastFailure = typeofByteCodeHelper.GetMethod("VerboseCastFailure");
SkipFinalizer = typeofByteCodeHelper.GetMethod("SkipFinalizer"); SkipFinalizer = typeofByteCodeHelper.GetMethod("SkipFinalizer");
DynamicInstanceOf = typeofByteCodeHelper.GetMethod("DynamicInstanceOf"); 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('.', '/'); package = index == -1 ? "" : package.Substring(0, index).Replace('.', '/');
sourcefile = new System.IO.FileInfo(JVM.SourcePath + "/" + package + "/" + sourcefile).FullName; 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 // 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 // to step into the method in Visual Studio .NET
ClassFile.Method.LineNumberTableEntry[] table = m.LineNumberTableAttribute; ClassFile.Method.LineNumberTableEntry[] table = m.LineNumberTableAttribute;