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,
88 public sealed class Universe : IDisposable
90 internal static readonly bool MonoRuntime = System.Type.GetType("Mono.Runtime") != null;
91 private readonly Dictionary<Type, Type> canonicalizedTypes = new Dictionary<Type, Type>();
92 private readonly List<AssemblyReader> assemblies = new List<AssemblyReader>();
93 private readonly List<AssemblyBuilder> dynamicAssemblies = new List<AssemblyBuilder>();
94 private readonly Dictionary<string, Assembly> assembliesByName = new Dictionary<string, Assembly>();
95 private readonly Dictionary<System.Type, Type> importedTypes = new Dictionary<System.Type, Type>();
96 private Dictionary<ScopedTypeName, Type> missingTypes;
97 private bool resolveMissingMembers;
98 private readonly bool enableFunctionPointers;
99 private readonly bool useNativeFusion;
100 private Type typeof_System_Object;
101 private Type typeof_System_ValueType;
102 private Type typeof_System_Enum;
103 private Type typeof_System_Void;
104 private Type typeof_System_Boolean;
105 private Type typeof_System_Char;
106 private Type typeof_System_SByte;
107 private Type typeof_System_Byte;
108 private Type typeof_System_Int16;
109 private Type typeof_System_UInt16;
110 private Type typeof_System_Int32;
111 private Type typeof_System_UInt32;
112 private Type typeof_System_Int64;
113 private Type typeof_System_UInt64;
114 private Type typeof_System_Single;
115 private Type typeof_System_Double;
116 private Type typeof_System_String;
117 private Type typeof_System_IntPtr;
118 private Type typeof_System_UIntPtr;
119 private Type typeof_System_TypedReference;
120 private Type typeof_System_Type;
121 private Type typeof_System_Array;
122 private Type typeof_System_DateTime;
123 private Type typeof_System_DBNull;
124 private Type typeof_System_Decimal;
125 private Type typeof_System_NonSerializedAttribute;
126 private Type typeof_System_SerializableAttribute;
127 private Type typeof_System_AttributeUsageAttribute;
128 private Type typeof_System_Runtime_InteropServices_DllImportAttribute;
129 private Type typeof_System_Runtime_InteropServices_FieldOffsetAttribute;
130 private Type typeof_System_Runtime_InteropServices_InAttribute;
131 private Type typeof_System_Runtime_InteropServices_MarshalAsAttribute;
132 private Type typeof_System_Runtime_InteropServices_UnmanagedType;
133 private Type typeof_System_Runtime_InteropServices_VarEnum;
134 private Type typeof_System_Runtime_InteropServices_OutAttribute;
135 private Type typeof_System_Runtime_InteropServices_StructLayoutAttribute;
136 private Type typeof_System_Runtime_InteropServices_OptionalAttribute;
137 private Type typeof_System_Runtime_InteropServices_PreserveSigAttribute;
138 private Type typeof_System_Runtime_InteropServices_CallingConvention;
139 private Type typeof_System_Runtime_InteropServices_CharSet;
140 private Type typeof_System_Runtime_InteropServices_ComImportAttribute;
141 private Type typeof_System_Runtime_CompilerServices_DecimalConstantAttribute;
142 private Type typeof_System_Runtime_CompilerServices_SpecialNameAttribute;
143 private Type typeof_System_Runtime_CompilerServices_MethodImplAttribute;
144 private Type typeof_System_Security_SuppressUnmanagedCodeSecurityAttribute;
145 private Type typeof_System_Reflection_AssemblyCopyrightAttribute;
146 private Type typeof_System_Reflection_AssemblyTrademarkAttribute;
147 private Type typeof_System_Reflection_AssemblyProductAttribute;
148 private Type typeof_System_Reflection_AssemblyCompanyAttribute;
149 private Type typeof_System_Reflection_AssemblyDescriptionAttribute;
150 private Type typeof_System_Reflection_AssemblyTitleAttribute;
151 private Type typeof_System_Reflection_AssemblyInformationalVersionAttribute;
152 private Type typeof_System_Reflection_AssemblyFileVersionAttribute;
153 private Type typeof_System_Security_Permissions_CodeAccessSecurityAttribute;
154 private Type typeof_System_Security_Permissions_PermissionSetAttribute;
155 private Type typeof_System_Security_Permissions_SecurityAction;
156 private List<ResolveEventHandler> resolvers = new List<ResolveEventHandler>();
157 private Predicate<Type> missingTypeIsValueType;
160 : this(UniverseOptions.None)
164 public Universe(UniverseOptions options)
166 enableFunctionPointers = (options & UniverseOptions.EnableFunctionPointers) != 0;
167 useNativeFusion = (options & UniverseOptions.DisableFusion) == 0 && GetUseNativeFusion();
170 private static bool GetUseNativeFusion()
174 return Environment.OSVersion.Platform == PlatformID.Win32NT
176 && Environment.GetEnvironmentVariable("IKVM_DISABLE_FUSION") == null;
178 catch (System.Security.SecurityException)
184 internal Assembly Mscorlib
186 get { return Load("mscorlib"); }
189 private Type ImportMscorlibType(System.Type type)
191 if (Mscorlib.__IsMissing)
193 return Mscorlib.ResolveType(new TypeName(type.Namespace, type.Name));
195 // We use FindType instead of ResolveType here, because on some versions of mscorlib some of
196 // the special types we use/support are missing and the type properties are defined to
197 // return null in that case.
198 // Note that we don't have to unescape type.Name here, because none of the names contain special characters.
199 return Mscorlib.FindType(new TypeName(type.Namespace, type.Name));
202 private Type ResolvePrimitive(string name)
204 // Primitive here means that these types have a special metadata encoding, which means that
205 // there can be references to them without referring to them by name explicitly.
206 // When 'resolve missing type' mode is enabled, we want these types to be usable even when
207 // they don't exist in mscorlib or there is no mscorlib loaded.
208 return Mscorlib.ResolveType(new TypeName("System", name));
211 internal Type System_Object
213 get { return typeof_System_Object ?? (typeof_System_Object = ResolvePrimitive("Object")); }
216 internal Type System_ValueType
218 // System.ValueType is not a primitive, but generic type parameters can have a ValueType constraint
219 // (we also don't want to return null here)
220 get { return typeof_System_ValueType ?? (typeof_System_ValueType = ResolvePrimitive("ValueType")); }
223 internal Type System_Enum
225 // System.Enum is not a primitive, but we don't want to return null
226 get { return typeof_System_Enum ?? (typeof_System_Enum = ResolvePrimitive("Enum")); }
229 internal Type System_Void
231 get { return typeof_System_Void ?? (typeof_System_Void = ResolvePrimitive("Void")); }
234 internal Type System_Boolean
236 get { return typeof_System_Boolean ?? (typeof_System_Boolean = ResolvePrimitive("Boolean")); }
239 internal Type System_Char
241 get { return typeof_System_Char ?? (typeof_System_Char = ResolvePrimitive("Char")); }
244 internal Type System_SByte
246 get { return typeof_System_SByte ?? (typeof_System_SByte = ResolvePrimitive("SByte")); }
249 internal Type System_Byte
251 get { return typeof_System_Byte ?? (typeof_System_Byte = ResolvePrimitive("Byte")); }
254 internal Type System_Int16
256 get { return typeof_System_Int16 ?? (typeof_System_Int16 = ResolvePrimitive("Int16")); }
259 internal Type System_UInt16
261 get { return typeof_System_UInt16 ?? (typeof_System_UInt16 = ResolvePrimitive("UInt16")); }
264 internal Type System_Int32
266 get { return typeof_System_Int32 ?? (typeof_System_Int32 = ResolvePrimitive("Int32")); }
269 internal Type System_UInt32
271 get { return typeof_System_UInt32 ?? (typeof_System_UInt32 = ResolvePrimitive("UInt32")); }
274 internal Type System_Int64
276 get { return typeof_System_Int64 ?? (typeof_System_Int64 = ResolvePrimitive("Int64")); }
279 internal Type System_UInt64
281 get { return typeof_System_UInt64 ?? (typeof_System_UInt64 = ResolvePrimitive("UInt64")); }
284 internal Type System_Single
286 get { return typeof_System_Single ?? (typeof_System_Single = ResolvePrimitive("Single")); }
289 internal Type System_Double
291 get { return typeof_System_Double ?? (typeof_System_Double = ResolvePrimitive("Double")); }
294 internal Type System_String
296 get { return typeof_System_String ?? (typeof_System_String = ResolvePrimitive("String")); }
299 internal Type System_IntPtr
301 get { return typeof_System_IntPtr ?? (typeof_System_IntPtr = ResolvePrimitive("IntPtr")); }
304 internal Type System_UIntPtr
306 get { return typeof_System_UIntPtr ?? (typeof_System_UIntPtr = ResolvePrimitive("UIntPtr")); }
309 internal Type System_TypedReference
311 get { return typeof_System_TypedReference ?? (typeof_System_TypedReference = ResolvePrimitive("TypedReference")); }
314 internal Type System_Type
316 // System.Type is not a primitive, but it does have a special encoding in custom attributes
317 get { return typeof_System_Type ?? (typeof_System_Type = ResolvePrimitive("Type")); }
320 internal Type System_Array
322 // System.Array is not a primitive, but it used as a base type for array types (that are primitives)
323 get { return typeof_System_Array ?? (typeof_System_Array = ResolvePrimitive("Array")); }
326 internal Type System_DateTime
328 get { return typeof_System_DateTime ?? (typeof_System_DateTime = ImportMscorlibType(typeof(System.DateTime))); }
331 internal Type System_DBNull
333 get { return typeof_System_DBNull ?? (typeof_System_DBNull = ImportMscorlibType(typeof(System.DBNull))); }
336 internal Type System_Decimal
338 get { return typeof_System_Decimal ?? (typeof_System_Decimal = ImportMscorlibType(typeof(System.Decimal))); }
341 internal Type System_NonSerializedAttribute
343 get { return typeof_System_NonSerializedAttribute ?? (typeof_System_NonSerializedAttribute = ImportMscorlibType(typeof(System.NonSerializedAttribute))); }
346 internal Type System_SerializableAttribute
348 get { return typeof_System_SerializableAttribute ?? (typeof_System_SerializableAttribute = ImportMscorlibType(typeof(System.SerializableAttribute))); }
351 internal Type System_AttributeUsageAttribute
353 get { return typeof_System_AttributeUsageAttribute ?? (typeof_System_AttributeUsageAttribute = ImportMscorlibType(typeof(System.AttributeUsageAttribute))); }
356 internal Type System_Runtime_InteropServices_DllImportAttribute
358 get { return typeof_System_Runtime_InteropServices_DllImportAttribute ?? (typeof_System_Runtime_InteropServices_DllImportAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.DllImportAttribute))); }
361 internal Type System_Runtime_InteropServices_FieldOffsetAttribute
363 get { return typeof_System_Runtime_InteropServices_FieldOffsetAttribute ?? (typeof_System_Runtime_InteropServices_FieldOffsetAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.FieldOffsetAttribute))); }
366 internal Type System_Runtime_InteropServices_InAttribute
368 get { return typeof_System_Runtime_InteropServices_InAttribute ?? (typeof_System_Runtime_InteropServices_InAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.InAttribute))); }
371 internal Type System_Runtime_InteropServices_MarshalAsAttribute
373 get { return typeof_System_Runtime_InteropServices_MarshalAsAttribute ?? (typeof_System_Runtime_InteropServices_MarshalAsAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.MarshalAsAttribute))); }
376 internal Type System_Runtime_InteropServices_UnmanagedType
378 get { return typeof_System_Runtime_InteropServices_UnmanagedType ?? (typeof_System_Runtime_InteropServices_UnmanagedType = ImportMscorlibType(typeof(System.Runtime.InteropServices.UnmanagedType))); }
381 internal Type System_Runtime_InteropServices_VarEnum
383 get { return typeof_System_Runtime_InteropServices_VarEnum ?? (typeof_System_Runtime_InteropServices_VarEnum = ImportMscorlibType(typeof(System.Runtime.InteropServices.VarEnum))); }
386 internal Type System_Runtime_InteropServices_OutAttribute
388 get { return typeof_System_Runtime_InteropServices_OutAttribute ?? (typeof_System_Runtime_InteropServices_OutAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.OutAttribute))); }
391 internal Type System_Runtime_InteropServices_StructLayoutAttribute
393 get { return typeof_System_Runtime_InteropServices_StructLayoutAttribute ?? (typeof_System_Runtime_InteropServices_StructLayoutAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.StructLayoutAttribute))); }
396 internal Type System_Runtime_InteropServices_OptionalAttribute
398 get { return typeof_System_Runtime_InteropServices_OptionalAttribute ?? (typeof_System_Runtime_InteropServices_OptionalAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.OptionalAttribute))); }
401 internal Type System_Runtime_InteropServices_PreserveSigAttribute
403 get { return typeof_System_Runtime_InteropServices_PreserveSigAttribute ?? (typeof_System_Runtime_InteropServices_PreserveSigAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.PreserveSigAttribute))); }
406 internal Type System_Runtime_InteropServices_CallingConvention
408 get { return typeof_System_Runtime_InteropServices_CallingConvention ?? (typeof_System_Runtime_InteropServices_CallingConvention = ImportMscorlibType(typeof(System.Runtime.InteropServices.CallingConvention))); }
411 internal Type System_Runtime_InteropServices_CharSet
413 get { return typeof_System_Runtime_InteropServices_CharSet ?? (typeof_System_Runtime_InteropServices_CharSet = ImportMscorlibType(typeof(System.Runtime.InteropServices.CharSet))); }
416 internal Type System_Runtime_InteropServices_ComImportAttribute
418 get { return typeof_System_Runtime_InteropServices_ComImportAttribute ?? (typeof_System_Runtime_InteropServices_ComImportAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.ComImportAttribute))); }
421 internal Type System_Runtime_CompilerServices_DecimalConstantAttribute
423 get { return typeof_System_Runtime_CompilerServices_DecimalConstantAttribute ?? (typeof_System_Runtime_CompilerServices_DecimalConstantAttribute = ImportMscorlibType(typeof(System.Runtime.CompilerServices.DecimalConstantAttribute))); }
426 internal Type System_Runtime_CompilerServices_SpecialNameAttribute
428 get { return typeof_System_Runtime_CompilerServices_SpecialNameAttribute ?? (typeof_System_Runtime_CompilerServices_SpecialNameAttribute = ImportMscorlibType(typeof(System.Runtime.CompilerServices.SpecialNameAttribute))); }
431 internal Type System_Runtime_CompilerServices_MethodImplAttribute
433 get { return typeof_System_Runtime_CompilerServices_MethodImplAttribute ?? (typeof_System_Runtime_CompilerServices_MethodImplAttribute = ImportMscorlibType(typeof(System.Runtime.CompilerServices.MethodImplAttribute))); }
436 internal Type System_Security_SuppressUnmanagedCodeSecurityAttribute
438 get { return typeof_System_Security_SuppressUnmanagedCodeSecurityAttribute ?? (typeof_System_Security_SuppressUnmanagedCodeSecurityAttribute = ImportMscorlibType(typeof(System.Security.SuppressUnmanagedCodeSecurityAttribute))); }
441 internal Type System_Reflection_AssemblyCopyrightAttribute
443 get { return typeof_System_Reflection_AssemblyCopyrightAttribute ?? (typeof_System_Reflection_AssemblyCopyrightAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyCopyrightAttribute))); }
446 internal Type System_Reflection_AssemblyTrademarkAttribute
448 get { return typeof_System_Reflection_AssemblyTrademarkAttribute ?? (typeof_System_Reflection_AssemblyTrademarkAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyTrademarkAttribute))); }
451 internal Type System_Reflection_AssemblyProductAttribute
453 get { return typeof_System_Reflection_AssemblyProductAttribute ?? (typeof_System_Reflection_AssemblyProductAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyProductAttribute))); }
456 internal Type System_Reflection_AssemblyCompanyAttribute
458 get { return typeof_System_Reflection_AssemblyCompanyAttribute ?? (typeof_System_Reflection_AssemblyCompanyAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyCompanyAttribute))); }
461 internal Type System_Reflection_AssemblyDescriptionAttribute
463 get { return typeof_System_Reflection_AssemblyDescriptionAttribute ?? (typeof_System_Reflection_AssemblyDescriptionAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyDescriptionAttribute))); }
466 internal Type System_Reflection_AssemblyTitleAttribute
468 get { return typeof_System_Reflection_AssemblyTitleAttribute ?? (typeof_System_Reflection_AssemblyTitleAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyTitleAttribute))); }
471 internal Type System_Reflection_AssemblyInformationalVersionAttribute
473 get { return typeof_System_Reflection_AssemblyInformationalVersionAttribute ?? (typeof_System_Reflection_AssemblyInformationalVersionAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyInformationalVersionAttribute))); }
476 internal Type System_Reflection_AssemblyFileVersionAttribute
478 get { return typeof_System_Reflection_AssemblyFileVersionAttribute ?? (typeof_System_Reflection_AssemblyFileVersionAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyFileVersionAttribute))); }
481 internal Type System_Security_Permissions_CodeAccessSecurityAttribute
483 get { return typeof_System_Security_Permissions_CodeAccessSecurityAttribute ?? (typeof_System_Security_Permissions_CodeAccessSecurityAttribute = ImportMscorlibType(typeof(System.Security.Permissions.CodeAccessSecurityAttribute))); }
486 internal Type System_Security_Permissions_PermissionSetAttribute
488 get { return typeof_System_Security_Permissions_PermissionSetAttribute ?? (typeof_System_Security_Permissions_PermissionSetAttribute = ImportMscorlibType(typeof(System.Security.Permissions.PermissionSetAttribute))); }
491 internal Type System_Security_Permissions_SecurityAction
493 get { return typeof_System_Security_Permissions_SecurityAction ?? (typeof_System_Security_Permissions_SecurityAction = ImportMscorlibType(typeof(System.Security.Permissions.SecurityAction))); }
496 internal bool HasMscorlib
498 get { return GetLoadedAssembly("mscorlib") != null; }
501 public event ResolveEventHandler AssemblyResolve
503 add { resolvers.Add(value); }
504 remove { resolvers.Remove(value); }
507 public Type Import(System.Type type)
510 if (!importedTypes.TryGetValue(type, out imported))
512 imported = ImportImpl(type);
513 if (imported != null)
515 importedTypes.Add(type, imported);
521 private Type ImportImpl(System.Type type)
523 if (type.Assembly == typeof(IKVM.Reflection.Type).Assembly)
525 throw new ArgumentException("Did you really want to import " + type.FullName + "?");
527 if (type.HasElementType)
531 if (type.Name.EndsWith("[]"))
533 return Import(type.GetElementType()).MakeArrayType();
537 return Import(type.GetElementType()).MakeArrayType(type.GetArrayRank());
540 else if (type.IsByRef)
542 return Import(type.GetElementType()).MakeByRefType();
544 else if (type.IsPointer)
546 return Import(type.GetElementType()).MakePointerType();
550 throw new InvalidOperationException();
553 else if (type.IsGenericParameter)
555 if (type.DeclaringMethod != null)
557 throw new NotImplementedException();
561 return Import(type.DeclaringType).GetGenericArguments()[type.GenericParameterPosition];
564 else if (type.IsGenericType && !type.IsGenericTypeDefinition)
566 System.Type[] args = type.GetGenericArguments();
567 Type[] importedArgs = new Type[args.Length];
568 for (int i = 0; i < args.Length; i++)
570 importedArgs[i] = Import(args[i]);
572 return Import(type.GetGenericTypeDefinition()).MakeGenericType(importedArgs);
574 else if (type.IsNested)
576 // note that we can't pass in the namespace here, because .NET's Type.Namespace implementation is broken for nested types
577 // (it returns the namespace of the declaring type)
578 return Import(type.DeclaringType).ResolveNestedType(new TypeName(null, type.Name));
580 else if (type.Assembly == typeof(object).Assembly)
582 // make sure mscorlib types always end up in our mscorlib
583 return Mscorlib.ResolveType(new TypeName(type.Namespace, type.Name));
587 return Import(type.Assembly).ResolveType(new TypeName(type.Namespace, type.Name));
591 private Assembly Import(System.Reflection.Assembly asm)
593 return Load(asm.FullName);
596 public RawModule OpenRawModule(string path)
598 path = Path.GetFullPath(path);
599 return OpenRawModule(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read), path);
602 public RawModule OpenRawModule(Stream stream, string location)
604 if (!stream.CanRead || !stream.CanSeek || stream.Position != 0)
606 throw new ArgumentException("Stream must support read/seek and current position must be zero.", "stream");
608 return new RawModule(new ModuleReader(null, this, stream, location));
611 public Assembly LoadAssembly(RawModule module)
613 string refname = module.GetAssemblyName().FullName;
614 Assembly asm = GetLoadedAssembly(refname);
617 AssemblyReader asm1 = module.ToAssembly();
618 assemblies.Add(asm1);
624 public Assembly LoadFile(string path)
628 using (RawModule module = OpenRawModule(path))
630 return LoadAssembly(module);
633 catch (IOException x)
635 throw new FileNotFoundException(x.Message, x);
637 catch (UnauthorizedAccessException x)
639 throw new FileNotFoundException(x.Message, x);
643 private static string GetSimpleAssemblyName(string refname)
647 if (Fusion.ParseAssemblySimpleName(refname, out pos, out name) != ParseAssemblyResult.OK)
649 throw new ArgumentException();
654 private Assembly GetLoadedAssembly(string refname)
657 if (!assembliesByName.TryGetValue(refname, out asm))
659 string simpleName = GetSimpleAssemblyName(refname);
660 for (int i = 0; i < assemblies.Count; i++)
662 AssemblyComparisonResult result;
663 if (simpleName.Equals(assemblies[i].Name, StringComparison.InvariantCultureIgnoreCase)
664 && CompareAssemblyIdentity(refname, false, assemblies[i].FullName, false, out result))
667 assembliesByName.Add(refname, asm);
675 private Assembly GetDynamicAssembly(string refname)
677 string simpleName = GetSimpleAssemblyName(refname);
678 foreach (AssemblyBuilder asm in dynamicAssemblies)
680 AssemblyComparisonResult result;
681 if (simpleName.Equals(asm.Name, StringComparison.InvariantCultureIgnoreCase)
682 && CompareAssemblyIdentity(refname, false, asm.FullName, false, out result))
690 public Assembly Load(string refname)
692 return Load(refname, null, true);
695 internal Assembly Load(string refname, Assembly requestingAssembly, bool throwOnError)
697 Assembly asm = GetLoadedAssembly(refname);
702 if (resolvers.Count == 0)
704 asm = DefaultResolver(refname, throwOnError);
708 ResolveEventArgs args = new ResolveEventArgs(refname, requestingAssembly);
709 foreach (ResolveEventHandler evt in resolvers)
711 asm = evt(this, args);
719 asm = GetDynamicAssembly(refname);
724 string defname = asm.FullName;
725 if (refname != defname)
727 assembliesByName.Add(refname, asm);
733 throw new FileNotFoundException(refname);
738 private Assembly DefaultResolver(string refname, bool throwOnError)
740 Assembly asm = GetDynamicAssembly(refname);
750 fileName = System.Reflection.Assembly.ReflectionOnlyLoad(refname).Location;
752 catch (System.BadImageFormatException x)
754 throw new BadImageFormatException(x.Message, x);
761 fileName = System.Reflection.Assembly.ReflectionOnlyLoad(refname).Location;
763 catch (System.BadImageFormatException x)
765 throw new BadImageFormatException(x.Message, x);
767 catch (FileNotFoundException)
769 // we intentionally only swallow the FileNotFoundException, if the file exists but isn't a valid assembly,
770 // we should throw an exception
774 return LoadFile(fileName);
777 public Type GetType(string assemblyQualifiedTypeName)
779 // to be more compatible with Type.GetType(), we could call Assembly.GetCallingAssembly(),
780 // import that assembly and pass it as the context, but implicitly importing is considered evil
781 return GetType(null, assemblyQualifiedTypeName, false, false);
784 public Type GetType(string assemblyQualifiedTypeName, bool throwOnError)
786 // to be more compatible with Type.GetType(), we could call Assembly.GetCallingAssembly(),
787 // import that assembly and pass it as the context, but implicitly importing is considered evil
788 return GetType(null, assemblyQualifiedTypeName, throwOnError, false);
791 public Type GetType(string assemblyQualifiedTypeName, bool throwOnError, bool ignoreCase)
793 // to be more compatible with Type.GetType(), we could call Assembly.GetCallingAssembly(),
794 // import that assembly and pass it as the context, but implicitly importing is considered evil
795 return GetType(null, assemblyQualifiedTypeName, throwOnError, ignoreCase);
798 // note that context is slightly different from the calling assembly (System.Type.GetType),
799 // because context is passed to the AssemblyResolve event as the RequestingAssembly
800 public Type GetType(Assembly context, string assemblyQualifiedTypeName, bool throwOnError)
802 return GetType(context, assemblyQualifiedTypeName, throwOnError, false);
805 // note that context is slightly different from the calling assembly (System.Type.GetType),
806 // because context is passed to the AssemblyResolve event as the RequestingAssembly
807 public Type GetType(Assembly context, string assemblyQualifiedTypeName, bool throwOnError, bool ignoreCase)
809 TypeNameParser parser = TypeNameParser.Parse(assemblyQualifiedTypeName, throwOnError);
814 return parser.GetType(this, context, throwOnError, assemblyQualifiedTypeName, false, ignoreCase);
817 // this is similar to GetType(Assembly context, string assemblyQualifiedTypeName, bool throwOnError),
818 // but instead it assumes that the type must exist (i.e. if EnableMissingMemberResolution is enabled
819 // it will create a missing type)
820 public Type ResolveType(Assembly context, string assemblyQualifiedTypeName)
822 TypeNameParser parser = TypeNameParser.Parse(assemblyQualifiedTypeName, false);
827 return parser.GetType(this, context, false, assemblyQualifiedTypeName, true, false);
830 public Assembly[] GetAssemblies()
832 Assembly[] array = new Assembly[assemblies.Count + dynamicAssemblies.Count];
833 for (int i = 0; i < assemblies.Count; i++)
835 array[i] = assemblies[i];
837 for (int i = 0, j = assemblies.Count; j < array.Length; i++, j++)
839 array[j] = dynamicAssemblies[i];
844 // this is equivalent to the Fusion CompareAssemblyIdentity API
845 public bool CompareAssemblyIdentity(string assemblyIdentity1, bool unified1, string assemblyIdentity2, bool unified2, out AssemblyComparisonResult result)
847 return useNativeFusion
848 ? Fusion.CompareAssemblyIdentityNative(assemblyIdentity1, unified1, assemblyIdentity2, unified2, out result)
849 : Fusion.CompareAssemblyIdentityPure(assemblyIdentity1, unified1, assemblyIdentity2, unified2, out result);
852 public AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access)
854 return DefineDynamicAssemblyImpl(name, access, null, null, null, null);
857 public AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access, string dir)
859 return DefineDynamicAssemblyImpl(name, access, dir, null, null, null);
865 public AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions)
867 return DefineDynamicAssemblyImpl(name, access, dir, requiredPermissions, optionalPermissions, refusedPermissions);
870 private AssemblyBuilder DefineDynamicAssemblyImpl(AssemblyName name, AssemblyBuilderAccess access, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions)
872 AssemblyBuilder asm = new AssemblyBuilder(this, name, dir, requiredPermissions, optionalPermissions, refusedPermissions);
873 dynamicAssemblies.Add(asm);
877 internal void RenameAssembly(Assembly assembly, AssemblyName oldName)
879 List<string> remove = new List<string>();
880 foreach (KeyValuePair<string, Assembly> kv in assembliesByName)
882 if (kv.Value == assembly)
887 foreach (string key in remove)
889 assembliesByName.Remove(key);
893 public void Dispose()
895 foreach (Assembly asm in assemblies)
897 foreach (Module mod in asm.GetLoadedModules())
902 foreach (AssemblyBuilder asm in dynamicAssemblies)
904 foreach (Module mod in asm.GetLoadedModules())
911 public Assembly CreateMissingAssembly(string assemblyName)
913 Assembly asm = new MissingAssembly(this, assemblyName);
914 string name = asm.FullName;
915 if (!assembliesByName.ContainsKey(name))
917 assembliesByName.Add(name, asm);
922 public void EnableMissingMemberResolution()
924 resolveMissingMembers = true;
927 internal bool MissingMemberResolution
929 get { return resolveMissingMembers; }
932 internal bool EnableFunctionPointers
934 get { return enableFunctionPointers; }
937 private struct ScopedTypeName : IEquatable<ScopedTypeName>
939 private readonly object scope;
940 private readonly TypeName name;
942 internal ScopedTypeName(object scope, TypeName name)
948 public override bool Equals(object obj)
950 ScopedTypeName? other = obj as ScopedTypeName?;
951 return other != null && ((IEquatable<ScopedTypeName>)other.Value).Equals(this);
954 public override int GetHashCode()
956 return scope.GetHashCode() * 7 + name.GetHashCode();
959 bool IEquatable<ScopedTypeName>.Equals(ScopedTypeName other)
961 return other.scope == scope && other.name == name;
965 internal Type GetMissingTypeOrThrow(Module module, Type declaringType, TypeName typeName)
967 if (resolveMissingMembers || module.Assembly.__IsMissing)
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);
982 string fullName = TypeNameParser.Escape(typeName.ToString());
983 if (declaringType != null)
985 fullName = declaringType.FullName + "+" + fullName;
987 throw new TypeLoadException(String.Format("Type '{0}' not found in assembly '{1}'", fullName, module.Assembly.FullName));
990 internal MethodBase GetMissingMethodOrThrow(Type declaringType, string name, MethodSignature signature)
992 if (resolveMissingMembers)
994 MethodInfo method = new MissingMethod(declaringType, name, signature);
997 return new ConstructorInfoImpl(method);
1001 throw new MissingMethodException(declaringType.ToString(), name);
1004 internal FieldInfo GetMissingFieldOrThrow(Type declaringType, string name, FieldSignature signature)
1006 if (resolveMissingMembers)
1008 return new MissingField(declaringType, name, signature);
1010 throw new MissingFieldException(declaringType.ToString(), name);
1013 internal PropertyInfo GetMissingPropertyOrThrow(Type declaringType, string name, PropertySignature propertySignature)
1015 // HACK we need to check __IsMissing here, because Type doesn't have a FindProperty API
1016 // since properties are never resolved, except by custom attributes
1017 if (resolveMissingMembers || declaringType.__IsMissing)
1019 return new MissingProperty(declaringType, name, propertySignature);
1021 throw new System.MissingMemberException(declaringType.ToString(), name);
1024 internal Type CanonicalizeType(Type type)
1027 if (!canonicalizedTypes.TryGetValue(type, out canon))
1030 canonicalizedTypes.Add(canon, canon);
1035 public Type MakeFunctionPointer(__StandAloneMethodSig sig)
1037 return FunctionPointerType.Make(this, sig);
1040 public __StandAloneMethodSig MakeStandAloneMethodSig(System.Runtime.InteropServices.CallingConvention callingConvention, Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers)
1042 return new __StandAloneMethodSig(true, callingConvention, 0, returnType ?? this.System_Void, Util.Copy(parameterTypes), Type.EmptyTypes,
1043 PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, Util.NullSafeLength(parameterTypes)));
1046 public __StandAloneMethodSig MakeStandAloneMethodSig(CallingConventions callingConvention, Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, Type[] optionalParameterTypes, CustomModifiers[] parameterTypeCustomModifiers)
1048 return new __StandAloneMethodSig(false, 0, callingConvention, returnType ?? this.System_Void, Util.Copy(parameterTypes), Util.Copy(optionalParameterTypes),
1049 PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, Util.NullSafeLength(parameterTypes) + Util.NullSafeLength(optionalParameterTypes)));
1052 public event Predicate<Type> MissingTypeIsValueType
1056 if (missingTypeIsValueType != null)
1058 throw new InvalidOperationException("Only a single MissingTypeIsValueType handler can be registered.");
1060 missingTypeIsValueType = value;
1064 if (value.Equals(missingTypeIsValueType))
1066 missingTypeIsValueType = null;
1071 internal bool ResolveMissingTypeIsValueType(MissingType missingType)
1073 if (missingTypeIsValueType != null)
1075 return missingTypeIsValueType(missingType);
1077 throw new MissingMemberException(missingType);