[PEAPI] Don't add mscorlib reference when no type needs it
[mono.git] / mcs / class / PEAPI / Metadata.cs
1 using System;
2 using System.IO;
3 using System.Collections;
4 using System.Text;
5 using System.Reflection;
6
7 namespace PEAPI {
8
9         #region Enums
10
11         /// <summary>
12         /// flags for the assembly (.corflags)
13         /// </summary>
14         public enum CorFlags {CF_IL_ONLY = 1, CF_32_BITREQUIRED = 2,
15                 CF_STRONGNAMESIGNED = 8, CF_TRACKDEBUGDATA = 0x10000 }
16
17         /// <summary>
18         /// subsystem for the assembly (.subsystem)
19         /// </summary>
20         public enum SubSystem { Native = 1, Windows_GUI = 2, 
21                 Windows_CUI = 3, OS2_CUI = 5, POSIX_CUI = 7, Native_Windows = 8, 
22                 Windows_CE_GUI = 9}
23
24         /// <summary>
25         /// Hash algorithms for the assembly
26         /// </summary>
27         public enum HashAlgorithm { None, SHA1 }
28
29         /// <summary>
30         /// Attributes for this assembly
31         /// </summary>
32         public enum AssemAttr { Retargetable = 0x100, EnableJITCompileTracking = 0x8000, 
33                 DisableJITCompileOptimizer = 0x4000}
34
35         /// <summary>
36         /// Method call conventions
37         /// </summary>
38         [Flags]
39         public enum CallConv { Default, Cdecl, Stdcall, Thiscall, 
40                 Fastcall, Vararg, Instance = 0x20, Generic = 0x10, InstanceExplicit = 0x60 }
41
42         /// <summary>
43         /// Type custom modifier
44         /// </summary>
45         public enum CustomModifier { modreq = 0x1F, modopt };
46
47         /// <summary>
48         /// Attibutes for a class
49         /// </summary>
50         [Flags]
51         public enum TypeAttr {Private, Public, NestedPublic, NestedPrivate, 
52                 NestedFamily, NestedAssembly, NestedFamAndAssem, NestedFamOrAssem, 
53                 SequentialLayout, ExplicitLayout = 0x10, Interface = 0x20, 
54                 Abstract = 0x80, PublicAbstract = 0x81, Sealed = 0x100, 
55                 PublicSealed = 0x101, SpecialName = 0x400, RTSpecialName = 0x800, 
56                 Import = 0x1000, Serializable = 0x2000, UnicodeClass = 0x10000,
57                 AutoClass = 0x20000, HasSecurity = 0x40000, BeforeFieldInit = 0x100000,
58                 Forwarder = 0x200000,
59                 VisibilityMask = 0x07 }
60
61         /// <summary>
62         /// Attributes for a field
63         /// </summary>
64         public enum FieldAttr {Default, Private, FamAndAssem, Assembly, 
65                 Family, FamOrAssem, Public, Static = 0x10, PublicStatic = 0x16, 
66                 Initonly = 0x20, Literal = 0x40, Notserialized = 0x80, 
67                 SpecialName = 0x200, RTSpecialName = 0x400, HasFieldMarshal = 0x1000 }
68
69         /// <summary>
70         /// Attributes for a method
71         /// </summary>
72         public enum MethAttr { Default, Private, FamAndAssem, Assembly,
73                 Family, FamOrAssem, Public, Static = 0x0010, PublicStatic = 0x16, 
74                 Final = 0x0020, PublicStaticFinal = 0x36, Virtual = 0x0040, 
75                 PrivateVirtual, PublicVirtual = 0x0046, HideBySig = 0x0080, 
76                 NewSlot = 0x0100, Strict = 0x200, Abstract = 0x0400, SpecialName = 0x0800,
77                 RTSpecialName = 0x1000, SpecialRTSpecialName = 0x1800, 
78                 HasSecurity = 0x4000, RequireSecObject = 0x8000}
79
80         /// <summary>
81         /// Attributes for .pinvokeimpl method declarations
82         /// </summary>
83         public enum PInvokeAttr { nomangle = 1, ansi = 2, unicode = 4, autochar = 6,
84                 bestfit_on = 0x0010, bestfit_off = 0x0020, bestfit_mask = 0x0030,
85                 lasterr = 0x0040, winapi = 0x0100, cdecl = 0x0200,
86                 stdcall = 0x0300, thiscall = 0x0400, fastcall = 0x0500,
87                 charmaperror_on = 0x1000, charmaperror_off = 0x2000
88         }
89
90         /// <summary>
91         /// Implementation attributes for a method
92         /// </summary>
93         public enum ImplAttr { IL, Native, Runtime = 0x03, Unmanaged = 0x04,
94                 ForwardRef = 0x10, PreserveSig = 0x0080, InternalCall = 0x1000, 
95                 Synchronised = 0x0020, Synchronized = 0x0020, NoInLining = 0x0008, NoOptimization = 0x0040, Optil = 0x0002,
96                 AggressiveInlining = 0x0100
97         }
98
99         /// <summary>
100         /// Storage location for initial field data
101         /// </summary>
102         public enum DataSegment { Data, TLS, CIL }
103
104         /// <summary>
105         /// Modes for a parameter
106         /// </summary>
107         public enum ParamAttr { Default, In, Out, Opt = 16, HasDefault = 0x1000, HasFieldMarshal = 0x2000 }
108
109         /// <summary>
110         /// CIL instructions
111         /// </summary>
112         public enum Op { nop, breakOp, ldarg_0, ldarg_1, ldarg_2, ldarg_3,
113                 ldloc_0, ldloc_1, ldloc_2, ldloc_3, stloc_0, stloc_1, stloc_2, stloc_3, 
114                 ldnull = 0x14, ldc_i4_m1, ldc_i4_0, ldc_i4_1, ldc_i4_2, ldc_i4_3, 
115                 ldc_i4_4, ldc_i4_5, ldc_i4_6, ldc_i4_7, ldc_i4_8, dup = 0x25, pop, 
116                 ret = 0x2A, ldind_i1 = 0x46, ldind_u1, ldind_i2, ldind_u2, ldind_i4, 
117                 ldind_u4, ldind_i8, ldind_i,  ldind_r4, ldind_r8, ldind_ref, stind_ref, 
118                 stind_i1, stind_i2, stind_i4, stind_i8, stind_r4, stind_r8, add, sub, mul,
119                 div, div_un, rem, rem_un, and, or, xor, shl, shr, shr_un, neg, not, 
120                 conv_i1, conv_i2, conv_i4, conv_i8, conv_r4, conv_r8, conv_u4, conv_u8, 
121                 conv_r_un = 0x76, throwOp = 0x7A, conv_ovf_i1_un = 0x82, conv_ovf_i2_un,
122                 conv_ovf_i4_un, conv_ovf_i8_un, conf_ovf_u1_un, conv_ovf_u2_un, 
123                 conv_ovf_u4_un, conv_ovf_u8_un, conv_ovf_i_un, conv_ovf_u_un, 
124                 ldlen = 0x8E, ldelem_i1 = 0x90, ldelem_u1, ldelem_i2, ldelem_u2, 
125                 ldelem_i4, ldelem_u4, ldelem_i8, ldelem_i, ldelem_r4, ldelem_r8, 
126                 ldelem_ref, stelem_i, stelem_i1, stelem_i2, stelem_i4, stelem_i8, stelem_r4 = 0xA0, stelem_r8,
127                 stelem_ref, conv_ovf_i1 = 0xb3, conv_ovf_u1, conv_ovf_i2, conv_ovf_u2, 
128                 conv_ovf_i4, conv_ovf_u4, conv_ovf_i8, conv_ovf_u8, ckfinite = 0xC3, 
129                 conv_u2 = 0xD1, conv_u1, conv_i, conv_ovf_i, conv_ovf_u, add_ovf, 
130                 add_ovf_un, mul_ovf, mul_ovf_un, sub_ovf, sub_ovf_un, endfinally, 
131                 stind_i = 0xDF, conv_u, arglist = 0xFE00, ceq, cgt, cgt_un, clt, clt_un, 
132                 localloc = 0xFE0F, endfilter = 0xFE11, volatile_ = 0xFE13, tail_, 
133                 cpblk = 0xFE17, initblk, rethrow = 0xFE1A, refanytype = 0xFE1D, readonly_ = 0xFE1E }
134
135         /// <summary>
136         /// CIL instructions requiring an integer parameter
137         /// </summary>
138         public enum IntOp {ldarg_s = 0x0E, ldarga_s, starg_s, ldloc_s, ldloca_s, 
139                 stloc_s, ldc_i4_s = 0x1F, ldc_i4, ldarg = 0xFE09,
140                 ldarga, starg, ldloc, ldloca, stloc, unaligned = 0xFE12 }
141
142         /// <summary>
143         /// CIL instructions requiring a field parameter
144         /// </summary>
145         public enum FieldOp {ldfld = 0x7B, ldflda, stfld, ldsfld, ldsflda,
146                 stsfld, ldtoken = 0xD0 }
147
148         /// <summary>
149         /// CIL instructions requiring a method parameter
150         /// </summary>
151         public enum MethodOp {jmp = 0x27, call, callvirt = 0x6F, newobj = 0x73, 
152                 ldtoken = 0xD0, ldftn = 0xFE06, ldvirtfn }
153
154         /// <summary>
155         /// CIL instructions requiring a type parameter
156         /// </summary>
157         public enum TypeOp {cpobj = 0x70, ldobj, castclass = 0x74, isinst, 
158                 unbox = 0x79, stobj = 0x81, box = 0x8C, newarr, 
159                 ldelema = 0x8F, refanyval = 0xC2, mkrefany = 0xC6, 
160                 ldtoken = 0xD0, initobj = 0xFE15, constrained = 0xFE16, 
161                 sizeOf = 0xFE1C, ldelem = 0xA3, stelem = 0xA4, unbox_any }
162
163         /// <summary>
164         /// CIL branch instructions
165         /// </summary>
166         public enum BranchOp {
167                 // short branches
168                 br_s = 0x2B, brfalse_s, brtrue_s, beq_s, bge_s, bgt_s,
169                 ble_s, blt_s, bne_un_s, bge_un_s, bgt_un_s, ble_un_s, blt_un_s,
170                 // long branches
171                 br = 0x38, brfalse, brtrue, beq, bge, bgt, ble, blt,
172                 bne_un, bge_un, bgt_un, ble_un, blt_un,
173
174                 leave = 0xDD, leave_s }
175
176         /// <summary>
177         /// Index for all the tables in the meta data
178         /// </summary>
179         public enum MDTable { Module, TypeRef, TypeDef, Field = 0x04, Method = 0x06,
180                 Param = 0x08, InterfaceImpl, MemberRef, Constant, CustomAttribute, 
181                 FieldMarshal, DeclSecurity, ClassLayout, FieldLayout, StandAloneSig, 
182                 EventMap, Event = 0x14, PropertyMap, Property = 0x17, MethodSemantics, 
183                 MethodImpl, ModuleRef, TypeSpec, ImplMap, FieldRVA, Assembly = 0x20, 
184                 AssemblyProcessor, AssemblyOS, AssemblyRef, AssemblyRefProcessor, 
185                 AssemblyRefOS, File, ExportedType, ManifestResource, NestedClass,
186                 GenericParam, MethodSpec, GenericParamConstraint  }
187
188         public enum SafeArrayType { int16 = 2, int32, float32, float64,
189                 currency, date, bstr, dispatch, error, boolean, variant, unknown,
190                 Decimal, int8 = 16, uint8, uint16, uint32, Int = 22, UInt }
191
192         internal enum CIx { TypeDefOrRef, HasConst, HasCustomAttr, HasFieldMarshal,
193                 HasDeclSecurity, MemberRefParent, HasSemantics, MethodDefOrRef, 
194                 MemberForwarded, Implementation, CustomAttributeType, ResolutionScope,
195                 TypeOrMethodDef, MaxCIx }
196
197         internal enum MapType { eventMap, propertyMap, nestedClass }
198
199         public enum ValueClass { ValueType, Enum }
200
201         public enum GenParamType : byte { 
202                 Var = 0x13, MVar = 0x1E 
203         }
204
205         [Flags]
206         public enum GenericParamAttributes : ushort {
207                 VarianceMask  = 0x0003,
208                 NonVariant    = 0x0000,
209                 Covariant     = 0x0001,
210                 Contravariant = 0x0002,
211
212                 SpecialConstraintMask = 0x001c,
213                 ReferenceTypeConstraint = 0x0004,
214                 NotNullableValueTypeConstraint = 0x0008,
215                 DefaultConstructorConstrait = 0x0010
216         }
217
218         /* Taken from Mono.Cecil */
219         public enum SecurityAction : short {
220                 Request = 1,
221                 Demand = 2,
222                 Assert = 3,
223                 Deny = 4,
224                 PermitOnly = 5,
225                 LinkDemand = 6,
226                 InheritDemand = 7,
227                 RequestMinimum = 8,
228                 RequestOptional = 9,
229                 RequestRefuse = 10,
230                 PreJitGrant = 11,
231                 PreJitDeny = 12,
232                 NonCasDemand = 13,
233                 NonCasLinkDemand = 14,
234                 NonCasInheritance = 15,
235                 LinkDemandChoice = 16,
236                 InheritDemandChoice = 17,
237                 DemandChoice = 18
238         }
239
240         #endregion
241
242         /**************************************************************************/  
243         /// <summary>
244         /// Base class for all Meta Data table elements
245         /// </summary>
246
247         public abstract class MetaDataElement: IComparable {
248                 protected ArrayList customAttributes;
249                 private uint row = 0;
250                 protected bool done = false;
251                 protected MDTable tabIx;
252                 protected bool sortTable = false;
253                 //Temporary hack.. 
254                 private bool has_custom_attrs = false;
255
256                 internal MetaDataElement() { }
257
258                 public uint Row {
259                         get {
260                                 return row;
261                         }
262                         set {
263                                 row = value;
264                         }
265                 }
266
267                 public bool HasCustomAttr {
268                         get { return has_custom_attrs; }
269                         set { has_custom_attrs = value; }
270                 }
271
272                 internal virtual uint GetCodedIx(CIx code) { return 0; }
273
274                 /// <summary>
275                 /// Add a custom attribute to this item
276                 /// </summary>
277                 /// <param name="ctorMeth">the constructor method for this attribute</param>
278                 /// <param name="val">the byte value of the parameters</param>
279                 public void AddCustomAttribute(Method ctorMeth, byte[] val) 
280                 {
281                         if (customAttributes == null) {
282                                 customAttributes = new ArrayList();
283                         } 
284                         customAttributes.Add(new CustomAttribute(this,ctorMeth,val));
285                 }
286
287                 /// <summary>
288                 /// Add a custom attribute to this item
289                 /// </summary>
290                 /// <param name="ctorMeth">the constructor method for this attribute</param>
291                 /// <param name="val">the constant values of the parameters</param>
292                 public void AddCustomAttribute(Method ctorMeth, Constant[] cVals) 
293                 {
294                         if (customAttributes == null) {
295                                 customAttributes = new ArrayList();
296                         } 
297                         //      customAttributes.Add(new CustomAttribute(this,ctorMeth,cVals));
298                 }
299
300                 internal uint Token() 
301                 {
302                         return (((uint)tabIx << 24) | row);
303                 }
304
305                 internal virtual void BuildTables(MetaData md) 
306                 {
307                         done = true;
308                 }
309
310                 internal virtual uint Size(MetaData md) 
311                 {
312                         return 0;
313                 }
314
315                 internal virtual void Write(FileImage output) {   }
316
317                 internal virtual uint SortKey() 
318                 { 
319                         throw new PEFileException("Trying to sort table of " + this);
320                         //return 0; 
321                 }
322
323                 internal virtual uint SortKey2()
324                 {
325                         return 0;
326                 }
327
328                 public int CompareTo(object obj) 
329                 {
330                         uint otherKey = ((MetaDataElement)obj).SortKey();
331                         uint thisKey = SortKey();
332
333                         if (thisKey == otherKey)  {
334
335                                 otherKey = ((MetaDataElement)obj).SortKey2();
336                                 thisKey = SortKey2();
337                                 if (thisKey == otherKey)
338                                         return 0;
339                                 if (thisKey < otherKey)
340                                         return -1;
341                                 return 1;
342                         }
343                         if (thisKey < otherKey) return -1;
344
345                         return 1;
346                 }
347
348         }
349
350         /**************************************************************************/  
351         /// <summary>
352         /// Layout information for a class (.class [sequential | explicit])
353         /// </summary>
354         internal class ClassLayout : MetaDataElement {
355
356                 ClassDef parent;
357                 ushort packSize = 0;
358                 uint classSize = 0;
359
360                 internal ClassLayout(int pack, int cSize, ClassDef par) 
361                 {
362                         packSize = (ushort)pack;
363                         classSize = (uint)cSize;
364                         parent = par;
365                         tabIx = MDTable.ClassLayout;
366                 }
367
368                 internal sealed override uint Size(MetaData md) 
369                 {
370                         return 6 + md.TableIndexSize(MDTable.TypeDef);
371                 }
372
373                 internal sealed override void Write(FileImage output) 
374                 {
375                         output.Write(packSize);
376                         output.Write(classSize);
377                         output.WriteIndex(MDTable.TypeDef,parent.Row);
378                 }
379
380         }
381
382         /**************************************************************************/  
383         /// <summary>
384         /// Summary description for ConstantElem.
385         /// </summary>
386         internal class ConstantElem : MetaDataElement {
387
388                 MetaDataElement parent;
389                 Constant cValue;
390                 uint valIx = 0;
391
392                 internal ConstantElem(MetaDataElement parent, Constant val) 
393                 {
394                         this.parent = parent;
395                         cValue = val;
396                         tabIx = MDTable.Constant;
397                         sortTable = true;
398                 }
399
400                 internal override uint SortKey() 
401                 {  
402                         return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasConst]) 
403                                 | parent.GetCodedIx(CIx.HasConst);
404                 }
405
406                 internal sealed override void BuildTables(MetaData md) 
407                 {
408                         if (done) return;
409                         valIx = cValue.GetBlobIndex(md);
410                         done = true;
411                 }
412
413                 internal void AddToBlob(BinaryWriter bw) 
414                 {
415                         cValue.Write(bw);
416                 }
417
418                 internal sealed override uint Size(MetaData md) 
419                 {
420                         return 2 + md.CodedIndexSize(CIx.HasConst) + md.BlobIndexSize();
421                 }
422
423                 internal sealed override void Write(FileImage output) 
424                 {
425                         output.Write(cValue.GetTypeIndex());
426                         output.Write((byte)0);
427                         output.WriteCodedIndex(CIx.HasConst,parent);
428                         output.BlobIndex(valIx);
429                 }
430
431         }
432         /**************************************************************************/  
433         /// <summary>
434         /// Descriptor for a Custom Attribute (.custom) 
435         /// </summary>
436
437         public class CustomAttribute : MetaDataElement {
438
439                 MetaDataElement parent;
440                 Method type;
441                 uint valIx;
442                 Constant cVal;
443                 byte[] byteVal;
444                 ushort numNamed = 0;
445                 ArrayList names, vals;
446
447                 internal CustomAttribute(MetaDataElement paren, Method constrType, 
448                                 Constant val) {
449                         parent = paren;
450                         type = constrType;
451                         cVal = val;
452                         tabIx = MDTable.CustomAttribute;
453
454                         byteVal = ConstantToByteArray (val);
455                 }
456
457                 static byte[] ConstantToByteArray (Constant c)
458                 {
459                         var bac = c as ByteArrConst;
460                         if (bac != null)
461                                 return bac.val;
462
463                         var ms = new MemoryStream ();
464                         // Version info
465                         ms.WriteByte (1);
466                         ms.WriteByte (0);
467
468                         if (c == null) {
469                                 ms.WriteByte (0);
470                                 ms.WriteByte (0);
471                                 return ms.ToArray ();
472                         }
473
474                         var sc = c as StringConst;
475                         if (sc != null) {
476                                 string value = sc.val;
477                                 if (value == null)
478                                         throw new NotImplementedException ();
479
480                                 var buf = Encoding.UTF8.GetBytes (value);
481                                 MetaData.CompressNum ((uint) buf.Length, ms);
482                                 var byteVal = ms.ToArray ();
483                                 System.Array.Resize (ref byteVal, (int) ms.Length + buf.Length + 2);
484                                 System.Array.Copy (buf, 0, byteVal, ms.Length, buf.Length);
485                                 return byteVal;
486                         }
487
488                         var ac = c as ArrayConstant;
489                         if (ac != null) {
490                                 var bw = new BinaryWriter (ms);
491                                 if (ac.ExplicitSize != null)
492                                         bw.Write (ac.ExplicitSize.Value);
493                                 ac.Write (bw);
494                                 bw.Write ((short)0);
495                                 return ms.ToArray ();
496                         }
497
498                         var bc = c as DataConstant;
499                         if (bc != null) {
500                                 var bw = new BinaryWriter (ms);
501                                 bc.Write (bw);
502                                 bw.Write ((short)0);
503                                 return ms.ToArray ();
504                         }
505
506                         throw new NotImplementedException (c.GetType ().ToString ());
507                 }
508
509                 internal CustomAttribute(MetaDataElement paren, Method constrType,
510                                 byte[] val) {
511                         parent = paren;
512                         type = constrType;
513                         tabIx = MDTable.CustomAttribute;
514                         byteVal = val;
515                 }
516
517                 internal override uint SortKey() 
518                 {
519                         return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasCustomAttr])
520                                 | parent.GetCodedIx(CIx.HasCustomAttr);
521                 }
522
523                 public void AddFieldOrProp(string name, Constant val) 
524                 {
525                         if (numNamed == 0) {
526                                 names = new ArrayList();
527                                 vals = new ArrayList();
528                         }
529                         names.Add(name);
530                         vals.Add(val);
531                 }
532
533                 internal sealed override void BuildTables(MetaData md) 
534                 {
535                         md.AddToTable(MDTable.CustomAttribute, this);
536                         if (byteVal == null) {
537                                 valIx = 0;
538                                 return;
539                         }
540
541                         BinaryWriter bw = new BinaryWriter(new MemoryStream());
542                         bw.Write(byteVal);
543                         MemoryStream str = (MemoryStream)bw.BaseStream;
544                         valIx = md.AddToBlobHeap(str.ToArray());
545                 }
546
547                 internal sealed override uint Size(MetaData md) 
548                 {
549                         return md.CodedIndexSize(CIx.HasCustomAttr) + md.CodedIndexSize(CIx.CustomAttributeType) + md.BlobIndexSize();
550                 }
551
552                 internal sealed override void Write(FileImage output) 
553                 {
554                         output.WriteCodedIndex(CIx.HasCustomAttr,parent);
555                         output.WriteCodedIndex(CIx.CustomAttributeType,type);
556                         output.BlobIndex(valIx);
557                 }
558
559         }
560
561         /**************************************************************************/  
562         /// <summary>
563         /// Descriptor for security permissions for a class or a method
564         /// </summary>
565
566         public abstract class BaseDeclSecurity : MetaDataElement {
567
568                 ushort action;
569                 MetaDataElement parent;
570                 uint permissionIx;
571
572                 internal BaseDeclSecurity(MetaDataElement paren, ushort act)
573                 {
574                         parent = paren;
575                         action = act;
576                         tabIx = MDTable.DeclSecurity;
577                 }
578
579                 internal override uint SortKey() 
580                 {
581                         return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasDeclSecurity])
582                                 | parent.GetCodedIx(CIx.HasDeclSecurity);
583                 }
584
585                 internal sealed override uint Size(MetaData md) 
586                 {
587                         return 2 + md.CodedIndexSize(CIx.HasDeclSecurity) + md.BlobIndexSize();
588                 }
589
590                 internal sealed override void BuildTables(MetaData md) 
591                 {
592                         if (done) return;
593
594                         BinaryWriter bw = new BinaryWriter (new MemoryStream ());
595                         md.AddToTable (MDTable.DeclSecurity, this);
596                         MemoryStream str = (MemoryStream)bw.BaseStream;
597                         WriteSig (bw);
598                         permissionIx = md.AddToBlobHeap(str.ToArray());
599
600                         done = true;
601                 }
602
603                 internal abstract void WriteSig (BinaryWriter bw);
604
605                 internal sealed override void Write(FileImage output) 
606                 {
607                         output.Write(action);
608                         output.WriteCodedIndex(CIx.HasDeclSecurity,parent);
609                         output.BlobIndex(permissionIx);
610                 }
611
612         }
613
614         public class DeclSecurity : BaseDeclSecurity {
615
616                 byte [] byteVal;
617
618                 internal DeclSecurity(MetaDataElement paren, ushort act, byte [] val)        
619                         : base (paren, act)
620                 {
621                         byteVal = val;
622                 }
623
624                 internal override void WriteSig (BinaryWriter bw)
625                 {
626                         bw.Write (byteVal);
627                 }
628
629         }
630
631         public class DeclSecurity_20 : BaseDeclSecurity {
632
633                 PermissionSet ps;
634
635                 internal DeclSecurity_20 (MetaDataElement paren, ushort act, PermissionSet ps)
636                         : base (paren, act)
637                 {
638                         this.ps = ps;
639                 }
640
641                 internal override void WriteSig (BinaryWriter bw)
642                 {
643                         ps.Write (bw);
644                 }
645         }
646
647         public class PermissionMember {
648
649                 MemberTypes member_type;
650                 PEAPI.Type type;
651                 string name;
652                 object value;
653
654                 public PermissionMember (MemberTypes member_type, PEAPI.Type type, string name, object value)
655                 {
656                         this.member_type = member_type;
657                         this.type = type;
658                         this.name = name;
659                         this.value = value;
660                 }
661
662                 public void Write (BinaryWriter bw)
663                 {
664                         byte [] b;
665
666                         if (member_type == MemberTypes.Field)
667                                 bw.Write ((byte) 0x53);
668                         else
669                                 //Property
670                                 bw.Write ((byte) 0x54);
671
672                         if (type is PrimitiveType) {
673                                 bw.Write (type.GetTypeIndex ());
674                         } else {
675                                 //must be enum
676                                 bw.Write ((byte) 0x55); //ENUM
677
678                                 b = Encoding.UTF8.GetBytes (((ClassRef) type).TypeName ());
679                                 MetaData.CompressNum ((uint) b.Length, (MemoryStream) bw.BaseStream);
680                                 bw.Write (b);
681                         }
682                         
683                         b = Encoding.UTF8.GetBytes (name);
684                         MetaData.CompressNum ((uint) b.Length, (MemoryStream) bw.BaseStream);
685                         bw.Write (b);
686
687                         ((Constant) value).Write (bw);
688                 }
689
690         }
691
692         public class Permission
693         {
694                 PEAPI.Type type;
695
696                 //PermissionMembers
697                 ArrayList members;
698                 string name;
699
700                 public Permission (PEAPI.Type type, string name)
701                 {
702                         this.type = type;
703                         this.name = name;
704                 }
705
706                 public void AddMember (PEAPI.PermissionMember member)
707                 {
708                         if (members == null)
709                                 members = new ArrayList ();
710
711                         members.Add (member);
712                 }
713
714                 public void Write (BinaryWriter bw)
715                 {
716                         byte [] b = Encoding.UTF8.GetBytes (name);
717                         MetaData.CompressNum ((uint) b.Length, (MemoryStream) bw.BaseStream);
718                         bw.Write (b);
719
720                         BinaryWriter perm_writer = new BinaryWriter (new MemoryStream (), Encoding.Unicode);
721                         MemoryStream str = (MemoryStream) perm_writer.BaseStream;
722
723                         MetaData.CompressNum ((uint) members.Count, str);//number of params
724                         foreach (PermissionMember member in members)
725                                 member.Write (perm_writer);
726
727                         bw.Write ((byte) str.Length); //(optional) parameters length
728                         bw.Write (str.ToArray ());
729                 }
730         }
731
732         public class PermissionSet 
733         {
734                 PEAPI.SecurityAction sec_action;
735                 ArrayList permissions;
736
737                 public PermissionSet (PEAPI.SecurityAction sec_action)
738                 {
739                         this.sec_action = sec_action;
740                 }
741
742                 public void AddPermission (PEAPI.Permission perm)
743                 {
744                         if (permissions == null)
745                                 permissions = new ArrayList ();
746
747                         permissions.Add (perm);
748                 }
749
750                 public void Write (BinaryWriter bw)
751                 {
752                         bw.Write ((byte) 0x2e);
753                         MetaData.CompressNum ((uint) permissions.Count, (MemoryStream) bw.BaseStream);
754
755                         foreach (Permission perm in permissions)
756                                 perm.Write (bw);
757                 }
758
759         }
760
761         /**************************************************************************/  
762         /// <summary>
763         /// Descriptor for layout information for a field
764         /// </summary>
765
766         public class FieldLayout : MetaDataElement {
767
768                 Field field;
769                 uint offset;
770
771                 internal FieldLayout(Field field, uint offset)      
772                 {
773                         this.field = field;
774                         this.offset = offset;
775                         tabIx = MDTable.FieldLayout;
776                 }
777
778                 internal sealed override uint Size(MetaData md) 
779                 {
780                         return 4 + md.TableIndexSize(MDTable.Field);
781                 }
782
783                 internal sealed override void Write(FileImage output) 
784                 {
785                         output.Write(offset);
786                         output.WriteIndex(MDTable.Field,field.Row);
787                 }
788
789         }
790
791         /*****************************************************************************/  
792         /// <summary>
793         /// Marshalling information for a field or param
794         /// </summary>
795         public class FieldMarshal : MetaDataElement {
796
797                 MetaDataElement field;
798                 NativeType nt;
799                 uint ntIx;
800
801                 internal FieldMarshal(MetaDataElement field, NativeType nType)      
802                 {
803                         this.field = field;
804                         this.nt = nType;
805                         tabIx = MDTable.FieldMarshal;
806                 }
807
808                 internal override uint SortKey() 
809                 {
810                         return (field.Row << MetaData.CIxShiftMap[(uint)CIx.HasFieldMarshal])
811                                 | field.GetCodedIx(CIx.HasFieldMarshal);
812                 }
813
814                 internal sealed override void BuildTables(MetaData md) 
815                 {
816                         if (done) return;
817                         ntIx = md.AddToBlobHeap(nt.ToBlob());
818                         done = true;
819                 }
820
821                 internal sealed override uint Size(MetaData md) 
822                 {
823                         return md.CodedIndexSize(CIx.HasFieldMarshal) + md.BlobIndexSize();
824                 }
825
826                 internal sealed override void Write(FileImage output) 
827                 {
828                         output.WriteCodedIndex(CIx.HasFieldMarshal,field);
829                         output.BlobIndex(ntIx);
830                 }
831
832         }
833
834         /**************************************************************************/  
835         /// <summary>
836         /// Descriptor for the address of a field's value in the PE file
837         /// </summary>
838         public class FieldRVA : MetaDataElement {
839
840                 Field field;
841                 DataConstant data;
842
843                 internal FieldRVA(Field field, DataConstant data)   
844                 {
845                         this.field = field;
846                         this.data = data;
847                         tabIx = MDTable.FieldRVA;
848                 }
849
850                 internal sealed override void BuildTables(MetaData md) 
851                 {
852                         if (done) return;
853                         md.AddData(data);
854                         done = true;
855                 }
856
857                 internal sealed override uint Size(MetaData md) 
858                 {
859                         return 4 + md.TableIndexSize(MDTable.Field);
860                 }
861
862                 internal sealed override void Write(FileImage output) 
863                 {
864                         output.WriteDataRVA(data.DataOffset);
865                         output.WriteIndex(MDTable.Field,field.Row);
866                 }
867
868         }
869
870         /**************************************************************************/  
871         /// <summary>
872         /// Descriptor for a file referenced in THIS assembly/module (.file)
873         /// </summary>
874         public class FileRef : MetaDataElement {
875
876                 private static readonly uint NoMetaData = 0x1;
877                 uint nameIx = 0, hashIx = 0;
878                 uint flags = 0;
879                 protected string name;
880
881                 internal FileRef(string name, byte[] hashBytes, bool metaData,
882                                 bool entryPoint, MetaData md) {
883                         if (!metaData) flags = NoMetaData;
884                         if (entryPoint) md.SetEntryPoint(this);
885                         this.name = name;
886                         nameIx = md.AddToStringsHeap(name);
887                         hashIx = md.AddToBlobHeap(hashBytes);
888                         tabIx = MDTable.File;
889                 }
890
891                 internal FileRef(uint nameIx, byte[] hashBytes, bool metaData,
892                                 bool entryPoint, MetaData md) {
893                         if (!metaData) flags = NoMetaData;
894                         if (entryPoint) md.SetEntryPoint(this);
895                         this.nameIx = nameIx;
896                         hashIx = md.AddToBlobHeap(hashBytes);
897                         tabIx = MDTable.File;
898                 }
899
900                 internal sealed override uint Size(MetaData md) 
901                 {
902                         return 4 + md.StringsIndexSize() + md.BlobIndexSize();
903                 }
904
905                 internal sealed override void BuildTables(MetaData md) 
906                 {
907                         md.AddToTable(MDTable.File,this);
908                 }
909
910                 internal sealed override void Write(FileImage output) 
911                 {
912                         output.Write(flags);
913                         output.StringsIndex(nameIx);
914                         output.BlobIndex(hashIx);
915                 }
916
917                 internal sealed override uint GetCodedIx(CIx code) 
918                 {
919                         switch (code) {
920                                 case (CIx.HasCustomAttr) : return 16; 
921                                 case (CIx.Implementation) : return 0;
922                         }
923                         return 0;
924                 }
925
926         }
927         /**************************************************************************/  
928         /// <summary>
929         /// Descriptor for pinvoke information for a method NOT YET IMPLEMENTED
930         /// </summary>
931         public class ImplMap : MetaDataElement {
932
933                 private static readonly ushort NoMangle = 0x01;
934                 ushort flags;
935                 Method meth;
936                 string importName;
937                 uint iNameIx;
938                 ModuleRef importScope;
939
940                 internal ImplMap(ushort flag, Method implMeth, string iName, ModuleRef mScope) 
941                 {
942                         flags = flag;
943                         meth = implMeth;
944                         importName = iName;
945                         importScope = mScope;
946                         tabIx = MDTable.ImplMap;
947                         if (iName == null) flags |= NoMangle;
948                         //throw(new NotYetImplementedException("PInvoke "));
949                 }
950
951                 internal override uint SortKey() 
952                 {
953                         return (meth.Row << MetaData.CIxShiftMap[(uint)CIx.MemberForwarded]) 
954                                 | meth.GetCodedIx(CIx.MemberForwarded);
955                 }
956
957                 internal sealed override void BuildTables(MetaData md) 
958                 {
959                         if (done) return;
960                         iNameIx = md.AddToStringsHeap(importName);
961                         done = true;
962                 }
963
964                 internal sealed override uint Size(MetaData md) 
965                 {
966                         return 2+ md.CodedIndexSize(CIx.MemberForwarded) + 
967                                 md.StringsIndexSize() +  md.TableIndexSize(MDTable.ModuleRef);
968                 }
969
970                 internal sealed override void Write(FileImage output) 
971                 {
972                         output.Write(flags);
973                         output.WriteCodedIndex(CIx.MemberForwarded,meth);
974                         output.StringsIndex(iNameIx);
975                         output.WriteIndex(MDTable.ModuleRef,importScope.Row);
976                 }
977
978         }
979
980         /**************************************************************************/  
981
982         public class GenericParameter : MetaDataElement {
983
984                 MetaDataElement owner;
985                 MetaData metadata;
986                 public string name;
987                 uint nameIx;
988                 short index;
989                 GenericParamAttributes attr;
990
991                 internal GenericParameter (ClassDef owner, MetaData metadata,
992                                 short index, string name, GenericParamAttributes attr) : this (owner, metadata, index, name, attr, true)
993                 {
994                 }
995
996                 internal GenericParameter (MethodDef owner, MetaData metadata,
997                                 short index, string name, GenericParamAttributes attr) : this (owner, metadata, index, name, attr, true)
998                 {
999                 }
1000
1001                 private GenericParameter (MetaDataElement owner, MetaData metadata,
1002                                 short index, string name, GenericParamAttributes attr, bool nadda) {
1003                         this.owner = owner;
1004                         this.metadata = metadata;
1005                         this.index = index;
1006                         tabIx = MDTable.GenericParam;
1007                         this.name = name;
1008                         this.attr = attr;
1009                 }
1010
1011                 internal override uint SortKey() 
1012                 {
1013                         return (owner.Row << MetaData.CIxShiftMap[(uint)CIx.TypeOrMethodDef])
1014                                 | owner.GetCodedIx(CIx.TypeOrMethodDef);
1015                 }
1016
1017                 internal override uint SortKey2 ()
1018                 {
1019                         return (uint) index;
1020                 }
1021
1022                 public void AddConstraint  (Type constraint) 
1023                 {
1024                         metadata.AddToTable (MDTable.GenericParamConstraint,
1025                                         new GenericParamConstraint (this, constraint));
1026                 }
1027
1028                 internal sealed override uint Size(MetaData md) 
1029                 {
1030                         return (uint) (4 +
1031                                         md.CodedIndexSize(CIx.TypeOrMethodDef) + 
1032                                         md.StringsIndexSize ());
1033                 }
1034
1035                 internal sealed override void BuildTables(MetaData md) 
1036                 {
1037                         if (done) return;
1038                         nameIx = md.AddToStringsHeap(name);
1039                         done = true;
1040                 }
1041
1042                 internal sealed override void Write(FileImage output) 
1043                 {
1044                         output.Write ((short) index);
1045                         output.Write ((short) attr);
1046                         output.WriteCodedIndex(CIx.TypeOrMethodDef, owner);
1047                         output.StringsIndex (nameIx);
1048                 }
1049
1050                 internal sealed override uint GetCodedIx(CIx code) 
1051                 {
1052                         switch (code) {
1053                                 case (CIx.HasCustomAttr) : return 19; 
1054                         }
1055                         return 0;
1056                 }
1057
1058         }
1059
1060         internal class GenericParamConstraint : MetaDataElement {
1061
1062                 GenericParameter param;
1063                 Type type;
1064
1065                 public GenericParamConstraint (GenericParameter param, Type type) 
1066                 {
1067                         this.param = param;
1068                         this.type = type;
1069                         tabIx = MDTable.GenericParamConstraint;
1070                 }
1071
1072                 internal override uint SortKey() 
1073                 {
1074                         return param.Row;
1075                 }
1076
1077                 internal sealed override uint Size(MetaData md) 
1078                 {
1079                         return (uint) (md.TableIndexSize(MDTable.GenericParam) +
1080                                         md.CodedIndexSize(CIx.TypeDefOrRef));
1081                 }
1082
1083                 internal sealed override void Write(FileImage output) 
1084                 {
1085                         output.WriteIndex(MDTable.GenericParam, param.Row);
1086                         output.WriteCodedIndex(CIx.TypeDefOrRef, type);
1087                 }
1088
1089         }
1090
1091         internal class MethodSpec : Method {
1092
1093                 Method meth;
1094                 GenericMethodSig g_sig;
1095                 uint sidx;
1096
1097                 internal MethodSpec (Method meth, GenericMethodSig g_sig) : base ("")
1098                 {
1099                         this.meth = meth;
1100                         this.g_sig = g_sig;
1101                         tabIx = MDTable.MethodSpec;
1102                 }
1103
1104                 internal override uint GetSigIx (MetaData md)
1105                 {
1106                         throw new Exception ("Should not be used.");
1107                 }
1108
1109                 public override void AddCallConv (CallConv cconv)
1110                 {
1111                         throw new Exception ("Should not be used.");
1112                 }
1113                 
1114                 internal sealed override void BuildTables (MetaData md) 
1115                 {
1116                         if (done) return;
1117                         sidx = g_sig.GetSigIx (md);
1118                         done = true;
1119                 }
1120
1121                 internal sealed override uint Size (MetaData md) 
1122                 {
1123                         return (uint) (md.CodedIndexSize(CIx.MethodDefOrRef) +
1124                                         md.BlobIndexSize ());
1125                 }
1126
1127                 internal sealed override void Write (FileImage output) 
1128                 {
1129                         output.WriteCodedIndex (CIx.MethodDefOrRef, meth);
1130                         output.BlobIndex (sidx);
1131                 }
1132
1133                 internal sealed override void TypeSig (MemoryStream sig)
1134                 {
1135                         throw new Exception ("Should not be used.");
1136                 }
1137         }
1138
1139         /**************************************************************************/
1140         /// <summary>
1141         /// Descriptor for interface implemented by a class
1142         /// </summary>
1143         public class InterfaceImpl: MetaDataElement {
1144
1145                 ClassDef theClass;
1146                 Class theInterface;
1147
1148                 internal InterfaceImpl(ClassDef theClass, Class theInterface) 
1149                 {
1150                         this.theClass = theClass;
1151                         this.theInterface = theInterface;
1152                         tabIx = MDTable.InterfaceImpl;
1153                 }
1154
1155                 internal sealed override uint Size(MetaData md) 
1156                 {
1157                         return md.TableIndexSize(MDTable.TypeDef) + 
1158                                 md.CodedIndexSize(CIx.TypeDefOrRef);
1159                 }
1160
1161                 internal sealed override void Write(FileImage output) 
1162                 {
1163                         output.WriteIndex(MDTable.TypeDef,theClass.Row);
1164                         output.WriteCodedIndex(CIx.TypeDefOrRef,theInterface);
1165                 }
1166
1167                 internal sealed override uint GetCodedIx(CIx code) { return 5; }
1168
1169                 internal override uint SortKey ()
1170                 {
1171                         return (theClass.Row << MetaData.CIxShiftMap[(uint)CIx.TypeDefOrRef])
1172                                 | theClass.GetCodedIx (CIx.TypeDefOrRef);
1173                 }
1174
1175         }
1176
1177         /**************************************************************************/  
1178         /// <summary>
1179         /// Descriptor for resources used in this PE file 
1180         /// </summary>
1181
1182         public class ManifestResource : MetaDataElement {
1183
1184                 public static readonly uint PublicResource = 0x1;
1185                 public static readonly uint PrivateResource = 0x2;
1186
1187                 string mrName;
1188                 MetaDataElement rRef;
1189                 uint fileOffset;
1190                 uint nameIx = 0;
1191                 uint flags = 0;
1192                 byte [] resourceBytes;
1193
1194                 public ManifestResource (string name, byte[] resBytes, uint flags) 
1195                 {
1196                         InitResource (name, flags);
1197                         this.resourceBytes = resBytes;
1198                 }
1199
1200                 public ManifestResource(string name, uint flags, FileRef fileRef) 
1201                 {
1202                         InitResource (name, flags);
1203                         rRef = fileRef;
1204                 }
1205
1206                 public ManifestResource(string name, uint flags, FileRef fileRef, 
1207                                 uint fileIx) {
1208                         InitResource (name, flags);
1209                         rRef = fileRef;
1210                         fileOffset = fileIx;
1211                 }
1212
1213                 public ManifestResource(string name, uint flags, AssemblyRef assemRef) 
1214                 {
1215                         InitResource (name, flags);
1216                         rRef = assemRef;
1217                 }
1218
1219                 internal ManifestResource (ManifestResource mres) 
1220                 {
1221                         mrName = mres.mrName;
1222                         flags = mres.flags;
1223                         rRef = mres.rRef;
1224                         fileOffset = mres.fileOffset;
1225                         resourceBytes = mres.resourceBytes;
1226                 }
1227
1228                 private void InitResource (string name, uint flags) 
1229                 {
1230                         mrName = name;
1231                         this.flags = flags;
1232                         tabIx = MDTable.ManifestResource;
1233                 }
1234
1235                 internal sealed override void BuildTables(MetaData md) 
1236                 {
1237                         if (done) return;
1238                         md.AddToTable (MDTable.ManifestResource, this);
1239                         nameIx = md.AddToStringsHeap(mrName);
1240                         if (resourceBytes != null) {
1241                                 if (rRef != null)
1242                                         throw new PEFileException ("Manifest Resource has byte value and file reference");
1243                                 fileOffset = md.AddResource(resourceBytes);
1244                         } else {
1245                                 if (rRef == null)
1246                                         throw new PEFileException ("Manifest Resource has no implementation or value");
1247                                 rRef.BuildTables (md);
1248                         }
1249
1250                         done = true;
1251                 }
1252
1253                 internal sealed override uint Size(MetaData md) 
1254                 {
1255                         return 8 + md.StringsIndexSize() + 
1256                                 md.CodedIndexSize(CIx.Implementation);
1257                 }
1258
1259                 internal sealed override void Write(FileImage output) 
1260                 {
1261                         output.Write(fileOffset);
1262                         output.Write(flags);
1263                         output.StringsIndex(nameIx);
1264                         output.WriteCodedIndex(CIx.Implementation,rRef);
1265                 }
1266
1267                 internal sealed override uint GetCodedIx(CIx code) { return 18; }
1268
1269                 public string Name {
1270                         get { return mrName; }
1271                         set { mrName = value; }
1272                 }
1273
1274         }
1275         /**************************************************************************/  
1276         /// <summary>
1277         /// Base class for elements in the PropertyMap, EventMap and 
1278         /// NestedClass MetaData tables
1279         /// </summary>
1280         public class MapElem : MetaDataElement {
1281
1282                 ClassDef parent;
1283                 uint elemIx;
1284                 MDTable elemTable;
1285
1286                 internal MapElem(ClassDef par, uint elIx, MDTable elemTab) 
1287                 {
1288                         parent = par;
1289                         elemIx = elIx;
1290                         elemTable = elemTab;
1291                 }
1292
1293                 internal sealed override uint Size(MetaData md) 
1294                 {
1295                         return md.TableIndexSize(MDTable.TypeDef) + md.TableIndexSize(elemTable);
1296                 }
1297
1298                 internal sealed override void Write(FileImage output) 
1299                 {
1300                         output.WriteIndex(MDTable.TypeDef,parent.Row);
1301                         output.WriteIndex(elemTable,elemIx);
1302                 }
1303         }
1304
1305         /**************************************************************************/  
1306         /// <summary>
1307         /// Descriptor for an overriding method (.override)
1308         /// </summary>
1309         public class MethodImpl : MetaDataElement {
1310
1311                 ClassDef parent;
1312                 Method header, body;
1313
1314                 internal MethodImpl(ClassDef par, Method decl, Method bod)      
1315                 {
1316                         parent = par;
1317                         header = decl;
1318                         body = bod;
1319                         tabIx = MDTable.MethodImpl;
1320                 }
1321
1322                 internal sealed override uint Size(MetaData md) 
1323                 {
1324                         return md.TableIndexSize(MDTable.TypeDef) + 2 * md.CodedIndexSize(CIx.MethodDefOrRef);
1325                 }
1326
1327                 internal sealed override void Write(FileImage output) 
1328                 {
1329                         output.WriteIndex(MDTable.TypeDef,parent.Row);
1330                         output.WriteCodedIndex(CIx.MethodDefOrRef,body);
1331                         output.WriteCodedIndex(CIx.MethodDefOrRef,header);
1332                 }
1333
1334         }
1335
1336         /**************************************************************************/  
1337         /// <summary>
1338         /// Descriptor for Property and Event methods
1339         /// </summary>
1340         public class MethodSemantics : MetaDataElement {
1341
1342                 Feature.MethodType type;
1343                 MethodDef meth;
1344                 Feature eventOrProp;
1345
1346                 internal MethodSemantics(Feature.MethodType mType, MethodDef method, Feature feature) 
1347                 {
1348                         type = mType;
1349                         meth = method;
1350                         eventOrProp = feature;
1351                         tabIx = MDTable.MethodSemantics;
1352                 }
1353
1354                 internal override uint SortKey() 
1355                 {
1356                         return (eventOrProp.Row << MetaData.CIxShiftMap [(uint)CIx.HasSemantics])
1357                                 | eventOrProp.GetCodedIx (CIx.HasSemantics);
1358                 }
1359
1360                 internal sealed override uint Size(MetaData md) 
1361                 {
1362                         return 2 + md.TableIndexSize(MDTable.Method) + md.CodedIndexSize(CIx.HasSemantics);
1363                 }
1364
1365                 internal sealed override void Write(FileImage output) 
1366                 {
1367                         output.Write((ushort)type);
1368                         output.WriteIndex(MDTable.Method,meth.Row);
1369                         output.WriteCodedIndex(CIx.HasSemantics,eventOrProp);
1370                 }
1371
1372         }
1373
1374         /**************************************************************************/  
1375         /// <summary>
1376         /// Descriptor for a parameter of a method defined in this assembly/module
1377         /// </summary>
1378         public class Param : MetaDataElement {
1379
1380
1381                 Type pType;
1382                 string pName;
1383                 internal ushort seqNo = 0;
1384                 ushort parMode;
1385                 ConstantElem defaultVal;
1386                 uint nameIx = 0;
1387                 FieldMarshal marshalInfo;
1388
1389                 /// <summary>
1390                 /// Create a new parameter for a method
1391                 /// </summary>
1392                 /// <param name="mode">param mode (in, out, opt)</param>
1393                 /// <param name="parName">parameter name</param>
1394                 /// <param name="parType">parameter type</param>
1395                 public Param(ParamAttr mode, string parName, Type parType) 
1396                 {
1397                         pName = parName;
1398                         pType = parType;
1399                         parMode = (ushort)mode;
1400                         tabIx = MDTable.Param;
1401                 }
1402
1403                 public bool HasMarshalInfo {
1404                         get { return marshalInfo != null; }
1405                 }
1406
1407                 /// <summary>
1408                 /// Add a default value to this parameter
1409                 /// </summary>
1410                 /// <param name="c">the default value for the parameter</param>
1411                 public void AddDefaultValue(Constant cVal) 
1412                 {
1413                         defaultVal = new ConstantElem(this,cVal);
1414                         parMode |= (ushort) ParamAttr.HasDefault;
1415                 }
1416
1417                 /// <summary>
1418                 /// Add marshalling information about this parameter
1419                 /// </summary>
1420                 public void AddMarshallInfo(NativeType marshallType) 
1421                 {
1422                         parMode |= (ushort) ParamAttr.HasFieldMarshal;
1423                         marshalInfo = new FieldMarshal(this,marshallType);
1424                 }
1425
1426                 internal Type GetParType() { return pType; }
1427
1428                 internal sealed override void BuildTables(MetaData md) 
1429                 {
1430                         if (done) return;
1431                         nameIx = md.AddToStringsHeap(pName);
1432                         if (defaultVal != null) {
1433                                 md.AddToTable(MDTable.Constant,defaultVal);
1434                                 defaultVal.BuildTables(md);
1435                         }
1436                         if (marshalInfo != null) {
1437                                 md.AddToTable(MDTable.FieldMarshal,marshalInfo);
1438                                 marshalInfo.BuildTables(md);
1439                         }
1440                         done = true;
1441                 }
1442
1443                 internal void TypeSig(MemoryStream str) 
1444                 {
1445                         pType.TypeSig(str);
1446                 }
1447
1448                 internal sealed override uint Size(MetaData md) 
1449                 {
1450                         return 4 + md.StringsIndexSize();
1451                 }
1452
1453                 internal sealed override void Write(FileImage output) 
1454                 {
1455                         output.Write(parMode);
1456                         output.Write(seqNo);
1457                         output.StringsIndex(nameIx);
1458                 }
1459
1460                 internal sealed override uint GetCodedIx(CIx code) 
1461                 {
1462                         switch (code) {
1463                                 case (CIx.HasCustomAttr) : return 4; 
1464                                 case (CIx.HasConst) : return 1; 
1465                                 case (CIx.HasFieldMarshal) : return 1; 
1466                         }
1467                         return 0;
1468                 }
1469
1470         }
1471
1472         /**************************************************************************/  
1473         public abstract class Signature : MetaDataElement  {
1474
1475                 protected uint sigIx;
1476
1477                 internal Signature() 
1478                 {
1479                         tabIx = MDTable.StandAloneSig;
1480                 }
1481
1482                 internal sealed override uint Size(MetaData md) 
1483                 {
1484                         return md.BlobIndexSize();
1485                 }
1486
1487                 internal sealed override void Write(FileImage output) 
1488                 {
1489                         output.BlobIndex(sigIx);
1490                 }
1491
1492                 internal sealed override uint GetCodedIx(CIx code) { return (uint)tabIx; }
1493
1494         }
1495
1496         /**************************************************************************/  
1497         public class TypeSpec : MetaDataElement {
1498                 uint sigIx = 0;
1499
1500                 internal TypeSpec(Type aType, MetaData md) 
1501                 {
1502                         MemoryStream sig = new MemoryStream();
1503                         aType.TypeSig(sig);
1504                         sigIx = md.AddToBlobHeap(sig.ToArray());
1505                         tabIx = MDTable.TypeSpec;
1506                 }
1507
1508                 internal sealed override uint GetCodedIx(CIx code) 
1509                 {
1510                         switch (code) {
1511                                 case (CIx.TypeDefOrRef) : return 2; 
1512                                 case (CIx.HasCustomAttr) : return 13; 
1513                                 case (CIx.MemberRefParent) : return 4; 
1514                         }
1515                         return 0;
1516                 }
1517
1518                 internal override uint Size(MetaData md) 
1519                 {
1520                         return md.BlobIndexSize();
1521                 }
1522
1523                 internal sealed override void Write(FileImage output) 
1524                 {
1525                         //Console.WriteLine("Writing the blob index for a TypeSpec");
1526                         output.BlobIndex(sigIx);
1527                 }
1528         }
1529
1530
1531         /**************************************************************************/  
1532         /// <summary>
1533         /// Base class for all IL types
1534         /// </summary>
1535         public abstract class Type : MetaDataElement {
1536                 protected byte typeIndex;
1537                 protected TypeSpec typeSpec;
1538
1539                 internal Type(byte tyIx) { typeIndex = tyIx; }
1540
1541                 internal byte GetTypeIndex() { return typeIndex; }
1542                 internal void SetTypeIndex (byte b) { typeIndex = b; }
1543
1544                 internal virtual MetaDataElement GetTypeSpec(MetaData md) 
1545                 {
1546                         if (typeSpec == null) {
1547                                 typeSpec = new TypeSpec(this,md);
1548                                 md.AddToTable(MDTable.TypeSpec,typeSpec);
1549                         }
1550                         return typeSpec;
1551                 }
1552
1553                 internal virtual void TypeSig(MemoryStream str) 
1554                 {
1555                         throw(new TypeSignatureException(this.GetType().AssemblyQualifiedName +
1556                                                 " doesn't have a type signature!!"));   
1557                 }
1558         }
1559
1560         public class ClassRefInst : Type {
1561
1562                 private Type type;
1563                 private bool is_value;
1564
1565                 public ClassRefInst (Type type, bool is_value) : base (PrimitiveType.Class.GetTypeIndex ()) 
1566                 {
1567                         this.type = type;
1568                         this.is_value = is_value;
1569                         if (is_value)
1570                                 typeIndex = PrimitiveType.ValueType.GetTypeIndex ();
1571                         tabIx = MDTable.TypeSpec;
1572                 }
1573
1574                 internal sealed override void TypeSig(MemoryStream str) 
1575                 {
1576                         type.TypeSig (str);
1577                 }
1578         }
1579
1580         /**************************************************************************/  
1581         /// <summary>
1582         /// The base descriptor for a class 
1583         /// </summary>
1584         public abstract class Class : Type {
1585
1586                 protected int row = 0;
1587                 public string name, nameSpace;
1588                 protected uint nameIx, nameSpaceIx;
1589                 protected MetaData _metaData;
1590                 internal Class(string nameSpaceName, string className, MetaData md)
1591                         : base(PrimitiveType.Class.GetTypeIndex ()) 
1592                 {
1593                                 nameSpace = nameSpaceName;
1594                                 name = className;
1595                                 nameIx = md.AddToStringsHeap(name);
1596                                 nameSpaceIx = md.AddToStringsHeap(nameSpace);
1597                                 _metaData = md;
1598                 }
1599
1600                 internal Class(uint nsIx, uint nIx) : base(PrimitiveType.Class.GetTypeIndex ()) 
1601                 {
1602                         nameSpaceIx = nsIx;
1603                         nameIx = nIx;
1604                 }
1605
1606                 internal Class (byte typeIndex) : base (typeIndex)
1607                 {
1608                         nameSpace = "Should not be used";
1609                         name = "Should not be used";
1610                 }
1611
1612                 internal virtual uint TypeDefOrRefToken() { return 0; }
1613
1614                 internal virtual void MakeValueClass(ValueClass vClass) 
1615                 {
1616                         typeIndex = PrimitiveType.ValueType.GetTypeIndex ();
1617                 }
1618
1619                 internal virtual string TypeName() 
1620                 {
1621                         return (nameSpace + "." + name);
1622                 }
1623
1624                 internal override MetaDataElement GetTypeSpec(MetaData md) 
1625                 {
1626                         return this;
1627                 }
1628         }
1629
1630         /**************************************************************************/  
1631         // This Class produces entries in the TypeDef table of the MetaData 
1632         // in the PE meta data.
1633
1634         // NOTE:  Entry 0 in TypeDef table is always the pseudo class <module> 
1635         // which is the parent for functions and variables declared a module level
1636
1637         /// <summary>
1638         /// The descriptor for a class defined in the IL (.class) in the current assembly/module
1639         /// </summary>
1640         /// 
1641         public class ClassDef : Class {
1642
1643                 Class superType;
1644                 bool setSuperType;
1645                 ArrayList fields = new ArrayList();
1646                 ArrayList methods = new ArrayList();
1647                 ArrayList events;
1648                 ArrayList properties;
1649                 bool typeIndexChecked = true;
1650                 uint fieldIx = 0, methodIx = 0;
1651                 uint flags;
1652                 ClassLayout layout;
1653                 ClassDef parentClass;
1654                 MetaData metaData;
1655
1656                 internal ClassDef(TypeAttr attrSet, string nsName, string name, 
1657                                 MetaData md) : base(nsName, name, md) 
1658                 {
1659                         metaData = md;
1660                         flags = (uint)attrSet;
1661                         tabIx = MDTable.TypeDef;
1662                 }
1663
1664                 internal void SetSuper(Class sClass) 
1665                 {
1666                         superType = sClass;
1667                         setSuperType = true;
1668                         if (! (sClass is GenericTypeInst))
1669                                 typeIndexChecked = false;
1670                 }
1671
1672                 internal override void MakeValueClass(ValueClass vClass) 
1673                 {
1674                         if (vClass == ValueClass.Enum)  
1675                                 superType = metaData.mscorlib.EnumType();
1676                         else  
1677                                 superType = metaData.mscorlib.ValueType();
1678
1679                         setSuperType = true;
1680                         typeIndex = PrimitiveType.ValueType.GetTypeIndex ();
1681                 }
1682
1683                 public void SpecialNoSuper() 
1684                 {
1685                         setSuperType = true;
1686                 }
1687
1688                 /// <summary>
1689                 /// Add an attribute to this class
1690                 /// </summary>
1691                 /// <param name="ta">the attribute to be added</param>
1692                 public void AddAttribute(TypeAttr ta) 
1693                 {
1694                         flags |= (uint)ta;
1695                 }
1696
1697                 /// <summary>
1698                 /// Add an interface that is implemented by this class
1699                 /// </summary>
1700                 /// <param name="iFace">the interface that is implemented</param>
1701                 public void AddImplementedInterface(Class iFace) 
1702                 {
1703                         metaData.AddToTable(MDTable.InterfaceImpl,new InterfaceImpl(this,iFace));
1704                 }
1705
1706                 /// <summary>
1707                 ///  Add a named generic type parameter
1708                 /// </summary>
1709                 public GenericParameter AddGenericParameter (short index, string name) 
1710                 {
1711                         return AddGenericParameter (index, name, 0);
1712                 }
1713
1714                 /// <summary>
1715                 ///  Add a named generic type parameter with attributes
1716                 /// </summary>
1717                 public GenericParameter AddGenericParameter (short index, string name, GenericParamAttributes attr)
1718                 {
1719                         GenericParameter gp = new GenericParameter (this, metaData, index, name, attr);
1720                         metaData.AddToTable (MDTable.GenericParam, gp);
1721                         return gp;
1722                 }
1723
1724                 /// <summary>
1725                 /// Add a field to this class
1726                 /// </summary>
1727                 /// <param name="name">field name</param>
1728                 /// <param name="fType">field type</param>
1729                 /// <returns>a descriptor for this new field</returns>
1730                 public FieldDef AddField(string name, Type fType) 
1731                 {
1732                         FieldDef field = new FieldDef(name,fType);
1733                         fields.Add(field);
1734                         return field;
1735                 }
1736
1737                 /// <summary>
1738                 /// Add a field to this class
1739                 /// </summary>
1740                 /// <param name="fAtts">attributes for this field</param>
1741                 /// <param name="name">field name</param>
1742                 /// <param name="fType">field type</param>
1743                 /// <returns>a descriptor for this new field</returns>
1744                 public FieldDef AddField(FieldAttr fAtts, string name, Type fType) 
1745                 {
1746                         FieldDef field = new FieldDef(fAtts,name,fType);
1747                         fields.Add(field);
1748                         return field;
1749                 }
1750
1751                 public void SetFieldOrder (ArrayList fields)
1752                 {
1753                         this.fields = fields;
1754                 }
1755
1756                 /// <summary>
1757                 /// Add a method to this class
1758                 /// </summary>
1759                 /// <param name="name">method name</param>
1760                 /// <param name="retType">return type</param>
1761                 /// <param name="pars">parameters</param>
1762                 /// <returns>a descriptor for this new method</returns>
1763                 public MethodDef AddMethod(string name, Type retType, Param[] pars) 
1764                 {
1765                         return AddMethod (name, new Param (ParamAttr.Default, "", retType), pars);
1766                 }
1767
1768                 public MethodDef AddMethod (string name, Param ret_param, Param [] pars) 
1769                 {
1770                         // Console.WriteLine("Adding method " + name + " to class " + this.name);
1771                         MethodDef meth = new MethodDef(metaData,name, ret_param, pars);
1772                         methods.Add(meth);
1773                         return meth;
1774                 }
1775
1776                 /// <summary>
1777                 /// Add a method to this class
1778                 /// </summary>
1779                 /// <param name="mAtts">attributes for this method</param>
1780                 /// <param name="iAtts">implementation attributes for this method</param>
1781                 /// <param name="name">method name</param>
1782                 /// <param name="retType">return type</param>
1783                 /// <param name="pars">parameters</param>
1784                 /// <returns>a descriptor for this new method</returns>
1785                 public MethodDef AddMethod(MethAttr mAtts, ImplAttr iAtts, string name, 
1786                                 Param ret_param, Param [] pars) {
1787                         // Console.WriteLine("Adding method " + name + " to class " + this.name);
1788                         MethodDef meth = new MethodDef (metaData, mAtts, iAtts, name, ret_param, pars);
1789                         methods.Add(meth);
1790                         return meth;
1791                 }
1792
1793                 /// <summary>
1794                 /// Add an event to this class
1795                 /// </summary>
1796                 /// <param name="name">event name</param>
1797                 /// <param name="eType">event type</param>
1798                 /// <returns>a descriptor for this new event</returns>
1799                 public Event AddEvent(string name, Type eType) 
1800                 {
1801                         Event e = new Event(name,eType,this);
1802                         if (events == null) events = new ArrayList();
1803                         events.Add(e);
1804                         return e;
1805                 }
1806
1807                 /// <summary>
1808                 /// Add a property to this class
1809                 /// </summary>
1810                 /// <param name="name">property name</param>
1811                 /// <param name="propType">property type</param>
1812                 /// <returns>a descriptor for this new property</returns>
1813                 public Property AddProperty(string name, Type retType, Type[] pars) 
1814                 {
1815                         Property p = new Property(name, retType, pars, this);
1816                         if (properties == null) properties = new ArrayList();
1817                         properties.Add(p);
1818                         return p;
1819                 }
1820
1821                 /// <summary>
1822                 /// Add a nested class to this class
1823                 /// </summary>
1824                 /// <param name="attrSet">attributes for this nested class</param>
1825                 /// <param name="nsName">nested name space name</param>
1826                 /// <param name="name">nested class name</param>
1827                 /// <returns>a descriptor for this new nested class</returns>
1828                 public ClassDef AddNestedClass(TypeAttr attrSet, string nsName, 
1829                                 string name) {
1830                         ClassDef nClass = new ClassDef(attrSet,"",name,metaData);
1831                         metaData.AddToTable(MDTable.TypeDef,nClass);
1832                         metaData.AddToTable(MDTable.NestedClass,new MapElem(nClass,Row,MDTable.TypeDef));
1833                         nClass.parentClass = this;
1834                         return (nClass);
1835                 }
1836
1837                 public static bool IsValueType (Class type)
1838                 {
1839                         return IsValueType (type.nameSpace, type.name);
1840                 }
1841
1842                 public static bool IsEnum (Class type)
1843                 {
1844                         return IsEnum (type.nameSpace, type.name);
1845                 }
1846
1847                 public static bool IsValueType (string nsName, string name)
1848                 {
1849                         return (nsName == "System" && name == "ValueType");
1850                 }
1851
1852                 public static bool IsEnum (string nsName, string name)
1853                 {
1854                         return (nsName == "System" && name == "Enum");
1855                 }
1856
1857                 /// <summary>
1858                 /// Add a nested class to this class
1859                 /// </summary>
1860                 /// <param name="attrSet">attributes for this nested class</param>
1861                 /// <param name="nsName">nested name space name</param>
1862                 /// <param name="name">nested class name</param>
1863                 /// <param name="sType">super type of this nested class</param>
1864                 /// <returns>a descriptor for this new nested class</returns>
1865                 public ClassDef AddNestedClass(TypeAttr attrSet, string nsName, 
1866                                 string name, Class sType) {
1867                         ClassDef nClass = AddNestedClass (attrSet, nsName, name);
1868                         nClass.SetSuper(sType);
1869                         if (ClassDef.IsValueType (sType))
1870                                 nClass.MakeValueClass (ValueClass.ValueType);
1871                         else
1872                                 if (ClassDef.IsEnum (sType))
1873                                         nClass.MakeValueClass (ValueClass.Enum);
1874
1875                         if (ClassDef.IsValueType (sType) || ClassDef.IsEnum (sType))
1876                                 nClass.SetTypeIndex (PrimitiveType.ValueType.GetTypeIndex ());
1877
1878                         nClass.typeIndexChecked = true;
1879                         return (nClass);
1880                 }
1881
1882                 /// <summary>
1883                 /// Add layout information for this class.  This class must have the
1884                 /// sequential or explicit attribute.
1885                 /// </summary>
1886                 /// <param name="packSize">packing size (.pack)</param>
1887                 /// <param name="classSize">class size (.size)</param>
1888                 public void AddLayoutInfo (int packSize, int classSize) 
1889                 {
1890                         layout = new ClassLayout(packSize,classSize,this);
1891                 }
1892
1893                 /// <summary>
1894                 /// Use a method as the implementation for another method (.override)
1895                 /// </summary>
1896                 /// <param name="decl">the method to be overridden</param>
1897                 /// <param name="body">the implementation to be used</param>
1898                 public void AddMethodOverride(Method decl, Method body) 
1899                 {
1900                         metaData.AddToTable(MDTable.MethodImpl,new MethodImpl(this,decl,body));
1901                 }
1902
1903                 /// <summary>
1904                 /// Add security to this class NOT YET IMPLEMENTED
1905                 /// </summary>
1906                 /// <param name="permissionSet"></param>
1907                 public void AddSecurity(byte[] permissionSet) 
1908                 {
1909                         throw(new NotYetImplementedException("Class security "));
1910                         //flags |= HasSecurity;
1911                         // securityActions = permissionSet;
1912                 }
1913
1914                 //public void AddLineInfo(int row, int col) { }
1915
1916                 internal void CheckTypeIndex() 
1917                 {
1918                         if (typeIndexChecked) return;
1919                         if (superType is ClassDef) 
1920                                 ((ClassDef)superType).CheckTypeIndex();
1921                         typeIndex = superType.GetTypeIndex();
1922                         typeIndexChecked = true;
1923                 }
1924
1925                 internal sealed override void BuildTables(MetaData md) 
1926                 {
1927                         if (done) 
1928                                 return;
1929                         
1930                         if ((flags & (uint)TypeAttr.Interface) != 0) {
1931                                 superType = null;
1932                                 setSuperType = true;
1933                         }
1934                         // Console.WriteLine("Building tables for " + name);
1935                         if (layout != null) md.AddToTable(MDTable.ClassLayout,layout);
1936                         // Console.WriteLine("adding methods " + methods.Count);
1937                         methodIx = md.TableIndex(MDTable.Method);
1938                         for (int i=0; i < methods.Count; i++) {
1939                                 md.AddToTable(MDTable.Method,(MetaDataElement)methods[i]);
1940                                 ((MethodDef)methods[i]).BuildTables(md);
1941                         }
1942                         // Console.WriteLine("adding fields");
1943                         fieldIx = md.TableIndex(MDTable.Field);
1944                         for (int i=0; i < fields.Count; i++) {
1945                                 md.AddToTable(MDTable.Field,(MetaDataElement)fields[i]);
1946                                 ((FieldDef)fields[i]).BuildTables(md);
1947                         }
1948                         // Console.WriteLine("adding events and properties");
1949                         if (events != null) { 
1950                                 for (int i=0; i < events.Count; i++) {
1951                                         md.AddToTable(MDTable.Event,(Event)events[i]);
1952                                         ((Event)events[i]).BuildTables(md);
1953                                 }
1954                                 md.AddToTable(MDTable.EventMap,
1955                                                 new MapElem(this,((Event)events[0]).Row,MDTable.Event));
1956                         }
1957                         if (properties != null) { 
1958                                 for (int i=0; i < properties.Count; i++) {
1959                                         md.AddToTable(MDTable.Property,(Property)properties[i]);
1960                                         ((Property)properties[i]).BuildTables(md);
1961                                 }
1962                                 md.AddToTable(MDTable.PropertyMap,new MapElem(this,
1963                                                         ((Property)properties[0]).Row,MDTable.Property));
1964                         }
1965                         // Console.WriteLine("End of building tables");
1966
1967                         if (!setSuperType)
1968                                 superType = metaData.mscorlib.GetSpecialSystemClass(PrimitiveType.Object);
1969
1970                         done = true;
1971                 }
1972
1973                 internal sealed override uint Size(MetaData md) 
1974                 {
1975                         return 4 + 2 * md.StringsIndexSize() + 
1976                                 md.CodedIndexSize(CIx.TypeDefOrRef) +
1977                                 md.TableIndexSize(MDTable.Field) + 
1978                                 md.TableIndexSize(MDTable.Method);
1979                 }
1980
1981                 internal sealed override void Write(FileImage output) 
1982                 {
1983                         output.Write(flags);
1984                         output.StringsIndex(nameIx);
1985                         output.StringsIndex(nameSpaceIx);
1986                         //if (superType != null) 
1987                         // Console.WriteLine("getting coded index for superType of " + name + " = " + superType.GetCodedIx(CIx.TypeDefOrRef));
1988                         output.WriteCodedIndex(CIx.TypeDefOrRef,superType);
1989                         output.WriteIndex(MDTable.Field,fieldIx);
1990                         output.WriteIndex(MDTable.Method,methodIx);
1991                 }
1992
1993                 internal sealed override uint TypeDefOrRefToken() 
1994                 {
1995                         uint cIx = Row;
1996                         cIx = cIx << 2;
1997                         return cIx;
1998                 }
1999
2000                 internal sealed override void TypeSig(MemoryStream sig) 
2001                 {
2002                         if (!typeIndexChecked) CheckTypeIndex();
2003                         sig.WriteByte(GetTypeIndex());
2004                         MetaData.CompressNum(TypeDefOrRefToken(),sig);
2005                 }
2006
2007                 internal sealed override uint GetCodedIx(CIx code) 
2008                 {
2009                         switch (code) {
2010                                 case (CIx.TypeDefOrRef) : return 0; 
2011                                 case (CIx.HasCustomAttr) : return 3; 
2012                                 case (CIx.HasDeclSecurity) : return 0; 
2013                                 case (CIx.TypeOrMethodDef) : return 0; 
2014                         }
2015                         return 0;
2016                 }
2017
2018         }
2019
2020         /**************************************************************************/  
2021         /// <summary>
2022         /// Descriptor for a class/interface declared in another module of THIS 
2023         /// assembly, or in another assembly.
2024         /// </summary>
2025         public class ClassRef : Class, IExternRef, IResolutionScope {
2026
2027                 protected IResolutionScope parent;
2028                 protected MetaData metaData;
2029
2030                 internal ClassRef(string nsName, string name, MetaData md) : base(nsName, name, md) 
2031                 {
2032                         metaData = md;
2033                         tabIx = MDTable.TypeRef;
2034                 }
2035
2036                 /// <summary>
2037                 /// Add a method to this class
2038                 /// </summary>
2039                 /// <param name="name">method name</param>
2040                 /// <param name="retType">return type</param>
2041                 /// <param name="pars">parameter types</param>
2042                 /// <returns>a descriptor for this method</returns>
2043                 public MethodRef AddMethod(string name, Type retType, Type[] pars) 
2044                 {
2045                         return AddMethod (name, retType, pars, 0);
2046                 }
2047                 
2048                 /// <summary>
2049                 /// Add a method to this class
2050                 /// </summary>
2051                 /// <param name="name">method name</param>
2052                 /// <param name="retType">return type</param>
2053                 /// <param name="pars">parameter types</param>
2054                 /// <param name="gen_param_count">num of generic parameters</param>
2055                 /// <returns>a descriptor for this method</returns>
2056                 public MethodRef AddMethod (string name, Type retType, Type[] pars, int gen_param_count) 
2057                 {
2058                         MethodRef meth = new MethodRef (this, name, retType, pars, false, null, gen_param_count);
2059                         metaData.AddToTable(MDTable.MemberRef,meth);
2060                         return meth;
2061                 }
2062
2063                 /// <summary>
2064                 /// Add a method to this class
2065                 /// </summary>
2066                 /// <param name="name">method name</param>
2067                 /// <param name="retType">return type</param>
2068                 /// <param name="pars">parameter types</param>
2069                 /// <returns>a descriptor for this method</returns>
2070                 public MethodRef AddVarArgMethod(string name, Type retType, 
2071                                 Type[] pars, Type[] optPars) 
2072                 {
2073                         MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars, 0);
2074                         metaData.AddToTable(MDTable.MemberRef,meth);
2075                         return meth;
2076                 }
2077
2078                 /// <summary>
2079                 /// Add a field to this class
2080                 /// </summary>
2081                 /// <param name="name">field name</param>
2082                 /// <param name="fType">field type</param>
2083                 /// <returns>a descriptor for this field</returns>
2084                 public FieldRef AddField(string name, Type fType) 
2085                 {
2086                         FieldRef field = new FieldRef(this,name,fType);
2087                         metaData.AddToTable(MDTable.MemberRef,field);
2088                         return field;
2089                 }
2090
2091                 public ClassRef AddClass (string nsName, string name)
2092                 {
2093                         ClassRef aClass = new ClassRef(nsName,name,metaData);
2094                         metaData.AddToTable(MDTable.TypeRef,aClass);
2095                         aClass.SetParent(this);
2096                         return aClass;
2097                 }
2098
2099                 public ClassRef AddValueClass (string nsName, string name)
2100                 {
2101                         ClassRef aClass = AddClass (nsName, name);
2102                         aClass.MakeValueClass (ValueClass.ValueType);
2103                         return aClass;
2104                 }
2105
2106                 internal void SetParent(IResolutionScope par) 
2107                 {
2108                         parent = par;
2109                 }
2110
2111                 internal override string TypeName() 
2112                 {
2113                         if ((parent != null) && (parent is AssemblyRef))
2114                                 return (nameSpace + "." + name + ", " + ((AssemblyRef)parent).TypeName());
2115                         else 
2116                                 return (nameSpace + name);
2117                 }
2118
2119                 internal sealed override uint Size(MetaData md) 
2120                 {
2121                         return md.CodedIndexSize(CIx.ResolutionScope) + 2 * 
2122                                 md.StringsIndexSize();
2123                 }
2124
2125                 internal sealed override void Write(FileImage output) 
2126                 {
2127                         output.WriteCodedIndex(CIx.ResolutionScope,(MetaDataElement) parent);
2128                         output.StringsIndex(nameIx);
2129                         output.StringsIndex(nameSpaceIx);
2130                 }
2131
2132                 internal override sealed uint TypeDefOrRefToken() 
2133                 {
2134                         uint cIx = Row;
2135                         cIx = (cIx << 2) | 0x1;
2136                         return cIx;
2137                 }
2138
2139                 internal override void TypeSig(MemoryStream sig) 
2140                 {
2141                         sig.WriteByte(GetTypeIndex());
2142                         MetaData.CompressNum(TypeDefOrRefToken(),sig);
2143                 }
2144
2145                 internal sealed override uint GetCodedIx(CIx code) 
2146                 {
2147                         switch (code) {
2148                                 case (CIx.TypeDefOrRef) : return 1; 
2149                                 case (CIx.HasCustomAttr) : return 2; 
2150                                 case (CIx.MemberRefParent) : return 1; 
2151                                 case (CIx.ResolutionScope) : return 3; 
2152                         }
2153                         return 0;
2154                 }
2155
2156         }
2157
2158         /**************************************************************************/  
2159         public class ExternClassRef : ClassRef {
2160
2161                 ExternClass externClass;
2162
2163                 internal ExternClassRef(TypeAttr attrs, string nsName, string name,
2164                                 MetaDataElement declRef, MetaData md) : base(nsName,name,md) 
2165                 {
2166                         externClass = new ExternClass(attrs,nameSpaceIx,nameIx,declRef);
2167                         metaData.AddToTable(MDTable.ExportedType,externClass);
2168                 }
2169
2170                 internal ExternClassRef(string name, MetaData md) : base(null,name,md) 
2171                 {
2172                 }
2173
2174                 public ClassRef AddNestedClass(TypeAttr attrs, string name) 
2175                 {
2176                         ExternClassRef nestedClass = new ExternClassRef(name,metaData);
2177                         externClass = new ExternClass(attrs,0,nameIx,this.externClass);
2178                         metaData.AddToTable(MDTable.ExportedType,externClass);
2179                         return nestedClass;
2180                 }
2181
2182         }
2183
2184         /**************************************************************************/  
2185         /// <summary>
2186         /// Descriptor for a class defined in another module of THIS assembly 
2187         /// and exported (.class extern)
2188         /// </summary>
2189
2190         internal class ExternClass : Class {
2191
2192                 MetaDataElement parent;
2193                 uint flags;
2194
2195                 internal ExternClass(TypeAttr attr, uint nsIx, uint nIx, 
2196                                 MetaDataElement paren) : base(nsIx,nIx) 
2197                 {
2198                         flags = (uint)attr;
2199                         parent = paren;
2200                         tabIx = MDTable.ExportedType;
2201                 }
2202
2203                 internal sealed override uint Size(MetaData md) 
2204                 {
2205                         return 8 + 2* md.StringsIndexSize() + md.CodedIndexSize(CIx.Implementation);
2206                 }
2207
2208                 internal sealed override void Write(FileImage output) 
2209                 {
2210                         output.Write(flags);
2211                         output.Write(0);
2212                         output.StringsIndex(nameIx);
2213                         output.StringsIndex(nameSpaceIx);
2214                         output.WriteCodedIndex(CIx.Implementation,parent);
2215                 }
2216
2217                 internal sealed override uint GetCodedIx(CIx code) 
2218                 {
2219                         switch (code) {
2220                                 case (CIx.HasCustomAttr) : return 17; 
2221                                 case (CIx.Implementation) : return 2; 
2222                         }
2223                         return 0;
2224                 }
2225
2226         }
2227
2228         public class GenParam : Class {
2229
2230                 private int index;
2231                 private string param_name;
2232                 private uint sigIx = 0;
2233
2234                 public GenParam (int index, string name, GenParamType ptype) : base ((byte) ptype) 
2235                 {
2236                         this.index = index;
2237                         this.param_name = name;
2238                         tabIx = MDTable.TypeSpec;
2239                 }
2240
2241                 public int Index {
2242                         get { return index; }
2243                         set { index = value; }
2244                 }
2245
2246                 public string Name {
2247                         get { return param_name; }
2248                         set { param_name = value; }
2249                 }
2250
2251                 public GenParamType Type {
2252                         get { return (GenParamType) GetTypeIndex (); }
2253                 }
2254                 
2255                 internal sealed override void BuildTables (MetaData md)
2256                 {
2257                         if (done)
2258                                 return;
2259                         MemoryStream str = new MemoryStream ();
2260                         TypeSig (str);
2261                         sigIx = md.AddToBlobHeap (str.ToArray ());
2262
2263                         done = true;
2264                 }
2265
2266                 internal sealed override void TypeSig(MemoryStream str) 
2267                 {
2268                         if (index < 0)
2269                                 throw new PEFileException (String.Format ("Unresolved {0} - {1}", (GenParamType) GetTypeIndex (), param_name));
2270                         str.WriteByte(typeIndex);
2271                         MetaData.CompressNum ((uint) index, str);
2272                 }
2273                 
2274                 internal override uint Size(MetaData md) 
2275                 {
2276                         return md.BlobIndexSize();
2277                 }
2278
2279                 internal sealed override void Write (FileImage output)
2280                 {
2281                         output.BlobIndex (sigIx);       
2282                 }
2283
2284                 internal sealed override uint GetCodedIx(CIx code) 
2285                 {
2286                         switch (code) {
2287                                 case (CIx.TypeDefOrRef) : return 2; 
2288                                 case (CIx.HasCustomAttr) : return 13; 
2289                                 case (CIx.MemberRefParent) : return 4; 
2290                         }
2291                         return 0;
2292                 }
2293         }
2294
2295         public class GenericTypeInst : Class {
2296
2297                 private Type gen_type;
2298                 private Type[] gen_param;
2299                 bool inTable = false;
2300                 uint sigIx = 0;
2301
2302                 public GenericTypeInst (Type gen_type, Type[] gen_param) 
2303                         : base ((byte) PrimitiveType.GenericInst.GetTypeIndex ())
2304                 {
2305                         this.gen_type = gen_type;
2306                         this.gen_param = gen_param;
2307                         tabIx = MDTable.TypeSpec;
2308                 }
2309
2310                 internal override MetaDataElement GetTypeSpec (MetaData md)
2311                 {
2312                         if (!inTable) {
2313                                 md.AddToTable (MDTable.TypeSpec, this);
2314                                 inTable = true;
2315                         }
2316
2317                         return this;
2318                 }
2319
2320                 internal sealed override void TypeSig(MemoryStream str) 
2321                 {
2322                         str.WriteByte(typeIndex);
2323                         gen_type.TypeSig (str);
2324                         MetaData.CompressNum ((uint) gen_param.Length, str);
2325                         foreach (Type param in gen_param)
2326                                 param.TypeSig (str);
2327                 }
2328
2329                 internal sealed override void BuildTables (MetaData md)
2330                 {
2331                         if (done)
2332                                 return;
2333                         MemoryStream str = new MemoryStream ();
2334                         TypeSig (str);
2335                         sigIx = md.AddToBlobHeap (str.ToArray ());
2336
2337                         done = true;
2338                 }
2339
2340                 internal sealed override uint Size (MetaData md)
2341                 {
2342                         return md.BlobIndexSize ();
2343                 }
2344
2345                 internal sealed override void Write (FileImage output)
2346                 {
2347                         output.BlobIndex (sigIx);       
2348                 }
2349
2350                 internal sealed override uint GetCodedIx (CIx code)
2351                 {
2352                         switch (code) {
2353                                 case (CIx.TypeDefOrRef): return 2;
2354                                 case (CIx.MemberRefParent): return 4;
2355                                 case (CIx.HasCustomAttr): return 13;
2356                         }
2357                         return 0;
2358                 }
2359         }
2360
2361         public class GenericMethodSig {
2362
2363                 private Type[] gen_param;
2364                 private bool done;
2365                 private uint sigIx = 0;
2366
2367                 public GenericMethodSig (Type[] gen_param)
2368                 {
2369                         this.gen_param = gen_param;
2370                         done = false;
2371                 }
2372
2373                 internal void TypeSig (MemoryStream str)
2374                 {
2375                         str.WriteByte (0x0A); /* GENERIC_INST */
2376                         MetaData.CompressNum ((uint) gen_param.Length, str);
2377                         foreach (Type param in gen_param)
2378                                 param.TypeSig (str);
2379                 }
2380
2381                 internal uint GetSigIx (MetaData md)
2382                 {
2383                         if (done)
2384                                 return sigIx;
2385
2386                         MemoryStream sig = new MemoryStream();
2387                         TypeSig (sig);
2388                         sigIx = md.AddToBlobHeap (sig.ToArray());
2389                         done = true;
2390                         return sigIx;
2391                 }
2392         }
2393
2394         public class Sentinel : Type {
2395
2396                 public Sentinel () : base (0x41) { }
2397
2398                 internal sealed override void TypeSig(MemoryStream str) 
2399                 {
2400                         str.WriteByte(typeIndex);
2401                 }
2402         }
2403
2404         /**************************************************************************/  
2405         /// <summary>
2406         /// Descriptor for a FunctionPointer type
2407         /// </summary>
2408         /// 
2409         public class MethPtrType : Type {
2410
2411                 bool varArgMeth;
2412                 Type retType;
2413                 Type [] parList;
2414                 Type [] optParList;
2415                 CallConv callConv;
2416                 uint numPars;
2417                 uint numOptPars;
2418                 uint sigIx = 0;
2419
2420                 /// <summary>
2421                 /// Create a new function pointer type
2422                 /// </summary>
2423                 /// <param name="meth">the function to be referenced</param>
2424                 public MethPtrType (CallConv callconv, Type retType, Type[] pars,
2425                                 bool varArgMeth, Type[] optPars) : base(0x1B) 
2426                 {
2427                         this.retType = retType;
2428                         callConv = callconv;
2429                         parList = pars;
2430                         this.varArgMeth = varArgMeth;
2431                         if (parList != null) numPars = (uint)parList.Length;
2432                         if (varArgMeth) {
2433                                 optParList = optPars;
2434                                 if (optParList != null) numOptPars = (uint)optParList.Length;
2435                                 callConv |= CallConv.Vararg;
2436                         }
2437                         tabIx = MDTable.TypeSpec;
2438                 }
2439
2440                 internal sealed override void TypeSig(MemoryStream sig) 
2441                 {
2442                         sig.WriteByte(typeIndex);
2443                         // Bootlegged from method ref
2444                         sig.WriteByte((byte)callConv);
2445                         MetaData.CompressNum (numPars + numOptPars, sig);
2446                         retType.TypeSig (sig);
2447                         for (int i=0; i < numPars; i++) {
2448                                 parList[i].TypeSig (sig);
2449                         }
2450                         if (varArgMeth) {
2451                                 sig.WriteByte (0x41); // Write the sentinel
2452                                 for (int i=0; i < numOptPars; i++) {
2453                                         optParList[i].TypeSig (sig);
2454                                 }
2455                         }
2456                 }
2457
2458                 internal sealed override void BuildTables(MetaData md) 
2459                 {
2460                         if (done) return;
2461                         MemoryStream sig = new MemoryStream();
2462                         TypeSig(sig);
2463                         sigIx = md.AddToBlobHeap(sig.ToArray());
2464                         done = true;
2465                 }
2466
2467                 internal sealed override uint Size(MetaData md) 
2468                 {
2469                         return md.BlobIndexSize();
2470                 }
2471
2472                 internal sealed override void Write(FileImage output) 
2473                 {
2474                         output.BlobIndex(sigIx);
2475                 }
2476
2477                 internal sealed override uint GetCodedIx(CIx code) { return 0x1B; }
2478
2479         }
2480
2481         #region Array Types
2482         /* Classes for Arrays */
2483
2484         /// <summary>
2485         /// The IL Array type
2486         /// </summary>
2487         public abstract class Array : Type {
2488
2489                 protected Type elemType;
2490                 protected MetaData metaData;
2491                 protected string cnameSpace, cname;
2492
2493                 internal Array(Type eType, byte TypeId) : base(TypeId) 
2494                 {
2495                         elemType = eType;
2496                         tabIx = MDTable.TypeSpec;
2497                 }
2498         }
2499
2500         /// <summary>
2501         /// Single dimensional array with zero lower bound
2502         /// </summary>
2503         public class ZeroBasedArray : Array {
2504
2505                 /// <summary>
2506                 /// Create a new array  -   elementType[]
2507                 /// </summary>
2508                 /// <param name="elementType">the type of the array elements</param>
2509                 public ZeroBasedArray(Type elementType) : base (elementType, PrimitiveType.SZArray.GetTypeIndex ()) { }
2510
2511                 internal sealed override void TypeSig(MemoryStream str) 
2512                 {
2513                         str.WriteByte(typeIndex);
2514                         elemType.TypeSig(str); 
2515                 }
2516
2517         }
2518
2519         /// <summary>
2520         /// Multi dimensional array with explicit bounds
2521         /// </summary>
2522         public class BoundArray : Array {
2523                 int[] lowerBounds;
2524                 int[] sizes;
2525                 uint numDims;
2526
2527                 /// <summary>
2528                 /// Create a new multi dimensional array type 
2529                 /// eg. elemType[1..5,3..10,5,,] would be 
2530                 /// new BoundArray(elemType,5,[1,3,0],[5,10,4])
2531                 /// </summary>
2532                 /// <param name="elementType">the type of the elements</param>
2533                 /// <param name="dimensions">the number of dimensions</param>
2534                 /// <param name="loBounds">lower bounds of dimensions</param>
2535                 /// <param name="sizes">sizes for the dimensions</param>
2536                 public BoundArray(Type elementType, uint dimensions, int[] loBounds, 
2537                                 int[] sizes) : base (elementType,0x14) 
2538                 {
2539                         numDims = dimensions;
2540                         lowerBounds = loBounds;
2541                         this.sizes = sizes;
2542                 }
2543
2544                 /// <summary>
2545                 /// Create a new multi dimensional array type 
2546                 /// eg. elemType[5,10,20] would be new BoundArray(elemType,3,[5,10,20])
2547                 /// </summary>
2548                 /// <param name="elementType">the type of the elements</param>
2549                 /// <param name="dimensions">the number of dimensions</param>
2550                 /// <param name="size">the sizes of the dimensions</param>
2551                 public BoundArray(Type elementType, uint dimensions, int[] size) 
2552                         : base (elementType,0x14) 
2553                 {
2554                         numDims = dimensions;
2555                         sizes = size;
2556                 }
2557
2558                 /// <summary>
2559                 /// Create a new multi dimensional array type 
2560                 /// eg. elemType[,,] would be new BoundArray(elemType,3)
2561                 /// </summary>
2562                 /// <param name="elementType">the type of the elements</param>
2563                 /// <param name="dimensions">the number of dimensions</param>
2564                 public BoundArray(Type elementType, uint dimensions)
2565                         : base (elementType,0x14) 
2566                 {
2567                         numDims = dimensions;
2568                 }
2569
2570                 internal sealed override void TypeSig(MemoryStream str) 
2571                 {
2572                         str.WriteByte(typeIndex);
2573                         elemType.TypeSig(str);
2574                         MetaData.CompressNum(numDims,str);
2575                         if ((sizes != null) && (sizes.Length > 0))  {
2576
2577                                 MetaData.CompressNum((uint)sizes.Length,str);
2578                                 for (int i=0; i < sizes.Length; i++) {
2579                                         MetaData.CompressNum((uint)sizes[i],str);
2580                                 }
2581                         } else str.WriteByte(0);
2582                         if ((lowerBounds != null) && (lowerBounds.Length > 0)) {
2583                                 MetaData.CompressNum((uint)lowerBounds.Length,str);
2584                                 for (int i=0; i < lowerBounds.Length; i++) {
2585                                         CompressSignedNum (lowerBounds[i],str);
2586                                 }
2587                         } else str.WriteByte(0);
2588                 }
2589                 private void CompressSignedNum (int val, MemoryStream str)
2590                 {
2591                         uint uval = (uint) val;
2592                         byte sign = 0;
2593                         if (val < 0) {
2594                                 val = -val;
2595                                 sign = 1;
2596                         }
2597
2598                         /* Map the signed number to an unsigned number in two ways.
2599
2600                              fval: left-rotated 2's complement representation
2601                              sval: map the signed number to unsigned as follows: 0 -> 0, -1 -> 1, 1 -> 2, -2 -> 3, 2 -> 4, ....
2602                                    the mapping is: x -> 2*|x| - signbit(x)
2603                         */
2604                         uint fval = (uval << 1) | sign;
2605                         int sval = (val  << 1) - sign;
2606
2607                         /* An overly clever transformation: 
2608
2609                            a. sval is used to determine the number of bytes in the compressed representation.
2610                            b. fval is truncated to the appropriate number of bits and output using the 
2611                               normal unsigned-int compressor.
2612
2613                            However, or certain values, the truncated fval doesn't carry enough information to round trip.
2614
2615                                 (fval & 0x3FFF) <= 0x7F => compressor emits 1 byte, not 2 => there is aliasing of values
2616
2617                            So, we use full 4 bytes to encode such values.
2618
2619                            LAMESPEC: The Microsoft implementation doesn't appear to handle this subtle case.
2620                                      e.g., it ends up encoding -8192 as the byte 0x01, which decodes to -64
2621                         */
2622                         if (sval <= 0x7F)
2623                                 MetaData.CompressNum (fval & 0x7F, str);
2624                         else if (sval <= 0x3FFF && (fval & 0x3FFF) > 0x7F)
2625                                 MetaData.CompressNum (fval & 0x3FFF, str);
2626                         else if (sval <= 0x1FFFFFFF && (fval & 0x1FFFFFFF) > 0x3FFF)
2627                                 MetaData.CompressNum (fval & 0x1FFFFFFF, str);
2628                         else
2629                                 /* FIXME: number cannot be represented.  Report a warning.  */
2630                                 // throw new Exception ("cannot represent signed value" + -val);
2631                                 MetaData.CompressNum (fval, str);
2632                 }
2633         }
2634
2635         #endregion
2636
2637
2638         /* Empty interface for grouping TypeRef's possible ResolutionScope
2639            namely : Module, ModuleRef, AssemblyRef and TypeRef */
2640         public interface IResolutionScope  {
2641         }
2642
2643         /**************************************************************************/  
2644         /// <summary>
2645         /// Base class for scopes (extended by Module, ModuleRef, Assembly, AssemblyRef)
2646         /// </summary>
2647         public abstract class ResolutionScope : MetaDataElement, IResolutionScope {
2648
2649                 protected uint nameIx = 0;
2650                 protected MetaData metaData;
2651                 protected string name;
2652
2653                 internal ResolutionScope(string name, MetaData md)
2654                 {
2655                         metaData = md;
2656                         this.name = name;
2657                         nameIx = md.AddToStringsHeap(name);
2658                 }
2659
2660                 internal string GetName() { return name; }
2661
2662         }
2663
2664         /**************************************************************************/  
2665         /// <summary>
2666         /// Descriptor for THIS assembly (.assembly)
2667         /// </summary>
2668         public class Assembly : ResolutionScope  {
2669
2670                 ushort majorVer, minorVer, buildNo, revisionNo;
2671                 uint flags;
2672                 uint hashAlgId;
2673                 uint keyIx = 0, cultIx = 0;
2674                 bool hasPublicKey = false;
2675
2676                 internal Assembly(string name, MetaData md) : base(name,md) 
2677                 {
2678                         tabIx = MDTable.Assembly;
2679                 }
2680
2681                 /// <summary>
2682                 /// Add details about THIS assembly
2683                 /// </summary>
2684                 /// <param name="majVer">Major Version</param>
2685                 /// <param name="minVer">Minor Version</param>
2686                 /// <param name="bldNo">Build Number</param>
2687                 /// <param name="revNo">Revision Number</param>
2688                 /// <param name="key">Hash Key</param>
2689                 /// <param name="hash">Hash Algorithm</param>
2690                 /// <param name="cult">Culture</param>
2691                 public void AddAssemblyInfo(int majVer, int minVer, int bldNo, int revNo, 
2692                                 byte[] key, uint hash, string cult) 
2693                 {
2694                         majorVer = (ushort)majVer;
2695                         minorVer = (ushort)minVer;
2696                         buildNo = (ushort)bldNo;
2697                         revisionNo = (ushort)revNo;
2698                         hashAlgId = hash;
2699                         hasPublicKey = (key != null);
2700                         keyIx = metaData.AddToBlobHeap(key);
2701                         cultIx = metaData.AddToStringsHeap(cult);
2702                 }
2703
2704                 /// <summary>
2705                 /// Add an attribute to THIS assembly
2706                 /// </summary>
2707                 /// <param name="aa">assembly attribute</param>
2708                 public void AddAssemblyAttr(AssemAttr aa) 
2709                 {
2710                         flags |= (uint)aa;
2711                 }
2712
2713                 internal sealed override uint Size(MetaData md) 
2714                 {
2715                         return 16 + md.BlobIndexSize() + 2 * md.StringsIndexSize();
2716                 }
2717
2718                 internal sealed override void Write(FileImage output) 
2719                 {
2720                         //      Console.WriteLine("Writing assembly element with nameIx of " + nameIx + " at file offset " + output.Seek(0,SeekOrigin.Current));
2721                         output.Write((uint)hashAlgId);
2722                         output.Write(majorVer);
2723                         output.Write(minorVer);
2724                         output.Write(buildNo);
2725                         output.Write(revisionNo);
2726                         output.Write(flags);
2727                         output.BlobIndex(keyIx);
2728                         output.StringsIndex(nameIx);
2729                         output.StringsIndex(cultIx);
2730                 }
2731
2732                 internal sealed override uint GetCodedIx(CIx code) 
2733                 {
2734                         switch (code) {
2735                                 case (CIx.HasCustomAttr) : return 14; 
2736                                 case (CIx.HasDeclSecurity) : return 2; 
2737                         }
2738                         return 0;
2739                 }
2740
2741                 internal bool HasPublicKey {
2742                         get { return hasPublicKey; }
2743                 }
2744         }
2745
2746         /**************************************************************************/  
2747         /// <summary>
2748         /// Descriptor for THIS module
2749         /// </summary>
2750         public class Module : ResolutionScope, IExternRef {
2751
2752                 Guid mvid;
2753                 uint mvidIx = 0;
2754
2755                 internal Module(string name, MetaData md) : base(name,md)       
2756                 {
2757                         mvid = Guid.NewGuid();
2758                         mvidIx = md.AddToGUIDHeap(mvid);
2759                         tabIx = MDTable.Module;
2760                 }
2761
2762                 public Guid Guid {
2763                         get { return mvid; }
2764                 }
2765
2766                 public ClassRef AddClass(string nsName, string name) 
2767                 {
2768                         ClassRef aClass = new ClassRef (nsName, name, metaData);
2769                         metaData.AddToTable (MDTable.TypeRef, aClass);
2770                         aClass.SetParent (this);
2771                         return aClass;
2772                 }
2773
2774                 public ClassRef AddValueClass(string nsName, string name) 
2775                 {
2776                         ClassRef aClass = AddClass (nsName, name);
2777                         aClass.MakeValueClass (ValueClass.ValueType);
2778                         return aClass;
2779                 }
2780
2781                 internal sealed override uint Size(MetaData md) 
2782                 {
2783                         return 2 + md.StringsIndexSize() + 3 * md.GUIDIndexSize();
2784                 }
2785
2786                 internal sealed override void Write(FileImage output) 
2787                 {
2788                         output.Write((short)0);
2789                         output.StringsIndex(nameIx);
2790                         output.GUIDIndex(mvidIx);
2791                         output.GUIDIndex(0);
2792                         output.GUIDIndex(0);
2793                 }
2794
2795                 internal sealed override uint GetCodedIx(CIx code) 
2796                 {
2797                         switch (code) {
2798                                 case (CIx.HasCustomAttr) : return 7; 
2799                                 case (CIx.ResolutionScope) : return 0;
2800                         }
2801                         return 0;
2802                 }
2803         }
2804         /**************************************************************************/  
2805         /// <summary>
2806         /// Descriptor for another module in THIS assembly
2807         /// </summary>
2808         public class ModuleRef : ResolutionScope, IExternRef {
2809
2810                 internal ModuleRef(MetaData md, string name) : base(name,md) 
2811                 {
2812                         tabIx = MDTable.ModuleRef;
2813                 }
2814
2815                 /// <summary>
2816                 /// Add a class to this external module.  This is a class declared in
2817                 /// another module of THIS assembly.
2818                 /// </summary>
2819                 /// <param name="nsName">name space name</param>
2820                 /// <param name="name">class name</param>
2821                 /// <returns>a descriptor for this class in another module</returns>
2822                 public ClassRef AddClass(string nsName, string name) 
2823                 {
2824                         ClassRef aClass = new ClassRef(nsName,name,metaData);
2825                         metaData.AddToTable(MDTable.TypeRef,aClass);
2826                         aClass.SetParent(this);
2827                         return aClass;
2828                 }
2829
2830                 /// <summary>
2831                 /// Make a file descriptor to correspond to this module.  The file
2832                 /// descriptor will have the same name as the module descriptor
2833                 /// </summary>
2834                 /// <param name="hashBytes">the hash of the file</param>
2835                 /// <param name="hasMetaData">the file contains metadata</param>
2836                 /// <param name="entryPoint">the program entry point is in this file</param>
2837                 /// <returns>a descriptor for the file which contains this module</returns>
2838                 public FileRef MakeFile(byte[] hashBytes, bool hasMetaData, bool entryPoint) 
2839                 {
2840                         FileRef file = new FileRef(nameIx,hashBytes,hasMetaData,entryPoint,metaData);
2841                         metaData.AddToTable(MDTable.File,file);
2842                         return file;
2843                 }
2844
2845                 /// <summary>
2846                 /// Add a value class to this module.  This is a class declared in
2847                 /// another module of THIS assembly.
2848                 /// </summary>
2849                 /// <param name="nsName">name space name</param>
2850                 /// <param name="name">class name</param>
2851                 /// <returns></returns>
2852                 public ClassRef AddValueClass(string nsName, string name) 
2853                 {
2854                         ClassRef aClass = new ClassRef(nsName,name,metaData);
2855                         metaData.AddToTable(MDTable.TypeRef,aClass);
2856                         aClass.SetParent(this);
2857                         aClass.MakeValueClass(ValueClass.ValueType);
2858                         return aClass;
2859                 }
2860
2861                 /// <summary>
2862                 /// Add a class which is declared public in this external module of
2863                 /// THIS assembly.  This class will be exported from this assembly.
2864                 /// The ilasm syntax for this is .extern class
2865                 /// </summary>
2866                 /// <param name="attrSet">attributes of the class to be exported</param>
2867                 /// <param name="nsName">name space name</param>
2868                 /// <param name="name">external class name</param>
2869                 /// <param name="declFile">the file where the class is declared</param>
2870                 /// <param name="isValueClass">is this class a value type?</param>
2871                 /// <returns>a descriptor for this external class</returns>
2872                 public ExternClassRef AddExternClass(TypeAttr attrSet, string nsName, 
2873                                 string name, FileRef declFile, 
2874                                 bool isValueClass) {
2875                         ExternClassRef cRef = new ExternClassRef(attrSet,nsName,name,declFile,metaData);
2876                         metaData.AddToTable(MDTable.TypeRef,cRef);
2877                         cRef.SetParent(this);
2878                         if (isValueClass) cRef.MakeValueClass(ValueClass.ValueType);
2879                         return cRef;
2880                 }
2881
2882                 /// <summary>
2883                 /// Add a "global" method in another module
2884                 /// </summary>
2885                 /// <param name="name">method name</param>
2886                 /// <param name="retType">return type</param>
2887                 /// <param name="pars">method parameter types</param>
2888                 /// <returns>a descriptor for this method in anther module</returns>
2889                 public MethodRef AddMethod(string name, Type retType, Type[] pars) 
2890                 {
2891                         MethodRef meth = new MethodRef(this,name,retType,pars,false,null, 0);
2892                         metaData.AddToTable(MDTable.MemberRef,meth);
2893                         return meth;
2894                 }
2895
2896                 /// <summary>
2897                 /// Add a vararg method to this class
2898                 /// </summary>
2899                 /// <param name="name">method name</param>
2900                 /// <param name="retType">return type</param>
2901                 /// <param name="pars">parameter types</param>
2902                 /// <param name="optPars">optional param types for this vararg method</param>
2903                 /// <returns>a descriptor for this method</returns>
2904                 public MethodRef AddVarArgMethod(string name, Type retType, 
2905                                 Type[] pars, Type[] optPars) {
2906                         MethodRef meth = new MethodRef(this,name,retType,pars,true,optPars, 0);
2907                         metaData.AddToTable(MDTable.MemberRef,meth);
2908                         return meth;
2909                 }
2910
2911                 /// <summary>
2912                 /// Add a field in another module
2913                 /// </summary>
2914                 /// <param name="name">field name</param>
2915                 /// <param name="fType">field type</param>
2916                 /// <returns>a descriptor for this field in another module</returns>
2917                 public FieldRef AddField(string name, Type fType) 
2918                 {
2919                         FieldRef field = new FieldRef(this,name,fType);
2920                         metaData.AddToTable(MDTable.MemberRef,field);
2921                         return field;
2922                 }
2923
2924                 internal sealed override uint Size(MetaData md) 
2925                 {
2926                         return md.StringsIndexSize();
2927                 }
2928
2929                 internal sealed override void Write(FileImage output) 
2930                 {
2931                         output.StringsIndex(nameIx);
2932                 }
2933
2934                 internal sealed override uint GetCodedIx(CIx code) 
2935                 {
2936                         switch (code) {
2937                                 case (CIx.HasCustomAttr) : return 12; 
2938                                 case (CIx.MemberRefParent) : return 2; 
2939                                 case (CIx.ResolutionScope) : return 1; 
2940                         }
2941                         return 0;
2942                 }
2943
2944         }
2945
2946         #region Classes for Constants
2947         /// <summary>
2948         /// Descriptor for a constant value
2949         /// </summary>
2950         public abstract class Constant {
2951                 protected uint size = 0;
2952                 protected Type type;
2953                 protected uint blobIndex;
2954                 protected bool addedToBlobHeap = false;
2955
2956                 internal Constant() { }
2957
2958                 internal virtual uint GetBlobIndex(MetaData md) { return 0; }
2959
2960                 internal uint GetSize() { return size; }
2961
2962                 internal byte GetTypeIndex() { return type.GetTypeIndex(); }
2963
2964                 internal virtual void Write(BinaryWriter bw) {  }
2965
2966         }
2967         /// <summary>
2968         /// Descriptor for a constant value
2969         /// </summary>
2970         public abstract class DataConstant : Constant {
2971                 private uint dataOffset = 0;
2972
2973                 internal DataConstant() { }
2974
2975                 public uint DataOffset {
2976                         get { return dataOffset; }
2977                         set { dataOffset = value; }
2978                 }
2979
2980         }
2981
2982         /// <summary>
2983         /// Boolean constant
2984         /// </summary>
2985         public class BoolConst : DataConstant {
2986                 bool val;
2987
2988                 /// <summary>
2989                 /// Create a new boolean constant with the value "val"
2990                 /// </summary>
2991                 /// <param name="val">value of this boolean constant</param>
2992                 public BoolConst(bool val) 
2993                 {
2994                         this.val = val;
2995                         size = 1;
2996                         type = PrimitiveType.Boolean;
2997                 }
2998
2999                 internal sealed override uint GetBlobIndex(MetaData md) 
3000                 {
3001                         if (!addedToBlobHeap) {
3002                                 if (val) blobIndex = md.AddToBlobHeap((sbyte)1);
3003                                 else blobIndex = md.AddToBlobHeap((sbyte)0);
3004                                 addedToBlobHeap = true;
3005                         }
3006                         return blobIndex;
3007                 }
3008
3009                 internal sealed override void Write(BinaryWriter bw) 
3010                 {
3011                         if (val) bw.Write((sbyte)1);
3012                         else bw.Write((sbyte)0);
3013                 }
3014
3015         }
3016
3017         public class ByteArrConst : DataConstant {
3018                 internal byte[] val;
3019
3020                 public ByteArrConst(byte[] val) 
3021                 {
3022                         type = PrimitiveType.String;
3023                         this.val = val;
3024                         size = (uint)val.Length;
3025                 }
3026
3027                 public Type Type {
3028                         get { return type; }
3029                         set { type = value; }
3030                 }
3031
3032                 internal sealed override uint GetBlobIndex(MetaData md) 
3033                 {
3034                         if (!addedToBlobHeap) {
3035                                 blobIndex = md.AddToBlobHeap(val);
3036                                 addedToBlobHeap = true;
3037                         }
3038                         return blobIndex;
3039                 }
3040
3041                 internal sealed override void Write(BinaryWriter bw) 
3042                 {
3043                         bw.Write(val);
3044                 }
3045
3046         }
3047
3048         public class CharConst : Constant {
3049                 char val;
3050
3051                 public CharConst(char val) 
3052                 {
3053                         this.val = val;
3054                         size = 2;
3055                         type = PrimitiveType.Char;
3056                 }
3057
3058                 internal sealed override uint GetBlobIndex(MetaData md) 
3059                 {
3060                         if (!addedToBlobHeap) {
3061                                 blobIndex = md.AddToBlobHeap(val);
3062                                 addedToBlobHeap = true;
3063                         }
3064                         return blobIndex;
3065                 }
3066
3067                 internal sealed override void Write(BinaryWriter bw) 
3068                 {
3069                         bw.Write(val);
3070                 }
3071
3072         }
3073
3074         public class FloatConst : DataConstant {
3075                 float val;
3076
3077                 public FloatConst(float val) 
3078                 {
3079                         this.val = val;
3080                         size = 4;
3081                         type = PrimitiveType.Float32;
3082                 }
3083
3084                 internal sealed override uint GetBlobIndex(MetaData md) 
3085                 {
3086                         if (!addedToBlobHeap) {
3087                                 blobIndex = md.AddToBlobHeap(val);
3088                                 addedToBlobHeap = true;
3089                         }
3090                         return blobIndex;
3091                 }
3092
3093                 internal sealed override void Write(BinaryWriter bw) 
3094                 {
3095                         bw.Write(val);
3096                 }
3097
3098         }
3099
3100         public class DoubleConst : DataConstant {
3101                 double val;
3102
3103                 public DoubleConst(double val) 
3104                 {
3105                         this.val = val;
3106                         size = 8;
3107                         type = PrimitiveType.Float64;
3108                 }
3109
3110                 internal sealed override uint GetBlobIndex(MetaData md) 
3111                 {
3112                         if (!addedToBlobHeap) {
3113                                 blobIndex = md.AddToBlobHeap(val);
3114                                 addedToBlobHeap = true;
3115                         }
3116                         return blobIndex;
3117                 }
3118
3119                 internal sealed override void Write(BinaryWriter bw) 
3120                 {
3121                         bw.Write(val);
3122                 }
3123
3124         }
3125
3126         public class IntConst : DataConstant {
3127                 long val;
3128
3129                 public IntConst(sbyte val) 
3130                 {
3131                         this.val = val;
3132                         size = 1;
3133                         type = PrimitiveType.Int8;
3134                 }
3135
3136                 public IntConst(short val) 
3137                 {
3138                         this.val = val;
3139                         size = 2;
3140                         type = PrimitiveType.Int16;
3141                 }
3142
3143                 public IntConst(int val) 
3144                 {
3145                         this.val = val;
3146                         size = 4;
3147                         type = PrimitiveType.Int32;
3148                 }
3149
3150                 public IntConst(long val) 
3151                 {
3152                         this.val = val;
3153                         size = 8;
3154                         type = PrimitiveType.Int64;
3155                 }
3156
3157                 internal sealed override uint GetBlobIndex(MetaData md) 
3158                 {
3159                         if (!addedToBlobHeap) {
3160                                 switch (size) {
3161                                         case (1) : blobIndex = md.AddToBlobHeap((sbyte)val); break;
3162                                         case (2) : blobIndex = md.AddToBlobHeap((short)val); break;
3163                                         case (4) : blobIndex = md.AddToBlobHeap((int)val); break;
3164                                         default : blobIndex = md.AddToBlobHeap(val); break; 
3165                                 }
3166                                 addedToBlobHeap = true;
3167                         }
3168                         return blobIndex;
3169                 }
3170
3171                 internal sealed override void Write(BinaryWriter bw) 
3172                 {
3173                         switch (size) {
3174                                 case (1) : bw.Write((sbyte)val); break;
3175                                 case (2) : bw.Write((short)val); break;
3176                                 case (4) : bw.Write((int)val); break;
3177                                 default : bw.Write(val); break; 
3178                         }
3179                 }
3180
3181         }
3182
3183         public class UIntConst : DataConstant {
3184                 ulong val;
3185
3186                 public UIntConst(byte val) 
3187                 {
3188                         this.val = val;
3189                         size = 1;
3190                         type = PrimitiveType.UInt8;
3191                 }
3192                 public UIntConst(ushort val) 
3193                 {
3194                         this.val = val;
3195                         size = 2;
3196                         type = PrimitiveType.UInt16;
3197                 }
3198                 public UIntConst(uint val) 
3199                 {
3200                         this.val = val;
3201                         size = 4;
3202                         type = PrimitiveType.UInt32;
3203                 }
3204                 public UIntConst(ulong val) 
3205                 {
3206                         this.val = val;
3207                         size = 8;
3208                         type = PrimitiveType.UInt64;
3209                 }
3210
3211                 internal sealed override uint GetBlobIndex(MetaData md) 
3212                 {
3213                         if (!addedToBlobHeap) {
3214                                 switch (size) {
3215                                         case (1) : blobIndex = md.AddToBlobHeap((byte)val); break;
3216                                         case (2) : blobIndex = md.AddToBlobHeap((ushort)val); break;
3217                                         case (4) : blobIndex = md.AddToBlobHeap((uint)val); break;
3218                                         default : blobIndex = md.AddToBlobHeap(val); break;
3219                                 }
3220                                 addedToBlobHeap = true;
3221                         }
3222                         return blobIndex;
3223                 }
3224
3225                 internal sealed override void Write(BinaryWriter bw) 
3226                 {
3227                         switch (size) {
3228                                 case (1) : bw.Write((byte)val); break;
3229                                 case (2) : bw.Write((ushort)val); break;
3230                                 case (4) : bw.Write((uint)val); break;
3231                                 default : bw.Write(val); break;
3232                         }
3233                 }
3234
3235         }
3236
3237         public class StringConst : DataConstant {
3238                 internal string val;
3239
3240                 public StringConst(string val) 
3241                 {
3242                         this.val = val;
3243                         size = (uint)val.Length;  // need to add null ??
3244                         type = PrimitiveType.String;
3245                 }
3246
3247                 internal sealed override uint GetBlobIndex(MetaData md) 
3248                 {
3249                         if (!addedToBlobHeap) {
3250                                 byte [] b = Encoding.Unicode.GetBytes (val);
3251                                 blobIndex = md.AddToBlobHeap(b);
3252                                 addedToBlobHeap = true;
3253                         }
3254                         return blobIndex;
3255                 }
3256
3257                 internal sealed override void Write(BinaryWriter bw) 
3258                 {
3259                         bw.Write(val);
3260                 }
3261
3262         }
3263
3264         public class NullConst : Constant {
3265
3266                 public NullConst() 
3267                 {
3268                         size = 4;
3269                         type = PrimitiveType.Class;
3270                 }
3271
3272                 internal sealed override uint GetBlobIndex(MetaData md) 
3273                 {
3274                         if (!addedToBlobHeap) {
3275                                 blobIndex = md.AddToBlobHeap((int)0);
3276                                 addedToBlobHeap = true;
3277                         }
3278                         return blobIndex;
3279                 }
3280
3281                 internal sealed override void Write(BinaryWriter bw) 
3282                 {
3283                         bw.Write((int)0); 
3284                 }
3285
3286         }
3287
3288         public class AddressConstant : DataConstant {
3289                 DataConstant data;
3290
3291                 public AddressConstant(DataConstant dConst) 
3292                 {
3293                         data = dConst;
3294                         size = 4;
3295                         type = PrimitiveType.TypedRef;
3296                 }
3297
3298                 internal sealed override void Write(BinaryWriter bw) 
3299                 {
3300                         ((FileImage)bw).WriteDataRVA(data.DataOffset);
3301                 }
3302
3303         }
3304
3305         public class RepeatedConstant : DataConstant {
3306                 DataConstant data;
3307                 uint repCount;
3308
3309                 public RepeatedConstant(DataConstant dConst, int repeatCount) 
3310                 {
3311                         data = dConst;
3312                         repCount = (uint)repeatCount;
3313                         int[] sizes = new int[1];
3314                         sizes[0] = repeatCount;
3315                         type = new BoundArray(type,1,sizes);
3316                         size = data.GetSize() * repCount;
3317                 }
3318
3319                 internal sealed override void Write(BinaryWriter bw) 
3320                 {
3321                         for (int i=0; i < repCount; i++) {
3322                                 data.Write(bw);
3323                         }
3324                 }
3325
3326         }
3327
3328         public class ArrayConstant : DataConstant {
3329                 DataConstant[] dataVals;
3330
3331                 public ArrayConstant(DataConstant[] dVals) 
3332                 {
3333                         dataVals = dVals;
3334                         for (int i=0; i < dataVals.Length; i++) {
3335                                 size += dataVals[i].GetSize();
3336                         }
3337                 }
3338
3339                 public int? ExplicitSize { get; set; }
3340
3341                 internal sealed override void Write(BinaryWriter bw) 
3342                 {
3343                         for (int i=0; i < dataVals.Length; i++) {
3344                                 dataVals[i].Write(bw);
3345                         }
3346                 }
3347
3348         }
3349
3350         public class ClassType : Constant {
3351                 string name;
3352                 Class desc;
3353
3354                 public ClassType(string className) 
3355                 {
3356                         name = className;
3357                         type = PrimitiveType.ClassType;
3358                 }
3359
3360                 public ClassType(Class classDesc) 
3361                 {
3362                         desc = classDesc;
3363                         type = PrimitiveType.ClassType;
3364                 }
3365
3366                 internal override void Write(BinaryWriter bw) 
3367                 {
3368                         if (name == null)  name = desc.TypeName();
3369                         bw.Write(name);
3370                 }
3371
3372         }
3373
3374         #endregion
3375
3376         /**************************************************************************/  
3377         /// <summary>
3378         /// Descriptor for a custom modifier of a type (modopt or modreq)
3379         /// </summary>
3380
3381         public class CustomModifiedType : Type {
3382
3383                 Type type;
3384                 Class cmodType;
3385                 PrimitiveTypeRef cmodPrimType;
3386
3387                 /// <summary>
3388                 /// Create a new custom modifier for a type
3389                 /// </summary>
3390                 /// <param name="type">the type to be modified</param>
3391                 /// <param name="cmod">the modifier</param>
3392                 /// <param name="cmodType">the type reference to be associated with the type</param>
3393                 public CustomModifiedType(Type type, CustomModifier cmod, Class cmodType)
3394                         : base((byte)cmod) 
3395                 {
3396                         this.type = type;
3397                         this.cmodType = cmodType;
3398                 }
3399
3400                 public CustomModifiedType(Type type, CustomModifier cmod, PrimitiveTypeRef cmodType)
3401                         : base((byte)cmod)
3402                 {
3403                         this.type = type;
3404                         this.cmodPrimType = cmodType;
3405                 }
3406
3407                 internal sealed override void TypeSig(MemoryStream str) 
3408                 {
3409                         str.WriteByte(typeIndex);
3410
3411                         if (cmodType != null) {
3412                                 MetaData.CompressNum(cmodType.TypeDefOrRefToken(),str);
3413                         } else {
3414                                 MetaData.CompressNum(cmodPrimType.TypeDefOrRefToken(),str);
3415                         }
3416
3417                         type.TypeSig(str);
3418                 }
3419
3420         }
3421
3422         /**************************************************************************/  
3423         /// <summary>
3424         /// Base class for Event and Property descriptors
3425         /// </summary>
3426
3427         public class Feature : MetaDataElement {
3428
3429                 internal enum MethodType : ushort { Setter = 0x01, Getter, Other = 0x04, AddOn = 0x08, 
3430                         RemoveOn = 0x10, Fire = 0x20 }
3431
3432                 private static readonly int INITSIZE = 5;
3433                 private static readonly ushort specialName = 0x200;
3434                 private static readonly ushort rtSpecialName = 0x400;
3435
3436                 protected ClassDef parent;
3437                 protected ushort flags = 0;
3438                 protected string name;
3439                 protected int tide = 0;
3440                 protected uint nameIx;
3441                 protected MethodSemantics[] methods = new MethodSemantics[INITSIZE];
3442
3443                 internal Feature(string name, ClassDef par) 
3444                 {
3445                         parent = par;
3446                         this.name = name;
3447                 }
3448
3449                 internal void AddMethod(MethodDef meth, MethodType mType) 
3450                 {
3451                         if (tide >= methods.Length) { 
3452                                 int len = methods.Length;
3453                                 MethodSemantics[] mTmp = methods;
3454                                 methods = new MethodSemantics[len * 2];
3455                                 for (int i=0; i < len; i++) {
3456                                         methods[i] = mTmp[i];
3457                                 }
3458                         }
3459                         methods[tide++] = new MethodSemantics(mType,meth,this);
3460                 }
3461
3462                 /// <summary>
3463                 /// Set the specialName attribute for this Event or Property
3464                 /// </summary>
3465                 public void SetSpecialName() 
3466                 {
3467                         flags |= specialName;
3468                 }
3469
3470                 /// <summary>
3471                 /// Set the RTSpecialName attribute for this Event or Property
3472                 /// </summary>
3473                 public void SetRTSpecialName() 
3474                 {
3475                         flags |= rtSpecialName;
3476                 }
3477
3478         }
3479
3480         /**************************************************************************/  
3481         /// <summary>
3482         /// Descriptor for an event
3483         /// </summary>
3484         public class Event : Feature {
3485
3486                 Type eventType;
3487
3488                 internal Event(string name, Type eType, ClassDef parent) 
3489                         : base(name, parent) 
3490                 {
3491                         eventType = eType;
3492                         tabIx = MDTable.Event;
3493                 }
3494
3495                 /// <summary>
3496                 /// Add the addon method to this event
3497                 /// </summary>
3498                 /// <param name="addon">the addon method</param>
3499                 public void AddAddon(MethodDef addon) 
3500                 {
3501                         AddMethod(addon,MethodType.AddOn);
3502                 }
3503
3504                 /// <summary>
3505                 /// Add the removeon method to this event
3506                 /// </summary>
3507                 /// <param name="removeOn">the removeon method</param>
3508                 public void AddRemoveOn(MethodDef removeOn) 
3509                 {
3510                         AddMethod(removeOn,MethodType.RemoveOn);
3511                 }
3512
3513                 /// <summary>
3514                 /// Add the fire method to this event
3515                 /// </summary>
3516                 /// <param name="fire">the fire method</param>
3517                 public void AddFire(MethodDef fire) 
3518                 {
3519                         AddMethod(fire,MethodType.Fire);
3520                 }
3521
3522                 /// <summary>
3523                 /// Add another method to this event
3524                 /// </summary>
3525                 /// <param name="other">the method to be added</param>
3526                 public void AddOther(MethodDef other) 
3527                 {
3528                         AddMethod(other,MethodType.Other);
3529                 }
3530
3531                 internal sealed override void BuildTables(MetaData md) 
3532                 {
3533                         if (done) return;
3534                         nameIx = md.AddToStringsHeap(name);
3535                         for (int i=0; i < tide; i++) {
3536                                 md.AddToTable(MDTable.MethodSemantics,methods[i]);
3537                         }
3538                         done = true;
3539                 }
3540
3541                 internal sealed override uint Size(MetaData md) 
3542                 {
3543                         return 2 + md.StringsIndexSize() + md.CodedIndexSize(CIx.TypeDefOrRef);
3544                 }
3545
3546                 internal sealed override void Write(FileImage output) 
3547                 {
3548                         output.Write(flags);
3549                         output.StringsIndex(nameIx);
3550                         output.WriteCodedIndex(CIx.TypeDefOrRef,eventType);
3551                 }
3552
3553                 internal sealed override uint GetCodedIx(CIx code) 
3554                 {
3555                         switch (code) {
3556                                 case (CIx.HasCustomAttr) : return 10; 
3557                                 case (CIx.HasSemantics) : return 0; 
3558                         }
3559                         return 0;
3560                 }
3561
3562         }
3563
3564         /**************************************************************************/  
3565         /// <summary>
3566         /// Descriptor for the Property of a class
3567         /// </summary>
3568         public class Property : Feature {
3569
3570                 private static readonly byte PropertyTag = 0x8;
3571                 private bool instance;
3572                 MethodDef getterMeth;
3573                 ConstantElem constVal;
3574                 uint typeBlobIx = 0;
3575                 Type[] parList;
3576                 Type returnType;
3577                 uint numPars = 0;
3578
3579                 internal Property(string name, Type retType, Type[] pars, ClassDef parent) : base(name, parent) 
3580                 {
3581                         returnType = retType;
3582                         parList = pars;
3583                         if (pars != null) numPars = (uint)pars.Length;
3584                         tabIx = MDTable.Property;
3585                 }
3586
3587                 /// <summary>
3588                 /// Add a set method to this property
3589                 /// </summary>
3590                 /// <param name="setter">the set method</param>
3591                 public void AddSetter(MethodDef setter) 
3592                 {
3593                         AddMethod(setter,MethodType.Setter);
3594                 }
3595
3596                 /// <summary>
3597                 /// Add a get method to this property
3598                 /// </summary>
3599                 /// <param name="getter">the get method</param>
3600                 public void AddGetter(MethodDef getter) 
3601                 {
3602                         AddMethod(getter,MethodType.Getter);
3603                         getterMeth = getter;
3604                 }
3605
3606                 /// <summary>
3607                 /// Add another method to this property
3608                 /// </summary>
3609                 /// <param name="other">the method</param>
3610                 public void AddOther(MethodDef other) 
3611                 {
3612                         AddMethod(other,MethodType.Other);
3613                 }
3614
3615                 /// <summary>
3616                 /// Add an initial value for this property
3617                 /// </summary>
3618                 /// <param name="constVal">the initial value for this property</param>
3619                 public void AddInitValue(Constant constVal) 
3620                 {
3621                         this.constVal = new ConstantElem(this,constVal);
3622                 }
3623
3624                 public void SetInstance (bool isInstance)
3625                 {
3626                         this.instance = isInstance;
3627                 }
3628
3629                 internal sealed override void BuildTables(MetaData md) 
3630                 {
3631                         if (done) return;
3632                         nameIx = md.AddToStringsHeap(name);
3633                         MemoryStream sig = new MemoryStream();
3634                         byte tag = PropertyTag;
3635                         if (instance)
3636                                 tag |= 0x20;
3637                         sig.WriteByte(tag);
3638                         MetaData.CompressNum(numPars,sig);
3639                         returnType.TypeSig(sig);
3640                         for (int i=0; i < numPars; i++) {
3641                                 parList[i].TypeSig(sig);
3642                         }
3643                         typeBlobIx = md.AddToBlobHeap(sig.ToArray());
3644                         for (int i=0; i < tide; i++) {
3645                                 md.AddToTable(MDTable.MethodSemantics,methods[i]);
3646                         }
3647                         if (constVal != null) {
3648                                 md.AddToTable(MDTable.Constant,constVal);
3649                                 constVal.BuildTables(md);
3650                         }
3651                         done = true;
3652                 }
3653
3654                 internal sealed override uint Size(MetaData md) 
3655                 {
3656                         return 2 + md.StringsIndexSize() + md.BlobIndexSize();
3657                 }
3658
3659                 internal sealed override void Write(FileImage output) 
3660                 {
3661                         output.Write(flags);
3662                         output.StringsIndex(nameIx);
3663                         output.BlobIndex(typeBlobIx);
3664                 }
3665
3666                 internal sealed override uint GetCodedIx(CIx code) 
3667                 {
3668                         switch (code) {
3669                                 case (CIx.HasCustomAttr) : return 9; 
3670                                 case (CIx.HasConst) : return 2; 
3671                                 case (CIx.HasSemantics) : return 1; 
3672                         }
3673                         return 0;
3674                 }
3675
3676         }
3677
3678         /**************************************************************************/  
3679         /// <summary>
3680         /// Base class for field/methods (member of a class)
3681         /// </summary>
3682         public abstract class Member : MetaDataElement {
3683
3684                 protected string name;
3685                 protected uint nameIx = 0, sigIx = 0;
3686
3687                 internal Member(string memName)
3688                 {
3689                         name = memName;
3690                         tabIx = MDTable.MemberRef;
3691                 }
3692
3693         }
3694
3695         /*****************************************************************************/  
3696         /// <summary>
3697         /// Descriptor for a field of a class
3698         /// </summary>
3699
3700         public abstract class Field : Member {
3701
3702                 protected static readonly byte FieldSig = 0x6;
3703
3704                 protected Type type;
3705
3706                 internal Field(string pfName, Type pfType) : base(pfName)
3707                 {
3708                         type = pfType;
3709                 }
3710
3711         }
3712         /**************************************************************************/  
3713         /// <summary>
3714         /// Descriptor for a field defined in a class of THIS assembly/module
3715         /// </summary>
3716         public class FieldDef : Field {
3717
3718                 //private static readonly uint PInvokeImpl = 0x2000;
3719                 private static readonly ushort HasFieldRVA = 0x100;
3720                 private static readonly ushort HasDefault = 0x8000;
3721
3722                 FieldRVA rva;
3723                 ConstantElem constVal;
3724                 FieldLayout layout;
3725                 FieldMarshal marshalInfo;
3726                 ushort flags;
3727
3728                 internal FieldDef(string name, Type fType) : base(name,fType) 
3729                 {
3730                         tabIx = MDTable.Field;
3731                 }
3732
3733                 internal FieldDef(FieldAttr attrSet, string name, Type fType) : base(name, fType) 
3734                 {
3735                         flags = (ushort)attrSet;
3736                         tabIx = MDTable.Field;
3737                 }
3738
3739                 /// <summary>
3740                 /// Add an attribute(s) to this field
3741                 /// </summary>
3742                 /// <param name="fa">the attribute(s) to be added</param>
3743                 public void AddFieldAttr(FieldAttr fa) 
3744                 {
3745                         flags |= (ushort)fa;
3746                 }
3747
3748                 /// <summary>
3749                 /// Add a value for this field
3750                 /// </summary>
3751                 /// <param name="val">the value for the field</param>
3752                 public void AddValue(Constant val) 
3753                 {
3754                         constVal = new ConstantElem(this,val);
3755                         flags |= HasDefault;
3756                 }
3757
3758                 /// <summary>
3759                 /// Add an initial value for this field (at dataLabel) (.data)
3760                 /// </summary>
3761                 /// <param name="val">the value for the field</param>
3762                 /// <param name="repeatVal">the number of repetitions of this value</param>
3763                 public void AddDataValue(DataConstant val) 
3764                 {
3765                         flags |= HasFieldRVA;
3766                         rva = new FieldRVA(this,val);
3767                 }
3768
3769                 /// <summary>
3770                 /// Set the offset of the field.  Used for sequential or explicit classes.
3771                 /// (.field [offs])
3772                 /// </summary>
3773                 /// <param name="offs">field offset</param>
3774                 public void SetOffset(uint offs) 
3775                 {
3776                         layout = new FieldLayout(this,offs);
3777                 }
3778
3779                 /// <summary>
3780                 /// Set the marshalling info for a field
3781                 /// </summary>
3782                 /// <param name="mInf"></param>
3783                 public void SetMarshalInfo(NativeType marshallType) 
3784                 {
3785                         flags |= (ushort) FieldAttr.HasFieldMarshal;
3786                         marshalInfo = new FieldMarshal(this,marshallType);
3787                 }
3788
3789                 internal sealed override void BuildTables(MetaData md) 
3790                 {
3791                         if (done) return;
3792                         nameIx = md.AddToStringsHeap(name);
3793                         MemoryStream sig = new MemoryStream();
3794                         sig.WriteByte(FieldSig);
3795                         type.TypeSig(sig);
3796                         sigIx = md.AddToBlobHeap(sig.ToArray());
3797                         if (rva != null) {
3798                                 md.AddToTable(MDTable.FieldRVA,rva);
3799                                 rva.BuildTables(md);
3800                         } else if (constVal != null) {
3801                                 md.AddToTable(MDTable.Constant,constVal);
3802                                 constVal.BuildTables(md);
3803                         }
3804                         if (layout != null) md.AddToTable(MDTable.FieldLayout,layout);
3805                         if (marshalInfo != null) {
3806                                 md.AddToTable(MDTable.FieldMarshal,marshalInfo);
3807                                 marshalInfo.BuildTables(md);
3808                         }
3809                         done = true;
3810                 }
3811
3812                 internal sealed override uint Size(MetaData md) 
3813                 {
3814                         return 2 + md.StringsIndexSize() + md.BlobIndexSize();
3815                 }
3816
3817                 internal sealed override void Write(FileImage output) 
3818                 {
3819                         output.Write(flags);
3820                         output.StringsIndex(nameIx);
3821                         output.BlobIndex(sigIx);
3822                 }
3823
3824                 internal sealed override uint GetCodedIx(CIx code) 
3825                 {
3826                         switch (code) {
3827                                 case (CIx.HasConst) : return 0; 
3828                                 case (CIx.HasCustomAttr) : return 1; 
3829                                 case (CIx.HasFieldMarshal) : return 0; 
3830                                 case (CIx.MemberForwarded) : return 0; 
3831                         }
3832                         return 0;
3833                 }
3834
3835         }
3836
3837         /**************************************************************************/  
3838         /// <summary>
3839         /// Descriptor for a field of a class defined in another assembly/module
3840         /// </summary>
3841         public class FieldRef : Field {
3842
3843                 MetaDataElement parent;
3844
3845                 internal FieldRef(MetaDataElement paren, string name, Type fType) : base(name, fType)   
3846                 {
3847                         parent = paren;
3848                 }
3849
3850                 internal sealed override void BuildTables(MetaData md) 
3851                 {
3852                         if (done) return;
3853                         nameIx = md.AddToStringsHeap(name);
3854                         MemoryStream sig = new MemoryStream();
3855                         sig.WriteByte(FieldSig);
3856                         type.TypeSig(sig);
3857                         sigIx = md.AddToBlobHeap(sig.ToArray());
3858                         done = true;
3859                 }
3860
3861                 internal sealed override uint Size(MetaData md) 
3862                 {
3863                         return md.CodedIndexSize(CIx.MemberRefParent) + md.StringsIndexSize() + md.BlobIndexSize();
3864                 }
3865
3866                 internal sealed override void Write(FileImage output) 
3867                 {
3868                         output.WriteCodedIndex(CIx.MemberRefParent,parent);
3869                         output.StringsIndex(nameIx);
3870                         output.BlobIndex(sigIx);
3871                 }
3872
3873                 internal sealed override uint GetCodedIx(CIx code) { return 6; }
3874
3875         }
3876
3877         /**************************************************************************/  
3878         /// <summary>
3879         /// Base class for Method Descriptors
3880         /// </summary>
3881
3882         public abstract class Method : Member {
3883
3884                 internal Method (string methName) : base (methName)
3885                 {}
3886
3887                 public abstract void AddCallConv(CallConv cconv);
3888                 internal abstract void TypeSig(MemoryStream sig);
3889                 internal abstract uint GetSigIx(MetaData md);
3890         }
3891
3892         /**************************************************************************/  
3893         /// <summary>
3894         /// Descriptor for a method defined in THIS assembly/module
3895         /// IL     .method
3896         /// </summary>
3897
3898         public class MethodDef : Method {
3899
3900                 private static readonly ushort PInvokeImpl = 0x2000;
3901                 //private static readonly uint UnmanagedExport = 0x0008;
3902                 // private static readonly byte LocalSigByte = 0x7;
3903                 uint parIx = 0, textOffset = 0;
3904                 private CallConv callConv = CallConv.Default;
3905                 private int gen_param_count;
3906
3907                 MetaData metaData;
3908                 CILInstructions code;
3909                 Param[] parList;
3910                 Local[] locals;
3911                 bool initLocals;
3912                 ushort methFlags = 0, implFlags = 0;
3913                 int maxStack = 0, numPars = 0;
3914                 bool entryPoint = false;
3915                 LocalSig localSig;
3916                 ArrayList varArgSigList;
3917                 ImplMap pinvokeImpl;
3918                 Param ret_param;
3919
3920                 internal MethodDef (MetaData md, string name, Param ret_param, Param [] pars)
3921                         : this (md, 0, 0, name, ret_param, pars)
3922                 {
3923                 }
3924
3925                 internal MethodDef (MetaData md, MethAttr mAttrSet, ImplAttr iAttrSet, string name, 
3926                                 Param ret_param, Param [] pars) 
3927                         : base (name)
3928                 {
3929                         methFlags = (ushort)mAttrSet;
3930                         implFlags = (ushort)iAttrSet;
3931                         this.ret_param = ret_param;
3932                         metaData = md;
3933                         parList = pars;
3934                         if (parList != null) 
3935                                 numPars = parList.Length;
3936                         tabIx = MDTable.Method;
3937                 }
3938
3939                 internal Param[] GetPars() 
3940                 {
3941                         return parList;
3942                 }
3943
3944                 internal override uint GetSigIx(MetaData md)
3945                 {
3946                         MemoryStream sig = new MemoryStream();
3947                         TypeSig(sig);
3948                         return md.AddToBlobHeap(sig.ToArray());
3949                 }
3950
3951                 public override void AddCallConv(CallConv cconv)
3952                 {
3953                         callConv |= cconv;
3954                 }
3955                 
3956                 /// <summary>
3957                 /// Add some attributes to this method descriptor
3958                 /// </summary>
3959                 /// <param name="ma">the attributes to be added</param>
3960                 public void AddMethAttribute(MethAttr ma) 
3961                 {
3962                         methFlags |= (ushort)ma;
3963                 }
3964
3965                 /// <summary>
3966                 /// Add some implementation attributes to this method descriptor
3967                 /// </summary>
3968                 /// <param name="ia">the attributes to be added</param>
3969                 public void AddImplAttribute(ImplAttr ia) 
3970                 {
3971                         implFlags |= (ushort)ia;
3972                 }
3973
3974                 public void AddPInvokeInfo(ModuleRef scope, string methName,
3975                                 PInvokeAttr callAttr) {
3976                         pinvokeImpl = new ImplMap((ushort)callAttr,this,methName,scope);
3977                         methFlags |= PInvokeImpl;
3978                 }
3979
3980                 /// <summary>
3981                 ///  Add a named generic type parameter
3982                 /// </summary>
3983                 public GenericParameter AddGenericParameter (short index, string name) 
3984                 {
3985                         return AddGenericParameter (index, name, 0);
3986                 }
3987
3988                 /// <summary>
3989                 ///  Add a named generic type parameter with attributes
3990                 /// </summary>
3991                 public GenericParameter AddGenericParameter (short index, string name, GenericParamAttributes attr) 
3992                 {
3993                         GenericParameter gp = new GenericParameter (this, metaData, index, name, attr);
3994                         metaData.AddToTable (MDTable.GenericParam, gp);
3995                         gen_param_count ++;
3996                         return gp;
3997                 }
3998
3999                 /// <summary>
4000                 /// Set the maximum stack height for this method
4001                 /// </summary>
4002                 /// <param name="maxStack">the maximum height of the stack</param>
4003                 public void SetMaxStack(int maxStack) 
4004                 {
4005                         this.maxStack = maxStack; 
4006                 }
4007
4008                 /// <summary>
4009                 /// Add local variables to this method
4010                 /// </summary>
4011                 /// <param name="locals">the locals to be added</param>
4012                 /// <param name="initLocals">are locals initialised to default values</param>
4013                 public void AddLocals(Local[] locals, bool initLocals) 
4014                 {
4015                         this.locals = locals;
4016                         this.initLocals = initLocals;
4017                 }
4018
4019                 /* Add Marshal info for return type */
4020                 public void AddRetTypeMarshallInfo (NativeType marshallType) 
4021                 {
4022                         ret_param.AddMarshallInfo (marshallType);
4023                 }
4024
4025                 /// <summary>
4026                 /// Mark this method as having an entry point
4027                 /// </summary>
4028                 public void DeclareEntryPoint() 
4029                 {
4030                         entryPoint = true;
4031                 }
4032
4033                 /// <summary>
4034                 /// Create a code buffer for this method to add the IL instructions to
4035                 /// </summary>
4036                 /// <returns>a buffer for this method's IL instructions</returns>
4037                 public CILInstructions CreateCodeBuffer() 
4038                 {
4039                         code = new CILInstructions(metaData);
4040                         return code;
4041                 }
4042
4043                 /// <summary>
4044                 /// Make a method reference descriptor for this method to be used 
4045                 /// as a callsite signature for this vararg method
4046                 /// </summary>
4047                 /// <param name="optPars">the optional pars for the vararg method call</param>
4048                 /// <returns></returns>
4049                 public MethodRef MakeVarArgSignature(Type[] optPars) 
4050                 {
4051                         Type[] pars = new Type[numPars];
4052                         MethodRef varArgSig;
4053                         for (int i=0; i < numPars; i++) {
4054                                 pars[i] = parList[i].GetParType();
4055                         }
4056                         varArgSig = new MethodRef (this, name, ret_param.GetParType (), pars, true, optPars, 0);
4057
4058                         if (varArgSigList == null)
4059                                 varArgSigList = new ArrayList ();
4060                         varArgSigList.Add (varArgSig);
4061                         return varArgSig;
4062                 }
4063
4064                 internal sealed override void TypeSig(MemoryStream sig) 
4065                 {
4066                         sig.WriteByte((byte)callConv);
4067                         if ((callConv & CallConv.Generic) == CallConv.Generic)
4068                                 MetaData.CompressNum ((uint) gen_param_count, sig);
4069                         MetaData.CompressNum((uint)numPars,sig);
4070
4071                         ret_param.seqNo = 0;
4072                         ret_param.TypeSig (sig);
4073                         for (ushort i=0; i < numPars; i++) {
4074                                 parList[i].seqNo = (ushort)(i+1);
4075                                 parList[i].TypeSig(sig);
4076                         }
4077                 }
4078
4079                 internal sealed override void BuildTables(MetaData md) 
4080                 {
4081                         if (done) return;
4082                         if (pinvokeImpl != null) {
4083                                 md.AddToTable(MDTable.ImplMap,pinvokeImpl);
4084                                 pinvokeImpl.BuildTables(md);
4085                         }
4086                         if (entryPoint) md.SetEntryPoint(this);
4087                         uint locToken = 0;
4088                         if (locals != null) {
4089                                 localSig = new LocalSig(locals);
4090                                 md.AddToTable(MDTable.StandAloneSig,localSig);
4091                                 localSig.BuildTables(md);
4092                                 locToken = localSig.Token();
4093                         }
4094                         if (code != null) {
4095                                 code.CheckCode(locToken,initLocals,maxStack);
4096                                 textOffset = md.AddCode(code);
4097                         }
4098                         nameIx = md.AddToStringsHeap(name);
4099                         sigIx = GetSigIx(md);
4100                         parIx = md.TableIndex(MDTable.Param);
4101                         if (ret_param.HasMarshalInfo || ret_param.HasCustomAttr) {
4102                                 md.AddToTable(MDTable.Param, ret_param);
4103                                 ret_param.BuildTables(md);
4104                         }
4105                         for (int i=0; i < numPars; i++) {
4106                                 md.AddToTable(MDTable.Param,parList[i]);
4107                                 parList[i].BuildTables(md);
4108                         }
4109                         if (varArgSigList != null) {
4110                                 foreach (MethodRef varArgSig in varArgSigList) {
4111                                         md.AddToTable(MDTable.MemberRef,varArgSig);
4112                                         varArgSig.BuildTables(md);
4113                                 }
4114                         }
4115                         // Console.WriteLine("method has " + numPars + " parameters");
4116                         done = true;
4117                 }
4118
4119                 internal sealed override uint Size(MetaData md) 
4120                 {
4121                         return 8 + md.StringsIndexSize() + md.BlobIndexSize() + md.TableIndexSize(MDTable.Param);
4122                 }
4123
4124                 internal sealed override void Write(FileImage output) 
4125                 {
4126                         if (ZeroRva ()) output.Write(0);
4127                         else output.WriteCodeRVA(textOffset);
4128                         output.Write(implFlags);
4129                         output.Write(methFlags);
4130                         output.StringsIndex(nameIx);
4131                         output.BlobIndex(sigIx);
4132                         output.WriteIndex(MDTable.Param,parIx);
4133                 }
4134
4135                 internal bool ZeroRva () 
4136                 {
4137                         return (((methFlags & (ushort)MethAttr.Abstract) != 0) ||
4138                                         ((implFlags & (ushort)ImplAttr.Runtime) != 0) ||
4139                                         ((implFlags & (ushort)ImplAttr.InternalCall) != 0) || 
4140                                         (pinvokeImpl != null)); // TODO: Not entirely true but works for now
4141                 }
4142
4143                 internal sealed override uint GetCodedIx(CIx code) 
4144                 {
4145                         switch (code) {
4146                                 case (CIx.HasCustomAttr) : return 0; 
4147                                 case (CIx.HasDeclSecurity) : return 1; 
4148                                 case (CIx.MemberRefParent) : return 3; 
4149                                 case (CIx.MethodDefOrRef) : return 0; 
4150                                 case (CIx.MemberForwarded) : return 1; 
4151                                 case (CIx.CustomAttributeType) : return 2; 
4152                                 case (CIx.TypeOrMethodDef) : return 1; 
4153                         }
4154                         return 0;
4155                 }
4156
4157         }
4158         /**************************************************************************/  
4159         /// <summary>
4160         /// Descriptor for a method defined in another assembly/module
4161         /// </summary>
4162         public class MethodRef : Method {
4163
4164                 private static readonly byte Sentinel = 0x41;
4165                 Type[] parList, optParList;
4166                 MetaDataElement parent;
4167                 uint numPars = 0, numOptPars = 0;
4168                 CallConv callConv = CallConv.Default;
4169                 Type retType;
4170                 int gen_param_count;
4171
4172                 internal MethodRef(MetaDataElement paren, string name, Type retType,
4173                                 Type[] pars, bool varArgMeth, Type[] optPars, int gen_param_count) : base(name)
4174                 {
4175                         parent = paren;
4176                         parList = pars;
4177                         this.retType = retType;
4178                         if (parList != null) numPars = (uint)parList.Length;
4179                         if (varArgMeth) {
4180                                 optParList = optPars;
4181                                 if (optParList != null) numOptPars = (uint)optParList.Length;
4182                                 callConv = CallConv.Vararg;
4183                         }
4184                         this.gen_param_count = gen_param_count;
4185                 }
4186
4187                 internal override uint GetSigIx(MetaData md)
4188                 {
4189                         MemoryStream sig = new MemoryStream();
4190                         TypeSig(sig);
4191                         return md.AddToBlobHeap(sig.ToArray());
4192                 }
4193
4194                 public override void AddCallConv(CallConv cconv)
4195                 {
4196                         callConv |= cconv;
4197                 }
4198                 
4199                 internal sealed override void TypeSig(MemoryStream sig) 
4200                 {
4201                         sig.WriteByte((byte)callConv);
4202                         if ((callConv & CallConv.Generic) == CallConv.Generic)
4203                                 MetaData.CompressNum ((uint) gen_param_count, sig);
4204                         MetaData.CompressNum(numPars+numOptPars,sig);
4205                         retType.TypeSig(sig);
4206                         for (int i=0; i < numPars; i++) {
4207                                 parList[i].TypeSig(sig);
4208                         }
4209                         if (numOptPars > 0) {
4210                                 sig.WriteByte(Sentinel);
4211                                 for (int i=0; i < numOptPars; i++) {
4212                                         optParList[i].TypeSig(sig);
4213                                 }
4214                         }
4215                 }
4216
4217                 internal sealed override void BuildTables(MetaData md) 
4218                 {
4219                         if (done) return;
4220                         nameIx = md.AddToStringsHeap(name);
4221                         sigIx = GetSigIx(md);
4222                         done = true;
4223                 }
4224
4225                 internal sealed override uint Size(MetaData md) 
4226                 {
4227                         return md.CodedIndexSize(CIx.MemberRefParent) + md.StringsIndexSize() + md.BlobIndexSize();
4228                 }
4229
4230                 internal sealed override void Write(FileImage output) 
4231                 {
4232                         output.WriteCodedIndex(CIx.MemberRefParent,parent);
4233                         output.StringsIndex(nameIx);
4234                         output.BlobIndex(sigIx);
4235                 }
4236
4237                 internal sealed override uint GetCodedIx(CIx code) 
4238                 {
4239                         switch (code) {
4240                                 case (CIx.HasCustomAttr) : return 6; 
4241                                 case (CIx.MethodDefOrRef) : return 1; 
4242                                 case (CIx.CustomAttributeType) : return 3; 
4243                         }
4244                         return 0;
4245                 }
4246
4247         }
4248
4249
4250         /**************************************************************************/  
4251         /// <summary>
4252         /// Descriptors for native types used for marshalling
4253         /// </summary>
4254         public class NativeType {
4255                 public static readonly NativeType Void = new NativeType(0x01);
4256                 public static readonly NativeType Boolean = new NativeType(0x02);
4257                 public static readonly NativeType Int8 = new NativeType(0x03);
4258                 public static readonly NativeType UInt8 = new NativeType(0x04);
4259                 public static readonly NativeType Int16 = new NativeType(0x05);
4260                 public static readonly NativeType UInt16 = new NativeType(0x06);
4261                 public static readonly NativeType Int32 = new NativeType(0x07);
4262                 public static readonly NativeType UInt32 = new NativeType(0x08);
4263                 public static readonly NativeType Int64 = new NativeType(0x09);
4264                 public static readonly NativeType UInt64 = new NativeType(0x0A);
4265                 public static readonly NativeType Float32 = new NativeType(0x0B);
4266                 public static readonly NativeType Float64 = new NativeType(0x0C);
4267                 public static readonly NativeType Currency = new NativeType(0x0F);
4268                 public static readonly NativeType BStr = new NativeType(0x13);
4269                 public static readonly NativeType LPStr = new NativeType(0x14);
4270                 public static readonly NativeType LPWStr = new NativeType(0x15);
4271                 public static readonly NativeType LPTStr = new NativeType(0x16);
4272                 public static readonly NativeType FixedSysString = new NativeType(0x17);
4273                 public static readonly NativeType IUnknown = new NativeType(0x19);
4274                 public static readonly NativeType IDispatch = new NativeType(0x1A);
4275                 public static readonly NativeType Struct = new NativeType(0x1B);
4276                 public static readonly NativeType Interface = new NativeType(0x1C);
4277                 public static readonly NativeType Int = new NativeType(0x1F);
4278                 public static readonly NativeType UInt = new NativeType(0x20);
4279                 public static readonly NativeType ByValStr = new NativeType(0x22);
4280                 public static readonly NativeType AnsiBStr = new NativeType(0x23);
4281                 public static readonly NativeType TBstr = new NativeType(0x24);
4282                 public static readonly NativeType VariantBool = new NativeType(0x25);
4283                 public static readonly NativeType FuncPtr = new NativeType(0x26);
4284                 public static readonly NativeType AsAny = new NativeType(0x28);
4285                 public static readonly NativeType LPStruct = new NativeType(0x2b);
4286                 public static readonly NativeType Error = new NativeType(0x2d);
4287
4288                 protected byte typeIndex;
4289
4290                 internal NativeType(byte tyIx) { typeIndex = tyIx; }
4291                 internal byte GetTypeIndex() { return typeIndex; }
4292
4293                 internal virtual byte[] ToBlob() 
4294                 {
4295                         byte[] bytes = new byte[1];
4296                         bytes[0] = GetTypeIndex();
4297                         return bytes;
4298                 }
4299
4300         }
4301
4302         public class FixedSysString : NativeType  {
4303
4304                 uint size;
4305
4306                 public FixedSysString (uint size) : base (NativeType.FixedSysString.GetTypeIndex ())
4307                 {
4308                         this.size = size;
4309                 }
4310
4311                 internal override byte [] ToBlob () 
4312                 {
4313                         MemoryStream str = new MemoryStream ();
4314                         str.WriteByte (GetTypeIndex ());
4315                         MetaData.CompressNum (size, str);
4316                         return str.ToArray ();
4317                 }
4318
4319         }  
4320
4321         public class NativeArray : NativeType  {
4322
4323                 NativeType elemType;
4324                 int numElem = -1, parNum = -1, elemMult = -1;
4325
4326                 public NativeArray(NativeType elemType) : this (elemType, -1, -1, -1) 
4327                 {
4328                         this.elemType = elemType;
4329                 }
4330
4331                 /*    public NativeArray(NativeType elemType, int len) : base(0x2A) {
4332                       this.elemType = elemType;
4333                       this.len = len;
4334                       }
4335                  */
4336
4337                 public NativeArray(NativeType elemType, int numElem, int parNumForLen, int elemMult) : base(0x2A) 
4338                 {
4339                         this.elemType = elemType;
4340                         this.numElem = numElem;
4341                         parNum = parNumForLen;
4342                         this.elemMult = elemMult;
4343                 }
4344
4345                 public NativeArray(NativeType elemType, int numElem, int parNumForLen) 
4346                         : this (elemType, numElem, parNumForLen, -1) 
4347                 {
4348                 }
4349
4350                 internal override byte[] ToBlob() 
4351                 {
4352                         MemoryStream str = new MemoryStream();
4353                         str.WriteByte(GetTypeIndex());
4354                         if (elemType == null) str.WriteByte(0x50);  // no info (MAX)
4355                         else str.WriteByte(elemType.GetTypeIndex());
4356
4357                         /* see : mono/metadata/metadata.c:mono_metadata_parse_marshal_spec
4358                          * LAMESPEC: Older spec versions say elemMult comes before
4359                          * len. Newer spec versions don't talk about elemMult at
4360                          * all, but csc still emits it, and it is used to distinguish
4361                          * between parNum being 0, and parNum being omitted.
4362                          */
4363
4364                         if (parNum == -1)
4365                                 // <native_type> []
4366                                 return str.ToArray ();
4367
4368                         MetaData.CompressNum((uint) parNum,str);
4369                         if (numElem != -1) {
4370                                 MetaData.CompressNum ((uint) numElem, str);
4371                                 if (elemMult != -1)
4372                                         // <native_type> [ int32 ]
4373                                         MetaData.CompressNum((uint) elemMult,str);
4374                                 //else <native_type> [ int32 + int32 ]
4375                         } else if (elemMult != -1) {
4376                                 // When can this occur ?
4377                                 MetaData.CompressNum (0, str);
4378                                 MetaData.CompressNum((uint) elemMult,str);
4379                         }
4380                         //else <native_type> [ + int32 ]
4381
4382                         return str.ToArray();
4383                 }
4384
4385         }
4386
4387         public class SafeArray : NativeType  {
4388
4389                 SafeArrayType elemType;
4390                 bool hasElemType;
4391
4392                 public SafeArray() : base(0x1D) 
4393                 {
4394                 }
4395
4396                 public SafeArray(SafeArrayType elemType) : base(0x1D) 
4397                 {
4398                         this.elemType = elemType;
4399                         hasElemType = true;
4400                 }
4401
4402                 internal override byte[] ToBlob() 
4403                 {
4404                         byte[] bytes = new byte[hasElemType ? 2 : 1];
4405                         bytes[0] = GetTypeIndex();
4406                         if (hasElemType)
4407                                 bytes[1] = (byte)elemType;
4408                         return bytes;
4409                 }
4410
4411         }
4412
4413         public class FixedArray : NativeType  {
4414
4415                 uint numElem;
4416
4417                 //public FixedArray(NativeType elemType, int numElems) : base(0x1E) {
4418                 public FixedArray(int numElems) : base(0x1E) 
4419                 {
4420                         //this.elemType = elemType;
4421                         numElem = (uint)numElems;
4422                 }
4423
4424                 internal override byte[] ToBlob() 
4425                 {
4426                         MemoryStream str = new MemoryStream();
4427                         str.WriteByte(GetTypeIndex());
4428                         MetaData.CompressNum(numElem,str);
4429                         /* FIXME: 
4430                            fixed array [5] lpstr [2]
4431                            This format is not supported by ilasm 1.1.4322.2032, 
4432                            but is supported by 2.0.5125..
4433                            ilasm 1.1 only supports "fixed array [5]" 
4434                            if (elemType == null) str.WriteByte(0x50);  // no info (MAX)
4435                            else str.WriteByte(elemType.GetTypeIndex());*/
4436
4437                         return str.ToArray();
4438                 }
4439
4440         }
4441
4442         public class CustomMarshaller : NativeType  {
4443
4444                 string typeName;
4445                 string marshallerName;
4446                 string cookie;
4447
4448                 public CustomMarshaller(string typeNameOrGUID, string marshallerName, 
4449                                 string optCookie) : base(0x2C) 
4450                 {
4451                         typeName = typeNameOrGUID;
4452                         this.marshallerName = marshallerName;
4453                         cookie = optCookie;
4454                 }
4455
4456                 public CustomMarshaller(string marshallerName, string optCookie)
4457                         :this (null, marshallerName, optCookie) 
4458                 {
4459                 }
4460
4461                 internal override byte[] ToBlob() 
4462                 {
4463                         MemoryStream str = new MemoryStream();
4464                         BinaryWriter bw = new BinaryWriter(str,new UTF8Encoding());
4465                         bw.Write(GetTypeIndex());
4466                         //Native type name & unmanaged type - unused
4467                         //See mono/metadata/metadata.c : mono_metadata_parse_marshal_spec
4468                         bw.Write ((byte) 0); // Native Type name, unused 
4469                         bw.Write ((byte) 0); // Unmanaged type, unused 
4470                         if (marshallerName != null) {
4471                                 MetaData.CompressNum ((uint)marshallerName.Length, str);
4472                                 bw.Write(marshallerName.ToCharArray());
4473                         } else { 
4474                                 bw.Write ((byte) 0);
4475                         }
4476                         if (cookie != null) {
4477                                 MetaData.CompressNum ((uint)cookie.Length, str);
4478                                 bw.Write(cookie.ToCharArray());
4479                         } else {
4480                                 bw.Write ((byte) 0);
4481                         }
4482                         bw.Flush();
4483                         return str.ToArray();
4484                 }
4485         }
4486
4487         /**************************************************************************/  
4488         /// <summary>
4489         /// Descriptor for the Primitive types defined in IL
4490         /// </summary>
4491         public class PrimitiveType : Type {
4492
4493                 private string name;
4494                 private int systemTypeIndex;
4495                 public static int NumSystemTypes = 18;
4496
4497                 public static readonly PrimitiveType Void = new PrimitiveType(0x01,"Void",0);
4498                 public static readonly PrimitiveType Boolean = new PrimitiveType(0x02,"Boolean",1);
4499                 public static readonly PrimitiveType Char = new PrimitiveType(0x03,"Char",2);
4500                 public static readonly PrimitiveType Int8 = new PrimitiveType(0x04,"SByte",3);
4501                 public static readonly PrimitiveType UInt8 = new PrimitiveType(0x05,"Byte",4);
4502                 public static readonly PrimitiveType Int16 = new PrimitiveType(0x06,"Int16",5);
4503                 public static readonly PrimitiveType UInt16 = new PrimitiveType(0x07,"UInt16",6);
4504                 public static readonly PrimitiveType Int32 = new PrimitiveType(0x08,"Int32",7);
4505                 public static readonly PrimitiveType UInt32 = new PrimitiveType(0x09,"UInt32",8);
4506                 public static readonly PrimitiveType Int64 = new PrimitiveType(0x0A,"Int64",9);
4507                 public static readonly PrimitiveType UInt64 = new PrimitiveType(0x0B,"UInt64",10);
4508                 public static readonly PrimitiveType Float32 = new PrimitiveType(0x0C,"Single",11);
4509                 public static readonly PrimitiveType Float64 = new PrimitiveType(0x0D,"Double",12);
4510                 public static readonly PrimitiveType String = new PrimitiveType(0x0E,"String",13);
4511                 internal static readonly PrimitiveType Class = new PrimitiveType(0x12);
4512                 internal static readonly PrimitiveType Var = new PrimitiveType(0x13);
4513                 internal static readonly PrimitiveType GenericInst = new PrimitiveType(0x15);
4514                 public static readonly PrimitiveType TypedRef = new PrimitiveType(0x16,"TypedReference",14);
4515                 public static readonly PrimitiveType IntPtr = new PrimitiveType(0x18,"IntPtr",15);
4516                 public static readonly PrimitiveType UIntPtr = new PrimitiveType(0x19,"UIntPtr",16);
4517                 public static readonly PrimitiveType Object = new PrimitiveType(0x1C,"Object",17);
4518                 internal static readonly PrimitiveType ClassType = new PrimitiveType(0x50);
4519                 internal static readonly PrimitiveType SZArray = new PrimitiveType(0x1D);
4520                 internal static readonly PrimitiveType MVar = new PrimitiveType(0x1E);
4521                 internal static readonly PrimitiveType ValueType = new PrimitiveType(0x11, "ValueType", 18);
4522                 public static readonly PrimitiveType NativeInt = IntPtr;
4523                 public static readonly PrimitiveType NativeUInt = UIntPtr;
4524
4525                 internal PrimitiveType(byte typeIx) : base(typeIx) { }
4526
4527                 internal PrimitiveType(byte typeIx, string name, int STIx) : base(typeIx) 
4528                 {
4529                         this.name = name;
4530                         this.systemTypeIndex = STIx;
4531                 }
4532
4533                 internal string GetName() { return name; }
4534
4535                 internal int GetSystemTypeIx() { return systemTypeIndex; }
4536
4537                 internal sealed override void TypeSig(MemoryStream str) 
4538                 {
4539                         str.WriteByte(typeIndex);
4540                 }
4541
4542                 internal override MetaDataElement GetTypeSpec(MetaData md) 
4543                 {
4544                         TypeSpec tS = md.GetPrimitiveTypeSpec(systemTypeIndex);
4545                         if (tS == null) {
4546                                 tS = new TypeSpec(this,md);
4547                                 md.SetPrimitiveTypeSpec(systemTypeIndex,tS);
4548                                 md.AddToTable(MDTable.TypeSpec,tS);
4549                         }
4550                         return tS;
4551                 }
4552
4553         }
4554
4555         public class PrimitiveTypeRef : Type
4556         {
4557                 PrimitiveType type;
4558                 MetaData metaData;
4559
4560                 internal PrimitiveTypeRef(PrimitiveType type, MetaData md)
4561                         : base (0)
4562                 {
4563                         this.type = type;
4564                         this.metaData = md;
4565                 }
4566
4567                 internal uint TypeDefOrRefToken()
4568                 {
4569                         uint cIx = type.GetTypeSpec (metaData).Row;
4570                         cIx = (cIx << 2) | 0x2;
4571                         return cIx;
4572                 }
4573         }
4574
4575         /**************************************************************************/  
4576         /// <summary>
4577         /// Descriptor for an pointer (type * or type &)
4578         /// </summary>
4579         public abstract class PtrType : Type {
4580
4581                 Type baseType;
4582
4583                 internal PtrType(Type bType, byte typeIx) : base(typeIx)
4584                 {
4585                         baseType = bType;
4586                         tabIx = MDTable.TypeSpec;
4587                 }
4588
4589                 internal sealed override void TypeSig(MemoryStream str) 
4590                 {
4591                         str.WriteByte(typeIndex);
4592                         baseType.TypeSig(str);
4593                 }
4594
4595         }
4596         /**************************************************************************/  
4597         /// <summary>
4598         /// Descriptor for a managed pointer (type &  or byref)
4599         /// </summary>
4600
4601         public class ManagedPointer : PtrType {
4602
4603                 /// <summary>
4604                 /// Create new managed pointer to baseType
4605                 /// </summary>
4606                 /// <param name="bType">the base type of the pointer</param>
4607                 public ManagedPointer(Type baseType) : base(baseType,0x10) { }
4608
4609         }
4610         /**************************************************************************/  
4611         /// <summary>
4612         /// Descriptor for an unmanaged pointer (type *)
4613         /// </summary>
4614         public class UnmanagedPointer : PtrType {
4615
4616                 /// <summary>
4617                 /// Create a new unmanaged pointer to baseType
4618                 /// </summary>
4619                 /// <param name="baseType">the base type of the pointer</param>
4620                 public UnmanagedPointer(Type baseType) : base(baseType, 0x0F) { }
4621
4622         }
4623
4624         /**************************************************************************/  
4625
4626         public interface IExternRef  {
4627                 ClassRef AddClass(string nsName, string name);
4628                 ClassRef AddValueClass(string nsName, string name);
4629         }
4630
4631         /// <summary>
4632         /// A reference to an external assembly (.assembly extern)
4633         /// </summary>
4634         public class AssemblyRef : ResolutionScope, IExternRef {
4635
4636                 private ushort major, minor, build, revision;
4637                 uint flags, keyIx, hashIx, cultIx;
4638                 bool hasVersion = false, isKeyToken = false;
4639                 byte[] keyBytes;
4640                 string culture;
4641
4642                 internal AssemblyRef(MetaData md, string name) : base(name,md) 
4643                 {
4644                         tabIx = MDTable.AssemblyRef;
4645                 }
4646
4647                 public void AddAssemblyAttr (AssemAttr aa)
4648                 {
4649                         flags |= (uint)aa;
4650                 }
4651
4652                 /// <summary>
4653                 /// Add version information about this external assembly
4654                 /// </summary>
4655                 /// <param name="majVer">Major Version</param>
4656                 /// <param name="minVer">Minor Version</param>
4657                 /// <param name="bldNo">Build Number</param>
4658                 /// <param name="revNo">Revision Number</param>
4659                 public void AddVersionInfo(int majVer, int minVer, int bldNo, int revNo) 
4660                 {
4661                         major = (ushort)majVer;
4662                         minor = (ushort)minVer;
4663                         build = (ushort)bldNo;
4664                         revision = (ushort)revNo;
4665                         hasVersion = true;
4666                 }
4667
4668                 /// <summary>
4669                 /// Add the hash value for this external assembly
4670                 /// </summary>
4671                 /// <param name="hash">bytes of the hash value</param>
4672                 public void AddHash(byte[] hash) 
4673                 {
4674                         hashIx = metaData.AddToBlobHeap(hash); 
4675                 }
4676
4677                 /// <summary>
4678                 /// Set the culture for this external assembly
4679                 /// </summary>
4680                 /// <param name="cult">the culture string</param>
4681                 public void AddCulture(string cult) 
4682                 {
4683                         cultIx = metaData.AddToStringsHeap(cult);
4684                         culture = cult;
4685                 }
4686
4687                 /// <summary>
4688                 /// Add the full public key for this external assembly
4689                 /// </summary>
4690                 /// <param name="key">bytes of the public key</param>
4691                 public void AddKey(byte[] key) 
4692                 {
4693                         flags |= 0x0001;   // full public key
4694                         keyBytes = key;
4695                         keyIx = metaData.AddToBlobHeap(key); 
4696                 }
4697
4698                 /// <summary>
4699                 /// Add the public key token (low 8 bytes of the public key)
4700                 /// </summary>
4701                 /// <param name="key">low 8 bytes of public key</param>
4702                 public void AddKeyToken(byte[] key) 
4703                 {
4704                         keyIx = metaData.AddToBlobHeap(key); 
4705                         keyBytes = key;
4706                         isKeyToken = true;
4707                 }
4708
4709                 /// <summary>
4710                 /// Add a class to this external assembly
4711                 /// </summary>
4712                 /// <param name="nsName">name space name</param>
4713                 /// <param name="name">class name</param>
4714                 /// <returns></returns>
4715                 public virtual ClassRef AddClass(string nsName, string name) 
4716                 {
4717                         ClassRef aClass = new ClassRef(nsName,name,metaData);
4718                         metaData.AddToTable(MDTable.TypeRef,aClass);
4719                         aClass.SetParent(this);
4720                         return aClass;
4721                 }
4722
4723                 /// <summary>
4724                 /// Add a value class to this external assembly
4725                 /// </summary>
4726                 /// <param name="nsName">name space name</param>
4727                 /// <param name="name">class name</param>
4728                 /// <returns></returns>
4729                 public virtual ClassRef AddValueClass(string nsName, string name) 
4730                 {
4731                         ClassRef aClass = new ClassRef(nsName,name,metaData);
4732                         metaData.AddToTable(MDTable.TypeRef,aClass);
4733                         aClass.SetParent(this);
4734                         aClass.MakeValueClass(ValueClass.ValueType);
4735                         return aClass;
4736                 }
4737
4738                 internal string TypeName() 
4739                 {
4740                         string result = name;
4741                         if (hasVersion) 
4742                                 result = result + ", Version=" + major + "." + minor + "." + 
4743                                         build + "." + revision;
4744                         if (keyBytes != null) {
4745                                 string tokenStr = "=";
4746                                 if (isKeyToken) tokenStr = "Token=";
4747                                 result = result + ", PublicKey" + tokenStr;
4748                                 for (int i=0; i < keyBytes.Length; i++) {
4749                                         result = result + Hex.Byte(keyBytes[i]);
4750                                 }
4751                         }
4752                         if (culture != null) 
4753                                 result = result + ", Culture=" + culture;
4754                         return result;
4755                 }
4756
4757                 internal sealed override uint Size(MetaData md) 
4758                 {
4759                         return 12 + 2 * md.StringsIndexSize() + 2 * md.BlobIndexSize();
4760                 }
4761
4762                 internal sealed override void Write(FileImage output) 
4763                 {
4764                         output.Write(major);
4765                         output.Write(minor);
4766                         output.Write(build);
4767                         output.Write(revision);
4768                         output.Write(flags);
4769                         output.BlobIndex(keyIx);
4770                         output.StringsIndex(nameIx);
4771                         output.StringsIndex(cultIx);
4772                         output.BlobIndex(hashIx);
4773                 }
4774
4775                 internal sealed override uint GetCodedIx(CIx code) 
4776                 {
4777                         switch (code) {
4778                                 case (CIx.ResolutionScope) : return 2; 
4779                                 case (CIx.HasCustomAttr) : return 15; 
4780                                 case (CIx.Implementation) : return 1; 
4781                         }
4782                         return 0;
4783                 }
4784
4785         }
4786
4787         /**************************************************************************/  
4788         /// <summary>
4789         /// Descriptor for a class defined in System (mscorlib)
4790         /// </summary>
4791         internal class SystemClass : ClassRef {
4792
4793                 PrimitiveType elemType; 
4794
4795                 internal SystemClass(PrimitiveType eType, AssemblyRef paren, MetaData md)
4796                         : base("System",eType.GetName(),md) {
4797                                 elemType = eType;
4798                                 parent = paren;
4799                         }
4800
4801                 internal override sealed MetaDataElement GetTypeSpec(MetaData md) 
4802                 {
4803                         if (typeSpec == null) typeSpec = (TypeSpec)elemType.GetTypeSpec(md);
4804                         return typeSpec;
4805                 }
4806
4807
4808                 internal sealed override void TypeSig(MemoryStream str) 
4809                 {
4810                         str.WriteByte(elemType.GetTypeIndex());
4811                 }
4812
4813         }
4814
4815         /**************************************************************************/  
4816         /// <summary>
4817         /// The assembly for mscorlib.  
4818         /// </summary>
4819         public sealed class MSCorLib : AssemblyRef {
4820
4821                 private static readonly int valueTypeIx = 18;
4822                 private readonly string systemName = "System";
4823                 private Class[] systemClasses = new Class[valueTypeIx+2];
4824                 private PrimitiveType[] systemTypes = new PrimitiveType[valueTypeIx];
4825
4826                 private static int[] specialNames = {
4827                         PrimitiveType.Void.GetName().GetHashCode(),
4828                         PrimitiveType.Boolean.GetName().GetHashCode(),
4829                         PrimitiveType.Char.GetName().GetHashCode(),
4830                         PrimitiveType.Int8.GetName().GetHashCode(),
4831                         PrimitiveType.UInt8.GetName().GetHashCode(),
4832                         PrimitiveType.Int16.GetName().GetHashCode(),
4833                         PrimitiveType.UInt16.GetName().GetHashCode(),
4834                         PrimitiveType.Int32.GetName().GetHashCode(),
4835                         PrimitiveType.UInt32.GetName().GetHashCode(),
4836                         PrimitiveType.Int64.GetName().GetHashCode(),
4837                         PrimitiveType.UInt64.GetName().GetHashCode(),
4838                         PrimitiveType.Float32.GetName().GetHashCode(),
4839                         PrimitiveType.Float64.GetName().GetHashCode(),
4840                         PrimitiveType.String.GetName().GetHashCode(),
4841                         PrimitiveType.TypedRef.GetName().GetHashCode(),
4842                         PrimitiveType.IntPtr.GetName().GetHashCode(),
4843                         PrimitiveType.UIntPtr.GetName().GetHashCode(),
4844                         PrimitiveType.Object.GetName().GetHashCode(),
4845                         PrimitiveType.ValueType.GetName ().GetHashCode(),
4846                         "Enum".GetHashCode()
4847                 };
4848
4849                 internal MSCorLib(MetaData md) : base(md,"mscorlib") 
4850                 {
4851                         if (!PEFile.IsMSCorlib)
4852                                 md.AddToTable(MDTable.AssemblyRef,this);
4853                         systemTypes[PrimitiveType.Void.GetSystemTypeIx()] = PrimitiveType.Void;
4854                         systemTypes[PrimitiveType.Boolean.GetSystemTypeIx()] = PrimitiveType.Boolean;
4855                         systemTypes[PrimitiveType.Char.GetSystemTypeIx()] = PrimitiveType.Char;
4856                         systemTypes[PrimitiveType.Int8.GetSystemTypeIx()] = PrimitiveType.Int8;
4857                         systemTypes[PrimitiveType.UInt8.GetSystemTypeIx()] = PrimitiveType.UInt8;
4858                         systemTypes[PrimitiveType.Int16.GetSystemTypeIx()] = PrimitiveType.Int16;
4859                         systemTypes[PrimitiveType.UInt16.GetSystemTypeIx()] = PrimitiveType.UInt16;
4860                         systemTypes[PrimitiveType.Int32.GetSystemTypeIx()] = PrimitiveType.Int32;
4861                         systemTypes[PrimitiveType.UInt32.GetSystemTypeIx()] = PrimitiveType.UInt32;
4862                         systemTypes[PrimitiveType.Int64.GetSystemTypeIx()] = PrimitiveType.Int64;
4863                         systemTypes[PrimitiveType.UInt64.GetSystemTypeIx()] = PrimitiveType.UInt64;
4864                         systemTypes[PrimitiveType.Float32.GetSystemTypeIx()] = PrimitiveType.Float32;
4865                         systemTypes[PrimitiveType.Float64.GetSystemTypeIx()] = PrimitiveType.Float64;
4866                         systemTypes[PrimitiveType.IntPtr.GetSystemTypeIx()] = PrimitiveType.IntPtr;
4867                         systemTypes[PrimitiveType.UIntPtr.GetSystemTypeIx()] = PrimitiveType.UIntPtr;
4868                         systemTypes[PrimitiveType.String.GetSystemTypeIx()] = PrimitiveType.String;
4869                         systemTypes[PrimitiveType.Object.GetSystemTypeIx()] = PrimitiveType.Object;
4870                         systemTypes[PrimitiveType.TypedRef.GetSystemTypeIx()] = PrimitiveType.TypedRef;
4871                 }
4872
4873                 /// <summary>
4874                 /// Add a class to the mscorlib assembly
4875                 /// </summary>
4876                 /// <param name="nsName">name space name</param>
4877                 /// <param name="name">class name</param>
4878                 /// <returns></returns>
4879                 public override ClassRef AddClass(string nsName, string name) 
4880                 {
4881                         /* This gets called by !mscorlib, for adding references INTO mscorlib, so
4882                            it should be returning ClassRef ..*/
4883                         Class aClass = GetSpecialClass(nsName,name);
4884                         if (aClass == null) {
4885                                 aClass = new ClassRef(nsName,name,metaData);
4886                                 metaData.AddToTable(MDTable.TypeRef,aClass);
4887                                 if (aClass is ClassRef)
4888                                         ((ClassRef) aClass).SetParent(this);
4889                         }
4890                         //FIXME: Check for !ClassRef here?
4891                         return (ClassRef) aClass;
4892                 }
4893
4894                 private Class GetSpecialClass(string nsName,string name) 
4895                 {
4896                         if (nsName.CompareTo(systemName) != 0) return null;
4897                         int hash = name.GetHashCode();
4898                         for (int i=0; i < specialNames.Length; i++) {
4899                                 if (hash != specialNames[i])
4900                                         continue;
4901                                 if (systemClasses[i] == null) {
4902                                         if (i < valueTypeIx) {
4903                                                 systemClasses[i] = new SystemClass(systemTypes[i],this,metaData);
4904                                                 if ((systemTypes[i] != PrimitiveType.Object) &&
4905                                                                 (systemTypes[i] != PrimitiveType.String)) {
4906                                                         systemClasses[i].MakeValueClass(ValueClass.ValueType);
4907                                                 }
4908                                         } else {
4909                                                 systemClasses[i] = new ClassRef(nsName,name,metaData);
4910                                                 ((ClassRef) systemClasses[i]).SetParent(this);
4911                                                 if (!ClassDef.IsValueType (nsName, name) && !ClassDef.IsEnum (nsName, name))
4912                                                         systemClasses[i].MakeValueClass(ValueClass.ValueType);
4913                                         }
4914                                         metaData.AddToTable(MDTable.TypeRef,systemClasses[i]);
4915                                 }
4916                                 return systemClasses[i];
4917                         }
4918                         return null;
4919                 }
4920
4921                 internal void SetSpecialSystemClass (string nsName, string name, Class aClass) 
4922                 {
4923                         if (nsName != systemName) return;
4924                         int hash = name.GetHashCode ();
4925                         for (int i = 0; i < specialNames.Length; i++) {
4926                                 if (hash != specialNames [i])
4927                                         continue;
4928                                 if (systemClasses [i] == null) {
4929                                         systemClasses [i] = aClass;
4930                                 }
4931                         }
4932                 }
4933
4934                 internal Class GetSpecialSystemClass(PrimitiveType pType) 
4935                 {
4936                         int ix = pType.GetSystemTypeIx();
4937                         if (systemClasses[ix] == null && !PEFile.IsMSCorlib) {
4938                                 systemClasses[ix] = new SystemClass(pType,this,metaData);
4939                                 metaData.AddToTable(MDTable.TypeRef,systemClasses[ix]);
4940                         }
4941                         return systemClasses[ix];
4942                 }
4943
4944                 private ClassRef GetValueClass(string name, int hash) 
4945                 {
4946                         /* Called by MSCorLib.AddValueClass, which is called by
4947                            !mscorlib, for adding ref to value class INTO mscorlib,
4948                            so this should be classref */
4949                         int ix = valueTypeIx;
4950                         if (hash != specialNames[valueTypeIx]) ix++;
4951                         if (systemClasses[ix] == null) {
4952                                 systemClasses[ix] = new ClassRef(systemName,name,metaData);
4953                                 ((ClassRef) systemClasses[ix]).SetParent(this);
4954                                 ((ClassRef) systemClasses[ix]).MakeValueClass(ValueClass.ValueType);
4955                                 metaData.AddToTable(MDTable.TypeRef,systemClasses[ix]);
4956                         }
4957                         return (ClassRef) systemClasses[ix];
4958                 }
4959
4960                 internal Class ValueType() 
4961                 {
4962                         if (systemClasses[valueTypeIx] == null && !PEFile.IsMSCorlib) {
4963                                 ClassRef valType = new ClassRef("System","ValueType",metaData);
4964                                 valType.SetParent(this);
4965                                 valType.MakeValueClass(ValueClass.ValueType);
4966                                 metaData.AddToTable(MDTable.TypeRef,valType);
4967                                 systemClasses[valueTypeIx] = valType;
4968                         }
4969                         return systemClasses[valueTypeIx];
4970                 }
4971
4972                 internal Class EnumType() 
4973                 {
4974                         /* Called by both mscorlib & !mscorlib, so can be
4975                            either ClassRef or ClassDef */
4976                         //systemClasses [ valueTypeIx + 1] -> System.Enum
4977                         if (systemClasses[valueTypeIx + 1] == null && !PEFile.IsMSCorlib) {
4978                                 ClassRef valType = new ClassRef("System","Enum",metaData);
4979                                 valType.SetParent(this);
4980                                 valType.MakeValueClass(ValueClass.Enum);
4981                                 metaData.AddToTable(MDTable.TypeRef,valType);
4982                                 systemClasses[valueTypeIx + 1] = valType;
4983                         }
4984                         return systemClasses[valueTypeIx + 1];
4985                 }
4986
4987                 /// <summary>
4988                 /// Add a value class to this external assembly
4989                 /// </summary>
4990                 /// <param name="nsName">name space name</param>
4991                 /// <param name="name">class name</param>
4992                 /// <returns></returns>
4993                 public override ClassRef AddValueClass(string nsName, string name) 
4994                 {
4995                         if (nsName.CompareTo(systemName) == 0) {
4996                                 int hash = name.GetHashCode();
4997                                 if ((hash == specialNames[valueTypeIx]) ||
4998                                                 (hash == specialNames[valueTypeIx+1])) {
4999                                         return GetValueClass(name,hash);
5000                                 }
5001                         }
5002                         ClassRef aClass = new ClassRef(nsName,name,metaData);
5003                         metaData.AddToTable(MDTable.TypeRef,aClass);
5004                         aClass.SetParent(this);
5005                         aClass.MakeValueClass(ValueClass.ValueType);
5006                         return aClass;
5007                 }
5008
5009         }
5010
5011         /**************************************************************************/  
5012         /// <summary>
5013         /// MetaData 
5014         ///   Root (20 bytes + UTF-8 Version String + quad align padding)
5015         ///   StreamHeaders (8 bytes + null terminated name string + quad align padding)
5016         ///   Streams 
5017         ///     #~        (always present - holds metadata tables)
5018         ///     #Strings  (always present - holds identifier strings)
5019         ///     #US       (Userstring heap)
5020         ///     #Blob     (signature blobs)
5021         ///     #GUID     (guids for assemblies or Modules)
5022         /// </summary>
5023         public class MetaData  {
5024
5025                 internal static readonly int[] CIxShiftMap = {2,2,5,1,2,3,1,1,1,2,3,2,1};
5026                 private static readonly byte StringsHeapMask = 0x1;
5027                 private static readonly byte GUIDHeapMask = 0x2;
5028                 private static readonly byte BlobHeapMask = 0x4;
5029                 private static readonly uint MetaDataSignature = 0x424A5342;
5030                 private static readonly uint maxSmlIxSize = 0xFFFF;
5031                 private static readonly uint max1BitSmlIx = 0x7FFF;
5032                 private static readonly uint max2BitSmlIx = 0x3FFF;
5033                 private static readonly uint max3BitSmlIx = 0x1FFF;
5034                 private static readonly uint max5BitSmlIx = 0x7FF;
5035                 // NOTE: version and stream name strings MUST always be quad padded
5036                 private static readonly string version = "v4.0.30319\0\0";
5037                 private static readonly char[] tildeName = {'#','~','\0','\0'};
5038                 private static readonly char[] stringsName = {'#','S','t','r','i','n','g','s','\0','\0','\0','\0'};
5039                 private static readonly char[] usName = {'#','U','S','\0'};
5040                 private static readonly char[] guidName = {'#','G','U','I','D','\0','\0','\0'};
5041                 private static readonly char[] blobName = {'#','B','l','o','b','\0','\0','\0'};
5042                 private static readonly uint MetaDataHeaderSize = 20 + (uint)version.Length;
5043                 private static readonly uint TildeHeaderSize = 24;
5044                 private static readonly uint StreamHeaderSize = 8;
5045                 private static readonly uint numMetaDataTables = (int)MDTable.GenericParamConstraint + 1;
5046
5047                 MetaDataStream strings, us, guid, blob;
5048
5049                 MetaDataStream[] streams = new MetaDataStream[5];
5050                 uint numStreams = 5;
5051                 uint tildeTide = 0, tildePadding = 0, tildeStart = 0;
5052                 uint numTables = 0, resourcesSize = 0;
5053                 ArrayList[] metaDataTables = new ArrayList[numMetaDataTables];
5054                 ArrayList byteCodes = new ArrayList();
5055                 uint codeSize = 0, codeStart, byteCodePadding = 0, metaDataSize = 0;
5056                 ulong valid = 0, /*sorted = 0x000002003301FA00;*/ sorted = 0;
5057                 bool[] largeIx = new bool[numMetaDataTables];
5058                 bool[] lgeCIx = new bool[(int)CIx.MaxCIx];
5059                 bool largeStrings = false, largeUS = false, largeGUID = false, largeBlob = false;
5060                 private FileImage file;
5061                 private byte heapSizes = 0;
5062                 MetaDataElement entryPoint;
5063                 BinaryWriter output;
5064                 MSCorLib _mscorlib;
5065                 private TypeSpec[] systemTypeSpecs = new TypeSpec[PrimitiveType.NumSystemTypes];
5066                 long mdStart;
5067                 private ArrayList cattr_list;
5068                 private ArrayList declsec_list;
5069                 ArrayList resources;            
5070
5071                 internal MetaData(FileImage file) 
5072                 {
5073                         // tilde = new MetaDataStream(tildeName,false,0);
5074                         this.file = file;
5075                         strings = new MetaDataStream(stringsName,new UTF8Encoding(),true);
5076                         us = new MetaDataStream(usName,new UnicodeEncoding(),true);
5077                         guid = new MetaDataStream(guidName,false);
5078                         blob = new MetaDataStream(blobName,true);
5079                         streams[1] = strings;
5080                         streams[2] = us;
5081                         streams[3] = guid;
5082                         streams[4] = blob;
5083                         for (int i=0; i < numMetaDataTables; i++) {
5084                                 largeIx[i] = false;
5085                         }
5086                         for (int i=0; i < lgeCIx.Length; i++) {
5087                                 lgeCIx[i] = false;
5088                         }
5089                 }
5090
5091                 public MSCorLib mscorlib {
5092                         get {
5093                                 return _mscorlib ?? (_mscorlib = new MSCorLib (this));
5094                         }
5095                 }
5096
5097
5098                 internal TypeSpec GetPrimitiveTypeSpec(int ix) 
5099                 {
5100                         return systemTypeSpecs[ix];
5101                 }
5102
5103                 internal void SetPrimitiveTypeSpec(int ix, TypeSpec typeSpec) 
5104                 {
5105                         systemTypeSpecs[ix] = typeSpec;
5106                 }
5107
5108                 internal uint Size() 
5109                 {
5110                         return metaDataSize;
5111                 }
5112
5113                 private void CalcHeapSizes ()
5114                 {
5115                         if (strings.LargeIx()) {
5116                                 largeStrings = true;
5117                                 heapSizes |= StringsHeapMask;
5118                         }
5119                         if (guid.LargeIx()) {
5120                                 largeGUID = true;
5121                                 heapSizes |= GUIDHeapMask;
5122                         }
5123                         if (blob.LargeIx()) {
5124                                 largeBlob = true;
5125                                 heapSizes |= BlobHeapMask;
5126                         }
5127
5128                         largeUS = us.LargeIx();
5129                 }
5130
5131                 internal void StreamSize(byte mask) 
5132                 {
5133                         heapSizes |= mask;
5134                 }
5135
5136                 internal uint AddToUSHeap(string str) 
5137                 {
5138                         if (str == null) return 0;
5139                         return us.Add(str,true);
5140                 }
5141
5142                 internal uint AddToUSHeap(byte[] str) 
5143                 {
5144                         if (str == null) return 0;
5145                         return us.Add (str, true);
5146                 }
5147
5148                 internal uint AddToStringsHeap(string str) 
5149                 {
5150                         if ((str == null) || (str.CompareTo("") == 0)) return 0;
5151                         return strings.Add(str,false);
5152                 }
5153
5154                 internal uint AddToGUIDHeap(Guid guidNum) 
5155                 {
5156                         return guid.Add(guidNum, false);
5157                 }
5158
5159                 internal uint AddToBlobHeap(byte[] blobBytes) 
5160                 {
5161                         if (blobBytes == null) return 0;
5162                         return blob.Add(blobBytes, true);
5163                 }
5164
5165                 internal uint AddToBlobHeap(byte val) 
5166                 {
5167                         return blob.Add(val, true);
5168                 }
5169
5170                 internal uint AddToBlobHeap(sbyte val) 
5171                 {
5172                         return blob.Add(val, true);
5173                 }
5174
5175                 internal uint AddToBlobHeap(ushort val) 
5176                 {
5177                         return blob.Add(val, true);
5178                 }
5179
5180                 internal uint AddToBlobHeap(short val) 
5181                 {
5182                         return blob.Add(val, true);
5183                 }
5184
5185                 internal uint AddToBlobHeap(uint val) 
5186                 {
5187                         return blob.Add(val, true);
5188                 }
5189
5190                 internal uint AddToBlobHeap(int val) 
5191                 {
5192                         return blob.Add(val, true);
5193                 }
5194
5195                 internal uint AddToBlobHeap(ulong val) 
5196                 {
5197                         return blob.Add(val, true);
5198                 }
5199
5200                 internal uint AddToBlobHeap(long val) 
5201                 {
5202                         return blob.Add(val, true);
5203                 }
5204
5205                 internal uint AddToBlobHeap(float val) 
5206                 {
5207                         return blob.Add(val, true);
5208                 }
5209
5210                 internal uint AddToBlobHeap(double val) 
5211                 {
5212                         return blob.Add(val, true);
5213                 }
5214
5215                 internal uint AddToBlobHeap(string val) 
5216                 {
5217                         return blob.Add(val,true);
5218                 }
5219
5220                 internal void AddCustomAttribute (CustomAttribute cattr)
5221                 {
5222                         if (cattr_list == null)
5223                                 cattr_list = new ArrayList ();
5224                         cattr_list.Add (cattr);
5225                 }
5226
5227                 internal void AddDeclSecurity (BaseDeclSecurity decl_sec)
5228                 {
5229                         if (declsec_list == null)
5230                                 declsec_list = new ArrayList ();
5231                         declsec_list.Add (decl_sec);
5232                 }
5233
5234                 private ArrayList GetTable(MDTable tableIx) 
5235                 {
5236                         int tabIx = (int)tableIx;
5237                         if (metaDataTables[tabIx] == null) {
5238                                 metaDataTables[tabIx] = new ArrayList();
5239                                 valid |= ((ulong)0x1 << tabIx);
5240                                 // Console.WriteLine("after creating table " + tableIx + "(" + tabIx + ") valid = " + valid);
5241                                 numTables++;
5242                         }
5243                         return metaDataTables[tabIx];
5244                 }
5245
5246                 internal void AddToTable(MDTable tableIx, MetaDataElement elem) 
5247                 {
5248                         if (elem.Row > 0) {
5249                                 // Console.Out.WriteLine("ERROR - element already in table " + tableIx);
5250                                 return;
5251                         }
5252                         // updates Row field of the element
5253                         // Console.WriteLine("Adding element to table " + (uint)tableIx);
5254                         ArrayList table = GetTable(tableIx);
5255                         elem.Row = (uint)table.Count + 1;
5256                         table.Add(elem);
5257                 }
5258
5259                 internal uint TableIndex(MDTable tableIx) 
5260                 {
5261                         if (metaDataTables[(int)tableIx] == null) return 1;
5262                         return (uint)metaDataTables[(int)tableIx].Count+1;
5263                 }
5264
5265                 internal uint AddCode(CILInstructions byteCode) 
5266                 {
5267                         byteCodes.Add(byteCode);
5268                         uint offset = codeSize + codeStart;
5269                         codeSize += byteCode.GetCodeSize();
5270                         return offset;
5271                 }
5272
5273                 internal void SetEntryPoint(MetaDataElement ep) 
5274                 {
5275                         entryPoint = ep;
5276                 }
5277
5278                 internal uint AddResource(byte[] resBytes) 
5279                 {
5280                         if (resources == null) resources = new ArrayList ();
5281                         resources.Add (resBytes);
5282                         uint offset = resourcesSize;
5283                         resourcesSize += (uint)resBytes.Length + 4;
5284                         return offset;
5285                 }
5286
5287                 internal void AddData(DataConstant cVal) 
5288                 {
5289                         file.AddInitData(cVal);
5290                 }
5291
5292                 internal static void CompressNum(uint val, MemoryStream sig) 
5293                 {
5294                         if (val <= 0x7F) {
5295                                 sig.WriteByte((byte)val);
5296                         } else if (val <= 0x3FFF) {
5297                                 byte b1 = (byte)((val >> 8) | 0x80);
5298                                 byte b2 = (byte)(val & FileImage.iByteMask[0]);
5299                                 sig.WriteByte(b1);
5300                                 sig.WriteByte(b2);
5301                         } else {
5302                                 byte b1 = (byte)((val >> 24) | 0xC0);
5303                                 byte b2 = (byte)((val & FileImage.iByteMask[2]) >> 16);
5304                                 byte b3 = (byte)((val & FileImage.iByteMask[1]) >> 8);;
5305                                 byte b4 = (byte)(val & FileImage.iByteMask[0]);
5306                                 sig.WriteByte(b1);
5307                                 sig.WriteByte(b2);
5308                                 sig.WriteByte(b3);
5309                                 sig.WriteByte(b4);
5310                         }
5311                 }
5312
5313                 internal uint CodeSize() 
5314                 {
5315                         return codeSize + byteCodePadding;
5316                 }
5317
5318                 internal uint GetResourcesSize() 
5319                 { 
5320                         return resourcesSize; 
5321                 }
5322
5323                 internal uint StringsIndexSize() 
5324                 {
5325                         if (largeStrings) return 4;
5326                         return 2;
5327                 }
5328
5329                 internal uint GUIDIndexSize() 
5330                 {
5331                         if (largeGUID) return 4;
5332                         return 2;
5333                 }
5334
5335                 internal uint USIndexSize() 
5336                 {
5337                         if (largeUS) return 4;
5338                         return 2;
5339                 }
5340
5341                 internal uint BlobIndexSize() 
5342                 {
5343                         if (largeBlob) return 4;
5344                         return 2;
5345                 }
5346
5347                 internal uint CodedIndexSize(CIx code) 
5348                 {
5349                         if (lgeCIx[(uint)code]) return 4;
5350                         return 2;
5351                 }
5352
5353                 internal uint TableIndexSize(MDTable tabIx) 
5354                 {
5355                         if (largeIx[(uint)tabIx]) return 4;
5356                         return 2;
5357                 }
5358
5359                 private void SetIndexSizes() 
5360                 {
5361                         for (int i=0; i < numMetaDataTables; i++) {
5362                                 if (metaDataTables[i] == null)
5363                                         continue;
5364
5365                                 uint count = (uint)metaDataTables[i].Count;
5366                                 if (count > maxSmlIxSize)
5367                                         largeIx[i] = true;
5368
5369                                 MDTable tabIx = (MDTable)i;
5370                                 if (count > max5BitSmlIx) {
5371                                         if (tabIx == MDTable.Method || tabIx == MDTable.Field || tabIx == MDTable.TypeRef ||
5372                                                 tabIx == MDTable.TypeDef || tabIx == MDTable.Param || tabIx == MDTable.InterfaceImpl ||
5373                                                 tabIx == MDTable.MemberRef || tabIx == MDTable.Module || tabIx == MDTable.DeclSecurity ||
5374                                                 tabIx == MDTable.Property || tabIx == MDTable.Event || tabIx == MDTable.StandAloneSig ||
5375                                                 tabIx == MDTable.ModuleRef || tabIx == MDTable.TypeSpec || tabIx == MDTable.Assembly ||
5376                                                 tabIx == MDTable.AssemblyRef || tabIx == MDTable.File || tabIx == MDTable.ExportedType ||
5377                                                 tabIx == MDTable.ManifestResource || tabIx == MDTable.GenericParam)
5378                                         lgeCIx[(int)CIx.HasCustomAttr] = true;
5379                                 }
5380                                 if (count > max3BitSmlIx) {
5381                                         if (tabIx == MDTable.Method || tabIx == MDTable.MemberRef)
5382                                                 lgeCIx[(int)CIx.CustomAttributeType] = true;
5383                                         if (tabIx == MDTable.TypeDef || tabIx == MDTable.TypeRef || tabIx == MDTable.ModuleRef ||
5384                                                 tabIx == MDTable.Method || tabIx == MDTable.TypeSpec)
5385                                                 lgeCIx[(int)CIx.MemberRefParent] = true;
5386                                 }
5387                                 if (count > max2BitSmlIx) {
5388                                         if ((tabIx == MDTable.Field) || (tabIx == MDTable.Param) || (tabIx == MDTable.Property)) 
5389                                                 lgeCIx[(int)CIx.HasConst] = true;
5390                                         if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.TypeRef) || (tabIx == MDTable.TypeSpec))
5391                                                 lgeCIx[(int)CIx.TypeDefOrRef] = true;
5392                                         if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.Method) || (tabIx == MDTable.Assembly))
5393                                                 lgeCIx[(int)CIx.HasDeclSecurity] = true;
5394                                         if ((tabIx == MDTable.File) || (tabIx == MDTable.AssemblyRef) || (tabIx == MDTable.ExportedType))
5395                                                 lgeCIx[(int)CIx.Implementation] = true;
5396                                         if ((tabIx == MDTable.Module) || (tabIx == MDTable.ModuleRef) || (tabIx == MDTable.AssemblyRef) || (tabIx == MDTable.TypeRef))
5397                                                 lgeCIx[(int)CIx.ResolutionScope] = true;
5398                                 }
5399                                 if (count > max1BitSmlIx) {
5400                                         if ((tabIx == MDTable.Field) || (tabIx == MDTable.Param)) 
5401                                                 lgeCIx[(int)CIx.HasFieldMarshal] = true;
5402                                         if ((tabIx == MDTable.Event) || (tabIx == MDTable.Property)) 
5403                                                 lgeCIx[(int)CIx.HasSemantics] = true;
5404                                         if ((tabIx == MDTable.Method) || (tabIx == MDTable.MemberRef)) 
5405                                                 lgeCIx[(int)CIx.MethodDefOrRef] = true;
5406                                         if ((tabIx == MDTable.Field) || (tabIx == MDTable.Method)) 
5407                                                 lgeCIx[(int)CIx.MemberForwarded] = true; 
5408                                         if ((tabIx == MDTable.TypeDef) || (tabIx == MDTable.Method)) 
5409                                                 lgeCIx[(int)CIx.TypeOrMethodDef] = true; 
5410                                 }
5411                         }
5412                 }
5413
5414                 private void SetStreamOffsets() 
5415                 {
5416                         uint sizeOfHeaders = StreamHeaderSize + (uint)tildeName.Length;
5417                         for (int i=1; i < numStreams; i++) {
5418                                 sizeOfHeaders += streams[i].headerSize();
5419                         }
5420                         metaDataSize = MetaDataHeaderSize + sizeOfHeaders;
5421                         tildeStart = metaDataSize;
5422                         metaDataSize += tildeTide + tildePadding;
5423                         for (int i=1; i < numStreams; i++) {
5424                                 streams[i].Start = metaDataSize;
5425                                 metaDataSize += streams[i].Size();
5426                                 streams[i].WriteDetails();
5427                         }
5428                 }
5429
5430                 internal void CalcTildeStreamSize() 
5431                 {
5432                         CalcHeapSizes ();
5433                         //tilde.SetIndexSizes(strings.LargeIx(),us.LargeIx(),guid.LargeIx(),blob.LargeIx());
5434                         tildeTide = TildeHeaderSize;
5435                         tildeTide += 4 * numTables;
5436                         //Console.WriteLine("Tilde header + sizes = " + tildeTide);
5437                         for (int i=0; i < numMetaDataTables; i++) {
5438                                 if (metaDataTables[i] != null) {
5439                                         ArrayList table = metaDataTables[i];
5440                                         // Console.WriteLine("Meta data table " + i + " at offset " + tildeTide);
5441                                         tildeTide += (uint)table.Count * ((MetaDataElement)table[0]).Size(this);
5442                                         // Console.WriteLine("Metadata table " + i + " has size " + table.Count);
5443                                         // Console.WriteLine("tildeTide = " + tildeTide);
5444                                 }
5445                         }
5446                         if ((tildeTide % 4) != 0) tildePadding = 4 - (tildeTide % 4);
5447                         //Console.WriteLine("tildePadding = " + tildePadding);
5448                 }
5449
5450                 internal void WriteTildeStream(FileImage output) 
5451                 {
5452                         output.Seek(0,SeekOrigin.Current);
5453                         output.Write((uint)0); // Reserved
5454                         output.Write((byte)2); // MajorVersion
5455                         output.Write((byte)0); // MinorVersion
5456                         output.Write(heapSizes);
5457                         output.Write((byte)1); // Reserved
5458                         output.Write(valid);
5459                         output.Write(sorted);
5460                         
5461                         for (int i=0; i < numMetaDataTables; i++) {
5462                                 if (metaDataTables[i] != null) {
5463                                         uint count = (uint)metaDataTables[i].Count;
5464                                         output.Write(count);
5465                                 }
5466                         }
5467                         
5468                         output.Seek(0,SeekOrigin.Current);
5469                         // Console.WriteLine("Starting metaData tables at " + tabStart);
5470                         for (int i=0; i < numMetaDataTables; i++) {
5471                                 if (metaDataTables[i] != null) {
5472                                         // Console.WriteLine("Starting metaData table " + i + " at " + (output.Seek(0,SeekOrigin.Current) - startTilde));
5473                                         ArrayList table = metaDataTables[i];
5474                                         for (int j=0; j < table.Count; j++) {
5475                                                 ((MetaDataElement)table[j]).Write(output);
5476                                         }
5477                                 }
5478                         }
5479                         // Console.WriteLine("Writing padding at " + output.Seek(0,SeekOrigin.Current));
5480                         for (int i=0; i < tildePadding; i++) output.Write((byte)0);
5481                 }
5482
5483                 private void BuildTable(ArrayList table) 
5484                 {
5485                         if (table == null) return;
5486                         for (int j=0; j < table.Count; j++) {
5487                                 ((MetaDataElement)table[j]).BuildTables(this);
5488                         }
5489                 }
5490
5491                 private void SortTable (ArrayList mTable) 
5492                 {
5493                         if (mTable == null) return;
5494                         mTable.Sort();
5495                         for (int i=0; i < mTable.Count; i++) {
5496                                 ((MetaDataElement)mTable[i]).Row = (uint)i+1;
5497                         }
5498                 }
5499
5500                 internal void BuildMetaData(uint codeStartOffset) 
5501                 {
5502                         codeStart = codeStartOffset;
5503                         BuildTable(metaDataTables[(int)MDTable.TypeDef]);
5504                         BuildTable(metaDataTables[(int)MDTable.TypeSpec]);
5505                         BuildTable(metaDataTables[(int)MDTable.MemberRef]);
5506                         BuildTable(metaDataTables[(int)MDTable.GenericParam]);
5507                         BuildTable(metaDataTables[(int)MDTable.MethodSpec]);
5508                         BuildTable(metaDataTables[(int)MDTable.GenericParamConstraint]);
5509                         BuildTable(metaDataTables[(int)MDTable.ManifestResource]);
5510
5511                         if (cattr_list != null) {
5512                                 foreach (CustomAttribute cattr in cattr_list)
5513                                         cattr.BuildTables (this);
5514                         }
5515
5516                         if (declsec_list != null) {
5517                                 foreach (BaseDeclSecurity decl_sec in declsec_list)
5518                                         decl_sec.BuildTables (this);
5519                         }
5520
5521                         /*      for (int i=0; i < metaDataTables.Length; i++) {
5522                                 ArrayList table = metaDataTables[i];
5523                                 if (table != null) {
5524                                 for (int j=0; j < table.Count; j++) {
5525                                 ((MetaDataElement)table[j]).BuildTables(this);
5526                                 }
5527                                 }
5528                                 }
5529                          */
5530
5531                         SetIndexSizes();
5532                         for (int i=1; i < numStreams; i++) {
5533                                 streams[i].EndStream();
5534                         }
5535                         CalcTildeStreamSize();
5536                         SetStreamOffsets();
5537                         byteCodePadding = NumToAlign(codeSize,4);
5538                         if (entryPoint != null) file.SetEntryPoint(entryPoint.Token());
5539
5540                         // Check ordering of specific tables
5541                         // Constant, CustomAttribute, FieldMarshal, DeclSecurity, MethodSemantics
5542                         // ImplMap, GenericParam
5543                         // Need to load GenericParamConstraint AFTER GenericParam table in correct order
5544                         // The tables:
5545                         //   InterfaceImpl, ClassLayout, FieldLayout, MethodImpl, FieldRVA, NestedClass
5546                         // will _ALWAYS_ be in the correct order as embedded in BuildMDTables
5547
5548                         SortTable(metaDataTables[(int)MDTable.Constant]);
5549                         SortTable(metaDataTables[(int)MDTable.FieldMarshal]);
5550                         SortTable(metaDataTables[(int)MDTable.DeclSecurity]);
5551                         SortTable(metaDataTables[(int)MDTable.MethodSemantics]);
5552                         SortTable(metaDataTables[(int)MDTable.ImplMap]);
5553                         if (metaDataTables[(int)MDTable.GenericParam] != null) {
5554                                 SortTable(metaDataTables[(int)MDTable.GenericParam]);
5555                                 // Now add GenericParamConstraints
5556                                 /*for (int i=0; i < metaDataTables[(int)MDTable.GenericParam].Count; i++) {
5557                                   ((GenericParameter)metaDataTables[(int)MDTable.GenericParam][i]).AddConstraints(this);
5558                                   }*/
5559                         }
5560                         SortTable(metaDataTables[(int)MDTable.GenericParamConstraint]);
5561                         SortTable(metaDataTables[(int)MDTable.InterfaceImpl]);
5562                         SortTable(metaDataTables[(int)MDTable.CustomAttribute]);
5563
5564                 }
5565
5566                 internal void WriteByteCodes(FileImage output) 
5567                 {
5568                         for (int i=0; i < byteCodes.Count; i++) {
5569                                 ((CILInstructions)byteCodes[i]).Write(output);
5570                         }
5571                         for (int i=0; i < byteCodePadding; i++) {
5572                                 output.Write((byte)0);
5573                         }
5574                 }
5575
5576                 internal void WriteResources (FileImage output) 
5577                 {
5578                         if (resources == null) return;
5579                         for (int i = 0; i < resources.Count; i ++) {
5580                                 byte [] resBytes = (byte []) resources [i];
5581                                 output.Write ((uint) resBytes.Length);
5582                                 output.Write (resBytes);
5583                         } 
5584                 }
5585
5586                 internal void WriteMetaData(FileImage output) 
5587                 {
5588                         this.output = output;
5589                         mdStart = output.Seek(0,SeekOrigin.Current);
5590                         // Console.WriteLine("Writing metaData at " + Hex.Long(mdStart));
5591                         output.Write(MetaDataSignature);
5592                         output.Write((short)1);  // Major Version
5593                         output.Write((short)1);  // Minor Version  ECMA = 0, PEFiles = 1
5594                         output.Write(0);         // Reserved
5595                         output.Write(version.Length);
5596                         output.Write(version.ToCharArray());   // version string is already zero padded
5597                         output.Write((short)0);
5598                         output.Write((ushort)numStreams);
5599                         // write tilde header
5600                         output.Write(tildeStart);
5601                         output.Write(tildeTide + tildePadding);
5602                         output.Write(tildeName);
5603                         for (int i=1; i < numStreams; i++) streams[i].WriteHeader(output);
5604                         // Console.WriteLine("Writing tilde stream at " + output.Seek(0,SeekOrigin.Current) + " = " + tildeStart);
5605                         WriteTildeStream(output);
5606                         for (int i=1; i < numStreams; i++) streams[i].Write(output);
5607                         // Console.WriteLine("Finished Writing metaData at " + output.Seek(0,SeekOrigin.Current));
5608                 }
5609
5610                 internal bool LargeStringsIndex() { return strings.LargeIx(); }
5611                 internal bool LargeGUIDIndex() { return guid.LargeIx(); }
5612                 internal bool LargeUSIndex() { return us.LargeIx(); }
5613                 internal bool LargeBlobIndex() { return blob.LargeIx(); }
5614
5615                 internal bool LargeIx(MDTable tabIx) { return largeIx[(uint)tabIx]; }
5616
5617
5618                 private uint NumToAlign(uint val, uint alignVal) 
5619                 {
5620                         if ((val % alignVal) == 0) return 0;
5621                         return alignVal - (val % alignVal);
5622                 }
5623
5624                 internal void WriteCodedIndex(CIx code, MetaDataElement elem, FileImage output) 
5625                 {
5626                         uint ix = 0;
5627                         if (elem != null) { 
5628                                 ix = (elem.Row << CIxShiftMap[(uint)code]) | elem.GetCodedIx(code);
5629                                 // Console.WriteLine("coded index = " + ix + " row = " + elem.Row);
5630                                 //} else {
5631                                 // Console.WriteLine("elem for coded index is null");
5632                         }
5633                         if (lgeCIx[(uint)code]) 
5634                                 output.Write(ix);
5635                         else
5636                                 output.Write((ushort)ix);
5637                 }
5638
5639         }
5640
5641         /**************************************************************************/  
5642         /// <summary>
5643         /// Stream in the Meta Data  (#Strings, #US, #Blob and #GUID)
5644         /// </summary>
5645
5646         internal class MetaDataStream : BinaryWriter  {
5647
5648                 private static readonly uint StreamHeaderSize = 8;
5649                 private static uint maxSmlIxSize = 0xFFFF;
5650
5651                 private uint start = 0; 
5652                 uint size = 0, tide = 1;
5653                 bool largeIx = false;
5654                 uint sizeOfHeader;
5655                 char[] name;
5656                 Hashtable htable = new Hashtable();
5657                 Hashtable btable = new Hashtable (new ByteArrayHashCodeProvider (), new ByteArrayComparer ());
5658
5659                 internal MetaDataStream(char[] name, bool addInitByte) : base(new MemoryStream()) 
5660                 {
5661                         if (addInitByte) { Write((byte)0); size = 1; }
5662                         this.name = name;
5663                         sizeOfHeader = StreamHeaderSize + (uint)name.Length;
5664                 }
5665
5666                 internal MetaDataStream(char[] name, System.Text.Encoding enc, bool addInitByte) : base(new MemoryStream(),enc) 
5667                 {
5668                         if (addInitByte) { Write((byte)0); size = 1; }
5669                         this.name = name;
5670                         sizeOfHeader = StreamHeaderSize + (uint)name.Length;
5671                 }
5672
5673                 public uint Start {
5674                         get { return start; }
5675                         set { start = value; }
5676                 }
5677
5678                 internal uint headerSize() 
5679                 {
5680                         // Console.WriteLine(name + " stream has headersize of " + sizeOfHeader);
5681                         return sizeOfHeader;
5682                 }
5683
5684                 internal void SetSize(uint siz) 
5685                 {
5686                         size = siz;
5687                 }
5688
5689                 internal uint Size() 
5690                 {
5691                         return size;
5692                 }
5693
5694                 internal bool LargeIx() 
5695                 {
5696                         return largeIx;
5697                 }
5698
5699                 internal void WriteDetails() 
5700                 {
5701                         // Console.WriteLine(name + " - size = " + size);
5702                 }
5703
5704                 internal uint Add(string str, bool prependSize) 
5705                 {
5706                         Object val = htable[str];
5707                         uint index = 0;
5708                         if (val == null) { 
5709                                 index = size;
5710                                 htable[str] = index;
5711                                 char[] arr = str.ToCharArray();
5712                                 if (prependSize) CompressNum((uint)arr.Length*2+1);
5713                                 Write(arr);
5714                                 Write((byte)0);
5715                                 size = (uint)Seek(0,SeekOrigin.Current);
5716                         } else {
5717                                 index = (uint)val;
5718                         }
5719                         return index;
5720                 }
5721                 internal uint Add (byte[] str, bool prependSize) 
5722                 {
5723                         Object val = btable [str];
5724                         uint index = 0;
5725                         if (val == null) {
5726                                 index = size;
5727                                 btable [str] = index;
5728                                 if (prependSize) CompressNum ((uint) str.Length);
5729                                 Write (str);
5730                                 size = (uint) Seek (0, SeekOrigin.Current);
5731                         } else {
5732                                 index = (uint) val;
5733                         }
5734                         return index;
5735                 }
5736
5737
5738                 internal uint Add(Guid guid, bool prependSize) 
5739                 {
5740                         byte [] b = guid.ToByteArray ();
5741                         if (prependSize) CompressNum ((uint) b.Length);
5742                         Write(guid.ToByteArray());
5743                         size =(uint)Seek(0,SeekOrigin.Current);
5744                         return tide++;
5745                 }
5746
5747                 internal uint Add(byte[] blob) 
5748                 {
5749                         uint ix = size;
5750                         CompressNum((uint)blob.Length);
5751                         Write(blob);
5752                         size = (uint)Seek(0,SeekOrigin.Current);
5753                         return ix;
5754                 }
5755
5756                 internal uint Add(byte val, bool prependSize) 
5757                 {
5758                         uint ix = size;
5759                         if (prependSize) CompressNum (1);
5760                         Write(val);
5761                         size = (uint)Seek(0,SeekOrigin.Current);
5762                         return ix;
5763                 }
5764
5765                 internal uint Add(sbyte val, bool prependSize) 
5766                 {
5767                         uint ix = size;
5768                         if (prependSize) CompressNum (1);
5769                         Write(val);
5770                         size = (uint)Seek(0,SeekOrigin.Current);
5771                         return ix;
5772                 }
5773
5774                 internal uint Add(ushort val, bool prependSize) 
5775                 {
5776                         uint ix = size;
5777                         if (prependSize) CompressNum (2);
5778                         Write(val);
5779                         size = (uint)Seek(0,SeekOrigin.Current);
5780                         return ix;
5781                 }
5782
5783                 internal uint Add(short val, bool prependSize) 
5784                 {
5785                         uint ix = size;
5786                         if (prependSize) CompressNum (2);
5787                         Write(val);
5788                         size = (uint)Seek(0,SeekOrigin.Current);
5789                         return ix;
5790                 }
5791
5792                 internal uint Add(uint val, bool prependSize) 
5793                 {
5794                         uint ix = size;
5795                         if (prependSize) CompressNum (4);
5796                         Write(val);
5797                         size = (uint)Seek(0,SeekOrigin.Current);
5798                         return ix;
5799                 }
5800
5801                 internal uint Add(int val, bool prependSize) 
5802                 {
5803                         uint ix = size;
5804                         if (prependSize) CompressNum (4);
5805                         Write (val);
5806                         size = (uint)Seek(0,SeekOrigin.Current);
5807                         return ix;
5808                 }
5809
5810                 internal uint Add(ulong val, bool prependSize) 
5811                 {
5812                         uint ix = size;
5813                         if (prependSize) CompressNum (8);
5814                         Write(val);
5815                         size = (uint)Seek(0,SeekOrigin.Current);
5816                         return ix;
5817                 }
5818
5819                 internal uint Add(long val, bool prependSize) 
5820                 {
5821                         uint ix = size;
5822                         if (prependSize) CompressNum (8);
5823                         Write(val);
5824                         size = (uint)Seek(0,SeekOrigin.Current);
5825                         return ix;
5826                 }
5827
5828                 internal uint Add(float val, bool prependSize) 
5829                 {
5830                         uint ix = size;
5831                         if (prependSize) CompressNum (4);
5832                         Write(val);
5833                         size = (uint)Seek(0,SeekOrigin.Current);
5834                         return ix;
5835                 }
5836
5837                 internal uint Add(double val, bool prependSize) 
5838                 {
5839                         uint ix = size;
5840                         if (prependSize) CompressNum (8);
5841                         Write(val);
5842                         size = (uint)Seek(0,SeekOrigin.Current);
5843                         return ix;
5844                 }
5845
5846                 private void CompressNum(uint val) 
5847                 {
5848                         if (val < 0x7F) {
5849                                 Write((byte)val);
5850                         } else if (val < 0x3FFF) {
5851                                 byte b1 = (byte)((val >> 8) | 0x80);
5852                                 byte b2 = (byte)(val & FileImage.iByteMask[0]);
5853                                 Write(b1);
5854                                 Write(b2);
5855                         } else {
5856                                 byte b1 = (byte)((val >> 24) | 0xC0);
5857                                 byte b2 = (byte)((val & FileImage.iByteMask[2]) >> 16);
5858                                 byte b3 = (byte)((val & FileImage.iByteMask[1]) >> 8);;
5859                                 byte b4 = (byte)(val & FileImage.iByteMask[0]);
5860                                 Write(b1);
5861                                 Write(b2);
5862                                 Write(b3);
5863                                 Write(b4);
5864                         }
5865                 }
5866
5867                 private void QuadAlign() 
5868                 {
5869                         if ((size % 4) != 0) {
5870                                 uint pad = 4 - (size % 4);
5871                                 size += pad;
5872                                 for (int i=0; i < pad; i++) {
5873                                         Write((byte)0);
5874                                 }
5875                         }
5876                 }
5877
5878                 internal void EndStream() 
5879                 {
5880                         QuadAlign();
5881                         if (size > maxSmlIxSize) {
5882                                 largeIx = true;
5883                         }
5884                 }
5885
5886                 internal void WriteHeader(BinaryWriter output) 
5887                 {
5888                         output.Write(start);
5889                         output.Write(size);
5890                         output.Write(name);
5891                 }
5892
5893                 internal virtual void Write(BinaryWriter output) 
5894                 {
5895                         // Console.WriteLine("Writing " + name + " stream at " + output.Seek(0,SeekOrigin.Current) + " = " + start);
5896                         MemoryStream str = (MemoryStream)BaseStream;
5897                         output.Write(str.ToArray());
5898                 }
5899
5900         }
5901
5902         /**************************************************************************/  
5903         class ByteArrayComparer : IComparer {
5904
5905                 public int Compare (object x, object y)
5906                 {
5907                         byte [] a = (byte []) x;
5908                         byte [] b = (byte []) y;
5909                         int len = a.Length;
5910
5911                         if (b.Length != len)
5912                                 return 1;
5913
5914                         for (int i = 0; i < len; ++i)
5915                                 if (a [i] != b [i])
5916                                         return 1;
5917                         return 0;
5918                 }
5919         }
5920
5921         class ByteArrayHashCodeProvider : IHashCodeProvider {
5922
5923                 public int GetHashCode (Object key)
5924                 {
5925                         byte [] arr = (byte []) key;
5926                         int len = arr.Length;
5927                         int h = 0;
5928
5929                         for (int i = 0; i < len; ++i)
5930                                 h = (h << 5) - h + arr [i];
5931
5932                         return h;
5933                 }
5934
5935         }
5936
5937
5938 }