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