BindingFlags.Public needed here as Exception.HResult is now public in .NET 4.5. This...
[mono.git] / mcs / class / IKVM.Reflection / Universe.cs
1 /*
2   Copyright (C) 2009-2012 Jeroen Frijters
3
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.
7
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:
11
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.
19
20   Jeroen Frijters
21   jeroen@frijters.net
22   
23 */
24 using System;
25 using System.Collections.Generic;
26 using System.IO;
27 using System.Security;
28 using System.Text;
29 using System.Diagnostics;
30 using IKVM.Reflection.Reader;
31 using IKVM.Reflection.Emit;
32
33 namespace IKVM.Reflection
34 {
35         public sealed class ResolveEventArgs : EventArgs
36         {
37                 private readonly string name;
38                 private readonly Assembly requestingAssembly;
39
40                 public ResolveEventArgs(string name)
41                         : this(name, null)
42                 {
43                 }
44
45                 public ResolveEventArgs(string name, Assembly requestingAssembly)
46                 {
47                         this.name = name;
48                         this.requestingAssembly = requestingAssembly;
49                 }
50
51                 public string Name
52                 {
53                         get { return name; }
54                 }
55
56                 public Assembly RequestingAssembly
57                 {
58                         get { return requestingAssembly; }
59                 }
60         }
61
62         public enum AssemblyComparisonResult
63         {
64                 Unknown = 0,
65                 EquivalentFullMatch = 1,
66                 EquivalentWeakNamed = 2,
67                 EquivalentFXUnified = 3,
68                 EquivalentUnified = 4,
69                 NonEquivalentVersion = 5,
70                 NonEquivalent = 6,
71                 EquivalentPartialMatch = 7,
72                 EquivalentPartialWeakNamed = 8,
73                 EquivalentPartialUnified = 9,
74                 EquivalentPartialFXUnified = 10,
75                 NonEquivalentPartialVersion = 11,
76         }
77
78         public delegate Assembly ResolveEventHandler(object sender, ResolveEventArgs args);
79
80         [Flags]
81         public enum UniverseOptions
82         {
83                 None = 0,
84                 EnableFunctionPointers = 1,
85                 DisableFusion = 2,
86         }
87
88         public sealed class Universe : IDisposable
89         {
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;
157
158                 public Universe()
159                         : this(UniverseOptions.None)
160                 {
161                 }
162
163                 public Universe(UniverseOptions options)
164                 {
165                         enableFunctionPointers = (options & UniverseOptions.EnableFunctionPointers) != 0;
166                         useNativeFusion = (options & UniverseOptions.DisableFusion) == 0 && GetUseNativeFusion();
167                 }
168
169                 private static bool GetUseNativeFusion()
170                 {
171                         try
172                         {
173                                 return Environment.OSVersion.Platform == PlatformID.Win32NT
174                                         && System.Type.GetType("Mono.Runtime") == null
175                                         && Environment.GetEnvironmentVariable("IKVM_DISABLE_FUSION") == null;
176                         }
177                         catch (System.Security.SecurityException)
178                         {
179                                 return false;
180                         }
181                 }
182
183                 internal Assembly Mscorlib
184                 {
185                         get { return Load("mscorlib"); }
186                 }
187
188                 private Type ImportMscorlibType(System.Type type)
189                 {
190                         if (Mscorlib.__IsMissing)
191                         {
192                                 return Mscorlib.ResolveType(new TypeName(type.Namespace, type.Name));
193                         }
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));
199                 }
200
201                 private Type ResolvePrimitive(string name)
202                 {
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));
208                 }
209
210                 internal Type System_Object
211                 {
212                         get { return typeof_System_Object ?? (typeof_System_Object = ResolvePrimitive("Object")); }
213                 }
214
215                 internal Type System_ValueType
216                 {
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")); }
220                 }
221
222                 internal Type System_Enum
223                 {
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")); }
226                 }
227
228                 internal Type System_Void
229                 {
230                         get { return typeof_System_Void ?? (typeof_System_Void = ResolvePrimitive("Void")); }
231                 }
232
233                 internal Type System_Boolean
234                 {
235                         get { return typeof_System_Boolean ?? (typeof_System_Boolean = ResolvePrimitive("Boolean")); }
236                 }
237
238                 internal Type System_Char
239                 {
240                         get { return typeof_System_Char ?? (typeof_System_Char = ResolvePrimitive("Char")); }
241                 }
242
243                 internal Type System_SByte
244                 {
245                         get { return typeof_System_SByte ?? (typeof_System_SByte = ResolvePrimitive("SByte")); }
246                 }
247
248                 internal Type System_Byte
249                 {
250                         get { return typeof_System_Byte ?? (typeof_System_Byte = ResolvePrimitive("Byte")); }
251                 }
252
253                 internal Type System_Int16
254                 {
255                         get { return typeof_System_Int16 ?? (typeof_System_Int16 = ResolvePrimitive("Int16")); }
256                 }
257
258                 internal Type System_UInt16
259                 {
260                         get { return typeof_System_UInt16 ?? (typeof_System_UInt16 = ResolvePrimitive("UInt16")); }
261                 }
262
263                 internal Type System_Int32
264                 {
265                         get { return typeof_System_Int32 ?? (typeof_System_Int32 = ResolvePrimitive("Int32")); }
266                 }
267
268                 internal Type System_UInt32
269                 {
270                         get { return typeof_System_UInt32 ?? (typeof_System_UInt32 = ResolvePrimitive("UInt32")); }
271                 }
272
273                 internal Type System_Int64
274                 {
275                         get { return typeof_System_Int64 ?? (typeof_System_Int64 = ResolvePrimitive("Int64")); }
276                 }
277
278                 internal Type System_UInt64
279                 {
280                         get { return typeof_System_UInt64 ?? (typeof_System_UInt64 = ResolvePrimitive("UInt64")); }
281                 }
282
283                 internal Type System_Single
284                 {
285                         get { return typeof_System_Single ?? (typeof_System_Single = ResolvePrimitive("Single")); }
286                 }
287
288                 internal Type System_Double
289                 {
290                         get { return typeof_System_Double ?? (typeof_System_Double = ResolvePrimitive("Double")); }
291                 }
292
293                 internal Type System_String
294                 {
295                         get { return typeof_System_String ?? (typeof_System_String = ResolvePrimitive("String")); }
296                 }
297
298                 internal Type System_IntPtr
299                 {
300                         get { return typeof_System_IntPtr ?? (typeof_System_IntPtr = ResolvePrimitive("IntPtr")); }
301                 }
302
303                 internal Type System_UIntPtr
304                 {
305                         get { return typeof_System_UIntPtr ?? (typeof_System_UIntPtr = ResolvePrimitive("UIntPtr")); }
306                 }
307
308                 internal Type System_TypedReference
309                 {
310                         get { return typeof_System_TypedReference ?? (typeof_System_TypedReference = ResolvePrimitive("TypedReference")); }
311                 }
312
313                 internal Type System_Type
314                 {
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")); }
317                 }
318
319                 internal Type System_Array
320                 {
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")); }
323                 }
324
325                 internal Type System_DateTime
326                 {
327                         get { return typeof_System_DateTime ?? (typeof_System_DateTime = ImportMscorlibType(typeof(System.DateTime))); }
328                 }
329
330                 internal Type System_DBNull
331                 {
332                         get { return typeof_System_DBNull ?? (typeof_System_DBNull = ImportMscorlibType(typeof(System.DBNull))); }
333                 }
334
335                 internal Type System_Decimal
336                 {
337                         get { return typeof_System_Decimal ?? (typeof_System_Decimal = ImportMscorlibType(typeof(System.Decimal))); }
338                 }
339
340                 internal Type System_NonSerializedAttribute
341                 {
342                         get { return typeof_System_NonSerializedAttribute ?? (typeof_System_NonSerializedAttribute = ImportMscorlibType(typeof(System.NonSerializedAttribute))); }
343                 }
344
345                 internal Type System_SerializableAttribute
346                 {
347                         get { return typeof_System_SerializableAttribute ?? (typeof_System_SerializableAttribute = ImportMscorlibType(typeof(System.SerializableAttribute))); }
348                 }
349
350                 internal Type System_AttributeUsageAttribute
351                 {
352                         get { return typeof_System_AttributeUsageAttribute ?? (typeof_System_AttributeUsageAttribute = ImportMscorlibType(typeof(System.AttributeUsageAttribute))); }
353                 }
354
355                 internal Type System_Runtime_InteropServices_DllImportAttribute
356                 {
357                         get { return typeof_System_Runtime_InteropServices_DllImportAttribute ?? (typeof_System_Runtime_InteropServices_DllImportAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.DllImportAttribute))); }
358                 }
359
360                 internal Type System_Runtime_InteropServices_FieldOffsetAttribute
361                 {
362                         get { return typeof_System_Runtime_InteropServices_FieldOffsetAttribute ?? (typeof_System_Runtime_InteropServices_FieldOffsetAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.FieldOffsetAttribute))); }
363                 }
364
365                 internal Type System_Runtime_InteropServices_InAttribute
366                 {
367                         get { return typeof_System_Runtime_InteropServices_InAttribute ?? (typeof_System_Runtime_InteropServices_InAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.InAttribute))); }
368                 }
369
370                 internal Type System_Runtime_InteropServices_MarshalAsAttribute
371                 {
372                         get { return typeof_System_Runtime_InteropServices_MarshalAsAttribute ?? (typeof_System_Runtime_InteropServices_MarshalAsAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.MarshalAsAttribute))); }
373                 }
374
375                 internal Type System_Runtime_InteropServices_UnmanagedType
376                 {
377                         get { return typeof_System_Runtime_InteropServices_UnmanagedType ?? (typeof_System_Runtime_InteropServices_UnmanagedType = ImportMscorlibType(typeof(System.Runtime.InteropServices.UnmanagedType))); }
378                 }
379
380                 internal Type System_Runtime_InteropServices_VarEnum
381                 {
382                         get { return typeof_System_Runtime_InteropServices_VarEnum ?? (typeof_System_Runtime_InteropServices_VarEnum = ImportMscorlibType(typeof(System.Runtime.InteropServices.VarEnum))); }
383                 }
384
385                 internal Type System_Runtime_InteropServices_OutAttribute
386                 {
387                         get { return typeof_System_Runtime_InteropServices_OutAttribute ?? (typeof_System_Runtime_InteropServices_OutAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.OutAttribute))); }
388                 }
389
390                 internal Type System_Runtime_InteropServices_StructLayoutAttribute
391                 {
392                         get { return typeof_System_Runtime_InteropServices_StructLayoutAttribute ?? (typeof_System_Runtime_InteropServices_StructLayoutAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.StructLayoutAttribute))); }
393                 }
394
395                 internal Type System_Runtime_InteropServices_OptionalAttribute
396                 {
397                         get { return typeof_System_Runtime_InteropServices_OptionalAttribute ?? (typeof_System_Runtime_InteropServices_OptionalAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.OptionalAttribute))); }
398                 }
399
400                 internal Type System_Runtime_InteropServices_PreserveSigAttribute
401                 {
402                         get { return typeof_System_Runtime_InteropServices_PreserveSigAttribute ?? (typeof_System_Runtime_InteropServices_PreserveSigAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.PreserveSigAttribute))); }
403                 }
404
405                 internal Type System_Runtime_InteropServices_CallingConvention
406                 {
407                         get { return typeof_System_Runtime_InteropServices_CallingConvention ?? (typeof_System_Runtime_InteropServices_CallingConvention = ImportMscorlibType(typeof(System.Runtime.InteropServices.CallingConvention))); }
408                 }
409
410                 internal Type System_Runtime_InteropServices_CharSet
411                 {
412                         get { return typeof_System_Runtime_InteropServices_CharSet ?? (typeof_System_Runtime_InteropServices_CharSet = ImportMscorlibType(typeof(System.Runtime.InteropServices.CharSet))); }
413                 }
414
415                 internal Type System_Runtime_InteropServices_ComImportAttribute
416                 {
417                         get { return typeof_System_Runtime_InteropServices_ComImportAttribute ?? (typeof_System_Runtime_InteropServices_ComImportAttribute = ImportMscorlibType(typeof(System.Runtime.InteropServices.ComImportAttribute))); }
418                 }
419
420                 internal Type System_Runtime_CompilerServices_DecimalConstantAttribute
421                 {
422                         get { return typeof_System_Runtime_CompilerServices_DecimalConstantAttribute ?? (typeof_System_Runtime_CompilerServices_DecimalConstantAttribute = ImportMscorlibType(typeof(System.Runtime.CompilerServices.DecimalConstantAttribute))); }
423                 }
424
425                 internal Type System_Runtime_CompilerServices_SpecialNameAttribute
426                 {
427                         get { return typeof_System_Runtime_CompilerServices_SpecialNameAttribute ?? (typeof_System_Runtime_CompilerServices_SpecialNameAttribute = ImportMscorlibType(typeof(System.Runtime.CompilerServices.SpecialNameAttribute))); }
428                 }
429
430                 internal Type System_Runtime_CompilerServices_MethodImplAttribute
431                 {
432                         get { return typeof_System_Runtime_CompilerServices_MethodImplAttribute ?? (typeof_System_Runtime_CompilerServices_MethodImplAttribute = ImportMscorlibType(typeof(System.Runtime.CompilerServices.MethodImplAttribute))); }
433                 }
434
435                 internal Type System_Security_SuppressUnmanagedCodeSecurityAttribute
436                 {
437                         get { return typeof_System_Security_SuppressUnmanagedCodeSecurityAttribute ?? (typeof_System_Security_SuppressUnmanagedCodeSecurityAttribute = ImportMscorlibType(typeof(System.Security.SuppressUnmanagedCodeSecurityAttribute))); }
438                 }
439
440                 internal Type System_Reflection_AssemblyCopyrightAttribute
441                 {
442                         get { return typeof_System_Reflection_AssemblyCopyrightAttribute ?? (typeof_System_Reflection_AssemblyCopyrightAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyCopyrightAttribute))); }
443                 }
444
445                 internal Type System_Reflection_AssemblyTrademarkAttribute
446                 {
447                         get { return typeof_System_Reflection_AssemblyTrademarkAttribute ?? (typeof_System_Reflection_AssemblyTrademarkAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyTrademarkAttribute))); }
448                 }
449
450                 internal Type System_Reflection_AssemblyProductAttribute
451                 {
452                         get { return typeof_System_Reflection_AssemblyProductAttribute ?? (typeof_System_Reflection_AssemblyProductAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyProductAttribute))); }
453                 }
454
455                 internal Type System_Reflection_AssemblyCompanyAttribute
456                 {
457                         get { return typeof_System_Reflection_AssemblyCompanyAttribute ?? (typeof_System_Reflection_AssemblyCompanyAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyCompanyAttribute))); }
458                 }
459
460                 internal Type System_Reflection_AssemblyDescriptionAttribute
461                 {
462                         get { return typeof_System_Reflection_AssemblyDescriptionAttribute ?? (typeof_System_Reflection_AssemblyDescriptionAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyDescriptionAttribute))); }
463                 }
464
465                 internal Type System_Reflection_AssemblyTitleAttribute
466                 {
467                         get { return typeof_System_Reflection_AssemblyTitleAttribute ?? (typeof_System_Reflection_AssemblyTitleAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyTitleAttribute))); }
468                 }
469
470                 internal Type System_Reflection_AssemblyInformationalVersionAttribute
471                 {
472                         get { return typeof_System_Reflection_AssemblyInformationalVersionAttribute ?? (typeof_System_Reflection_AssemblyInformationalVersionAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyInformationalVersionAttribute))); }
473                 }
474
475                 internal Type System_Reflection_AssemblyFileVersionAttribute
476                 {
477                         get { return typeof_System_Reflection_AssemblyFileVersionAttribute ?? (typeof_System_Reflection_AssemblyFileVersionAttribute = ImportMscorlibType(typeof(System.Reflection.AssemblyFileVersionAttribute))); }
478                 }
479
480                 internal Type System_Security_Permissions_CodeAccessSecurityAttribute
481                 {
482                         get { return typeof_System_Security_Permissions_CodeAccessSecurityAttribute ?? (typeof_System_Security_Permissions_CodeAccessSecurityAttribute = ImportMscorlibType(typeof(System.Security.Permissions.CodeAccessSecurityAttribute))); }
483                 }
484
485                 internal Type System_Security_Permissions_PermissionSetAttribute
486                 {
487                         get { return typeof_System_Security_Permissions_PermissionSetAttribute ?? (typeof_System_Security_Permissions_PermissionSetAttribute = ImportMscorlibType(typeof(System.Security.Permissions.PermissionSetAttribute))); }
488                 }
489
490                 internal Type System_Security_Permissions_SecurityAction
491                 {
492                         get { return typeof_System_Security_Permissions_SecurityAction ?? (typeof_System_Security_Permissions_SecurityAction = ImportMscorlibType(typeof(System.Security.Permissions.SecurityAction))); }
493                 }
494
495                 internal bool HasMscorlib
496                 {
497                         get { return GetLoadedAssembly("mscorlib") != null; }
498                 }
499
500                 public event ResolveEventHandler AssemblyResolve
501                 {
502                         add { resolvers.Add(value); }
503                         remove { resolvers.Remove(value); }
504                 }
505
506                 public Type Import(System.Type type)
507                 {
508                         Type imported;
509                         if (!importedTypes.TryGetValue(type, out imported))
510                         {
511                                 imported = ImportImpl(type);
512                                 if (imported != null)
513                                 {
514                                         importedTypes.Add(type, imported);
515                                 }
516                         }
517                         return imported;
518                 }
519
520                 private Type ImportImpl(System.Type type)
521                 {
522                         if (type.Assembly == typeof(IKVM.Reflection.Type).Assembly)
523                         {
524                                 throw new ArgumentException("Did you really want to import " + type.FullName + "?");
525                         }
526                         if (type.HasElementType)
527                         {
528                                 if (type.IsArray)
529                                 {
530                                         if (type.Name.EndsWith("[]"))
531                                         {
532                                                 return Import(type.GetElementType()).MakeArrayType();
533                                         }
534                                         else
535                                         {
536                                                 return Import(type.GetElementType()).MakeArrayType(type.GetArrayRank());
537                                         }
538                                 }
539                                 else if (type.IsByRef)
540                                 {
541                                         return Import(type.GetElementType()).MakeByRefType();
542                                 }
543                                 else if (type.IsPointer)
544                                 {
545                                         return Import(type.GetElementType()).MakePointerType();
546                                 }
547                                 else
548                                 {
549                                         throw new InvalidOperationException();
550                                 }
551                         }
552                         else if (type.IsGenericParameter)
553                         {
554                                 if (type.DeclaringMethod != null)
555                                 {
556                                         throw new NotImplementedException();
557                                 }
558                                 else
559                                 {
560                                         return Import(type.DeclaringType).GetGenericArguments()[type.GenericParameterPosition];
561                                 }
562                         }
563                         else if (type.IsGenericType && !type.IsGenericTypeDefinition)
564                         {
565                                 System.Type[] args = type.GetGenericArguments();
566                                 Type[] importedArgs = new Type[args.Length];
567                                 for (int i = 0; i < args.Length; i++)
568                                 {
569                                         importedArgs[i] = Import(args[i]);
570                                 }
571                                 return Import(type.GetGenericTypeDefinition()).MakeGenericType(importedArgs);
572                         }
573                         else if (type.IsNested)
574                         {
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));
578                         }
579                         else if (type.Assembly == typeof(object).Assembly)
580                         {
581                                 // make sure mscorlib types always end up in our mscorlib
582                                 return Mscorlib.ResolveType(new TypeName(type.Namespace, type.Name));
583                         }
584                         else
585                         {
586                                 return Import(type.Assembly).ResolveType(new TypeName(type.Namespace, type.Name));
587                         }
588                 }
589
590                 private Assembly Import(System.Reflection.Assembly asm)
591                 {
592                         return Load(asm.FullName);
593                 }
594
595                 public RawModule OpenRawModule(string path)
596                 {
597                         path = Path.GetFullPath(path);
598                         return OpenRawModule(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read), path);
599                 }
600
601                 public RawModule OpenRawModule(Stream stream, string location)
602                 {
603                         if (!stream.CanRead || !stream.CanSeek || stream.Position != 0)
604                         {
605                                 throw new ArgumentException("Stream must support read/seek and current position must be zero.", "stream");
606                         }
607                         return new RawModule(new ModuleReader(null, this, stream, location));
608                 }
609
610                 public Assembly LoadAssembly(RawModule module)
611                 {
612                         string refname = module.GetAssemblyName().FullName;
613                         Assembly asm = GetLoadedAssembly(refname);
614                         if (asm == null)
615                         {
616                                 AssemblyReader asm1 = module.ToAssembly();
617                                 assemblies.Add(asm1);
618                                 asm = asm1;
619                         }
620                         return asm;
621                 }
622
623                 public Assembly LoadFile(string path)
624                 {
625                         try
626                         {
627                                 using (RawModule module = OpenRawModule(path))
628                                 {
629                                         return LoadAssembly(module);
630                                 }
631                         }
632                         catch (IOException x)
633                         {
634                                 throw new FileNotFoundException(x.Message, x);
635                         }
636                         catch (UnauthorizedAccessException x)
637                         {
638                                 throw new FileNotFoundException(x.Message, x);
639                         }
640                 }
641
642                 private static string GetSimpleAssemblyName(string refname)
643                 {
644                         int pos;
645                         string name;
646                         if (Fusion.ParseAssemblySimpleName(refname, out pos, out name) != ParseAssemblyResult.OK)
647                         {
648                                 throw new ArgumentException();
649                         }
650                         return name;
651                 }
652
653                 private Assembly GetLoadedAssembly(string refname)
654                 {
655                         Assembly asm;
656                         if (!assembliesByName.TryGetValue(refname, out asm))
657                         {
658                                 string simpleName = GetSimpleAssemblyName(refname);
659                                 for (int i = 0; i < assemblies.Count; i++)
660                                 {
661                                         AssemblyComparisonResult result;
662                                         if (simpleName.Equals(assemblies[i].Name, StringComparison.InvariantCultureIgnoreCase)
663                                                 && CompareAssemblyIdentity(refname, false, assemblies[i].FullName, false, out result))
664                                         {
665                                                 asm = assemblies[i];
666                                                 assembliesByName.Add(refname, asm);
667                                                 break;
668                                         }
669                                 }
670                         }
671                         return asm;
672                 }
673
674                 private Assembly GetDynamicAssembly(string refname)
675                 {
676                         string simpleName = GetSimpleAssemblyName(refname);
677                         foreach (AssemblyBuilder asm in dynamicAssemblies)
678                         {
679                                 AssemblyComparisonResult result;
680                                 if (simpleName.Equals(asm.Name, StringComparison.InvariantCultureIgnoreCase)
681                                         && CompareAssemblyIdentity(refname, false, asm.FullName, false, out result))
682                                 {
683                                         return asm;
684                                 }
685                         }
686                         return null;
687                 }
688
689                 public Assembly Load(string refname)
690                 {
691                         return Load(refname, null, true);
692                 }
693
694                 internal Assembly Load(string refname, Assembly requestingAssembly, bool throwOnError)
695                 {
696                         Assembly asm = GetLoadedAssembly(refname);
697                         if (asm != null)
698                         {
699                                 return asm;
700                         }
701                         if (resolvers.Count == 0)
702                         {
703                                 asm = DefaultResolver(refname, throwOnError);
704                         }
705                         else
706                         {
707                                 ResolveEventArgs args = new ResolveEventArgs(refname, requestingAssembly);
708                                 foreach (ResolveEventHandler evt in resolvers)
709                                 {
710                                         asm = evt(this, args);
711                                         if (asm != null)
712                                         {
713                                                 break;
714                                         }
715                                 }
716                                 if (asm == null)
717                                 {
718                                         asm = GetDynamicAssembly(refname);
719                                 }
720                         }
721                         if (asm != null)
722                         {
723                                 string defname = asm.FullName;
724                                 if (refname != defname)
725                                 {
726                                         assembliesByName.Add(refname, asm);
727                                 }
728                                 return asm;
729                         }
730                         if (throwOnError)
731                         {
732                                 throw new FileNotFoundException(refname);
733                         }
734                         return null;
735                 }
736
737                 private Assembly DefaultResolver(string refname, bool throwOnError)
738                 {
739                         Assembly asm = GetDynamicAssembly(refname);
740                         if (asm != null)
741                         {
742                                 return asm;
743                         }
744                         string fileName;
745                         if (throwOnError)
746                         {
747                                 try
748                                 {
749                                         fileName = System.Reflection.Assembly.ReflectionOnlyLoad(refname).Location;
750                                 }
751                                 catch (System.BadImageFormatException x)
752                                 {
753                                         throw new BadImageFormatException(x.Message, x);
754                                 }
755                         }
756                         else
757                         {
758                                 try
759                                 {
760                                         fileName = System.Reflection.Assembly.ReflectionOnlyLoad(refname).Location;
761                                 }
762                                 catch (System.BadImageFormatException x)
763                                 {
764                                         throw new BadImageFormatException(x.Message, x);
765                                 }
766                                 catch (FileNotFoundException)
767                                 {
768                                         // we intentionally only swallow the FileNotFoundException, if the file exists but isn't a valid assembly,
769                                         // we should throw an exception
770                                         return null;
771                                 }
772                         }
773                         return LoadFile(fileName);
774                 }
775
776                 public Type GetType(string assemblyQualifiedTypeName)
777                 {
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);
781                 }
782
783                 public Type GetType(string assemblyQualifiedTypeName, bool throwOnError)
784                 {
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);
788                 }
789
790                 public Type GetType(string assemblyQualifiedTypeName, bool throwOnError, bool ignoreCase)
791                 {
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);
795                 }
796
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)
800                 {
801                         return GetType(context, assemblyQualifiedTypeName, throwOnError, false);
802                 }
803
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)
807                 {
808                         TypeNameParser parser = TypeNameParser.Parse(assemblyQualifiedTypeName, throwOnError);
809                         if (parser.Error)
810                         {
811                                 return null;
812                         }
813                         return parser.GetType(this, context, throwOnError, assemblyQualifiedTypeName, false, ignoreCase);
814                 }
815
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)
820                 {
821                         TypeNameParser parser = TypeNameParser.Parse(assemblyQualifiedTypeName, false);
822                         if (parser.Error)
823                         {
824                                 return null;
825                         }
826                         return parser.GetType(this, context, false, assemblyQualifiedTypeName, true, false);
827                 }
828
829                 public Assembly[] GetAssemblies()
830                 {
831                         Assembly[] array = new Assembly[assemblies.Count + dynamicAssemblies.Count];
832                         for (int i = 0; i < assemblies.Count; i++)
833                         {
834                                 array[i] = assemblies[i];
835                         }
836                         for (int i = 0, j = assemblies.Count; j < array.Length; i++, j++)
837                         {
838                                 array[j] = dynamicAssemblies[i];
839                         }
840                         return array;
841                 }
842
843                 // this is equivalent to the Fusion CompareAssemblyIdentity API
844                 public bool CompareAssemblyIdentity(string assemblyIdentity1, bool unified1, string assemblyIdentity2, bool unified2, out AssemblyComparisonResult result)
845                 {
846                         return useNativeFusion
847                                 ? Fusion.CompareAssemblyIdentityNative(assemblyIdentity1, unified1, assemblyIdentity2, unified2, out result)
848                                 : Fusion.CompareAssemblyIdentityPure(assemblyIdentity1, unified1, assemblyIdentity2, unified2, out result);
849                 }
850
851                 public AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access)
852                 {
853                         return DefineDynamicAssemblyImpl(name, access, null, null, null, null);
854                 }
855
856                 public AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access, string dir)
857                 {
858                         return DefineDynamicAssemblyImpl(name, access, dir, null, null, null);
859                 }
860
861 #if NET_4_0
862                 [Obsolete]
863 #endif
864                 public AssemblyBuilder DefineDynamicAssembly(AssemblyName name, AssemblyBuilderAccess access, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions)
865                 {
866                         return DefineDynamicAssemblyImpl(name, access, dir, requiredPermissions, optionalPermissions, refusedPermissions);
867                 }
868
869                 private AssemblyBuilder DefineDynamicAssemblyImpl(AssemblyName name, AssemblyBuilderAccess access, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions)
870                 {
871                         AssemblyBuilder asm = new AssemblyBuilder(this, name, dir, requiredPermissions, optionalPermissions, refusedPermissions);
872                         dynamicAssemblies.Add(asm);
873                         return asm;
874                 }
875
876                 internal void RenameAssembly(Assembly assembly, AssemblyName oldName)
877                 {
878                         List<string> remove = new List<string>();
879                         foreach (KeyValuePair<string, Assembly> kv in assembliesByName)
880                         {
881                                 if (kv.Value == assembly)
882                                 {
883                                         remove.Add(kv.Key);
884                                 }
885                         }
886                         foreach (string key in remove)
887                         {
888                                 assembliesByName.Remove(key);
889                         }
890                 }
891
892                 public void Dispose()
893                 {
894                         foreach (Assembly asm in assemblies)
895                         {
896                                 foreach (Module mod in asm.GetLoadedModules())
897                                 {
898                                         mod.Dispose();
899                                 }
900                         }
901                         foreach (AssemblyBuilder asm in dynamicAssemblies)
902                         {
903                                 foreach (Module mod in asm.GetLoadedModules())
904                                 {
905                                         mod.Dispose();
906                                 }
907                         }
908                 }
909
910                 public Assembly CreateMissingAssembly(string assemblyName)
911                 {
912                         Assembly asm = new MissingAssembly(this, assemblyName);
913                         string name = asm.FullName;
914                         if (!assembliesByName.ContainsKey(name))
915                         {
916                                 assembliesByName.Add(name, asm);
917                         }
918                         return asm;
919                 }
920
921                 public void EnableMissingMemberResolution()
922                 {
923                         resolveMissingMembers = true;
924                 }
925
926                 internal bool MissingMemberResolution
927                 {
928                         get { return resolveMissingMembers; }
929                 }
930
931                 internal bool EnableFunctionPointers
932                 {
933                         get { return enableFunctionPointers; }
934                 }
935
936                 private struct ScopedTypeName : IEquatable<ScopedTypeName>
937                 {
938                         private readonly object scope;
939                         private readonly TypeName name;
940
941                         internal ScopedTypeName(object scope, TypeName name)
942                         {
943                                 this.scope = scope;
944                                 this.name = name;
945                         }
946
947                         public override bool Equals(object obj)
948                         {
949                                 ScopedTypeName? other = obj as ScopedTypeName?;
950                                 return other != null && ((IEquatable<ScopedTypeName>)other.Value).Equals(this);
951                         }
952
953                         public override int GetHashCode()
954                         {
955                                 return scope.GetHashCode() * 7 + name.GetHashCode();
956                         }
957
958                         bool IEquatable<ScopedTypeName>.Equals(ScopedTypeName other)
959                         {
960                                 return other.scope == scope && other.name == name;
961                         }
962                 }
963
964                 internal Type GetMissingTypeOrThrow(Module module, Type declaringType, TypeName typeName)
965                 {
966                         if (resolveMissingMembers || module.Assembly.__IsMissing)
967                         {
968                                 if (missingTypes == null)
969                                 {
970                                         missingTypes = new Dictionary<ScopedTypeName, Type>();
971                                 }
972                                 ScopedTypeName stn = new ScopedTypeName(declaringType ?? (object)module, typeName);
973                                 Type type;
974                                 if (!missingTypes.TryGetValue(stn, out type))
975                                 {
976                                         type = new MissingType(module, declaringType, typeName.Namespace, typeName.Name);
977                                         missingTypes.Add(stn, type);
978                                 }
979                                 return type;
980                         }
981                         string fullName = TypeNameParser.Escape(typeName.ToString());
982                         if (declaringType != null)
983                         {
984                                 fullName = declaringType.FullName + "+" + fullName;
985                         }
986                         throw new TypeLoadException(String.Format("Type '{0}' not found in assembly '{1}'", fullName, module.Assembly.FullName));
987                 }
988
989                 internal MethodBase GetMissingMethodOrThrow(Type declaringType, string name, MethodSignature signature)
990                 {
991                         if (resolveMissingMembers)
992                         {
993                                 MethodInfo method = new MissingMethod(declaringType, name, signature);
994                                 if (name == ".ctor")
995                                 {
996                                         return new ConstructorInfoImpl(method);
997                                 }
998                                 return method;
999                         }
1000                         throw new MissingMethodException(declaringType.ToString(), name);
1001                 }
1002
1003                 internal FieldInfo GetMissingFieldOrThrow(Type declaringType, string name, FieldSignature signature)
1004                 {
1005                         if (resolveMissingMembers)
1006                         {
1007                                 return new MissingField(declaringType, name, signature);
1008                         }
1009                         throw new MissingFieldException(declaringType.ToString(), name);
1010                 }
1011
1012                 internal PropertyInfo GetMissingPropertyOrThrow(Type declaringType, string name, PropertySignature propertySignature)
1013                 {
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)
1017                         {
1018                                 return new MissingProperty(declaringType, name, propertySignature);
1019                         }
1020                         throw new System.MissingMemberException(declaringType.ToString(), name);
1021                 }
1022
1023                 internal Type CanonicalizeType(Type type)
1024                 {
1025                         Type canon;
1026                         if (!canonicalizedTypes.TryGetValue(type, out canon))
1027                         {
1028                                 canon = type;
1029                                 canonicalizedTypes.Add(canon, canon);
1030                         }
1031                         return canon;
1032                 }
1033
1034                 public Type MakeFunctionPointer(__StandAloneMethodSig sig)
1035                 {
1036                         return FunctionPointerType.Make(this, sig);
1037                 }
1038
1039                 public __StandAloneMethodSig MakeStandAloneMethodSig(System.Runtime.InteropServices.CallingConvention callingConvention, Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers)
1040                 {
1041                         return new __StandAloneMethodSig(true, callingConvention, 0, returnType ?? this.System_Void, Util.Copy(parameterTypes), Type.EmptyTypes,
1042                                 PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, Util.NullSafeLength(parameterTypes)));
1043                 }
1044
1045                 public __StandAloneMethodSig MakeStandAloneMethodSig(CallingConventions callingConvention, Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, Type[] optionalParameterTypes, CustomModifiers[] parameterTypeCustomModifiers)
1046                 {
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)));
1049                 }
1050
1051                 public event Predicate<Type> MissingTypeIsValueType
1052                 {
1053                         add
1054                         {
1055                                 if (missingTypeIsValueType != null)
1056                                 {
1057                                         throw new InvalidOperationException("Only a single MissingTypeIsValueType handler can be registered.");
1058                                 }
1059                                 missingTypeIsValueType = value;
1060                         }
1061                         remove
1062                         {
1063                                 if (value.Equals(missingTypeIsValueType))
1064                                 {
1065                                         missingTypeIsValueType = null;
1066                                 }
1067                         }
1068                 }
1069
1070                 internal bool ResolveMissingTypeIsValueType(MissingType missingType)
1071                 {
1072                         if (missingTypeIsValueType != null)
1073                         {
1074                                 return missingTypeIsValueType(missingType);
1075                         }
1076                         throw new MissingMemberException(missingType);
1077                 }
1078         }
1079 }