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