2 Copyright (C) 2009-2012 Jeroen Frijters
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
25 using System.Collections.Generic;
27 using System.Security;
29 using System.Diagnostics;
30 using IKVM.Reflection.Reader;
31 using IKVM.Reflection.Emit;
33 namespace IKVM.Reflection
35 public sealed class ResolveEventArgs : EventArgs
37 private readonly string name;
38 private readonly Assembly requestingAssembly;
40 public ResolveEventArgs(string name)
45 public ResolveEventArgs(string name, Assembly requestingAssembly)
48 this.requestingAssembly = requestingAssembly;
56 public Assembly RequestingAssembly
58 get { return requestingAssembly; }
62 public enum AssemblyComparisonResult
65 EquivalentFullMatch = 1,
66 EquivalentWeakNamed = 2,
67 EquivalentFXUnified = 3,
68 EquivalentUnified = 4,
69 NonEquivalentVersion = 5,
71 EquivalentPartialMatch = 7,
72 EquivalentPartialWeakNamed = 8,
73 EquivalentPartialUnified = 9,
74 EquivalentPartialFXUnified = 10,
75 NonEquivalentPartialVersion = 11,
78 public delegate Assembly ResolveEventHandler(object sender, ResolveEventArgs args);
81 public enum UniverseOptions
84 EnableFunctionPointers = 1,
86 DisablePseudoCustomAttributeRetrieval = 4,
89 public sealed class Universe : IDisposable
91 internal static readonly bool MonoRuntime = System.Type.GetType("Mono.Runtime") != null;
92 private readonly Dictionary<Type, Type> canonicalizedTypes = new Dictionary<Type, Type>();
93 private readonly List<AssemblyReader> assemblies = new List<AssemblyReader>();
94 private readonly List<AssemblyBuilder> dynamicAssemblies = new List<AssemblyBuilder>();
95 private readonly Dictionary<string, Assembly> assembliesByName = new Dictionary<string, Assembly>();
96 private readonly Dictionary<System.Type, Type> importedTypes = new Dictionary<System.Type, Type>();
97 private Dictionary<ScopedTypeName, Type> missingTypes;
98 private bool resolveMissingMembers;
99 private readonly bool enableFunctionPointers;
100 private readonly bool useNativeFusion;
101 private readonly bool returnPseudoCustomAttributes;
102 private Type typeof_System_Object;
103 private Type typeof_System_ValueType;
104 private Type typeof_System_Enum;
105 private Type typeof_System_Void;
106 private Type typeof_System_Boolean;
107 private Type typeof_System_Char;
108 private Type typeof_System_SByte;
109 private Type typeof_System_Byte;
110 private Type typeof_System_Int16;
111 private Type typeof_System_UInt16;
112 private Type typeof_System_Int32;
113 private Type typeof_System_UInt32;
114 private Type typeof_System_Int64;
115 private Type typeof_System_UInt64;
116 private Type typeof_System_Single;
117 private Type typeof_System_Double;
118 private Type typeof_System_String;
119 private Type typeof_System_IntPtr;
120 private Type typeof_System_UIntPtr;
121 private Type typeof_System_TypedReference;
122 private Type typeof_System_Type;
123 private Type typeof_System_Array;
124 private Type typeof_System_DateTime;
125 private Type typeof_System_DBNull;
126 private Type typeof_System_Decimal;
127 private Type typeof_System_NonSerializedAttribute;
128 private Type typeof_System_SerializableAttribute;
129 private Type typeof_System_AttributeUsageAttribute;
130 private Type typeof_System_Runtime_InteropServices_DllImportAttribute;
131 private Type typeof_System_Runtime_InteropServices_FieldOffsetAttribute;
132 private Type typeof_System_Runtime_InteropServices_InAttribute;
133 private Type typeof_System_Runtime_InteropServices_MarshalAsAttribute;
134 private Type typeof_System_Runtime_InteropServices_UnmanagedType;
135 private Type typeof_System_Runtime_InteropServices_VarEnum;
136 private Type typeof_System_Runtime_InteropServices_OutAttribute;
137 private Type typeof_System_Runtime_InteropServices_StructLayoutAttribute;
138 private Type typeof_System_Runtime_InteropServices_OptionalAttribute;
139 private Type typeof_System_Runtime_InteropServices_PreserveSigAttribute;
140 private Type typeof_System_Runtime_InteropServices_CallingConvention;
141 private Type typeof_System_Runtime_InteropServices_CharSet;
142 private Type typeof_System_Runtime_InteropServices_ComImportAttribute;
143 private Type typeof_System_Runtime_CompilerServices_DecimalConstantAttribute;
144 private Type typeof_System_Runtime_CompilerServices_SpecialNameAttribute;
145 private Type typeof_System_Runtime_CompilerServices_MethodImplAttribute;
146 private Type typeof_System_Security_SuppressUnmanagedCodeSecurityAttribute;
147 private Type typeof_System_Reflection_AssemblyCopyrightAttribute;
148 private Type typeof_System_Reflection_AssemblyTrademarkAttribute;
149 private Type typeof_System_Reflection_AssemblyProductAttribute;
150 private Type typeof_System_Reflection_AssemblyCompanyAttribute;
151 private Type typeof_System_Reflection_AssemblyDescriptionAttribute;
152 private Type typeof_System_Reflection_AssemblyTitleAttribute;
153 private Type typeof_System_Reflection_AssemblyInformationalVersionAttribute;
154 private Type typeof_System_Reflection_AssemblyFileVersionAttribute;
155 private Type typeof_System_Security_Permissions_CodeAccessSecurityAttribute;
156 private Type typeof_System_Security_Permissions_PermissionSetAttribute;
157 private Type typeof_System_Security_Permissions_SecurityAction;
158 private List<ResolveEventHandler> resolvers = new List<ResolveEventHandler>();
159 private Predicate<Type> missingTypeIsValueType;
162 : this(UniverseOptions.None)
166 public Universe(UniverseOptions options)
168 enableFunctionPointers = (options & UniverseOptions.EnableFunctionPointers) != 0;
169 useNativeFusion = (options & UniverseOptions.DisableFusion) == 0 && GetUseNativeFusion();
170 returnPseudoCustomAttributes = (options & UniverseOptions.DisablePseudoCustomAttributeRetrieval) == 0;
173 private static bool GetUseNativeFusion()
177 return Environment.OSVersion.Platform == PlatformID.Win32NT
179 && Environment.GetEnvironmentVariable("IKVM_DISABLE_FUSION") == null;
181 catch (System.Security.SecurityException)
187 internal Assembly Mscorlib
189 get { return Load("mscorlib"); }
192 private Type ImportMscorlibType(System.Type type)
194 if (Mscorlib.__IsMissing)
196 return Mscorlib.ResolveType(new TypeName(type.Namespace, type.Name));
198 // We use FindType instead of ResolveType here, because on some versions of mscorlib some of
199 // the special types we use/support are missing and the type properties are defined to
200 // return null in that case.
201 // Note that we don't have to unescape type.Name here, because none of the names contain special characters.
202 return Mscorlib.FindType(new TypeName(type.Namespace, type.Name));
205 private Type ResolvePrimitive(string name)
207 // Primitive here means that these types have a special metadata encoding, which means that
208 // there can be references to them without referring to them by name explicitly.
209 // We want these types to be usable even when they don't exist in mscorlib or there is no mscorlib loaded.
210 return Mscorlib.FindType(new TypeName("System", name)) ?? GetMissingType(Mscorlib.ManifestModule, null, new TypeName("System", name));
213 internal Type System_Object
215 get { return typeof_System_Object ?? (typeof_System_Object = ResolvePrimitive("Object")); }
218 internal Type System_ValueType
220 // System.ValueType is not a primitive, but generic type parameters can have a ValueType constraint
221 // (we also don't want to return null here)
222 get { return typeof_System_ValueType ?? (typeof_System_ValueType = ResolvePrimitive("ValueType")); }
225 internal Type System_Enum
227 // System.Enum is not a primitive, but we don't want to return null
228 get { return typeof_System_Enum ?? (typeof_System_Enum = ResolvePrimitive("Enum")); }
231 internal Type System_Void
233 get { return typeof_System_Void ?? (typeof_System_Void = ResolvePrimitive("Void")); }
236 internal Type System_Boolean
238 get { return typeof_System_Boolean ?? (typeof_System_Boolean = ResolvePrimitive("Boolean")); }
241 internal Type System_Char
243 get { return typeof_System_Char ?? (typeof_System_Char = ResolvePrimitive("Char")); }
246 internal Type System_SByte
248 get { return typeof_System_SByte ?? (typeof_System_SByte = ResolvePrimitive("SByte")); }
251 internal Type System_Byte
253 get { return typeof_System_Byte ?? (typeof_System_Byte = ResolvePrimitive("Byte")); }
256 internal Type System_Int16
258 get { return typeof_System_Int16 ?? (typeof_System_Int16 = ResolvePrimitive("Int16")); }
261 internal Type System_UInt16
263 get { return typeof_System_UInt16 ?? (typeof_System_UInt16 = ResolvePrimitive("UInt16")); }
266 internal Type System_Int32
268 get { return typeof_System_Int32 ?? (typeof_System_Int32 = ResolvePrimitive("Int32")); }
271 internal Type System_UInt32
273 get { return typeof_System_UInt32 ?? (typeof_System_UInt32 = ResolvePrimitive("UInt32")); }
276 internal Type System_Int64
278 get { return typeof_System_Int64 ?? (typeof_System_Int64 = ResolvePrimitive("Int64")); }
281 internal Type System_UInt64
283 get { return typeof_System_UInt64 ?? (typeof_System_UInt64 = ResolvePrimitive("UInt64")); }
286 internal Type System_Single
288 get { return typeof_System_Single ?? (typeof_System_Single = ResolvePrimitive("Single")); }
291 internal Type System_Double
293 get { return typeof_System_Double ?? (typeof_System_Double = ResolvePrimitive("Double")); }
296 internal Type System_String
298 get { return typeof_System_String ?? (typeof_System_String = ResolvePrimitive("String")); }
301 internal Type System_IntPtr
303 get { return typeof_System_IntPtr ?? (typeof_System_IntPtr = ResolvePrimitive("IntPtr")); }
306 internal Type System_UIntPtr
308 get { return typeof_System_UIntPtr ?? (typeof_System_UIntPtr = ResolvePrimitive("UIntPtr")); }
311 internal Type System_TypedReference
313 get { return typeof_System_TypedReference ?? (typeof_System_TypedReference = ResolvePrimitive("TypedReference")); }
316 internal Type System_Type
318 // System.Type is not a primitive, but it does have a special encoding in custom attributes
319 get { return typeof_System_Type ?? (typeof_System_Type = ResolvePrimitive("Type")); }
322 internal Type System_Array
324 // System.Array is not a primitive, but it used as a base type for array types (that are primitives)
325 get { return typeof_System_Array ?? (typeof_System_Array = ResolvePrimitive("Array")); }
328 internal Type System_DateTime
330 get { return typeof_System_DateTime ?? (typeof_System_DateTime = ImportMscorlibType(typeof(System.DateTime))); }
333 internal Type System_DBNull
335 get { return typeof_System_DBNull ?? (typeof_System_DBNull = ImportMscorlibType(typeof(System.DBNull))); }
338 internal Type System_Decimal
340 get { return typeof_System_Decimal ?? (typeof_System_Decimal = ImportMscorlibType(typeof(System.Decimal))); }
343 internal Type System_NonSerializedAttribute
345 get { return typeof_System_NonSerializedAttribute ?? (typeof_System_NonSerializedAttribute = ImportMscorlibType(typeof(System.NonSerializedAttribute))); }
348 internal Type System_SerializableAttribute
350 get { return typeof_System_SerializableAttribute ?? (typeof_System_SerializableAttribute = ImportMscorlibType(typeof(System.SerializableAttribute))); }
353 internal Type System_AttributeUsageAttribute
355 get { return typeof_System_AttributeUsageAttribute ?? (typeof_System_AttributeUsageAttribute = ImportMscorlibType(typeof(System.AttributeUsageAttribute))); }
358 internal Type System_Runtime_InteropServices_DllImportAttribute
360 get { return typeof_System_Runtime_InteropServices_DllImportAttribute ?? (typeof_System_Runtime_InteropServices_DllImportAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.DllImportAttribute))); }
363 internal Type System_Runtime_InteropServices_FieldOffsetAttribute
365 get { return typeof_System_Runtime_InteropServices_FieldOffsetAttribute ?? (typeof_System_Runtime_InteropServices_FieldOffsetAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.FieldOffsetAttribute))); }
368 internal Type System_Runtime_InteropServices_InAttribute
370 get { return typeof_System_Runtime_InteropServices_InAttribute ?? (typeof_System_Runtime_InteropServices_InAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.InAttribute))); }
373 internal Type System_Runtime_InteropServices_MarshalAsAttribute
375 get { return typeof_System_Runtime_InteropServices_MarshalAsAttribute ?? (typeof_System_Runtime_InteropServices_MarshalAsAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.MarshalAsAttribute))); }
378 internal Type System_Runtime_InteropServices_UnmanagedType
380 get { return typeof_System_Runtime_InteropServices_UnmanagedType ?? (typeof_System_Runtime_InteropServices_UnmanagedType = ImportMscorlibType(typeof(System.Runtime.InteropServices.UnmanagedType))); }
383 internal Type System_Runtime_InteropServices_VarEnum
385 get { return typeof_System_Runtime_InteropServices_VarEnum ?? (typeof_System_Runtime_InteropServices_VarEnum = ImportMscorlibType(typeof(System.Runtime.InteropServices.VarEnum))); }
388 internal Type System_Runtime_InteropServices_OutAttribute
390 get { return typeof_System_Runtime_InteropServices_OutAttribute ?? (typeof_System_Runtime_InteropServices_OutAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.OutAttribute))); }
393 internal Type System_Runtime_InteropServices_StructLayoutAttribute
395 get { return typeof_System_Runtime_InteropServices_StructLayoutAttribute ?? (typeof_System_Runtime_InteropServices_StructLayoutAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.StructLayoutAttribute))); }
398 internal Type System_Runtime_InteropServices_OptionalAttribute
400 get { return typeof_System_Runtime_InteropServices_OptionalAttribute ?? (typeof_System_Runtime_InteropServices_OptionalAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.OptionalAttribute))); }
403 internal Type System_Runtime_InteropServices_PreserveSigAttribute
405 get { return typeof_System_Runtime_InteropServices_PreserveSigAttribute ?? (typeof_System_Runtime_InteropServices_PreserveSigAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.PreserveSigAttribute))); }
408 internal Type System_Runtime_InteropServices_CallingConvention
410 get { return typeof_System_Runtime_InteropServices_CallingConvention ?? (typeof_System_Runtime_InteropServices_CallingConvention = ImportMscorlibType(typeof(System.Runtime.InteropServices.CallingConvention))); }
413 internal Type System_Runtime_InteropServices_CharSet
415 get { return typeof_System_Runtime_InteropServices_CharSet ?? (typeof_System_Runtime_InteropServices_CharSet = ImportMscorlibType(typeof(System.Runtime.InteropServices.CharSet))); }
418 internal Type System_Runtime_InteropServices_ComImportAttribute
420 get { return typeof_System_Runtime_InteropServices_ComImportAttribute ?? (typeof_System_Runtime_InteropServices_ComImportAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.ComImportAttribute))); }
423 internal Type System_Runtime_CompilerServices_DecimalConstantAttribute
425 get { return typeof_System_Runtime_CompilerServices_DecimalConstantAttribute ?? (typeof_System_Runtime_CompilerServices_DecimalConstantAttribute = ImportMscorlibType(typeof(System.Runtime.CompilerServices.DecimalConstantAttribute))); }
428 internal Type System_Runtime_CompilerServices_SpecialNameAttribute
430 get { return typeof_System_Runtime_CompilerServices_SpecialNameAttribute ?? (typeof_System_Runtime_CompilerServices_SpecialNameAttribute = ImportMscorlibType(typeof(System.Runtime.CompilerServices.SpecialNameAttribute))); }
433 internal Type System_Runtime_CompilerServices_MethodImplAttribute
435 get { return typeof_System_Runtime_CompilerServices_MethodImplAttribute ?? (typeof_System_Runtime_CompilerServices_MethodImplAttribute = ImportMscorlibType(typeof(System.Runtime.CompilerServices.MethodImplAttribute))); }
438 internal Type System_Security_SuppressUnmanagedCodeSecurityAttribute
440 get { return typeof_System_Security_SuppressUnmanagedCodeSecurityAttribute ?? (typeof_System_Security_SuppressUnmanagedCodeSecurityAttribute = ImportMscorlibType(typeof(System.Security.SuppressUnmanagedCodeSecurityAttribute))); }
443 internal Type System_Reflection_AssemblyCopyrightAttribute
445 get { return typeof_System_Reflection_AssemblyCopyrightAttribute ?? (typeof_System_Reflection_AssemblyCopyrightAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyCopyrightAttribute))); }
448 internal Type System_Reflection_AssemblyTrademarkAttribute
450 get { return typeof_System_Reflection_AssemblyTrademarkAttribute ?? (typeof_System_Reflection_AssemblyTrademarkAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyTrademarkAttribute))); }
453 internal Type System_Reflection_AssemblyProductAttribute
455 get { return typeof_System_Reflection_AssemblyProductAttribute ?? (typeof_System_Reflection_AssemblyProductAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyProductAttribute))); }
458 internal Type System_Reflection_AssemblyCompanyAttribute
460 get { return typeof_System_Reflection_AssemblyCompanyAttribute ?? (typeof_System_Reflection_AssemblyCompanyAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyCompanyAttribute))); }
463 internal Type System_Reflection_AssemblyDescriptionAttribute
465 get { return typeof_System_Reflection_AssemblyDescriptionAttribute ?? (typeof_System_Reflection_AssemblyDescriptionAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyDescriptionAttribute))); }
468 internal Type System_Reflection_AssemblyTitleAttribute
470 get { return typeof_System_Reflection_AssemblyTitleAttribute ?? (typeof_System_Reflection_AssemblyTitleAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyTitleAttribute))); }
473 internal Type System_Reflection_AssemblyInformationalVersionAttribute
475 get { return typeof_System_Reflection_AssemblyInformationalVersionAttribute ?? (typeof_System_Reflection_AssemblyInformationalVersionAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyInformationalVersionAttribute))); }
478 internal Type System_Reflection_AssemblyFileVersionAttribute
480 get { return typeof_System_Reflection_AssemblyFileVersionAttribute ?? (typeof_System_Reflection_AssemblyFileVersionAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyFileVersionAttribute))); }
483 internal Type System_Security_Permissions_CodeAccessSecurityAttribute
485 get { return typeof_System_Security_Permissions_CodeAccessSecurityAttribute ?? (typeof_System_Security_Permissions_CodeAccessSecurityAttribute = ImportMscorlibType(typeof(System.Security.Permissions.CodeAccessSecurityAttribute))); }
488 internal Type System_Security_Permissions_PermissionSetAttribute
490 get { return typeof_System_Security_Permissions_PermissionSetAttribute ?? (typeof_System_Security_Permissions_PermissionSetAttribute = ImportMscorlibType(typeof(System.Security.Permissions.PermissionSetAttribute))); }
493 internal Type System_Security_Permissions_SecurityAction
495 get { return typeof_System_Security_Permissions_SecurityAction ?? (typeof_System_Security_Permissions_SecurityAction = ImportMscorlibType(typeof(System.Security.Permissions.SecurityAction))); }
498 internal bool HasMscorlib
500 get { return GetLoadedAssembly("mscorlib") != null; }
503 public event ResolveEventHandler AssemblyResolve
505 add { resolvers.Add(value); }
506 remove { resolvers.Remove(value); }
509 public Type Import(System.Type type)
512 if (!importedTypes.TryGetValue(type, out imported))
514 imported = ImportImpl(type);
515 if (imported != null)
517 importedTypes.Add(type, imported);
523 private Type ImportImpl(System.Type type)
525 if (type.Assembly == typeof(IKVM.Reflection.Type).Assembly)
527 throw new ArgumentException("Did you really want to import " + type.FullName + "?");
529 if (type.HasElementType)
533 if (type.Name.EndsWith("[]"))
535 return Import(type.GetElementType()).MakeArrayType();
539 return Import(type.GetElementType()).MakeArrayType(type.GetArrayRank());
542 else if (type.IsByRef)
544 return Import(type.GetElementType()).MakeByRefType();
546 else if (type.IsPointer)
548 return Import(type.GetElementType()).MakePointerType();
552 throw new InvalidOperationException();
555 else if (type.IsGenericParameter)
557 if (type.DeclaringMethod != null)
559 throw new NotImplementedException();
563 return Import(type.DeclaringType).GetGenericArguments()[type.GenericParameterPosition];
566 else if (type.IsGenericType && !type.IsGenericTypeDefinition)
568 System.Type[] args = type.GetGenericArguments();
569 Type[] importedArgs = new Type[args.Length];
570 for (int i = 0; i < args.Length; i++)
572 importedArgs[i] = Import(args[i]);
574 return Import(type.GetGenericTypeDefinition()).MakeGenericType(importedArgs);
576 else if (type.IsNested)
578 // note that we can't pass in the namespace here, because .NET's Type.Namespace implementation is broken for nested types
579 // (it returns the namespace of the declaring type)
580 return Import(type.DeclaringType).ResolveNestedType(new TypeName(null, type.Name));
582 else if (type.Assembly == typeof(object).Assembly)
584 // make sure mscorlib types always end up in our mscorlib
585 return Mscorlib.ResolveType(new TypeName(type.Namespace, type.Name));
589 return Import(type.Assembly).ResolveType(new TypeName(type.Namespace, type.Name));
593 private Assembly Import(System.Reflection.Assembly asm)
595 return Load(asm.FullName);
598 public RawModule OpenRawModule(string path)
600 path = Path.GetFullPath(path);
601 return OpenRawModule(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read), path);
604 public RawModule OpenRawModule(Stream stream, string location)
606 if (!stream.CanRead || !stream.CanSeek || stream.Position != 0)
608 throw new ArgumentException("Stream must support read/seek and current position must be zero.", "stream");
610 return new RawModule(new ModuleReader(null, this, stream, location));
613 public Assembly LoadAssembly(RawModule module)
615 string refname = module.GetAssemblyName().FullName;
616 Assembly asm = GetLoadedAssembly(refname);
619 AssemblyReader asm1 = module.ToAssembly();
620 assemblies.Add(asm1);
626 public Assembly LoadFile(string path)
630 using (RawModule module = OpenRawModule(path))
632 return LoadAssembly(module);
635 catch (IOException x)
637 throw new FileNotFoundException(x.Message, x);
639 catch (UnauthorizedAccessException x)
641 throw new FileNotFoundException(x.Message, x);
645 private static string GetSimpleAssemblyName(string refname)
649 if (Fusion.ParseAssemblySimpleName(refname, out pos, out name) != ParseAssemblyResult.OK)
651 throw new ArgumentException();
656 private Assembly GetLoadedAssembly(string refname)
659 if (!assembliesByName.TryGetValue(refname, out asm))
661 string simpleName = GetSimpleAssemblyName(refname);
662 for (int i = 0; i < assemblies.Count; i++)
664 AssemblyComparisonResult result;
665 if (simpleName.Equals(assemblies[i].Name, StringComparison.InvariantCultureIgnoreCase)
666 && CompareAssemblyIdentity(refname, false, assemblies[i].FullName, false, out result))
669 assembliesByName.Add(refname, asm);
677 private Assembly GetDynamicAssembly(string refname)
679 string simpleName = GetSimpleAssemblyName(refname);
680 foreach (AssemblyBuilder asm in dynamicAssemblies)
682 AssemblyComparisonResult result;
683 if (simpleName.Equals(asm.Name, StringComparison.InvariantCultureIgnoreCase)
684 && CompareAssemblyIdentity(refname, false, asm.FullName, false, out result))
692 public Assembly Load(string refname)
694 return Load(refname, null, true);
697 internal Assembly Load(string refname, Assembly requestingAssembly, bool throwOnError)
699 Assembly asm = GetLoadedAssembly(refname);
704 if (resolvers.Count == 0)
706 asm = DefaultResolver(refname, throwOnError);
710 ResolveEventArgs args = new ResolveEventArgs(refname, requestingAssembly);
711 foreach (ResolveEventHandler evt in resolvers)
713 asm = evt(this, args);
721 asm = GetDynamicAssembly(refname);
726 string defname = asm.FullName;
727 if (refname != defname)
729 assembliesByName.Add(refname, asm);
735 throw new FileNotFoundException(refname);
740 private Assembly DefaultResolver(string refname, bool throwOnError)
742 Assembly asm = GetDynamicAssembly(refname);
752 fileName = System.Reflection.Assembly.ReflectionOnlyLoad(refname).Location;
754 catch (System.BadImageFormatException x)
756 throw new BadImageFormatException(x.Message, x);
763 fileName = System.Reflection.Assembly.ReflectionOnlyLoad(refname).Location;
765 catch (System.BadImageFormatException x)
767 throw new BadImageFormatException(x.Message, x);
769 catch (FileNotFoundException)
771 // we intentionally only swallow the FileNotFoundException, if the file exists but isn't a valid assembly,
772 // we should throw an exception
776 return LoadFile(fileName);
779 public Type GetType(string assemblyQualifiedTypeName)
781 // to be more compatible with Type.GetType(), we could call Assembly.GetCallingAssembly(),
782 // import that assembly and pass it as the context, but implicitly importing is considered evil
783 return GetType(null, assemblyQualifiedTypeName, false, false);
786 public Type GetType(string assemblyQualifiedTypeName, bool throwOnError)
788 // to be more compatible with Type.GetType(), we could call Assembly.GetCallingAssembly(),
789 // import that assembly and pass it as the context, but implicitly importing is considered evil
790 return GetType(null, assemblyQualifiedTypeName, throwOnError, false);
793 public Type GetType(string assemblyQualifiedTypeName, bool throwOnError, bool ignoreCase)
795 // to be more compatible with Type.GetType(), we could call Assembly.GetCallingAssembly(),
796 // import that assembly and pass it as the context, but implicitly importing is considered evil
797 return GetType(null, assemblyQualifiedTypeName, throwOnError, ignoreCase);
800 // note that context is slightly different from the calling assembly (System.Type.GetType),
801 // because context is passed to the AssemblyResolve event as the RequestingAssembly
802 public Type GetType(Assembly context, string assemblyQualifiedTypeName, bool throwOnError)
804 return GetType(context, assemblyQualifiedTypeName, throwOnError, false);
807 // note that context is slightly different from the calling assembly (System.Type.GetType),
808 // because context is passed to the AssemblyResolve event as the RequestingAssembly
809 public Type GetType(Assembly context, string assemblyQualifiedTypeName, bool throwOnError, bool ignoreCase)
811 TypeNameParser parser = TypeNameParser.Parse(assemblyQualifiedTypeName, throwOnError);
816 return parser.GetType(this, context, throwOnError, assemblyQualifiedTypeName, false, ignoreCase);
819 // this is similar to GetType(Assembly context, string assemblyQualifiedTypeName, bool throwOnError),
820 // but instead it assumes that the type must exist (i.e. if EnableMissingMemberResolution is enabled
821 // it will create a missing type)
822 public Type ResolveType(Assembly context, string assemblyQualifiedTypeName)
824 TypeNameParser parser = TypeNameParser.Parse(assemblyQualifiedTypeName, false);
829 return parser.GetType(this, context, false, assemblyQualifiedTypeName, true, false);
832 public Assembly[] GetAssemblies()
834 Assembly[] array = new Assembly[assemblies.Count + dynamicAssemblies.Count];
835 for (int i = 0; i < assemblies.Count; i++)
837 array[i] = assemblies[i];
839 for (int i = 0, j = assemblies.Count; j < array.Length; i++, j++)
841 array[j] = dynamicAssemblies[i];
846 // this is equivalent to the Fusion CompareAssemblyIdentity API
847 public bool CompareAssemblyIdentity(string assemblyIdentity1, bool unified1, string assemblyIdentity2, bool unified2, out AssemblyComparisonResult result)
849 return useNativeFusion
850 ? Fusion.CompareAssemblyIdentityNative(assemblyIdentity1, unified1, assemblyIdentity2, unified2, out result)
851 : Fusion.CompareAssemblyIdentityPure(assemblyIdentity1, unified1, assemblyIdentity2, unified2, out result);
854 public AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access)
856 return DefineDynamicAssemblyImpl(name, access, null, null, null, null);
859 public AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access, string dir)
861 return DefineDynamicAssemblyImpl(name, access, dir, null, null, null);
867 public AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions)
869 return DefineDynamicAssemblyImpl(name, access, dir, requiredPermissions, optionalPermissions, refusedPermissions);
872 private AssemblyBuilder DefineDynamicAssemblyImpl(AssemblyName name, AssemblyBuilderAccess access, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions)
874 AssemblyBuilder asm = new AssemblyBuilder(this, name, dir, requiredPermissions, optionalPermissions, refusedPermissions);
875 dynamicAssemblies.Add(asm);
879 internal void RenameAssembly(Assembly assembly, AssemblyName oldName)
881 List<string> remove = new List<string>();
882 foreach (KeyValuePair<string, Assembly> kv in assembliesByName)
884 if (kv.Value == assembly)
889 foreach (string key in remove)
891 assembliesByName.Remove(key);
895 public void Dispose()
897 foreach (Assembly asm in assemblies)
899 foreach (Module mod in asm.GetLoadedModules())
904 foreach (AssemblyBuilder asm in dynamicAssemblies)
906 foreach (Module mod in asm.GetLoadedModules())
913 public Assembly CreateMissingAssembly(string assemblyName)
915 Assembly asm = new MissingAssembly(this, assemblyName);
916 string name = asm.FullName;
917 if (!assembliesByName.ContainsKey(name))
919 assembliesByName.Add(name, asm);
924 public void EnableMissingMemberResolution()
926 resolveMissingMembers = true;
929 internal bool MissingMemberResolution
931 get { return resolveMissingMembers; }
934 internal bool EnableFunctionPointers
936 get { return enableFunctionPointers; }
939 private struct ScopedTypeName : IEquatable<ScopedTypeName>
941 private readonly object scope;
942 private readonly TypeName name;
944 internal ScopedTypeName(object scope, TypeName name)
950 public override bool Equals(object obj)
952 ScopedTypeName? other = obj as ScopedTypeName?;
953 return other != null && ((IEquatable<ScopedTypeName>)other.Value).Equals(this);
956 public override int GetHashCode()
958 return scope.GetHashCode() * 7 + name.GetHashCode();
961 bool IEquatable<ScopedTypeName>.Equals(ScopedTypeName other)
963 return other.scope == scope && other.name == name;
967 private Type GetMissingType(Module module, Type declaringType, TypeName typeName)
969 if (missingTypes == null)
971 missingTypes = new Dictionary<ScopedTypeName, Type>();
973 ScopedTypeName stn = new ScopedTypeName(declaringType ?? (object)module, typeName);
975 if (!missingTypes.TryGetValue(stn, out type))
977 type = new MissingType(module, declaringType, typeName.Namespace, typeName.Name);
978 missingTypes.Add(stn, type);
983 internal Type GetMissingTypeOrThrow(Module module, Type declaringType, TypeName typeName)
985 if (resolveMissingMembers || module.Assembly.__IsMissing)
987 return GetMissingType(module, declaringType, typeName);
989 string fullName = TypeNameParser.Escape(typeName.ToString());
990 if (declaringType != null)
992 fullName = declaringType.FullName + "+" + fullName;
994 throw new TypeLoadException(String.Format("Type '{0}' not found in assembly '{1}'", fullName, module.Assembly.FullName));
997 internal MethodBase GetMissingMethodOrThrow(Type declaringType, string name, MethodSignature signature)
999 if (resolveMissingMembers)
1001 MethodInfo method = new MissingMethod(declaringType, name, signature);
1002 if (name == ".ctor")
1004 return new ConstructorInfoImpl(method);
1008 throw new MissingMethodException(declaringType.ToString(), name);
1011 internal FieldInfo GetMissingFieldOrThrow(Type declaringType, string name, FieldSignature signature)
1013 if (resolveMissingMembers)
1015 return new MissingField(declaringType, name, signature);
1017 throw new MissingFieldException(declaringType.ToString(), name);
1020 internal PropertyInfo GetMissingPropertyOrThrow(Type declaringType, string name, PropertySignature propertySignature)
1022 // HACK we need to check __IsMissing here, because Type doesn't have a FindProperty API
1023 // since properties are never resolved, except by custom attributes
1024 if (resolveMissingMembers || declaringType.__IsMissing)
1026 return new MissingProperty(declaringType, name, propertySignature);
1028 throw new System.MissingMemberException(declaringType.ToString(), name);
1031 internal Type CanonicalizeType(Type type)
1034 if (!canonicalizedTypes.TryGetValue(type, out canon))
1037 canonicalizedTypes.Add(canon, canon);
1042 public Type MakeFunctionPointer(__StandAloneMethodSig sig)
1044 return FunctionPointerType.Make(this, sig);
1047 public __StandAloneMethodSig MakeStandAloneMethodSig(System.Runtime.InteropServices.CallingConvention callingConvention, Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers)
1049 return new __StandAloneMethodSig(true, callingConvention, 0, returnType ?? this.System_Void, Util.Copy(parameterTypes), Type.EmptyTypes,
1050 PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, Util.NullSafeLength(parameterTypes)));
1053 public __StandAloneMethodSig MakeStandAloneMethodSig(CallingConventions callingConvention, Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, Type[] optionalParameterTypes, CustomModifiers[] parameterTypeCustomModifiers)
1055 return new __StandAloneMethodSig(false, 0, callingConvention, returnType ?? this.System_Void, Util.Copy(parameterTypes), Util.Copy(optionalParameterTypes),
1056 PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, Util.NullSafeLength(parameterTypes) + Util.NullSafeLength(optionalParameterTypes)));
1059 public event Predicate<Type> MissingTypeIsValueType
1063 if (missingTypeIsValueType != null)
1065 throw new InvalidOperationException("Only a single MissingTypeIsValueType handler can be registered.");
1067 missingTypeIsValueType = value;
1071 if (value.Equals(missingTypeIsValueType))
1073 missingTypeIsValueType = null;
1078 internal bool ResolveMissingTypeIsValueType(MissingType missingType)
1080 if (missingTypeIsValueType != null)
1082 return missingTypeIsValueType(missingType);
1084 throw new MissingMemberException(missingType);
1087 internal bool ReturnPseudoCustomAttributes
1089 get { return returnPseudoCustomAttributes; }