Added AssemblyBuilder.__AddModule() to allow pre-existing modules to be linked in.

This commit is contained in:
jfrijters 2010-11-29 09:28:48 +00:00
Родитель 1410ece953
Коммит e0a6956435
4 изменённых файлов: 83 добавлений и 10 удалений

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

@ -60,6 +60,7 @@ namespace IKVM.Reflection.Emit
private Module pseudoManifestModule;
private readonly List<ResourceFile> resourceFiles = new List<ResourceFile>();
private readonly List<ModuleBuilder> modules = new List<ModuleBuilder>();
private readonly List<Module> addedModules = new List<Module>();
private readonly List<CustomAttributeBuilder> customAttributes = new List<CustomAttributeBuilder>();
private readonly List<CustomAttributeBuilder> declarativeSecurity = new List<CustomAttributeBuilder>();
private readonly List<Type> typeForwarders = new List<Type>();
@ -387,6 +388,12 @@ namespace IKVM.Reflection.Emit
}
}
foreach (Module module in addedModules)
{
int fileToken = AddFile(manifestModule, module.FullyQualifiedName, 0 /*ContainsMetaData*/);
module.ExportTypes(fileToken, manifestModule);
}
if (entryPointToken == 0 && entryPoint != null)
{
entryPointToken = entryPoint.MetadataToken;
@ -414,7 +421,7 @@ namespace IKVM.Reflection.Emit
}
FileTable.Record file = new FileTable.Record();
file.Flags = flags;
file.Name = manifestModule.Strings.Add(fileName);
file.Name = manifestModule.Strings.Add(Path.GetFileName(fileName));
file.HashValue = manifestModule.Blobs.Add(ByteBuffer.Wrap(hash.Hash));
return 0x26000000 + manifestModule.File.AddRecord(file);
}
@ -477,6 +484,10 @@ namespace IKVM.Reflection.Emit
{
module.GetTypesImpl(list);
}
foreach (Module module in addedModules)
{
module.GetTypesImpl(list);
}
return list.ToArray();
}
@ -490,6 +501,14 @@ namespace IKVM.Reflection.Emit
return type;
}
}
foreach (Module module in modules)
{
Type type = module.GetTypeImpl(typeName);
if (type != null)
{
return type;
}
}
return null;
}
@ -541,6 +560,13 @@ namespace IKVM.Reflection.Emit
list.Add(module);
}
}
foreach (Module module in addedModules)
{
if (getResourceModules || !module.IsResource())
{
list.Add(module);
}
}
return list.ToArray();
}
@ -553,9 +579,23 @@ namespace IKVM.Reflection.Emit
return module;
}
}
foreach (Module module in addedModules)
{
if (module.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
{
return module;
}
}
return null;
}
public Module __AddModule(RawModule module)
{
Module mod = module.ToModule(this);
addedModules.Add(mod);
return mod;
}
public override ManifestResourceInfo GetManifestResourceInfo(string resourceName)
{
throw new NotSupportedException();

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

@ -859,19 +859,24 @@ namespace IKVM.Reflection.Emit
return buf;
}
internal void ExportTypes(int fileToken, ModuleBuilder manifestModule)
internal override void ExportTypes(int fileToken, ModuleBuilder manifestModule)
{
manifestModule.ExportTypes(types.ToArray(), fileToken);
}
internal void ExportTypes(Type[] types, int fileToken)
{
Dictionary<Type, int> declaringTypes = new Dictionary<Type, int>();
foreach (TypeBuilder type in types)
foreach (Type type in types)
{
if (type != moduleType && IsVisible(type))
if (!type.IsModulePseudoType && IsVisible(type))
{
ExportedTypeTable.Record rec = new ExportedTypeTable.Record();
rec.Flags = (int)type.Attributes;
rec.TypeDefId = type.MetadataToken & 0xFFFFFF;
rec.TypeName = manifestModule.Strings.Add(TypeNameParser.Unescape(type.Name));
rec.TypeName = this.Strings.Add(TypeNameParser.Unescape(type.Name));
string ns = type.Namespace;
rec.TypeNamespace = ns == null ? 0 : manifestModule.Strings.Add(TypeNameParser.Unescape(ns));
rec.TypeNamespace = ns == null ? 0 : this.Strings.Add(TypeNameParser.Unescape(ns));
if (type.IsNested)
{
rec.Implementation = declaringTypes[type.DeclaringType];
@ -880,7 +885,7 @@ namespace IKVM.Reflection.Emit
{
rec.Implementation = fileToken;
}
int exportTypeToken = 0x27000000 | manifestModule.ExportedType.AddRecord(rec);
int exportTypeToken = 0x27000000 | this.ExportedType.AddRecord(rec);
declaringTypes.Add(type, exportTypeToken);
}
}

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

@ -1,5 +1,5 @@
/*
Copyright (C) 2009 Jeroen Frijters
Copyright (C) 2009-2010 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
@ -31,11 +31,13 @@ namespace IKVM.Reflection
public sealed class RawModule : IDisposable
{
private readonly ModuleReader module;
private readonly bool isManifestModule;
private bool imported;
internal RawModule(ModuleReader module)
{
this.module = module;
this.isManifestModule = module.Assembly != null;
}
public string Location
@ -45,7 +47,7 @@ namespace IKVM.Reflection
public bool IsManifestModule
{
get { return module.Assembly != null; }
get { return isManifestModule; }
}
private void CheckManifestModule()
@ -85,6 +87,17 @@ namespace IKVM.Reflection
imported = true;
return module.Assembly;
}
internal Module ToModule(Assembly assembly)
{
if (module.Assembly != null)
{
throw new InvalidOperationException();
}
imported = true;
module.SetAssembly(assembly);
return module;
}
}
public abstract class Module : ICustomAttributeProvider
@ -425,6 +438,10 @@ namespace IKVM.Reflection
internal virtual void Dispose()
{
}
internal virtual void ExportTypes(int fileToken, IKVM.Reflection.Emit.ModuleBuilder manifestModule)
{
}
}
public delegate bool TypeFilter(Type m, object filterCriteria);

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

@ -56,7 +56,7 @@ namespace IKVM.Reflection.Reader
{
internal readonly Stream stream;
private readonly string location;
private readonly AssemblyReader assembly;
private Assembly assembly;
private readonly PEReader peFile = new PEReader();
private readonly CliHeader cliHeader = new CliHeader();
private string imageRuntimeVersion;
@ -144,6 +144,11 @@ namespace IKVM.Reflection.Reader
}
}
internal void SetAssembly(Assembly assembly)
{
this.assembly = assembly;
}
private static StreamHeader[] ReadStreamHeaders(BinaryReader br, out string Version)
{
uint Signature = br.ReadUInt32();
@ -984,5 +989,11 @@ namespace IKVM.Reflection.Reader
{
stream.Close();
}
internal override void ExportTypes(int fileToken, IKVM.Reflection.Emit.ModuleBuilder manifestModule)
{
PopulateTypeDef();
manifestModule.ExportTypes(typeDefs, fileToken);
}
}
}