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