Merge branch 'sgen-disable-gc'
[mono.git] / mcs / class / corlib / System.Reflection.Emit / AssemblyBuilder.cs
1 //
2 // System.Reflection.Emit/AssemblyBuilder.cs
3 //
4 // Author:
5 //   Paolo Molaro (lupus@ximian.com)
6 //
7 // (C) 2001 Ximian, Inc.  http://www.ximian.com
8 //
9
10 //
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 using System;
34 using System.Reflection;
35 using System.Resources;
36 using System.IO;
37 using System.Security.Policy;
38 using System.Runtime.Serialization;
39 using System.Globalization;
40 using System.Runtime.CompilerServices;
41 using System.Collections;
42 using System.Collections.Generic;
43 using System.Runtime.InteropServices;
44 using System.Security;
45 using System.Security.Cryptography;
46 using System.Security.Permissions;
47
48 using Mono.Security;
49 using Mono.Security.Cryptography;
50
51 namespace System.Reflection.Emit
52 {
53         internal enum NativeResourceType
54         {
55                 None,
56                 Unmanaged,
57                 Assembly,
58                 Explicit
59         }
60
61         internal struct RefEmitPermissionSet {
62                 public SecurityAction action;
63                 public string pset;
64
65                 public RefEmitPermissionSet (SecurityAction action, string pset) {
66                         this.action = action;
67                         this.pset = pset;
68                 }
69         }
70
71         internal struct MonoResource {
72                 public byte[] data;
73                 public string name;
74                 public string filename;
75                 public ResourceAttributes attrs;
76                 public int offset;
77                 public Stream stream;
78         }
79
80         internal struct MonoWin32Resource {
81                 public int res_type;
82                 public int res_id;
83                 public int lang_id;
84                 public byte[] data;
85
86                 public MonoWin32Resource (int res_type, int res_id, int lang_id, byte[] data) {
87                         this.res_type = res_type;
88                         this.res_id = res_id;
89                         this.lang_id = lang_id;
90                         this.data = data;
91                 }
92         }
93
94         internal class GenericInstanceKey {
95                 Type gtd;
96                 internal Type[] args;
97                 int hash_code;
98
99                 internal GenericInstanceKey (Type gtd, Type[] args)
100                 {
101                         this.gtd = gtd;
102                         this.args = args;
103
104                         hash_code = gtd.GetHashCode ();
105                         for (int i = 0; i < args.Length; ++i)
106                                 hash_code ^= args [i].GetHashCode ();
107                 }
108
109                 static bool IsBoundedVector (Type type) {
110                         ArrayType at = type as ArrayType;
111                         if (at != null)
112                                 return at.GetEffectiveRank () == 1;
113                         return type.ToString ().EndsWith ("[*]", StringComparison.Ordinal); /*Super uggly hack, SR doesn't allow one to query for it */
114                 }
115
116                 static bool TypeEquals (Type a, Type b) {
117                         if (a == b)
118                                 return true;
119
120                         if (a.HasElementType) {
121                                 if (!b.HasElementType)
122                                         return false;
123                                 if (!TypeEquals (a.GetElementType (), b.GetElementType ()))
124                                         return false;
125                                 if (a.IsArray) {
126                                         if (!b.IsArray)
127                                                 return false;
128                                         int rank = a.GetArrayRank ();
129                                         if (rank != b.GetArrayRank ())
130                                                 return false;
131                                         if (rank == 1 && IsBoundedVector (a) != IsBoundedVector (b))
132                                                 return false;
133                                 } else if (a.IsByRef) {
134                                         if (!b.IsByRef)
135                                                 return false;
136                                 } else if (a.IsPointer) {
137                                         if (!b.IsPointer)
138                                                 return false;
139                                 }
140                                 return true;
141                         }
142
143                         if (a.IsGenericType) {
144                                 if (!b.IsGenericType)
145                                         return false;
146                                 if (a.IsGenericParameter)
147                                         return a == b;
148                                 if (a.IsGenericParameter) //previous test should have caught it
149                                         return false;
150
151                                 if (a.IsGenericTypeDefinition) {
152                                         if (!b.IsGenericTypeDefinition)
153                                                 return false;
154                                 } else {
155                                         if (b.IsGenericTypeDefinition)
156                                                 return false;
157                                         if (!TypeEquals (a.GetGenericTypeDefinition (), b.GetGenericTypeDefinition ()))
158                                                 return false;
159
160                                         Type[] argsA = a.GetGenericArguments ();
161                                         Type[] argsB = b.GetGenericArguments ();
162                                         for (int i = 0; i < argsA.Length; ++i) {
163                                                 if (!TypeEquals (argsA [i], argsB [i]))
164                                                         return false;
165                                         }
166                                 }
167                         }
168
169                         /*
170                         Now only non-generic, non compound types are left. To properly deal with user
171                         types we would have to call UnderlyingSystemType, but we let them have their
172                         own instantiation as this is MS behavior and mcs (pre C# 4.0, at least) doesn't
173                         depend on proper UT canonicalization.
174                         */
175                         return a == b;
176                 }
177
178                 public override bool Equals (object obj)
179                 {
180                         GenericInstanceKey other = obj as GenericInstanceKey;
181                         if (other == null)
182                                 return false;
183                         if (gtd != other.gtd)
184                                 return false;
185                         for (int i = 0; i < args.Length; ++i) {
186                                 Type a = args [i];
187                                 Type b = other.args [i];
188                                 /*
189                                 We must cannonicalize as much as we can. Using equals means that some resulting types
190                                 won't have the exact same types as the argument ones. 
191                                 For example, flyweight types used array, pointer and byref will should this behavior.
192                                 MCS seens to be resilient to this problem so hopefully this won't show up.   
193                                 */
194                                 if (a != b && !a.Equals (b))
195                                         return false;
196                         }
197                         return true;
198                 }
199
200                 public override int GetHashCode ()
201                 {
202                         return hash_code;
203                 }
204         }
205
206
207         [ComVisible (true)]
208         [ComDefaultInterface (typeof (_AssemblyBuilder))]
209         [ClassInterface (ClassInterfaceType.None)]
210         public sealed class AssemblyBuilder : Assembly, _AssemblyBuilder {
211 #pragma warning disable 169, 414
212                 #region Sync with object-internals.h
213                 private UIntPtr dynamic_assembly; /* GC-tracked */
214                 private MethodInfo entry_point;
215                 private ModuleBuilder[] modules;
216                 private string name;
217                 private string dir;
218                 private CustomAttributeBuilder[] cattrs;
219                 private MonoResource[] resources;
220                 byte[] public_key;
221                 string version;
222                 string culture;
223                 uint algid;
224                 uint flags;
225                 PEFileKinds pekind = PEFileKinds.Dll;
226                 bool delay_sign;
227                 uint access;
228                 Module[] loaded_modules;
229                 MonoWin32Resource[] win32_resources;
230                 private RefEmitPermissionSet[] permissions_minimum;
231                 private RefEmitPermissionSet[] permissions_optional;
232                 private RefEmitPermissionSet[] permissions_refused;
233                 PortableExecutableKinds peKind;
234                 ImageFileMachine machine;
235                 bool corlib_internal;
236                 Type[] type_forwarders;
237                 byte[] pktoken;
238                 #endregion
239 #pragma warning restore 169, 414
240                 
241                 internal Type corlib_object_type = typeof (System.Object);
242                 internal Type corlib_value_type = typeof (System.ValueType);
243                 internal Type corlib_enum_type = typeof (System.Enum);
244                 internal Type corlib_void_type = typeof (void);
245                 ArrayList resource_writers = null;
246                 Win32VersionResource version_res;
247                 bool created;
248                 bool is_module_only;
249                 private Mono.Security.StrongName sn;
250                 NativeResourceType native_resource;
251                 readonly bool is_compiler_context;
252                 string versioninfo_culture;
253                 Hashtable generic_instances = new Hashtable ();
254
255                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
256                 private static extern void basic_init (AssemblyBuilder ab);
257
258                 /* Keep this in sync with codegen.cs in mcs */
259                 private const AssemblyBuilderAccess COMPILER_ACCESS = (AssemblyBuilderAccess) 0x800;
260
261                 internal AssemblyBuilder (AssemblyName n, string directory, AssemblyBuilderAccess access, bool corlib_internal)
262                 {
263                         is_compiler_context = (access & COMPILER_ACCESS) != 0;
264
265                         // remove Mono specific flag to allow enum check to pass
266                         access &= ~COMPILER_ACCESS;
267
268 #if MOONLIGHT
269                         // only "Run" is supported by Silverlight
270                         // however SMCS requires more than this but runs outside the CoreCLR sandbox
271                         if (SecurityManager.SecurityEnabled && (access != AssemblyBuilderAccess.Run))
272                                 throw new ArgumentException ("access");
273 #endif
274
275                         if (!Enum.IsDefined (typeof (AssemblyBuilderAccess), access))
276                                 throw new ArgumentException (string.Format (CultureInfo.InvariantCulture,
277                                         "Argument value {0} is not valid.", (int) access),
278                                         "access");
279
280                         name = n.Name;
281                         this.access = (uint)access;
282                         flags = (uint) n.Flags;
283
284                         // don't call GetCurrentDirectory for Run-only builders (CAS may not like that)
285                         if (IsSave && (directory == null || directory.Length == 0)) {
286                                 dir = Directory.GetCurrentDirectory ();
287                         } else {
288                                 dir = directory;
289                         }
290
291                         /* Set defaults from n */
292                         if (n.CultureInfo != null) {
293                                 culture = n.CultureInfo.Name;
294                                 versioninfo_culture = n.CultureInfo.Name;
295                         }
296                         Version v = n.Version;
297                         if (v != null) {
298                                 version = v.ToString ();
299                         }
300
301                         if (n.KeyPair != null) {
302                                 // full keypair is available (for signing)
303                                 sn = n.KeyPair.StrongName ();
304                         } else {
305                                 // public key is available (for delay-signing)
306                                 byte[] pk = n.GetPublicKey ();
307                                 if ((pk != null) && (pk.Length > 0)) {
308                                         sn = new Mono.Security.StrongName (pk);
309                                 }
310                         }
311
312                         if (sn != null)
313                                 flags |= (uint) AssemblyNameFlags.PublicKey;
314
315                         this.corlib_internal = corlib_internal;
316                         if (sn != null) {
317                                 this.pktoken = new byte[sn.PublicKeyToken.Length * 2];
318                                 int pkti = 0;
319                                 foreach (byte pkb in sn.PublicKeyToken) {
320                                         string part = pkb.ToString("x2");
321                                         this.pktoken[pkti++] = (byte)part[0];
322                                         this.pktoken[pkti++] = (byte)part[1];
323                                 }
324                         }
325
326                         basic_init (this);
327                 }
328
329                 public override string CodeBase {
330                         get {
331                                 throw not_supported ();
332                         }
333                 }
334                 
335                 public override MethodInfo EntryPoint {
336                         get {
337                                 return entry_point;
338                         }
339                 }
340
341                 public override string Location {
342                         get {
343                                 throw not_supported ();
344                         }
345                 }
346
347                 /* This is to keep signature compatibility with MS.NET */
348                 public override string ImageRuntimeVersion {
349                         get {
350                                 return base.ImageRuntimeVersion;
351                         }
352                 }
353
354                 [MonoTODO]
355                 public override bool ReflectionOnly {
356                         get { return base.ReflectionOnly; }
357                 }
358
359                 public void AddResourceFile (string name, string fileName)
360                 {
361                         AddResourceFile (name, fileName, ResourceAttributes.Public);
362                 }
363
364                 public void AddResourceFile (string name, string fileName, ResourceAttributes attribute)
365                 {
366                         AddResourceFile (name, fileName, attribute, true);
367                 }
368
369                 private void AddResourceFile (string name, string fileName, ResourceAttributes attribute, bool fileNeedsToExists)
370                 {
371                         check_name_and_filename (name, fileName, fileNeedsToExists);
372
373                         // Resource files are created/searched under the assembly storage
374                         // directory
375                         if (dir != null)
376                                 fileName = Path.Combine (dir, fileName);
377
378                         if (resources != null) {
379                                 MonoResource[] new_r = new MonoResource [resources.Length + 1];
380                                 System.Array.Copy(resources, new_r, resources.Length);
381                                 resources = new_r;
382                         } else {
383                                 resources = new MonoResource [1];
384                         }
385                         int p = resources.Length - 1;
386                         resources [p].name = name;
387                         resources [p].filename = fileName;
388                         resources [p].attrs = attribute;
389                 }
390
391                 /// <summary>
392                 /// Don't change the method name and parameters order. It is used by mcs 
393                 /// </summary>
394                 internal void AddPermissionRequests (PermissionSet required, PermissionSet optional, PermissionSet refused)
395                 {
396 #if !NET_2_1
397                         if (created)
398                                 throw new InvalidOperationException ("Assembly was already saved.");
399
400                         // required for base Assembly class (so the permissions
401                         // can be used even if the assembly isn't saved to disk)
402                         _minimum = required;
403                         _optional = optional;
404                         _refuse = refused;
405
406                         // required to reuse AddDeclarativeSecurity support 
407                         // already present in the runtime
408                         if (required != null) {
409                                 permissions_minimum = new RefEmitPermissionSet [1];
410                                 permissions_minimum [0] = new RefEmitPermissionSet (
411                                         SecurityAction.RequestMinimum, required.ToXml ().ToString ());
412                         }
413                         if (optional != null) {
414                                 permissions_optional = new RefEmitPermissionSet [1];
415                                 permissions_optional [0] = new RefEmitPermissionSet (
416                                         SecurityAction.RequestOptional, optional.ToXml ().ToString ());
417                         }
418                         if (refused != null) {
419                                 permissions_refused = new RefEmitPermissionSet [1];
420                                 permissions_refused [0] = new RefEmitPermissionSet (
421                                         SecurityAction.RequestRefuse, refused.ToXml ().ToString ());
422                         }
423 #endif
424                 }
425
426                 // Still in use by al.exe
427                 internal void EmbedResourceFile (string name, string fileName)
428                 {
429                         EmbedResourceFile (name, fileName, ResourceAttributes.Public);
430                 }
431
432                 void EmbedResourceFile (string name, string fileName, ResourceAttributes attribute)
433                 {
434                         if (resources != null) {
435                                 MonoResource[] new_r = new MonoResource [resources.Length + 1];
436                                 System.Array.Copy(resources, new_r, resources.Length);
437                                 resources = new_r;
438                         } else {
439                                 resources = new MonoResource [1];
440                         }
441                         int p = resources.Length - 1;
442                         resources [p].name = name;
443                         resources [p].attrs = attribute;
444                         try {
445                                 FileStream s = new FileStream (fileName, FileMode.Open, FileAccess.Read);
446                                 long len = s.Length;
447                                 resources [p].data = new byte [len];
448                                 s.Read (resources [p].data, 0, (int)len);
449                                 s.Close ();
450                         } catch {
451                         }
452                 }
453 /*
454                 internal void EmbedResource (string name, byte[] blob, ResourceAttributes attribute)
455                 {
456                         if (resources != null) {
457                                 MonoResource[] new_r = new MonoResource [resources.Length + 1];
458                                 System.Array.Copy(resources, new_r, resources.Length);
459                                 resources = new_r;
460                         } else {
461                                 resources = new MonoResource [1];
462                         }
463                         int p = resources.Length - 1;
464                         resources [p].name = name;
465                         resources [p].attrs = attribute;
466                         resources [p].data = blob;
467                 }
468 */
469                 internal void AddTypeForwarder (Type t) {
470                         if (t == null)
471                                 throw new ArgumentNullException ("t");
472                         if (t.IsNested)
473                                 throw new ArgumentException ();
474
475                         if (type_forwarders == null) {
476                                 type_forwarders = new Type [1] { t };
477                         } else {
478                                 Type[] arr = new Type [type_forwarders.Length + 1];
479                                 Array.Copy (type_forwarders, arr, type_forwarders.Length);
480                                 arr [type_forwarders.Length] = t;
481                                 type_forwarders = arr;
482                         }
483                 }
484
485                 public ModuleBuilder DefineDynamicModule (string name)
486                 {
487                         return DefineDynamicModule (name, name, false, true);
488                 }
489
490                 public ModuleBuilder DefineDynamicModule (string name, bool emitSymbolInfo)
491                 {
492                         return DefineDynamicModule (name, name, emitSymbolInfo, true);
493                 }
494
495                 public ModuleBuilder DefineDynamicModule(string name, string fileName)
496                 {
497                         return DefineDynamicModule (name, fileName, false, false);
498                 }
499
500                 public ModuleBuilder DefineDynamicModule (string name, string fileName,
501                                                           bool emitSymbolInfo)
502                 {
503                         return DefineDynamicModule (name, fileName, emitSymbolInfo, false);
504                 }
505
506                 private ModuleBuilder DefineDynamicModule (string name, string fileName, bool emitSymbolInfo, bool transient)
507                 {
508                         check_name_and_filename (name, fileName, false);
509
510                         if (!transient) {
511                                 if (Path.GetExtension (fileName) == String.Empty)
512                                         throw new ArgumentException ("Module file name '" + fileName + "' must have file extension.");
513                                 if (!IsSave)
514                                         throw new NotSupportedException ("Persistable modules are not supported in a dynamic assembly created with AssemblyBuilderAccess.Run");
515                                 if (created)
516                                         throw new InvalidOperationException ("Assembly was already saved.");
517                         }
518
519                         ModuleBuilder r = new ModuleBuilder (this, name, fileName, emitSymbolInfo, transient);
520
521                         if ((modules != null) && is_module_only)
522                                 throw new InvalidOperationException ("A module-only assembly can only contain one module.");
523
524                         if (modules != null) {
525                                 ModuleBuilder[] new_modules = new ModuleBuilder [modules.Length + 1];
526                                 System.Array.Copy(modules, new_modules, modules.Length);
527                                 modules = new_modules;
528                         } else {
529                                 modules = new ModuleBuilder [1];
530                         }
531                         modules [modules.Length - 1] = r;
532                         return r;
533                 }
534
535                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
536                 private extern Module InternalAddModule (string fileName);
537
538                 /*
539                  * Mono extension to support /addmodule in mcs.
540                  */
541                 internal Module AddModule (string fileName)
542                 {
543                         if (fileName == null)
544                                 throw new ArgumentNullException (fileName);
545
546                         Module m = InternalAddModule (fileName);
547
548                         if (loaded_modules != null) {
549                                 Module[] new_modules = new Module [loaded_modules.Length + 1];
550                                 System.Array.Copy (loaded_modules, new_modules, loaded_modules.Length);
551                                 loaded_modules = new_modules;
552                         } else {
553                                 loaded_modules = new Module [1];
554                         }
555                         loaded_modules [loaded_modules.Length - 1] = m;
556
557                         return m;
558                 }
559
560                 public IResourceWriter DefineResource (string name, string description, string fileName)
561                 {
562                         return DefineResource (name, description, fileName, ResourceAttributes.Public);
563                 }
564
565                 public IResourceWriter DefineResource (string name, string description,
566                                                        string fileName, ResourceAttributes attribute)
567                 {
568                         IResourceWriter writer;
569
570                         // description seems to be ignored
571                         AddResourceFile (name, fileName, attribute, false);
572                         writer = new ResourceWriter (fileName);
573                         if (resource_writers == null)
574                                 resource_writers = new ArrayList ();
575                         resource_writers.Add (writer);
576                         return writer;
577                 }
578
579                 private void AddUnmanagedResource (Win32Resource res) {
580                         MemoryStream ms = new MemoryStream ();
581                         res.WriteTo (ms);
582
583                         if (win32_resources != null) {
584                                 MonoWin32Resource[] new_res = new MonoWin32Resource [win32_resources.Length + 1];
585                                 System.Array.Copy (win32_resources, new_res, win32_resources.Length);
586                                 win32_resources = new_res;
587                         }
588                         else
589                                 win32_resources = new MonoWin32Resource [1];
590
591                         win32_resources [win32_resources.Length - 1] = new MonoWin32Resource (res.Type.Id, res.Name.Id, res.Language, ms.ToArray ());
592                 }
593
594                 [MonoTODO ("Not currently implemenented")]
595                 public void DefineUnmanagedResource (byte[] resource)
596                 {
597                         if (resource == null)
598                                 throw new ArgumentNullException ("resource");
599                         if (native_resource != NativeResourceType.None)
600                                 throw new ArgumentException ("Native resource has already been defined.");
601
602                         // avoid definition of more than one unmanaged resource
603                         native_resource = NativeResourceType.Unmanaged;
604
605                         /*
606                          * The format of the argument byte array is not documented
607                          * so this method is impossible to implement.
608                          *
609                          * https://connect.microsoft.com/VisualStudio/feedback/details/95784/fatal-assemblybuilder-defineunmanagedresource-byte-and-modulebuilder-defineunmanagedresource-byte-bugs-renders-them-useless
610                          */
611
612                         throw new NotImplementedException ();
613                 }
614
615                 public void DefineUnmanagedResource (string resourceFileName)
616                 {
617                         if (resourceFileName == null)
618                                 throw new ArgumentNullException ("resourceFileName");
619                         if (resourceFileName.Length == 0)
620                                 throw new ArgumentException ("resourceFileName");
621                         if (!File.Exists (resourceFileName) || Directory.Exists (resourceFileName))
622                                 throw new FileNotFoundException ("File '" + resourceFileName + "' does not exists or is a directory.");
623                         if (native_resource != NativeResourceType.None)
624                                 throw new ArgumentException ("Native resource has already been defined.");
625
626                         // avoid definition of more than one unmanaged resource
627                         native_resource = NativeResourceType.Unmanaged;
628
629                         using (FileStream fs = new FileStream (resourceFileName, FileMode.Open, FileAccess.Read)) {
630                                 Win32ResFileReader reader = new Win32ResFileReader (fs);
631
632                                 foreach (Win32EncodedResource res in reader.ReadResources ()) {
633                                         if (res.Name.IsName || res.Type.IsName)
634                                                 throw new InvalidOperationException ("resource files with named resources or non-default resource types are not supported.");
635
636                                         AddUnmanagedResource (res);
637                                 }
638                         }
639                 }
640
641                 public void DefineVersionInfoResource ()
642                 {
643                         if (native_resource != NativeResourceType.None)
644                                 throw new ArgumentException ("Native resource has already been defined.");
645
646                         // avoid definition of more than one unmanaged resource
647                         native_resource = NativeResourceType.Assembly;
648
649                         version_res = new Win32VersionResource (1, 0, IsCompilerContext);
650                 }
651
652                 public void DefineVersionInfoResource (string product, string productVersion,
653                                                        string company, string copyright, string trademark)
654                 {
655                         if (native_resource != NativeResourceType.None)
656                                 throw new ArgumentException ("Native resource has already been defined.");
657
658                         // avoid definition of more than one unmanaged resource
659                         native_resource = NativeResourceType.Explicit;
660
661                         /*
662                          * We can only create the resource later, when the file name and
663                          * the binary version is known.
664                          */
665
666                         version_res = new Win32VersionResource (1, 0, false);
667                         version_res.ProductName = product != null ? product : " ";
668                         version_res.ProductVersion = productVersion != null ? productVersion : " ";
669                         version_res.CompanyName = company != null ? company : " ";
670                         version_res.LegalCopyright = copyright != null ? copyright : " ";
671                         version_res.LegalTrademarks = trademark != null ? trademark : " ";
672                 }
673
674                 /* 
675                  * Mono extension to support /win32icon in mcs
676                  */
677                 internal void DefineIconResource (string iconFileName)
678                 {
679                         if (iconFileName == null)
680                                 throw new ArgumentNullException ("iconFileName");
681                         if (iconFileName.Length == 0)
682                                 throw new ArgumentException ("iconFileName");
683                         if (!File.Exists (iconFileName) || Directory.Exists (iconFileName))
684                                 throw new FileNotFoundException ("File '" + iconFileName + "' does not exists or is a directory.");
685
686                         using (FileStream fs = new FileStream (iconFileName, FileMode.Open, FileAccess.Read)) {
687                                 Win32IconFileReader reader = new Win32IconFileReader (fs);
688                                 
689                                 ICONDIRENTRY[] entries = reader.ReadIcons ();
690
691                                 Win32IconResource[] icons = new Win32IconResource [entries.Length];
692                                 for (int i = 0; i < entries.Length; ++i) {
693                                         icons [i] = new Win32IconResource (i + 1, 0, entries [i]);
694                                         AddUnmanagedResource (icons [i]);
695                                 }
696
697                                 Win32GroupIconResource group = new Win32GroupIconResource (1, 0, icons);
698                                 AddUnmanagedResource (group);
699                         }
700                 }
701
702                 private void DefineVersionInfoResourceImpl (string fileName)
703                 {
704                         if (versioninfo_culture != null)
705                                 version_res.FileLanguage = new CultureInfo (versioninfo_culture).LCID;
706                         version_res.Version = version == null ? "0.0.0.0" : version;
707
708                         if (cattrs != null) {
709                                 switch (native_resource) {
710                                 case NativeResourceType.Assembly:
711                                         foreach (CustomAttributeBuilder cb in cattrs) {
712                                                 string attrname = cb.Ctor.ReflectedType.FullName;
713
714                                                 if (attrname == "System.Reflection.AssemblyProductAttribute")
715                                                         version_res.ProductName = cb.string_arg ();
716                                                 else if (attrname == "System.Reflection.AssemblyCompanyAttribute")
717                                                         version_res.CompanyName = cb.string_arg ();
718                                                 else if (attrname == "System.Reflection.AssemblyCopyrightAttribute")
719                                                         version_res.LegalCopyright = cb.string_arg ();
720                                                 else if (attrname == "System.Reflection.AssemblyTrademarkAttribute")
721                                                         version_res.LegalTrademarks = cb.string_arg ();
722                                                 else if (attrname == "System.Reflection.AssemblyCultureAttribute") {
723                                                         if (!IsCompilerContext)
724                                                                 version_res.FileLanguage = new CultureInfo (cb.string_arg ()).LCID;
725                                                 } else if (attrname == "System.Reflection.AssemblyFileVersionAttribute") {
726                                                         string fileversion = cb.string_arg ();
727                                                         if (!IsCompilerContext || fileversion != null && fileversion.Length != 0)
728                                                                 version_res.FileVersion = fileversion;
729                                                 } else if (attrname == "System.Reflection.AssemblyInformationalVersionAttribute")
730                                                         version_res.ProductVersion = cb.string_arg ();
731                                                 else if (attrname == "System.Reflection.AssemblyTitleAttribute")
732                                                         version_res.FileDescription = cb.string_arg ();
733                                                 else if (attrname == "System.Reflection.AssemblyDescriptionAttribute")
734                                                         version_res.Comments = cb.string_arg ();
735                                         }
736                                         break;
737                                 case NativeResourceType.Explicit:
738                                         foreach (CustomAttributeBuilder cb in cattrs) {
739                                                 string attrname = cb.Ctor.ReflectedType.FullName;
740
741                                                 if (attrname == "System.Reflection.AssemblyCultureAttribute") {
742                                                         if (!IsCompilerContext)
743                                                                 version_res.FileLanguage = new CultureInfo (cb.string_arg ()).LCID;
744                                                 } else if (attrname == "System.Reflection.AssemblyDescriptionAttribute")
745                                                         version_res.Comments = cb.string_arg ();
746                                         }
747                                         break;
748                                 }
749                         }
750
751                         version_res.OriginalFilename = fileName;
752
753                         if (IsCompilerContext) {
754                                 version_res.InternalName = fileName;
755                                 if (version_res.ProductVersion.Trim ().Length == 0)
756                                         version_res.ProductVersion = version_res.FileVersion;
757                         } else {
758                                 version_res.InternalName = Path.GetFileNameWithoutExtension (fileName);
759                         }
760
761                         AddUnmanagedResource (version_res);
762                 }
763
764                 public ModuleBuilder GetDynamicModule (string name)
765                 {
766                         if (name == null)
767                                 throw new ArgumentNullException ("name");
768                         if (name.Length == 0)
769                                 throw new ArgumentException ("Empty name is not legal.", "name");
770
771                         if (modules != null)
772                                 for (int i = 0; i < modules.Length; ++i)
773                                         if (modules [i].name == name)
774                                                 return modules [i];
775                         return null;
776                 }
777
778                 public override Type[] GetExportedTypes ()
779                 {
780                         throw not_supported ();
781                 }
782
783                 public override FileStream GetFile (string name)
784                 {
785                         throw not_supported ();
786                 }
787
788                 public override FileStream[] GetFiles(bool getResourceModules) {
789                         throw not_supported ();
790                 }
791
792                 internal override Module[] GetModulesInternal () {
793                         if (modules == null)
794                                 return new Module [0];
795                         else
796                                 return (Module[])modules.Clone ();
797                 }
798
799                 internal override Type[] GetTypes (bool exportedOnly) {
800                         Type[] res = null;
801                         if (modules != null) {
802                                 for (int i = 0; i < modules.Length; ++i) {
803                                         Type[] types = modules [i].GetTypes ();
804                                         if (res == null)
805                                                 res = types;
806                                         else {
807                                                 Type[] tmp = new Type [res.Length + types.Length];
808                                                 Array.Copy (res, 0, tmp, 0, res.Length);
809                                                 Array.Copy (types, 0, tmp, res.Length, types.Length);
810                                         }
811                                 }
812                         }
813                         if (loaded_modules != null) {
814                                 for (int i = 0; i < loaded_modules.Length; ++i) {
815                                         Type[] types = loaded_modules [i].GetTypes ();
816                                         if (res == null)
817                                                 res = types;
818                                         else {
819                                                 Type[] tmp = new Type [res.Length + types.Length];
820                                                 Array.Copy (res, 0, tmp, 0, res.Length);
821                                                 Array.Copy (types, 0, tmp, res.Length, types.Length);
822                                         }
823                                 }
824                         }
825
826                         if (res != null) {
827                                 List<Exception> exceptions = null;
828                                 foreach (var type in res) {
829                                         if (type is TypeBuilder) {
830                                                 if (exceptions == null)
831                                                         exceptions = new List <Exception> ();
832                                                 exceptions.Add (new TypeLoadException (string.Format ("Type '{0}' is not finished", type.FullName))); 
833                                         }
834                                 }
835                                 if (exceptions != null)
836                                         throw new ReflectionTypeLoadException (new Type [exceptions.Count], exceptions.ToArray ());
837                         }
838                         
839                         return res == null ? Type.EmptyTypes : res;
840                 }
841
842                 public override ManifestResourceInfo GetManifestResourceInfo(string resourceName) {
843                         throw not_supported ();
844                 }
845
846                 public override string[] GetManifestResourceNames() {
847                         throw not_supported ();
848                 }
849
850                 public override Stream GetManifestResourceStream(string name) {
851                         throw not_supported ();
852                 }
853                 public override Stream GetManifestResourceStream(Type type, string name) {
854                         throw not_supported ();
855                 }
856
857                 /*
858                  * This is set when the the AssemblyBuilder is created by (g)mcs
859                  * or vbnc.
860                  */
861                 internal bool IsCompilerContext
862                 {
863                         get { return is_compiler_context; }
864                 }
865
866                 internal bool IsSave {
867                         get {
868                                 return access != (uint)AssemblyBuilderAccess.Run;
869                         }
870                 }
871
872                 internal bool IsRun {
873                         get {
874                                 return access == (uint)AssemblyBuilderAccess.Run || access == (uint)AssemblyBuilderAccess.RunAndSave
875 #if NET_4_0
876                                          || access == (uint)AssemblyBuilderAccess.RunAndCollect
877 #endif
878                                 ;
879
880                         }
881                 }
882 /*
883                 internal bool IsCollectible {
884                         get {
885                                 return access == (uint)AssemblyBuilderAccess.RunAndCollect;
886                         }
887                 }
888 */
889                 internal string AssemblyDir {
890                         get {
891                                 return dir;
892                         }
893                 }
894
895                 /*
896                  * Mono extension. If this is set, the assembly can only contain one
897                  * module, access should be Save, and the saved image will not contain an
898                  * assembly manifest.
899                  */
900                 internal bool IsModuleOnly {
901                         get {
902                                 return is_module_only;
903                         }
904                         set {
905                                 is_module_only = value;
906                         }
907                 }
908
909                 ModuleBuilder manifest_module;
910
911                 //
912                 // MS.NET seems to return a ModuleBuilder when GetManifestModule () is called
913                 // on an assemblybuilder.
914                 //
915                 internal override Module GetManifestModule () {
916                         if (manifest_module == null)
917                                 manifest_module = DefineDynamicModule ("Default Dynamic Module");
918                         return manifest_module;
919                 }
920
921                 [MonoLimitation ("No support for PE32+ assemblies for AMD64 and IA64")]
922                 public 
923                 void Save (string assemblyFileName, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
924                 {
925                         this.peKind = portableExecutableKind;
926                         this.machine = imageFileMachine;
927
928                         if ((peKind & PortableExecutableKinds.PE32Plus) != 0 || (peKind & PortableExecutableKinds.Unmanaged32Bit) != 0)
929                                 throw new NotImplementedException (peKind.ToString ());
930                         if (machine == ImageFileMachine.IA64 || machine == ImageFileMachine.AMD64)
931                                 throw new NotImplementedException (machine.ToString ());
932
933                         if (resource_writers != null) {
934                                 foreach (IResourceWriter writer in resource_writers) {
935                                         writer.Generate ();
936                                         writer.Close ();
937                                 }
938                         }
939
940                         // Create a main module if not already created
941                         ModuleBuilder mainModule = null;
942                         if (modules != null) {
943                                 foreach (ModuleBuilder module in modules)
944                                         if (module.FullyQualifiedName == assemblyFileName)
945                                                 mainModule = module;
946                         }
947                         if (mainModule == null)
948                                 mainModule = DefineDynamicModule ("RefEmit_OnDiskManifestModule", assemblyFileName);
949
950                         if (!is_module_only)
951                                 mainModule.IsMain = true;
952
953                         /* 
954                          * Create a new entry point if the one specified
955                          * by the user is in another module.
956                          */
957                         if ((entry_point != null) && entry_point.DeclaringType.Module != mainModule) {
958                                 Type[] paramTypes;
959                                 if (entry_point.GetParameters ().Length == 1)
960                                         paramTypes = new Type [] { typeof (string) };
961                                 else
962                                         paramTypes = Type.EmptyTypes;
963
964                                 MethodBuilder mb = mainModule.DefineGlobalMethod ("__EntryPoint$", MethodAttributes.Static|MethodAttributes.PrivateScope, entry_point.ReturnType, paramTypes);
965                                 ILGenerator ilgen = mb.GetILGenerator ();
966                                 if (paramTypes.Length == 1)
967                                         ilgen.Emit (OpCodes.Ldarg_0);
968                                 ilgen.Emit (OpCodes.Tailcall);
969                                 ilgen.Emit (OpCodes.Call, entry_point);
970                                 ilgen.Emit (OpCodes.Ret);
971
972                                 entry_point = mb;
973                         }
974
975                         if (version_res != null)
976                                 DefineVersionInfoResourceImpl (assemblyFileName);
977
978                         if (sn != null) {
979                                 // runtime needs to value to embed it into the assembly
980                                 public_key = sn.PublicKey;
981                         }
982
983                         foreach (ModuleBuilder module in modules)
984                                 if (module != mainModule)
985                                         module.Save ();
986
987                         // Write out the main module at the end, because it needs to
988                         // contain the hash of the other modules
989                         mainModule.Save ();
990
991                         if ((sn != null) && (sn.CanSign)) {
992                                 sn.Sign (System.IO.Path.Combine (this.AssemblyDir, assemblyFileName));
993                         }
994
995                         created = true;
996                 }
997
998                 public void Save (string assemblyFileName)
999                 {
1000                         Save (assemblyFileName, PortableExecutableKinds.ILOnly, ImageFileMachine.I386);
1001                 }
1002
1003                 public void SetEntryPoint (MethodInfo entryMethod)
1004                 {
1005                         SetEntryPoint (entryMethod, PEFileKinds.ConsoleApplication);
1006                 }
1007
1008                 public void SetEntryPoint (MethodInfo entryMethod, PEFileKinds fileKind)
1009                 {
1010                         if (entryMethod == null)
1011                                 throw new ArgumentNullException ("entryMethod");
1012                         if (entryMethod.DeclaringType.Assembly != this)
1013                                 throw new InvalidOperationException ("Entry method is not defined in the same assembly.");
1014
1015                         entry_point = entryMethod;
1016                         pekind = fileKind;
1017                 }
1018
1019                 public void SetCustomAttribute( CustomAttributeBuilder customBuilder) 
1020                 {
1021                         if (customBuilder == null)
1022                                 throw new ArgumentNullException ("customBuilder");
1023
1024                         if (IsCompilerContext) {
1025                                 string attrname = customBuilder.Ctor.ReflectedType.FullName;
1026                                 byte [] data;
1027                                 int pos;
1028
1029                                 if (attrname == "System.Reflection.AssemblyVersionAttribute") {
1030                                         version = create_assembly_version (customBuilder.string_arg ());
1031                                         return;
1032                                 } else if (attrname == "System.Reflection.AssemblyCultureAttribute") {
1033                                         culture = GetCultureString (customBuilder.string_arg ());
1034                                 } else if (attrname == "System.Reflection.AssemblyAlgorithmIdAttribute") {
1035                                         data = customBuilder.Data;
1036                                         pos = 2;
1037                                         algid = (uint) data [pos];
1038                                         algid |= ((uint) data [pos + 1]) << 8;
1039                                         algid |= ((uint) data [pos + 2]) << 16;
1040                                         algid |= ((uint) data [pos + 3]) << 24;
1041                                 } else if (attrname == "System.Reflection.AssemblyFlagsAttribute") {
1042                                         data = customBuilder.Data;
1043                                         pos = 2;
1044                                         flags |= (uint) data [pos];
1045                                         flags |= ((uint) data [pos + 1]) << 8;
1046                                         flags |= ((uint) data [pos + 2]) << 16;
1047                                         flags |= ((uint) data [pos + 3]) << 24;
1048
1049                                         // ignore PublicKey flag if assembly is not strongnamed
1050                                         if (sn == null)
1051                                                 flags &= ~(uint) AssemblyNameFlags.PublicKey;
1052                                 }
1053                         }
1054
1055                         if (cattrs != null) {
1056                                 CustomAttributeBuilder[] new_array = new CustomAttributeBuilder [cattrs.Length + 1];
1057                                 cattrs.CopyTo (new_array, 0);
1058                                 new_array [cattrs.Length] = customBuilder;
1059                                 cattrs = new_array;
1060                         } else {
1061                                 cattrs = new CustomAttributeBuilder [1];
1062                                 cattrs [0] = customBuilder;
1063                         }
1064                 }
1065
1066                 [ComVisible (true)]
1067                 public void SetCustomAttribute ( ConstructorInfo con, byte[] binaryAttribute) {
1068                         if (con == null)
1069                                 throw new ArgumentNullException ("con");
1070                         if (binaryAttribute == null)
1071                                 throw new ArgumentNullException ("binaryAttribute");
1072
1073                         SetCustomAttribute (new CustomAttributeBuilder (con, binaryAttribute));
1074                 }
1075
1076                 internal void SetCorlibTypeBuilders (Type corlib_object_type, Type corlib_value_type, Type corlib_enum_type) {
1077                         this.corlib_object_type = corlib_object_type;
1078                         this.corlib_value_type = corlib_value_type;
1079                         this.corlib_enum_type = corlib_enum_type;
1080                 }
1081
1082                 internal void SetCorlibTypeBuilders (Type corlib_object_type, Type corlib_value_type, Type corlib_enum_type, Type corlib_void_type)
1083                 {
1084                         SetCorlibTypeBuilders (corlib_object_type, corlib_value_type, corlib_enum_type);
1085                         this.corlib_void_type = corlib_void_type;
1086                 }
1087
1088                 private Exception not_supported () {
1089                         // Strange message but this is what MS.NET prints...
1090                         return new NotSupportedException ("The invoked member is not supported in a dynamic module.");
1091                 }
1092
1093                 private void check_name_and_filename (string name, string fileName,
1094                                                                                           bool fileNeedsToExists) {
1095                         if (name == null)
1096                                 throw new ArgumentNullException ("name");
1097                         if (fileName == null)
1098                                 throw new ArgumentNullException ("fileName");
1099                         if (name.Length == 0)
1100                                 throw new ArgumentException ("Empty name is not legal.", "name");
1101                         if (fileName.Length == 0)
1102                                 throw new ArgumentException ("Empty file name is not legal.", "fileName");
1103                         if (Path.GetFileName (fileName) != fileName)
1104                                 throw new ArgumentException ("fileName '" + fileName + "' must not include a path.", "fileName");
1105
1106                         // Resource files are created/searched under the assembly storage
1107                         // directory
1108                         string fullFileName = fileName;
1109                         if (dir != null)
1110                                 fullFileName = Path.Combine (dir, fileName);
1111
1112                         if (fileNeedsToExists && !File.Exists (fullFileName))
1113                                 throw new FileNotFoundException ("Could not find file '" + fileName + "'");
1114
1115                         if (resources != null) {
1116                                 for (int i = 0; i < resources.Length; ++i) {
1117                                         if (resources [i].filename == fullFileName)
1118                                                 throw new ArgumentException ("Duplicate file name '" + fileName + "'");
1119                                         if (resources [i].name == name)
1120                                                 throw new ArgumentException ("Duplicate name '" + name + "'");
1121                                 }
1122                         }
1123
1124                         if (modules != null) {
1125                                 for (int i = 0; i < modules.Length; ++i) {
1126                                         // Use fileName instead of fullFileName here
1127                                         if (!modules [i].IsTransient () && (modules [i].FileName == fileName))
1128                                                 throw new ArgumentException ("Duplicate file name '" + fileName + "'");
1129                                         if (modules [i].Name == name)
1130                                                 throw new ArgumentException ("Duplicate name '" + name + "'");
1131                                 }
1132                         }
1133                 }
1134
1135                 private String create_assembly_version (String version) {
1136                         String[] parts = version.Split ('.');
1137                         int[] ver = new int [4] { 0, 0, 0, 0 };
1138
1139                         if ((parts.Length < 0) || (parts.Length > 4))
1140                                 throw new ArgumentException ("The version specified '" + version + "' is invalid");
1141
1142                         for (int i = 0; i < parts.Length; ++i) {
1143                                 if (parts [i] == "*") {
1144                                         DateTime now = DateTime.Now;
1145
1146                                         if (i == 2) {
1147                                                 ver [2] = (now - new DateTime (2000, 1, 1)).Days;
1148                                                 if (parts.Length == 3)
1149                                                         ver [3] = (now.Second + (now.Minute * 60) + (now.Hour * 3600)) / 2;
1150                                         }
1151                                         else
1152                                                 if (i == 3)
1153                                                         ver [3] = (now.Second + (now.Minute * 60) + (now.Hour * 3600)) / 2;
1154                                         else
1155                                                 throw new ArgumentException ("The version specified '" + version + "' is invalid");
1156                                 }
1157                                 else {
1158                                         try {
1159                                                 ver [i] = Int32.Parse (parts [i]);
1160                                         }
1161                                         catch (FormatException) {
1162                                                 throw new ArgumentException ("The version specified '" + version + "' is invalid");
1163                                         }
1164                                 }
1165                         }
1166
1167                         return ver [0] + "." + ver [1] + "." + ver [2] + "." + ver [3];
1168                 }
1169
1170                 private string GetCultureString (string str)
1171                 {
1172                         return (str == "neutral" ? String.Empty : str);
1173                 }
1174
1175                 internal override AssemblyName UnprotectedGetName ()
1176                 {
1177                         AssemblyName an = base.UnprotectedGetName ();
1178                         if (sn != null) {
1179                                 an.SetPublicKey (sn.PublicKey);
1180                                 an.SetPublicKeyToken (sn.PublicKeyToken);
1181                         }
1182                         return an;
1183                 }
1184
1185                 /*Warning, @typeArguments must be a mscorlib internal array. So make a copy before passing it in*/
1186                 internal Type MakeGenericType (Type gtd, Type[] typeArguments)
1187                 {
1188                         if (!IsCompilerContext)
1189                                 return new MonoGenericClass (gtd, typeArguments);
1190
1191                         GenericInstanceKey key = new GenericInstanceKey (gtd, typeArguments);
1192                         MonoGenericClass res = (MonoGenericClass)generic_instances [key];
1193                         if (res == null) {
1194                                 res = new MonoGenericClass (gtd, typeArguments);
1195                                 generic_instances [key] = res;
1196                         }
1197                         return res;
1198                 }
1199
1200                 void _AssemblyBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
1201                 {
1202                         throw new NotImplementedException ();
1203                 }
1204
1205                 void _AssemblyBuilder.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
1206                 {
1207                         throw new NotImplementedException ();
1208                 }
1209
1210                 void _AssemblyBuilder.GetTypeInfoCount (out uint pcTInfo)
1211                 {
1212                         throw new NotImplementedException ();
1213                 }
1214
1215                 void _AssemblyBuilder.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
1216                 {
1217                         throw new NotImplementedException ();
1218                 }
1219
1220 #if NET_4_0 || MOONLIGHT || MOBILE
1221                 public override Type GetType (string name, bool throwOnError, bool ignoreCase)
1222                 {
1223                         if (name == null)
1224                                 throw new ArgumentNullException (name);
1225                         if (name.Length == 0)
1226                         throw new ArgumentException ("name", "Name cannot be empty");
1227
1228                         var res = InternalGetType (null, name, throwOnError, ignoreCase);
1229                         if (res is TypeBuilder) {
1230                                 if (throwOnError)
1231                                         throw new TypeLoadException (string.Format ("Could not load type '{0}' from assembly '{1}'", name, this.name));
1232                                 return null;
1233                         }
1234                         return res;
1235                 }
1236
1237                 public override Module GetModule (String name)
1238                 {
1239                         if (name == null)
1240                                 throw new ArgumentNullException ("name");
1241                         if (name.Length == 0)
1242                                 throw new ArgumentException ("Name can't be empty");
1243
1244                         if (modules == null)
1245                                 return null;
1246
1247                         foreach (Module module in modules) {
1248                                 if (module.ScopeName == name)
1249                                         return module;
1250                         }
1251
1252                         return null;
1253                 }
1254
1255                 public override Module[] GetModules (bool getResourceModules)
1256                 {
1257                         Module[] modules = GetModulesInternal ();
1258
1259                         if (!getResourceModules) {
1260                                 var result = new List<Module> (modules.Length);
1261                                 foreach (Module m in modules)
1262                                         if (!m.IsResource ())
1263                                                 result.Add (m);
1264                                 return result.ToArray ();
1265                         }
1266                         return modules;
1267                 }
1268
1269                 [MonoTODO ("This always returns an empty array")]
1270                 public override AssemblyName[] GetReferencedAssemblies () {
1271                         return GetReferencedAssemblies (this);
1272                 }
1273
1274                 public override Module[] GetLoadedModules (bool getResourceModules)
1275                 {
1276                         return GetModules (getResourceModules);
1277                 }
1278
1279                 //FIXME MS has issues loading satelite assemblies from SRE
1280                 public override Assembly GetSatelliteAssembly (CultureInfo culture)
1281                 {
1282                         return GetSatelliteAssembly (culture, null, true);
1283                 }
1284
1285                 //FIXME MS has issues loading satelite assemblies from SRE
1286                 public override Assembly GetSatelliteAssembly (CultureInfo culture, Version version)
1287                 {
1288                         return GetSatelliteAssembly (culture, version, true);
1289                 }
1290
1291                 public override Module ManifestModule {
1292                         get {
1293                                 return GetManifestModule ();
1294                         }
1295                 }
1296
1297                 public override bool GlobalAssemblyCache {
1298                         get {
1299                                 return false;
1300                         }
1301                 }
1302
1303                 public override bool IsDynamic {
1304                         get { return true; }
1305                 }
1306 #endif
1307         }
1308 }