Moved secondary assembly loading (from a shared class loader group) to an explicit step early in the compilation process. Referencing a secondary assembly is now an error, instead of a warning.

This commit is contained in:
jfrijters 2013-01-15 14:55:50 +00:00
Родитель 81f663b7de
Коммит 0a155fdaad
4 изменённых файлов: 45 добавлений и 36 удалений

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

@ -32,7 +32,6 @@ namespace IKVM.Internal
sealed class AssemblyResolver sealed class AssemblyResolver
{ {
private readonly List<string> libpath = new List<string>(); private readonly List<string> libpath = new List<string>();
private readonly Dictionary<string, string> hintpaths = new Dictionary<string, string>();
private Universe universe; private Universe universe;
private Version mscorlibVersion; private Version mscorlibVersion;
@ -276,15 +275,6 @@ namespace IKVM.Internal
return LoadFile(path); return LoadFile(path);
} }
} }
string hintpath;
if (hintpaths.TryGetValue(name.FullName, out hintpath))
{
string path = Path.Combine(hintpath, name.Name + ".dll");
if (File.Exists(path) && Match(AssemblyName.GetAssemblyName(path), name, ref previousMatch, ref previousMatchLevel))
{
return LoadFile(path);
}
}
if (previousMatch != null) if (previousMatch != null)
{ {
if (previousMatchLevel == 2) if (previousMatchLevel == 2)
@ -437,10 +427,5 @@ namespace IKVM.Internal
} }
} }
} }
internal void AddHintPath(string assemblyName, string path)
{
hintpaths.Add(assemblyName, path);
}
} }
} }

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

@ -30,6 +30,7 @@ using ICSharpCode.SharpZipLib.Zip;
using IKVM.Internal; using IKVM.Internal;
using IKVM.Reflection; using IKVM.Reflection;
using IKVM.Reflection.Emit; using IKVM.Reflection.Emit;
using Type = IKVM.Reflection.Type;
sealed class FatalCompilerErrorException : Exception sealed class FatalCompilerErrorException : Exception
{ {
@ -1125,6 +1126,21 @@ sealed class IkvmcCompiler
} }
} }
} }
// verify that we didn't reference any secondary assemblies of a shared class loader group
foreach (CompilerOptions target in targets)
{
if (target.references != null)
{
foreach (Assembly asm in target.references)
{
Type forwarder = asm.GetType("__<MainAssembly>");
if (forwarder != null && forwarder.Assembly != asm)
{
StaticCompiler.IssueMessage(Message.NonPrimaryAssemblyReference, asm.Location, forwarder.Assembly.GetName().Name);
}
}
}
}
// add legacy references (from stub files) // add legacy references (from stub files)
foreach (CompilerOptions target in targets) foreach (CompilerOptions target in targets)
{ {
@ -1133,6 +1149,17 @@ sealed class IkvmcCompiler
ArrayAppend(ref target.references, resolver.LegacyLoad(new AssemblyName(assemblyName), null)); ArrayAppend(ref target.references, resolver.LegacyLoad(new AssemblyName(assemblyName), null));
} }
} }
// now pre-load the secondary assemblies of any shared class loader groups
foreach (CompilerOptions target in targets)
{
if (target.references != null)
{
foreach (Assembly asm in target.references)
{
AssemblyClassLoader.PreloadExportedAssemblies(asm);
}
}
}
} }
private static void ArrayAppend<T>(ref T[] array, T element) private static void ArrayAppend<T>(ref T[] array, T element)

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

