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 private readonly Dictionary<Type, Type> canonicalizedTypes = new Dictionary<Type, Type>();
91 private readonly List<AssemblyReader> assemblies = new List<AssemblyReader>();
92 private readonly List<AssemblyBuilder> dynamicAssemblies = new List<AssemblyBuilder>();
93 private readonly Dictionary<string, Assembly> assembliesByName = new Dictionary<string, Assembly>();
94 private readonly Dictionary<System.Type, Type> importedTypes = new Dictionary<System.Type, Type>();
95 private Dictionary<ScopedTypeName, Type> missingTypes;
96 private bool resolveMissingMembers;
97 private readonly bool enableFunctionPointers;
98 private readonly bool useNativeFusion;
99 private Type typeof_System_Object;
100 private Type typeof_System_ValueType;
101 private Type typeof_System_Enum;
102 private Type typeof_System_Void;
103 private Type typeof_System_Boolean;
104 private Type typeof_System_Char;
105 private Type typeof_System_SByte;
106 private Type typeof_System_Byte;
107 private Type typeof_System_Int16;
108 private Type typeof_System_UInt16;
109 private Type typeof_System_Int32;
110 private Type typeof_System_UInt32;
111 private Type typeof_System_Int64;
112 private Type typeof_System_UInt64;
113 private Type typeof_System_Single;
114 private Type typeof_System_Double;
115 private Type typeof_System_String;
116 private Type typeof_System_IntPtr;
117 private Type typeof_System_UIntPtr;
118 private Type typeof_System_TypedReference;
119 private Type typeof_System_Type;
120 private Type typeof_System_Array;
121 private Type typeof_System_DateTime;
122 private Type typeof_System_DBNull;
123 private Type typeof_System_Decimal;
124 private Type typeof_System_NonSerializedAttribute;
125 private Type typeof_System_SerializableAttribute;
126 private Type typeof_System_AttributeUsageAttribute;
127 private Type typeof_System_Runtime_InteropServices_DllImportAttribute;
128 private Type typeof_System_Runtime_InteropServices_FieldOffsetAttribute;
129 private Type typeof_System_Runtime_InteropServices_InAttribute;
130 private Type typeof_System_Runtime_InteropServices_MarshalAsAttribute;
131 private Type typeof_System_Runtime_InteropServices_UnmanagedType;
132 private Type typeof_System_Runtime_InteropServices_VarEnum;
133 private Type typeof_System_Runtime_InteropServices_OutAttribute;
134 private Type typeof_System_Runtime_InteropServices_StructLayoutAttribute;
135 private Type typeof_System_Runtime_InteropServices_OptionalAttribute;
136 private Type typeof_System_Runtime_InteropServices_PreserveSigAttribute;
137 private Type typeof_System_Runtime_InteropServices_CallingConvention;
138 private Type typeof_System_Runtime_InteropServices_CharSet;
139 private Type typeof_System_Runtime_InteropServices_ComImportAttribute;
140 private Type typeof_System_Runtime_CompilerServices_DecimalConstantAttribute;
141 private Type typeof_System_Runtime_CompilerServices_SpecialNameAttribute;
142 private Type typeof_System_Runtime_CompilerServices_MethodImplAttribute;
143 private Type typeof_System_Security_SuppressUnmanagedCodeSecurityAttribute;
144 private Type typeof_System_Reflection_AssemblyCopyrightAttribute;
145 private Type typeof_System_Reflection_AssemblyTrademarkAttribute;
146 private Type typeof_System_Reflection_AssemblyProductAttribute;
147 private Type typeof_System_Reflection_AssemblyCompanyAttribute;
148 private Type typeof_System_Reflection_AssemblyDescriptionAttribute;
149 private Type typeof_System_Reflection_AssemblyTitleAttribute;
150 private Type typeof_System_Reflection_AssemblyInformationalVersionAttribute;
151 private Type typeof_System_Reflection_AssemblyFileVersionAttribute;
152 private Type typeof_System_Security_Permissions_CodeAccessSecurityAttribute;
153 private Type typeof_System_Security_Permissions_PermissionSetAttribute;
154 private Type typeof_System_Security_Permissions_SecurityAction;
155 private List<ResolveEventHandler> resolvers = new List<ResolveEventHandler>();
156 private Predicate<Type> missingTypeIsValueType;
159 : this(UniverseOptions.None)
163 public Universe(UniverseOptions options)
165 enableFunctionPointers = (options & UniverseOptions.EnableFunctionPointers) != 0;
166 useNativeFusion = (options & UniverseOptions.DisableFusion) == 0 && GetUseNativeFusion();
169 private static bool GetUseNativeFusion()
173 return Environment.OSVersion.Platform == PlatformID.Win32NT
174 && System.Type.GetType("Mono.Runtime") == null
175 && Environment.GetEnvironmentVariable("IKVM_DISABLE_FUSION") == null;
177 catch (System.Security.SecurityException)
183 internal Assembly Mscorlib
185 get { return Load("mscorlib"); }
188 private Type ImportMscorlibType(System.Type type)
190 if (Mscorlib.__IsMissing)
192 return Mscorlib.ResolveType(new TypeName(type.Namespace, type.Name));
194 // We use FindType instead of ResolveType here, because on some versions of mscorlib some of
195 // the special types we use/support are missing and the type properties are defined to
196 // return null in that case.
197 // Note that we don't have to unescape type.Name here, because none of the names contain special characters.
198 return Mscorlib.FindType(new TypeName(type.Namespace, type.Name));
201 private Type ResolvePrimitive(string name)
203 // Primitive here means that these types have a special metadata encoding, which means that
204 // there can be references to them without referring to them by name explicitly.
205 // When 'resolve missing type' mode is enabled, we want these types to be usable even when
206 // they don't exist in mscorlib or there is no mscorlib loaded.
207 return Mscorlib.ResolveType(new TypeName("System", name));
210 internal Type System_Object
212 get { return typeof_System_Object ?? (typeof_System_Object = ResolvePrimitive("Object")); }
215 internal Type System_ValueType
217 // System.ValueType is not a primitive, but generic type parameters can have a ValueType constraint
218 // (we also don't want to return null here)
219 get { return typeof_System_ValueType ?? (typeof_System_ValueType = ResolvePrimitive("ValueType")); }
222 internal Type System_Enum
224 // System.Enum is not a primitive, but we don't want to return null
225 get { return typeof_System_Enum ?? (typeof_System_Enum = ResolvePrimitive("Enum")); }
228 internal Type System_Void
230 get { return typeof_System_Void ?? (typeof_System_Void = ResolvePrimitive("Void")); }
233 internal Type System_Boolean
235 get { return typeof_System_Boolean ?? (typeof_System_Boolean = ResolvePrimitive("Boolean")); }
238 internal Type System_Char
240 get { return typeof_System_Char ?? (typeof_System_Char = ResolvePrimitive("Char")); }
243 internal Type System_SByte
245 get { return typeof_System_SByte ?? (typeof_System_SByte = ResolvePrimitive("SByte")); }
248 internal Type System_Byte
250 get { return typeof_System_Byte ?? (typeof_System_Byte = ResolvePrimitive("Byte")); }
253 internal Type System_Int16
255 get { return typeof_System_Int16 ?? (typeof_System_Int16 = ResolvePrimitive("Int16")); }
258 internal Type System_UInt16
260 get { return typeof_System_UInt16 ?? (typeof_System_UInt16 = ResolvePrimitive("UInt16")); }
263 internal Type System_Int32
265 get { return typeof_System_Int32 ?? (typeof_System_Int32 = ResolvePrimitive("Int32")); }
268 internal Type System_UInt32
270 get { return typeof_System_UInt32 ?? (typeof_System_UInt32 = ResolvePrimitive("UInt32")); }
273 internal Type System_Int64
275 get { return typeof_System_Int64 ?? (typeof_System_Int64 = ResolvePrimitive("Int64")); }
278 internal Type System_UInt64
280 get { return typeof_System_UInt64 ?? (typeof_System_UInt64 = ResolvePrimitive("UInt64")); }
283 internal Type System_Single
285 get { return typeof_System_Single ?? (typeof_System_Single = ResolvePrimitive("Single")); }
288 internal Type System_Double
290 get { return typeof_System_Double ?? (typeof_System_Double = ResolvePrimitive("Double")); }
293 internal Type System_String
295 get { return typeof_System_String ?? (typeof_System_String = ResolvePrimitive("String")); }
298 internal Type System_IntPtr
300 get { return typeof_System_IntPtr ?? (typeof_System_IntPtr = ResolvePrimitive("IntPtr")); }
303 internal Type System_UIntPtr
305 get { return typeof_System_UIntPtr ?? (typeof_System_UIntPtr = ResolvePrimitive("UIntPtr")); }
308 internal Type System_TypedReference
310 get { return typeof_System_TypedReference ?? (typeof_System_TypedReference = ResolvePrimitive("TypedReference")); }
313 internal Type System_Type
315 // System.Type is not a primitive, but it does have a special encoding in custom attributes
316 get { return typeof_System_Type ?? (typeof_System_Type = ResolvePrimitive("Type")); }
319 internal Type System_Array
321 // System.Array is not a primitive, but it used as a base type for array types (that are primitives)
322 get { return typeof_System_Array ?? (typeof_System_Array = ResolvePrimitive("Array")); }
325 internal Type System_DateTime
327 get { return typeof_System_DateTime ?? (typeof_System_DateTime = ImportMscorlibType(typeof(System.DateTime))); }
330 internal Type System_DBNull
332 get { return typeof_System_DBNull ?? (typeof_System_DBNull = ImportMscorlibType(typeof(System.DBNull))); }
335 internal Type System_Decimal
337 get { return typeof_System_Decimal ?? (typeof_System_Decimal = ImportMscorlibType(typeof(System.Decimal))); }
340 internal Type System_NonSerializedAttribute
342 get { return typeof_System_NonSerializedAttribute ?? (typeof_System_NonSerializedAttribute = ImportMscorlibType(typeof(System.NonSerializedAttribute))); }
345 internal Type System_SerializableAttribute
347 get { return typeof_System_SerializableAttribute ?? (typeof_System_SerializableAttribute = ImportMscorlibType(typeof(System.SerializableAttribute))); }
350 internal Type System_AttributeUsageAttribute
352 get { return typeof_System_AttributeUsageAttribute ?? (typeof_System_AttributeUsageAttribute = ImportMscorlibType(typeof(System.AttributeUsageAttribute))); }
355 internal Type System_Runtime_InteropServices_DllImportAttribute
357 get { return typeof_System_Runtime_InteropServices_DllImportAttribute ?? (typeof_System_Runtime_InteropServices_DllImportAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.DllImportAttribute))); }
360 internal Type System_Runtime_InteropServices_FieldOffsetAttribute
362 get { return typeof_System_Runtime_InteropServices_FieldOffsetAttribute ?? (typeof_System_Runtime_InteropServices_FieldOffsetAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.FieldOffsetAttribute))); }
365 internal Type System_Runtime_InteropServices_InAttribute
367 get { return typeof_System_Runtime_InteropServices_InAttribute ?? (typeof_System_Runtime_InteropServices_InAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.InAttribute))); }
370 internal Type System_Runtime_InteropServices_MarshalAsAttribute
372 get { return typeof_System_Runtime_InteropServices_MarshalAsAttribute ?? (typeof_System_Runtime_InteropServices_MarshalAsAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.MarshalAsAttribute))); }
375 internal Type System_Runtime_InteropServices_UnmanagedType
377 get { return typeof_System_Runtime_InteropServices_UnmanagedType ?? (typeof_System_Runtime_InteropServices_UnmanagedType = ImportMscorlibType(typeof(System.Runtime.InteropServices.UnmanagedType))); }
380 internal Type System_Runtime_InteropServices_VarEnum
382 get { return typeof_System_Runtime_InteropServices_VarEnum ?? (typeof_System_Runtime_InteropServices_VarEnum = ImportMscorlibType(typeof(System.Runtime.InteropServices.VarEnum))); }
385 internal Type System_Runtime_InteropServices_OutAttribute
387 get { return typeof_System_Runtime_InteropServices_OutAttribute ?? (typeof_System_Runtime_InteropServices_OutAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.OutAttribute))); }
390 internal Type System_Runtime_InteropServices_StructLayoutAttribute
392 get { return typeof_System_Runtime_InteropServices_StructLayoutAttribute ?? (typeof_System_Runtime_InteropServices_StructLayoutAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.StructLayoutAttribute))); }
395 internal Type System_Runtime_InteropServices_OptionalAttribute
397 get { return typeof_System_Runtime_InteropServices_OptionalAttribute ?? (typeof_System_Runtime_InteropServices_OptionalAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.OptionalAttribute))); }
400 internal Type System_Runtime_InteropServices_PreserveSigAttribute
402 get { return typeof_System_Runtime_InteropServices_PreserveSigAttribute ?? (typeof_System_Runtime_InteropServices_PreserveSigAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.PreserveSigAttribute))); }
405 internal Type System_Runtime_InteropServices_CallingConvention
407 get { return typeof_System_Runtime_InteropServices_CallingConvention ?? (typeof_System_Runtime_InteropServices_CallingConvention = ImportMscorlibType(typeof(System.Runtime.InteropServices.CallingConvention))); }
410 internal Type System_Runtime_InteropServices_CharSet
412 get { return typeof_System_Runtime_InteropServices_CharSet ?? (typeof_System_Runtime_InteropServices_CharSet = ImportMscorlibType(typeof(System.Runtime.InteropServices.CharSet))); }
415 internal Type System_Runtime_InteropServices_ComImportAttribute
417 get { return typeof_System_Runtime_InteropServices_ComImportAttribute ?? (typeof_System_Runtime_InteropServices_ComImportAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.ComImportAttribute))); }
420 internal Type System_Runtime_CompilerServices_DecimalConstantAttribute
422 get { return typeof_System_Runtime_CompilerServices_DecimalConstantAttribute ?? (typeof_System_Runtime_CompilerServices_DecimalConstantAttribute = ImportMscorlibType(typeof(System.Runtime.CompilerServices.DecimalConstantAttribute))); }
425 internal Type System_Runtime_CompilerServices_SpecialNameAttribute
427 get { return typeof_System_Runtime_CompilerServices_SpecialNameAttribute ?? (typeof_System_Runtime_CompilerServices_SpecialNameAttribute = ImportMscorlibType(typeof(System.Runtime.CompilerServices.SpecialNameAttribute))); }
430 internal Type System_Runtime_CompilerServices_MethodImplAttribute
432 get { return typeof_System_Runtime_CompilerServices_MethodImplAttribute ?? (typeof_System_Runtime_CompilerServices_MethodImplAttribute = ImportMscorlibType(typeof(System.Runtime.CompilerServices.MethodImplAttribute))); }
435 internal Type System_Security_SuppressUnmanagedCodeSecurityAttribute
437 get { return typeof_System_Security_SuppressUnmanagedCodeSecurityAttribute ?? (typeof_System_Security_SuppressUnmanagedCodeSecurityAttribute = ImportMscorlibType(typeof(System.Security.SuppressUnmanagedCodeSecurityAttribute))); }
440 internal Type System_Reflection_AssemblyCopyrightAttribute
442 get { return typeof_System_Reflection_AssemblyCopyrightAttribute ?? (typeof_System_Reflection_AssemblyCopyrightAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyCopyrightAttribute))); }
445 internal Type System_Reflection_AssemblyTrademarkAttribute
447 get { return typeof_System_Reflection_AssemblyTrademarkAttribute ?? (typeof_System_Reflection_AssemblyTrademarkAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyTrademarkAttribute))); }
450 internal Type System_Reflection_AssemblyProductAttribute
452 get { return typeof_System_Reflection_AssemblyProductAttribute ?? (typeof_System_Reflection_AssemblyProductAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyProductAttribute))); }
455 internal Type System_Reflection_AssemblyCompanyAttribute
457 get { return typeof_System_Reflection_AssemblyCompanyAttribute ?? (typeof_System_Reflection_AssemblyCompanyAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyCompanyAttribute))); }
460 internal Type System_Reflection_AssemblyDescriptionAttribute
462 get { return typeof_System_Reflection_AssemblyDescriptionAttribute ?? (typeof_System_Reflection_AssemblyDescriptionAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyDescriptionAttribute))); }
465 internal Type System_Reflection_AssemblyTitleAttribute
467 get { return typeof_System_Reflection_AssemblyTitleAttribute ?? (typeof_System_Reflection_AssemblyTitleAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyTitleAttribute))); }
470 internal Type System_Reflection_AssemblyInformationalVersionAttribute
472 get { return typeof_System_Reflection_AssemblyInformationalVersionAttribute ?? (typeof_System_Reflection_AssemblyInformationalVersionAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyInformationalVersionAttribute))); }
475 internal Type System_Reflection_AssemblyFileVersionAttribute
477 get { return typeof_System_Reflection_AssemblyFileVersionAttribute ?? (typeof_System_Reflection_AssemblyFileVersionAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyFileVersionAttribute))); }
480 internal Type System_Security_Permissions_CodeAccessSecurityAttribute
482 get { return typeof_System_Security_Permissions_CodeAccessSecurityAttribute ?? (typeof_System_Security_Permissions_CodeAccessSecurityAttribute = ImportMscorlibType(typeof(System.Security.Permissions.CodeAccessSecurityAttribute))); }
485 internal Type System_Security_Permissions_PermissionSetAttribute
487 get { return typeof_System_Security_Permissions_PermissionSetAttribute ?? (typeof_System_Security_Permissions_PermissionSetAttribute = ImportMscorlibType(typeof(System.Security.Permissions.PermissionSetAttribute))); }
490 internal Type System_Security_Permissions_SecurityAction
492 get { return typeof_System_Security_Permissions_SecurityAction ?? (typeof_System_Security_Permissions_SecurityAction = ImportMscorlibType(typeof(System.Security.Permissions.SecurityAction))); }
495 internal bool HasMscorlib
497 get { return GetLoadedAssembly("mscorlib") != null; }
500 public event ResolveEventHandler AssemblyResolve
502 add { resolvers.Add(value); }
503 remove { resolvers.Remove(value); }
506 public Type Import(System.Type type)
509 if (!importedTypes.TryGetValue(type, out imported))
511 imported = ImportImpl(type);
512 if (imported != null)
514 importedTypes.Add(type, imported);
520 private Type ImportImpl(System.Type type)
522 if (type.Assembly == typeof(IKVM.Reflection.Type).Assembly)
524 throw new ArgumentException("Did you really want to import " + type.FullName + "?");
526 if (type.HasElementType)
530 if (type.Name.EndsWith("[]"))
532 return Import(type.GetElementType()).MakeArrayType();
536 return Import(type.GetElementType()).MakeArrayType(type.GetArrayRank());
539 else if (type.IsByRef)
541 return Import(type.GetElementType()).MakeByRefType();
543 else if (type.IsPointer)
545 return Import(type.GetElementType()).MakePointerType();
549 throw new InvalidOperationException();
552 else if (type.IsGenericParameter)
554 if (type.DeclaringMethod != null)
556 throw new NotImplementedException();
560 return Import(type.DeclaringType).GetGenericArguments()[type.GenericParameterPosition];
563 else if (type.IsGenericType && !type.IsGenericTypeDefinition)
565 System.Type[] args = type.GetGenericArguments();
566 Type[] importedArgs = new Type[args.Length];
567 for (int i = 0; i < args.Length; i++)
569 importedArgs[i] = Import(args[i]);
571 return Import(type.GetGenericTypeDefinition()).MakeGenericType(importedArgs);
573 else if (type.IsNested)
575 // note that we can't pass in the namespace here, because .NET's Type.Namespace implementation is broken for nested types
576 // (it returns the namespace of the declaring type)
577 return Import(type.DeclaringType).ResolveNestedType(new TypeName(null, type.Name));
579 else if (type.Assembly == typeof(object).Assembly)
581 // make sure mscorlib types always end up in our mscorlib
582 return Mscorlib.ResolveType(new TypeName(type.Namespace, type.Name));
586 return Import(type.Assembly).ResolveType(new TypeName(type.Namespace, type.Name));
590 private Assembly Import(System.Reflection.Assembly asm)
592 return Load(asm.FullName);
595 public RawModule OpenRawModule(string path)
597 path = Path.GetFullPath(path);
598 return OpenRawModule(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read), path);
601 public RawModule OpenRawModule(Stream stream, string location)
603 if (!stream.CanRead || !stream.CanSeek || stream.Position != 0)
605 throw new ArgumentException("Stream must support read/seek and current position must be zero.", "stream");
607 return new RawModule(new ModuleReader(null, this, stream, location));
610 public Assembly LoadAssembly(RawModule module)
612 string refname = module.GetAssemblyName().FullName;
613 Assembly asm = GetLoadedAssembly(refname);
616 AssemblyReader asm1 = module.ToAssembly();
617 assemblies.Add(asm1);
623 public Assembly LoadFile(string path)
627 using (RawModule module = OpenRawModule(path))
629 return LoadAssembly(module);
632 catch (IOException x)
634 throw new FileNotFoundException(x.Message, x);
636 catch (UnauthorizedAccessException x)
638 throw new FileNotFoundException(x.Message, x);
642 private static string GetSimpleAssemblyName(string refname)
646 if (Fusion.ParseAssemblySimpleName(refname, out pos, out name) != ParseAssemblyResult.OK)
648 throw new ArgumentException();
653 private Assembly GetLoadedAssembly(string refname)
656 if (!assembliesByName.TryGetValue(refname, out asm))
658 string simpleName = GetSimpleAssemblyName(refname);
659 for (int i = 0; i < assemblies.Count; i++)
661 AssemblyComparisonResult result;
662 if (simpleName.Equals(assemblies[i].Name, StringComparison.InvariantCultureIgnoreCase)
663 && CompareAssemblyIdentity(refname, false, assemblies[i].FullName, false, out result))
666 assembliesByName.Add(refname, asm);
674 private Assembly GetDynamicAssembly(string refname)
676 string simpleName = GetSimpleAssemblyName(refname);
677 foreach (AssemblyBuilder asm in dynamicAssemblies)
679 AssemblyComparisonResult result;
680 if (simpleName.Equals(asm.Name, StringComparison.InvariantCultureIgnoreCase)
681 && CompareAssemblyIdentity(refname, false, asm.FullName, false, out result))
689 public Assembly Load(string refname)
691 return Load(refname, null, true);
694 internal Assembly Load(string refname, Assembly requestingAssembly, bool throwOnError)
696 Assembly asm = GetLoadedAssembly(refname);
701 if (resolvers.Count == 0)
703 asm = DefaultResolver(refname, throwOnError);
707 ResolveEventArgs args = new ResolveEventArgs(refname, requestingAssembly);
708 foreach (ResolveEventHandler evt in resolvers)
710 asm = evt(this, args);
718 asm = GetDynamicAssembly(refname);
723 string defname = asm.FullName;
724 if (refname != defname)
726 assembliesByName.Add(refname, asm);
732 throw new FileNotFoundException(refname);
737 private Assembly DefaultResolver(string refname, bool throwOnError)
739 Assembly asm = GetDynamicAssembly(refname);
749 fileName = System.Reflection.Assembly.ReflectionOnlyLoad(refname).Location;
751 catch (System.BadImageFormatException x)
753 throw new BadImageFormatException(x.Message, x);
760 fileName = System.Reflection.Assembly.ReflectionOnlyLoad(refname).Location;
762 catch (System.BadImageFormatException x)
764 throw new BadImageFormatException(x.Message, x);
766 catch (FileNotFoundException)
768 // we intentionally only swallow the FileNotFoundException, if the file exists but isn't a valid assembly,
769 // we should throw an exception
773 return LoadFile(fileName);
776 public Type GetType(string assemblyQualifiedTypeName)
778 // to be more compatible with Type.GetType(), we could call Assembly.GetCallingAssembly(),
779 // import that assembly and pass it as the context, but implicitly importing is considered evil
780 return GetType(null, assemblyQualifiedTypeName, false, false);
783 public Type GetType(string assemblyQualifiedTypeName, bool throwOnError)
785 // to be more compatible with Type.GetType(), we could call Assembly.GetCallingAssembly(),
786 // import that assembly and pass it as the context, but implicitly importing is considered evil
787 return GetType(null, assemblyQualifiedTypeName, throwOnError, false);
790 public Type GetType(string assemblyQualifiedTypeName, bool throwOnError, bool ignoreCase)
792 // to be more compatible with Type.GetType(), we could call Assembly.GetCallingAssembly(),
793 // import that assembly and pass it as the context, but implicitly importing is considered evil
794 return GetType(null, assemblyQualifiedTypeName, throwOnError, ignoreCase);
797 // note that context is slightly different from the calling assembly (System.Type.GetType),
798 // because context is passed to the AssemblyResolve event as the RequestingAssembly
799 public Type GetType(Assembly context, string assemblyQualifiedTypeName, bool throwOnError)
801 return GetType(context, assemblyQualifiedTypeName, throwOnError, false);
804 // note that context is slightly different from the calling assembly (System.Type.GetType),
805 // because context is passed to the AssemblyResolve event as the RequestingAssembly
806 public Type GetType(Assembly context, string assemblyQualifiedTypeName, bool throwOnError, bool ignoreCase)
808 TypeNameParser parser = TypeNameParser.Parse(assemblyQualifiedTypeName, throwOnError);
813 return parser.GetType(this, context, throwOnError, assemblyQualifiedTypeName, false, ignoreCase);
816 // this is similar to GetType(Assembly context, string assemblyQualifiedTypeName, bool throwOnError),
817 // but instead it assumes that the type must exist (i.e. if EnableMissingMemberResolution is enabled
818 // it will create a missing type)
819 public Type ResolveType(Assembly context, string assemblyQualifiedTypeName)
821 TypeNameParser parser = TypeNameParser.Parse(assemblyQualifiedTypeName, false);
826 return parser.GetType(this, context, false, assemblyQualifiedTypeName, true, false);
829 public Assembly[] GetAssemblies()
831 Assembly[] array = new Assembly[assemblies.Count + dynamicAssemblies.Count];
832 for (int i = 0; i < assemblies.Count; i++)
834 array[i] = assemblies[i];
836 for (int i = 0, j = assemblies.Count; j < array.Length; i++, j++)
838 array[j] = dynamicAssemblies[i];
843 // this is equivalent to the Fusion CompareAssemblyIdentity API
844 public bool CompareAssemblyIdentity(string assemblyIdentity1, bool unified1, string assemblyIdentity2, bool unified2, out AssemblyComparisonResult result)
846 return useNativeFusion
847 ? Fusion.CompareAssemblyIdentityNative(assemblyIdentity1, unified1, assemblyIdentity2, unified2, out result)
848 : Fusion.CompareAssemblyIdentityPure(assemblyIdentity1, unified1, assemblyIdentity2, unified2, out result);
851 public AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access)
853 return DefineDynamicAssemblyImpl(name, access, null, null, null, null);
856 public AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access, string dir)
858 return DefineDynamicAssemblyImpl(name, access, dir, null, null, null);
864 public AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions)
866 return DefineDynamicAssemblyImpl(name, access, dir, requiredPermissions, optionalPermissions, refusedPermissions);
869 private AssemblyBuilder DefineDynamicAssemblyImpl(AssemblyName name, AssemblyBuilderAccess access, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions)
871 AssemblyBuilder asm = new AssemblyBuilder(this, name, dir, requiredPermissions, optionalPermissions, refusedPermissions);
872 dynamicAssemblies.Add(asm);
876 internal void RenameAssembly(Assembly assembly, AssemblyName oldName)
878 List<string> remove = new List<string>();
879 foreach (KeyValuePair<string, Assembly> kv in assembliesByName)
881 if (kv.Value == assembly)
886 foreach (string key in remove)
888 assembliesByName.Remove(key);
892 public void Dispose()
894 foreach (Assembly asm in assemblies)
896 foreach (Module mod in asm.GetLoadedModules())
901 foreach (AssemblyBuilder asm in dynamicAssemblies)
903 foreach (Module mod in asm.GetLoadedModules())
910 public Assembly CreateMissingAssembly(string assemblyName)
912 Assembly asm = new MissingAssembly(this, assemblyName);
913 string name = asm.FullName;
914 if (!assembliesByName.ContainsKey(name))
916 assembliesByName.Add(name, asm);
921 public void EnableMissingMemberResolution()
923 resolveMissingMembers = true;
926 internal bool MissingMemberResolution
928 get { return resolveMissingMembers; }
931 internal bool EnableFunctionPointers
933 get { return enableFunctionPointers; }
936 private struct ScopedTypeName : IEquatable<ScopedTypeName>
938 private readonly object scope;
939 private readonly TypeName name;
941 internal ScopedTypeName(object scope, TypeName name)
947 public override bool Equals(object obj)
949 ScopedTypeName? other = obj as ScopedTypeName?;
950 return other != null && ((IEquatable<ScopedTypeName>)other.Value).Equals(this);
953 public override int GetHashCode()
955 return scope.GetHashCode() * 7 + name.GetHashCode();
958 bool IEquatable<ScopedTypeName>.Equals(ScopedTypeName other)
960 return other.scope == scope && other.name == name;
964 internal Type GetMissingTypeOrThrow(Module module, Type declaringType, TypeName typeName)
966 if (resolveMissingMembers || module.Assembly.__IsMissing)
968 if (missingTypes == null)
970 missingTypes = new Dictionary<ScopedTypeName, Type>();
972 ScopedTypeName stn = new ScopedTypeName(declaringType ?? (object)module, typeName);
974 if (!missingTypes.TryGetValue(stn, out type))
976 type = new MissingType(module, declaringType, typeName.Namespace, typeName.Name);
977 missingTypes.Add(stn, type);
981 string fullName = TypeNameParser.Escape(typeName.ToString());
982 if (declaringType != null)
984 fullName = declaringType.FullName + "+" + fullName;
986 throw new TypeLoadException(String.Format("Type '{0}' not found in assembly '{1}'", fullName, module.Assembly.FullName));
989 internal MethodBase GetMissingMethodOrThrow(Type declaringType, string name, MethodSignature signature)
991 if (resolveMissingMembers)
993 MethodInfo method = new MissingMethod(declaringType, name, signature);
996 return new ConstructorInfoImpl(method);
1000 throw new MissingMethodException(declaringType.ToString(), name);
1003 internal FieldInfo GetMissingFieldOrThrow(Type declaringType, string name, FieldSignature signature)
1005 if (resolveMissingMembers)
1007 return new MissingField(declaringType, name, signature);
1009 throw new MissingFieldException(declaringType.ToString(), name);
1012 internal PropertyInfo GetMissingPropertyOrThrow(Type declaringType, string name, PropertySignature propertySignature)
1014 // HACK we need to check __IsMissing here, because Type doesn't have a FindProperty API
1015 // since properties are never resolved, except by custom attributes
1016 if (resolveMissingMembers || declaringType.__IsMissing)
1018 return new MissingProperty(declaringType, name, propertySignature);
1020 throw new System.MissingMemberException(declaringType.ToString(), name);
1023 internal Type CanonicalizeType(Type type)
1026 if (!canonicalizedTypes.TryGetValue(type, out canon))
1029 canonicalizedTypes.Add(canon, canon);
1034 public Type MakeFunctionPointer(__StandAloneMethodSig sig)
1036 return FunctionPointerType.Make(this, sig);
1039 public __StandAloneMethodSig MakeStandAloneMethodSig(System.Runtime.InteropServices.CallingConvention callingConvention, Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers)
1041 return new __StandAloneMethodSig(true, callingConvention, 0, returnType ?? this.System_Void, Util.Copy(parameterTypes), Type.EmptyTypes,
1042 PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, Util.NullSafeLength(parameterTypes)));
1045 public __StandAloneMethodSig MakeStandAloneMethodSig(CallingConventions callingConvention, Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, Type[] optionalParameterTypes, CustomModifiers[] parameterTypeCustomModifiers)
1047 return new __StandAloneMethodSig(false, 0, callingConvention, returnType ?? this.System_Void, Util.Copy(parameterTypes), Util.Copy(optionalParameterTypes),
1048 PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, Util.NullSafeLength(parameterTypes) + Util.NullSafeLength(optionalParameterTypes)));
1051 public event Predicate<Type> MissingTypeIsValueType
1055 if (missingTypeIsValueType != null)
1057 throw new InvalidOperationException("Only a single MissingTypeIsValueType handler can be registered.");
1059 missingTypeIsValueType = value;
1063 if (value.Equals(missingTypeIsValueType))
1065 missingTypeIsValueType = null;
1070 internal bool ResolveMissingTypeIsValueType(MissingType missingType)
1072 if (missingTypeIsValueType != null)
1074 return missingTypeIsValueType(missingType);
1076 throw new MissingMemberException(missingType);