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
{
private readonly List<string> libpath = new List<string>();
private readonly Dictionary<string, string> hintpaths = new Dictionary<string, string>();
private Universe universe;
private Version mscorlibVersion;
@ -276,15 +275,6 @@ namespace IKVM.Internal
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 (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.Reflection;
using IKVM.Reflection.Emit;
using Type = IKVM.Reflection.Type;
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)
foreach (CompilerOptions target in targets)
{
@ -1133,6 +1149,17 @@ sealed class IkvmcCompiler
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)

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

@ -2831,10 +2831,6 @@ namespace IKVM.Internal
for(int i = 0; i < references.Count; 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)
{
StaticCompiler.IssueMessage(options, Message.DuplicateAssemblyReference, acl.MainAssembly.FullName);
@ -2904,6 +2900,7 @@ namespace IKVM.Internal
}
if(asm != null && IsCoreAssembly(asm))
{
AssemblyClassLoader.PreloadExportedAssemblies(asm);
JVM.CoreAssembly = asm;
break;
}
@ -3437,7 +3434,6 @@ namespace IKVM.Internal
InterfaceMethodCantBeInternal = 128,
DllExportMustBeStaticMethod = 129,
DllExportRequiresSupportedPlatform = 130,
NonPrimaryAssemblyReference = 131,
DuplicateAssemblyReference = 132,
UnableToResolveType = 133,
StubsAreDeprecated = 134,
@ -3456,6 +3452,7 @@ namespace IKVM.Internal
InvalidMemberSignatureInMapFile = 4010,
InvalidPropertyNameInMapFile = 4011,
InvalidPropertySignatureInMapFile = 4012,
NonPrimaryAssemblyReference = 4013,
// Fatal errors
ResponseFileDepthExceeded = 5000,
ErrorReadingFile = 5001,
@ -3742,7 +3739,7 @@ namespace IKVM.Internal
msg = "Ignoring @ikvm.lang.DllExport annotation due to unsupported target platform";
break;
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;
case Message.DuplicateAssemblyReference:
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
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.references = fixedReferences;
}
#if STATIC_COMPILER
internal static void PreloadExportedAssemblies(Assembly assembly)
{
if (assembly.GetManifestResourceInfo("ikvm.exports") != null)
{
using (Stream stream = assembly.GetManifestResourceStream("ikvm.exports"))
@ -404,19 +407,23 @@ namespace IKVM.Internal
{
string assemblyName = rdr.ReadString();
int typeCount = rdr.ReadInt32();
if (typeCount != 0)
{
for (int j = 0; j < typeCount; j++)
{
rdr.ReadInt32();
}
if (typeCount != 0)
try
{
IkvmcCompiler.resolver.AddHintPath(assemblyName, Path.GetDirectoryName(assembly.Location));
StaticCompiler.LoadFile(assembly.Location + "/../" + new AssemblyName(assemblyName).Name + ".dll");
}
catch { }
}
}
}
}
}
#endif
}
private void DoInitializeExports()
{
@ -534,14 +541,7 @@ namespace IKVM.Internal
try
{
#if STATIC_COMPILER || STUB_GENERATOR
if (exported)
{
return StaticCompiler.LoadFile(this.MainAssembly.Location + "/../" + new AssemblyName(name).Name + ".dll");
}
else
{
return StaticCompiler.Load(name);
}
#else
return Assembly.Load(name);
#endif