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