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