@ -2831,10 +2831,6 @@ namespace IKVM.Internal
for(int i = 0; i < references.Count; i++) for(int i = 0; i < references.Count; i++)
{ {
AssemblyClassLoader acl = AssemblyClassLoader.FromAssembly(references[i]); AssemblyClassLoader acl = AssemblyClassLoader.FromAssembly(references[i]);
if (acl.MainAssembly != references[i])
{
StaticCompiler.IssueMessage(options, Message.NonPrimaryAssemblyReference, references[i].GetName().Name, acl.MainAssembly.GetName().Name);
}
if (Array.IndexOf(referencedAssemblies, acl) != -1) if (Array.IndexOf(referencedAssemblies, acl) != -1)
{ {
StaticCompiler.IssueMessage(options, Message.DuplicateAssemblyReference, acl.MainAssembly.FullName); StaticCompiler.IssueMessage(options, Message.DuplicateAssemblyReference, acl.MainAssembly.FullName);
@ -2904,6 +2900,7 @@ namespace IKVM.Internal
} }
if(asm != null && IsCoreAssembly(asm)) if(asm != null && IsCoreAssembly(asm))
{ {
AssemblyClassLoader.PreloadExportedAssemblies(asm);
JVM.CoreAssembly = asm; JVM.CoreAssembly = asm;
break; break;
} }
@ -3437,7 +3434,6 @@ namespace IKVM.Internal
InterfaceMethodCantBeInternal = 128, InterfaceMethodCantBeInternal = 128,
DllExportMustBeStaticMethod = 129, DllExportMustBeStaticMethod = 129,
DllExportRequiresSupportedPlatform = 130, DllExportRequiresSupportedPlatform = 130,
NonPrimaryAssemblyReference = 131,
DuplicateAssemblyReference = 132, DuplicateAssemblyReference = 132,
UnableToResolveType = 133, UnableToResolveType = 133,
StubsAreDeprecated = 134, StubsAreDeprecated = 134,
@ -3456,6 +3452,7 @@ namespace IKVM.Internal
InvalidMemberSignatureInMapFile = 4010, InvalidMemberSignatureInMapFile = 4010,
InvalidPropertyNameInMapFile = 4011, InvalidPropertyNameInMapFile = 4011,
InvalidPropertySignatureInMapFile = 4012, InvalidPropertySignatureInMapFile = 4012,
NonPrimaryAssemblyReference = 4013,
// Fatal errors // Fatal errors
ResponseFileDepthExceeded = 5000, ResponseFileDepthExceeded = 5000,
ErrorReadingFile = 5001, ErrorReadingFile = 5001,
@ -3742,7 +3739,7 @@ namespace IKVM.Internal
msg = "Ignoring @ikvm.lang.DllExport annotation due to unsupported target platform"; msg = "Ignoring @ikvm.lang.DllExport annotation due to unsupported target platform";
break; break;
case Message.NonPrimaryAssemblyReference: case Message.NonPrimaryAssemblyReference:
msg = "Referenced assembly \"{0}\" is not the primary assembly of a shared class loader group, referencing primary assembly \"{1}\" instead"; msg = "Referenced assembly \"{0}\" is not the primary assembly of a shared class loader group, please reference primary assembly \"{1}\" instead";
break; break;
case Message.DuplicateAssemblyReference: case Message.DuplicateAssemblyReference:
msg = "Duplicate assembly reference \"{0}\""; msg = "Duplicate assembly reference \"{0}\"";

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

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2002-2010 Jeroen Frijters Copyright (C) 2002-2013 Jeroen Frijters
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -392,8 +392,11 @@ namespace IKVM.Internal
{ {
this.assemblyLoader = new AssemblyLoader(assembly); this.assemblyLoader = new AssemblyLoader(assembly);
this.references = fixedReferences; this.references = fixedReferences;
}
#if STATIC_COMPILER #if STATIC_COMPILER
internal static void PreloadExportedAssemblies(Assembly assembly)
{
if (assembly.GetManifestResourceInfo("ikvm.exports") != null) if (assembly.GetManifestResourceInfo("ikvm.exports") != null)
{ {
using (Stream stream = assembly.GetManifestResourceStream("ikvm.exports")) using (Stream stream = assembly.GetManifestResourceStream("ikvm.exports"))
@ -404,19 +407,23 @@ namespace IKVM.Internal
{ {
string assemblyName = rdr.ReadString(); string assemblyName = rdr.ReadString();
int typeCount = rdr.ReadInt32(); int typeCount = rdr.ReadInt32();
for (int j = 0; j < typeCount; j++)
{
rdr.ReadInt32();
}
if (typeCount != 0) if (typeCount != 0)
{ {
IkvmcCompiler.resolver.AddHintPath(assemblyName, Path.GetDirectoryName(assembly.Location)); for (int j = 0; j < typeCount; j++)
{
rdr.ReadInt32();
}
try
{
StaticCompiler.LoadFile(assembly.Location + "/../" + new AssemblyName(assemblyName).Name + ".dll");
}
catch { }
} }
} }
} }
} }
#endif
} }
#endif
private void DoInitializeExports() private void DoInitializeExports()
{ {
@ -534,14 +541,7 @@ namespace IKVM.Internal
try try
{ {
#if STATIC_COMPILER || STUB_GENERATOR #if STATIC_COMPILER || STUB_GENERATOR
if (exported) return StaticCompiler.Load(name);
{
return StaticCompiler.LoadFile(this.MainAssembly.Location + "/../" + new AssemblyName(name).Name + ".dll");
}
else
{
return StaticCompiler.Load(name);
}
#else #else
return Assembly.Load(name); return Assembly.Load(name);
#endif #endif