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