2008-09-18 Jb Evain <jbevain@novell.com>
[mono.git] / mcs / class / Mono.Cecil / Mono.Cecil / ReflectionReader.cs
1 //
2 // ReflectionReader.cs
3 //
4 // Author:
5 //   Jb Evain (jbevain@gmail.com)
6 //
7 // (C) 2005 - 2007 Jb Evain
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 namespace Mono.Cecil {
30
31         using System;
32         using System.IO;
33         using System.Text;
34
35         using Mono.Cecil.Binary;
36         using Mono.Cecil.Cil;
37         using Mono.Cecil.Metadata;
38         using Mono.Cecil.Signatures;
39
40         internal abstract class ReflectionReader : BaseReflectionReader {
41
42                 ModuleDefinition m_module;
43                 ImageReader m_reader;
44                 SecurityDeclarationReader m_secReader;
45                 protected MetadataTableReader m_tableReader;
46                 protected MetadataRoot m_root;
47                 protected TablesHeap m_tHeap;
48                 protected bool m_checkDeleted;
49
50                 protected TypeDefinition [] m_typeDefs;
51                 protected TypeReference [] m_typeRefs;
52                 protected TypeReference [] m_typeSpecs;
53                 protected MethodDefinition [] m_meths;
54                 protected FieldDefinition [] m_fields;
55                 protected EventDefinition [] m_events;
56                 protected PropertyDefinition [] m_properties;
57                 protected MemberReference [] m_memberRefs;
58                 protected ParameterDefinition [] m_parameters;
59                 protected GenericParameter [] m_genericParameters;
60                 protected GenericInstanceMethod [] m_methodSpecs;
61
62                 bool m_isCorlib;
63                 AssemblyNameReference m_corlib;
64
65                 protected SignatureReader m_sigReader;
66                 protected CodeReader m_codeReader;
67                 protected ISymbolReader m_symbolReader;
68
69                 internal AssemblyNameReference Corlib {
70                         get {
71                                 if (m_corlib != null)
72                                         return m_corlib;
73
74                                 foreach (AssemblyNameReference ar in m_module.AssemblyReferences) {
75                                         if (ar.Name == Constants.Corlib) {
76                                                 m_corlib = ar;
77                                                 return m_corlib;
78                                         }
79                                 }
80
81                                 return null;
82                         }
83                 }
84
85                 public ModuleDefinition Module {
86                         get { return m_module; }
87                 }
88
89                 public SignatureReader SigReader {
90                         get { return m_sigReader; }
91                 }
92
93                 public MetadataTableReader TableReader {
94                         get { return m_tableReader; }
95                 }
96
97                 public CodeReader Code {
98                         get { return m_codeReader; }
99                 }
100
101                 public ISymbolReader SymbolReader {
102                         get { return m_symbolReader; }
103                         set { m_symbolReader = value; }
104                 }
105
106                 public MetadataRoot MetadataRoot {
107                         get { return m_root; }
108                 }
109
110                 public ReflectionReader (ModuleDefinition module)
111                 {
112                         m_module = module;
113                         m_reader = m_module.ImageReader;
114                         m_root = m_module.Image.MetadataRoot;
115                         m_tHeap = m_root.Streams.TablesHeap;
116                         m_checkDeleted = (m_tHeap.HeapSizes & 0x80) != 0;
117                         if (m_reader != null)
118                                 m_tableReader = m_reader.MetadataReader.TableReader;
119                         m_codeReader = new CodeReader (this);
120                         m_sigReader = new SignatureReader (m_root, this);
121                         m_isCorlib = module.Assembly.Name.Name == Constants.Corlib;
122                 }
123
124                 public TypeDefinition GetTypeDefAt (uint rid)
125                 {
126                         if (rid > m_typeDefs.Length)
127                                 return null;
128
129                         return m_typeDefs [rid - 1];
130                 }
131
132                 public TypeReference GetTypeRefAt (uint rid)
133                 {
134                         if (rid > m_typeRefs.Length)
135                                 return null;
136
137                         return m_typeRefs [rid - 1];
138                 }
139
140                 public TypeReference GetTypeSpecAt (uint rid, GenericContext context)
141                 {
142                         if (rid > m_typeSpecs.Length)
143                                 return null;
144
145                         int index = (int) rid - 1;
146                         TypeReference tspec = m_typeSpecs [index];
147                         if (tspec != null)
148                                 return tspec;
149
150                         TypeSpecTable tsTable = m_tableReader.GetTypeSpecTable ();
151                         TypeSpecRow tsRow = tsTable [index];
152                         TypeSpec ts = m_sigReader.GetTypeSpec (tsRow.Signature);
153                         tspec = GetTypeRefFromSig (ts.Type, context);
154                         tspec = GetModifierType (ts.CustomMods, tspec);
155                         tspec.MetadataToken = MetadataToken.FromMetadataRow (TokenType.TypeSpec, index);
156                         m_typeSpecs [index] = tspec;
157
158                         return tspec;
159                 }
160
161                 public FieldDefinition GetFieldDefAt (uint rid)
162                 {
163                         if (rid > m_fields.Length)
164                                 return null;
165
166                         return m_fields [rid - 1];
167                 }
168
169                 public MethodDefinition GetMethodDefAt (uint rid)
170                 {
171                         if (rid > m_meths.Length)
172                                 return null;
173
174                         return m_meths [rid - 1];
175                 }
176
177                 protected bool IsDeleted (IMemberDefinition member)
178                 {
179                         if (!m_checkDeleted)
180                                 return false;
181
182                         if (!member.IsSpecialName || !member.IsRuntimeSpecialName)
183                                 return false;
184
185                         return member.Name.StartsWith (Constants.Deleted);
186                 }
187
188                 public MemberReference GetMemberRefAt (uint rid, GenericContext context)
189                 {
190                         if (rid > m_memberRefs.Length)
191                                 return null;
192
193                         int index = (int) rid - 1;
194                         MemberReference member = m_memberRefs [index];
195                         if (member != null)
196                                 return member;
197
198                         MemberRefTable mrTable = m_tableReader.GetMemberRefTable ();
199                         MemberRefRow mrefRow = mrTable [index];
200
201                         Signature sig = m_sigReader.GetMemberRefSig (mrefRow.Class.TokenType, mrefRow.Signature);
202                         switch (mrefRow.Class.TokenType) {
203                         case TokenType.TypeDef :
204                         case TokenType.TypeRef :
205                         case TokenType.TypeSpec :
206                                 TypeReference declaringType = GetTypeDefOrRef (mrefRow.Class, context);
207                                 GenericContext nc = context.Clone ();
208
209                                 if (declaringType is GenericInstanceType) {
210                                         TypeReference ct = declaringType;
211                                         while (ct is GenericInstanceType)
212                                                 ct = (ct as GenericInstanceType).ElementType;
213
214                                         nc.Type = ct;
215                                 }
216
217                                 if (sig is FieldSig) {
218                                         FieldSig fs = sig as FieldSig;
219                                         TypeReference fieldType = GetTypeRefFromSig (fs.Type, nc);
220                                         fieldType = GetModifierType (fs.CustomMods, fieldType);
221
222                                         member = new FieldReference (
223                                                 m_root.Streams.StringsHeap [mrefRow.Name],
224                                                 declaringType,
225                                                 fieldType);
226                                 } else {
227                                         string name = m_root.Streams.StringsHeap [mrefRow.Name];
228                                         MethodSig ms = (MethodSig) sig;
229
230                                         member = CreateMethodReferenceFromSig (ms, name, declaringType, nc);
231                                 }
232                                 break;
233                         case TokenType.Method :
234                                 // really not sure about this
235                                 MethodDefinition methdef = GetMethodDefAt (mrefRow.Class.RID);
236
237                                 member = CreateMethodReferenceFromSig ((MethodSig) sig, methdef.Name, methdef.DeclaringType, new GenericContext ());
238                                 break;
239                         case TokenType.ModuleRef :
240                                 break; // TODO, implement that, or not
241                         }
242
243                         member.MetadataToken = MetadataToken.FromMetadataRow (TokenType.MemberRef, index);
244                         m_module.MemberReferences.Add (member);
245                         m_memberRefs [index] = member;
246
247                         return member;
248                 }
249
250                 MethodReference CreateMethodReferenceFromSig (MethodSig ms, string name, TypeReference declaringType, GenericContext context)
251                 {
252                         MethodReference methref = new MethodReference (
253                                 name, ms.HasThis, ms.ExplicitThis, ms.MethCallConv);
254                         methref.DeclaringType = declaringType;
255
256                         if (ms is MethodDefSig) {
257                                 int arity = (ms as MethodDefSig).GenericParameterCount;
258                                 for (int i = 0; i < arity; i++)
259                                         methref.GenericParameters.Add (new GenericParameter (i, methref));
260                         }
261
262                         if (methref.GenericParameters.Count > 0)
263                                 context.Method = methref;
264
265                         methref.ReturnType = GetMethodReturnType (ms, context);
266
267                         methref.ReturnType.Method = methref;
268                         for (int j = 0; j < ms.ParamCount; j++) {
269                                 Param p = ms.Parameters [j];
270                                 ParameterDefinition pdef = BuildParameterDefinition (j, p, context);
271                                 pdef.Method = methref;
272                                 methref.Parameters.Add (pdef);
273                         }
274
275                         CreateSentinelIfNeeded (methref, ms);
276
277                         return methref;
278                 }
279
280                 public static void CreateSentinelIfNeeded (IMethodSignature meth, MethodSig signature)
281                 {
282                         MethodDefSig sig = signature as MethodDefSig;
283                         if (sig == null)
284                                 return;
285
286                         int sentinel = sig.Sentinel;
287
288                         if (sig.Sentinel < 0 || sig.Sentinel >= meth.Parameters.Count)
289                                 return;
290
291                         ParameterDefinition param = meth.Parameters [sentinel];
292                         param.ParameterType = new SentinelType (param.ParameterType);
293                 }
294
295                 public PropertyDefinition GetPropertyDefAt (uint rid)
296                 {
297                         if (rid > m_properties.Length)
298                                 return null;
299
300                         return m_properties [rid - 1];
301                 }
302
303                 public EventDefinition GetEventDefAt (uint rid)
304                 {
305                         if (rid > m_events.Length)
306                                 return null;
307
308                         return m_events [rid - 1];
309                 }
310
311                 public ParameterDefinition GetParamDefAt (uint rid)
312                 {
313                         if (rid > m_parameters.Length)
314                                 return null;
315
316                         return m_parameters [rid - 1];
317                 }
318
319                 public GenericParameter GetGenericParameterAt (uint rid)
320                 {
321                         if (rid > m_genericParameters.Length)
322                                 return null;
323
324                         return m_genericParameters [rid - 1];
325                 }
326
327                 public GenericInstanceMethod GetMethodSpecAt (uint rid, GenericContext context)
328                 {
329                         if (rid > m_methodSpecs.Length)
330                                 return null;
331
332                         int index = (int) rid - 1;
333                         GenericInstanceMethod gim = m_methodSpecs [index];
334                         if (gim != null)
335                                 return gim;
336
337                         MethodSpecTable msTable = m_tableReader.GetMethodSpecTable ();
338                         MethodSpecRow msRow = msTable [index];
339
340                         MethodSpec sig = m_sigReader.GetMethodSpec (msRow.Instantiation);
341
342                         MethodReference meth;
343                         if (msRow.Method.TokenType == TokenType.Method)
344                                 meth = GetMethodDefAt (msRow.Method.RID);
345                         else if (msRow.Method.TokenType == TokenType.MemberRef)
346                                 meth = (MethodReference) GetMemberRefAt (msRow.Method.RID, context);
347                         else
348                                 throw new ReflectionException ("Unknown method type for method spec");
349
350                         gim = new GenericInstanceMethod (meth);
351                         context.CheckProvider (meth, sig.Signature.Arity);
352                         foreach (GenericArg arg in sig.Signature.Types)
353                                 gim.GenericArguments.Add (GetGenericArg (arg, context));
354
355                         m_methodSpecs [index] = gim;
356
357                         return gim;
358                 }
359
360                 public TypeReference GetTypeDefOrRef (MetadataToken token, GenericContext context)
361                 {
362                         if (token.RID == 0)
363                                 return null;
364
365                         switch (token.TokenType) {
366                         case TokenType.TypeDef :
367                                 return GetTypeDefAt (token.RID);
368                         case TokenType.TypeRef :
369                                 return GetTypeRefAt (token.RID);
370                         case TokenType.TypeSpec :
371                                 return GetTypeSpecAt (token.RID, context);
372                         default :
373                                 return null;
374                         }
375                 }
376
377                 public TypeReference SearchCoreType (string fullName)
378                 {
379                         if (m_isCorlib)
380                                 return m_module.Types [fullName];
381
382                         TypeReference coreType =  m_module.TypeReferences [fullName];
383                         if (coreType == null) {
384                                 string [] parts = fullName.Split ('.');
385                                 if (parts.Length != 2)
386                                         throw new ReflectionException ("Unvalid core type name");
387                                 coreType = new TypeReference (parts [1], parts [0], Corlib);
388                                 m_module.TypeReferences.Add (coreType);
389                         }
390                         if (!coreType.IsValueType) {
391                                 switch (coreType.FullName) {
392                                 case Constants.Boolean :
393                                 case Constants.Char :
394                                 case Constants.Single :
395                                 case Constants.Double :
396                                 case Constants.SByte :
397                                 case Constants.Byte :
398                                 case Constants.Int16 :
399                                 case Constants.UInt16 :
400                                 case Constants.Int32 :
401                                 case Constants.UInt32 :
402                                 case Constants.Int64 :
403                                 case Constants.UInt64 :
404                                 case Constants.IntPtr :
405                                 case Constants.UIntPtr :
406                                         coreType.IsValueType = true;
407                                         break;
408                                 }
409                         }
410                         return coreType;
411                 }
412
413                 public IMetadataTokenProvider LookupByToken (MetadataToken token)
414                 {
415                         switch (token.TokenType) {
416                         case TokenType.TypeDef :
417                                 return GetTypeDefAt (token.RID);
418                         case TokenType.TypeRef :
419                                 return GetTypeRefAt (token.RID);
420                         case TokenType.Method :
421                                 return GetMethodDefAt (token.RID);
422                         case TokenType.Field :
423                                 return GetFieldDefAt (token.RID);
424                         case TokenType.Event :
425                                 return GetEventDefAt (token.RID);
426                         case TokenType.Property :
427                                 return GetPropertyDefAt (token.RID);
428                         case TokenType.Param :
429                                 return GetParamDefAt (token.RID);
430                         default :
431                                 throw new NotSupportedException ("Lookup is not allowed on this kind of token");
432                         }
433                 }
434
435                 public CustomAttribute GetCustomAttribute (MethodReference ctor, byte [] data, bool resolve)
436                 {
437                         CustomAttrib sig = m_sigReader.GetCustomAttrib (data, ctor, resolve);
438                         return BuildCustomAttribute (ctor, data, sig);
439                 }
440
441                 public CustomAttribute GetCustomAttribute (MethodReference ctor, byte [] data)
442                 {
443                         return GetCustomAttribute (ctor, data, false);
444                 }
445
446                 public override void VisitModuleDefinition (ModuleDefinition mod)
447                 {
448                         VisitTypeDefinitionCollection (mod.Types);
449                 }
450
451                 public override void VisitTypeDefinitionCollection (TypeDefinitionCollection types)
452                 {
453                         // type def reading
454                         TypeDefTable typesTable = m_tableReader.GetTypeDefTable ();
455                         m_typeDefs = new TypeDefinition [typesTable.Rows.Count];
456                         for (int i = 0; i < typesTable.Rows.Count; i++) {
457                                 TypeDefRow type = typesTable [i];
458                                 TypeDefinition t = new TypeDefinition (
459                                         m_root.Streams.StringsHeap [type.Name],
460                                         m_root.Streams.StringsHeap [type.Namespace],
461                                         type.Flags);
462                                 t.MetadataToken = MetadataToken.FromMetadataRow (TokenType.TypeDef, i);
463
464                                 m_typeDefs [i] = t;
465                         }
466
467                         // nested types
468                         if (m_tHeap.HasTable (NestedClassTable.RId)) {
469                                 NestedClassTable nested = m_tableReader.GetNestedClassTable ();
470                                 for (int i = 0; i < nested.Rows.Count; i++) {
471                                         NestedClassRow row = nested [i];
472
473                                         TypeDefinition parent = GetTypeDefAt (row.EnclosingClass);
474                                         TypeDefinition child = GetTypeDefAt (row.NestedClass);
475
476                                         if (!IsDeleted (child))
477                                                 parent.NestedTypes.Add (child);
478                                 }
479                         }
480
481                         foreach (TypeDefinition type in m_typeDefs)
482                                 if (!IsDeleted (type))
483                                         types.Add (type);
484
485                         // type ref reading
486                         if (m_tHeap.HasTable (TypeRefTable.RId)) {
487                                 TypeRefTable typesRef = m_tableReader.GetTypeRefTable ();
488
489                                 m_typeRefs = new TypeReference [typesRef.Rows.Count];
490
491                                 for (int i = 0; i < typesRef.Rows.Count; i++)
492                                         AddTypeRef (typesRef, i);
493                         } else
494                                 m_typeRefs = new TypeReference [0];
495
496                         ReadTypeSpecs ();
497                         ReadMethodSpecs ();
498
499                         ReadMethods ();
500                         ReadGenericParameters ();
501
502                         // set base types
503                         for (int i = 0; i < typesTable.Rows.Count; i++) {
504                                 TypeDefRow type = typesTable [i];
505                                 TypeDefinition child = m_typeDefs [i];
506                                 child.BaseType = GetTypeDefOrRef (type.Extends, new GenericContext (child));
507                         }
508
509                         CompleteMethods ();
510                         ReadAllFields ();
511                         ReadMemberReferences ();
512                 }
513
514                 void AddTypeRef (TypeRefTable typesRef, int i)
515                 {
516                         // Check if index has been already added.
517                         if (m_typeRefs [i] != null)
518                                 return;
519
520                         TypeRefRow type = typesRef [i];
521                         IMetadataScope scope = null;
522                         TypeReference parent = null;
523
524                         if (type.ResolutionScope.RID != 0) {
525                                 int rid = (int) type.ResolutionScope.RID - 1;
526                                 switch (type.ResolutionScope.TokenType) {
527                                 case TokenType.AssemblyRef:
528                                         scope = m_module.AssemblyReferences [rid];
529                                         break;
530                                 case TokenType.ModuleRef:
531                                         scope = m_module.ModuleReferences [rid];
532                                         break;
533                                 case TokenType.Module:
534                                         scope = m_module.Assembly.Modules [rid];
535                                         break;
536                                 case TokenType.TypeRef:
537                                         AddTypeRef (typesRef, rid);
538                                         parent = GetTypeRefAt (type.ResolutionScope.RID);
539                                         scope = parent.Scope;
540                                         break;
541                                 }
542                         }
543
544                         TypeReference t = new TypeReference (
545                                 m_root.Streams.StringsHeap [type.Name],
546                                 m_root.Streams.StringsHeap [type.Namespace],
547                                 scope);
548                         t.MetadataToken = MetadataToken.FromMetadataRow (TokenType.TypeRef, i);
549
550                         if (parent != null)
551                                 t.DeclaringType = parent;
552
553                         m_typeRefs [i] = t;
554                         m_module.TypeReferences.Add (t);
555                 }
556
557                 void ReadTypeSpecs ()
558                 {
559                         if (!m_tHeap.HasTable (TypeSpecTable.RId))
560                                 return;
561
562                         TypeSpecTable tsTable = m_tableReader.GetTypeSpecTable ();
563                         m_typeSpecs = new TypeReference [tsTable.Rows.Count];
564                 }
565
566                 void ReadMethodSpecs ()
567                 {
568                         if (!m_tHeap.HasTable (MethodSpecTable.RId))
569                                 return;
570
571                         MethodSpecTable msTable = m_tableReader.GetMethodSpecTable ();
572                         m_methodSpecs = new GenericInstanceMethod [msTable.Rows.Count];
573                 }
574
575                 void ReadGenericParameters ()
576                 {
577                         if (!m_tHeap.HasTable (GenericParamTable.RId))
578                                 return;
579
580                         GenericParamTable gpTable = m_tableReader.GetGenericParamTable ();
581                         m_genericParameters = new GenericParameter [gpTable.Rows.Count];
582                         for (int i = 0; i < gpTable.Rows.Count; i++) {
583                                 GenericParamRow gpRow = gpTable [i];
584                                 IGenericParameterProvider owner;
585                                 if (gpRow.Owner.TokenType == TokenType.Method)
586                                         owner = GetMethodDefAt (gpRow.Owner.RID);
587                                 else if (gpRow.Owner.TokenType == TokenType.TypeDef)
588                                         owner = GetTypeDefAt (gpRow.Owner.RID);
589                                 else
590                                         throw new ReflectionException ("Unknown owner type for generic parameter");
591
592                                 GenericParameter gp = new GenericParameter (gpRow.Number, owner);
593                                 gp.Attributes = gpRow.Flags;
594                                 gp.Name = MetadataRoot.Streams.StringsHeap [gpRow.Name];
595                                 gp.MetadataToken = MetadataToken.FromMetadataRow (TokenType.GenericParam, i);
596
597                                 owner.GenericParameters.Add (gp);
598                                 m_genericParameters [i] = gp;
599                         }
600                 }
601
602                 void ReadAllFields ()
603                 {
604                         TypeDefTable tdefTable = m_tableReader.GetTypeDefTable ();
605
606                         if (!m_tHeap.HasTable (FieldTable.RId)) {
607                                 m_fields = new FieldDefinition [0];
608                                 return;
609                         }
610
611                         FieldTable fldTable = m_tableReader.GetFieldTable ();
612                         m_fields = new FieldDefinition [fldTable.Rows.Count];
613
614                         for (int i = 0; i < m_typeDefs.Length; i++) {
615                                 TypeDefinition dec = m_typeDefs [i];
616                                 GenericContext context = new GenericContext (dec);
617
618                                 int index = i, next;
619
620                                 if (index == tdefTable.Rows.Count - 1)
621                                         next = fldTable.Rows.Count + 1;
622                                 else
623                                         next = (int) (tdefTable [index + 1]).FieldList;
624
625                                 for (int j = (int) tdefTable [index].FieldList; j < next; j++) {
626                                         FieldRow frow = fldTable [j - 1];
627                                         FieldSig fsig = m_sigReader.GetFieldSig (frow.Signature);
628
629                                         FieldDefinition fdef = new FieldDefinition (
630                                                 m_root.Streams.StringsHeap [frow.Name],
631                                                 GetTypeRefFromSig (fsig.Type, context), frow.Flags);
632                                         fdef.MetadataToken = MetadataToken.FromMetadataRow (TokenType.Field, j - 1);
633
634                                         if (fsig.CustomMods.Length > 0)
635                                                 fdef.FieldType = GetModifierType (fsig.CustomMods, fdef.FieldType);
636
637                                         if (!IsDeleted (fdef))
638                                                 dec.Fields.Add (fdef);
639
640                                         m_fields [j - 1] = fdef;
641                                 }
642                         }
643                 }
644
645                 void ReadMethods ()
646                 {
647                         if (!m_tHeap.HasTable (MethodTable.RId)) {
648                                 m_meths = new MethodDefinition [0];
649                                 return;
650                         }
651
652                         MethodTable mTable = m_tableReader.GetMethodTable ();
653                         m_meths = new MethodDefinition [mTable.Rows.Count];
654                         for (int i = 0; i < mTable.Rows.Count; i++) {
655                                 MethodRow mRow = mTable [i];
656                                 MethodDefinition meth = new MethodDefinition (
657                                         m_root.Streams.StringsHeap [mRow.Name],
658                                         mRow.Flags);
659                                 meth.RVA = mRow.RVA;
660                                 meth.ImplAttributes = mRow.ImplFlags;
661
662                                 meth.MetadataToken = MetadataToken.FromMetadataRow (TokenType.Method, i);
663
664                                 m_meths [i] = meth;
665                         }
666                 }
667
668                 void CompleteMethods ()
669                 {
670                         TypeDefTable tdefTable = m_tableReader.GetTypeDefTable ();
671
672                         if (!m_tHeap.HasTable (MethodTable.RId)) {
673                                 m_meths = new MethodDefinition [0];
674                                 return;
675                         }
676
677                         MethodTable methTable = m_tableReader.GetMethodTable ();
678                         ParamTable paramTable = m_tableReader.GetParamTable ();
679                         if (!m_tHeap.HasTable (ParamTable.RId))
680                                 m_parameters = new ParameterDefinition [0];
681                         else
682                                 m_parameters = new ParameterDefinition [paramTable.Rows.Count];
683
684                         for (int i = 0; i < m_typeDefs.Length; i++) {
685                                 TypeDefinition dec = m_typeDefs [i];
686
687                                 int index = i, next;
688
689                                 if (index == tdefTable.Rows.Count - 1)
690                                         next = methTable.Rows.Count + 1;
691                                 else
692                                         next = (int) (tdefTable [index + 1]).MethodList;
693
694                                 for (int j = (int) tdefTable [index].MethodList; j < next; j++) {
695                                         MethodRow methRow = methTable [j - 1];
696                                         MethodDefinition mdef = m_meths [j - 1];
697
698                                         if (!IsDeleted (mdef)) {
699                                                 if (mdef.IsConstructor)
700                                                         dec.Constructors.Add (mdef);
701                                                 else
702                                                         dec.Methods.Add (mdef);
703                                         }
704
705                                         GenericContext context = new GenericContext (mdef);
706
707                                         MethodDefSig msig = m_sigReader.GetMethodDefSig (methRow.Signature);
708                                         mdef.HasThis = msig.HasThis;
709                                         mdef.ExplicitThis = msig.ExplicitThis;
710                                         mdef.CallingConvention = msig.MethCallConv;
711
712                                         int prms;
713                                         if (j == methTable.Rows.Count)
714                                                 prms = m_parameters.Length + 1;
715                                         else
716                                                 prms = (int) (methTable [j]).ParamList;
717
718                                         ParameterDefinition retparam = null;
719
720                                         //TODO: optimize this
721                                         int start = (int) methRow.ParamList - 1;
722
723                                         if (paramTable != null && start < prms - 1) {
724
725                                                 ParamRow pRetRow = paramTable [start];
726
727                                                 if (pRetRow != null && pRetRow.Sequence == 0) { // ret type
728
729                                                         retparam = new ParameterDefinition (
730                                                                 m_root.Streams.StringsHeap [pRetRow.Name],
731                                                                 0,
732                                                                 pRetRow.Flags,
733                                                                 null);
734
735                                                         retparam.Method = mdef;
736                                                         m_parameters [start] = retparam;
737                                                         start++;
738                                                 }
739                                         }
740
741                                         for (int k = 0; k < msig.ParamCount; k++) {
742
743                                                 int pointer = start + k;
744
745                                                 ParamRow pRow = null;
746
747                                                 if (paramTable != null && pointer < prms - 1)
748                                                         pRow = paramTable [pointer];
749
750                                                 Param psig = msig.Parameters [k];
751
752                                                 ParameterDefinition pdef;
753                                                 if (pRow != null) {
754                                                         pdef = BuildParameterDefinition (
755                                                                 m_root.Streams.StringsHeap [pRow.Name],
756                                                                 pRow.Sequence, pRow.Flags, psig, context);
757                                                         pdef.MetadataToken = MetadataToken.FromMetadataRow (TokenType.Param, pointer);
758                                                         m_parameters [pointer] = pdef;
759                                                 } else
760                                                         pdef = BuildParameterDefinition (k + 1, psig, context);
761
762                                                 pdef.Method = mdef;
763                                                 mdef.Parameters.Add (pdef);
764                                         }
765
766                                         mdef.ReturnType = GetMethodReturnType (msig, context);
767                                         MethodReturnType mrt = mdef.ReturnType;
768                                         mrt.Method = mdef;
769                                         if (retparam != null) {
770                                                 mrt.Parameter = retparam;
771                                                 mrt.Parameter.ParameterType = mrt.ReturnType;
772                                         }
773                                 }
774                         }
775
776                         uint eprid = CodeReader.GetRid ((int) m_reader.Image.CLIHeader.EntryPointToken);
777                         if (eprid > 0 && eprid <= m_meths.Length)
778                                 m_module.Assembly.EntryPoint = GetMethodDefAt (eprid);
779                 }
780
781                 void ReadMemberReferences ()
782                 {
783                         if (!m_tHeap.HasTable (MemberRefTable.RId))
784                                 return;
785
786                         MemberRefTable mrefTable = m_tableReader.GetMemberRefTable ();
787                         m_memberRefs = new MemberReference [mrefTable.Rows.Count];
788                 }
789
790                 public override void VisitExternTypeCollection (ExternTypeCollection externs)
791                 {
792                         ExternTypeCollection ext = externs;
793
794                         if (!m_tHeap.HasTable (ExportedTypeTable.RId))
795                                 return;
796
797                         ExportedTypeTable etTable = m_tableReader.GetExportedTypeTable ();
798                         TypeReference [] buffer = new TypeReference [etTable.Rows.Count];
799
800                         for (int i = 0; i < etTable.Rows.Count; i++) {
801                                 ExportedTypeRow etRow = etTable [i];
802                                 if (etRow.Implementation.TokenType != TokenType.File)
803                                         continue;
804
805                                 string name = m_root.Streams.StringsHeap [etRow.TypeName];
806                                 string ns = m_root.Streams.StringsHeap [etRow.TypeNamespace];
807                                 if (ns.Length == 0)
808                                         buffer [i] = m_module.TypeReferences [name];
809                                 else
810                                         buffer [i] = m_module.TypeReferences [string.Concat (ns, '.', name)];
811                         }
812
813                         for (int i = 0; i < etTable.Rows.Count; i++) {
814                                 ExportedTypeRow etRow = etTable [i];
815                                 if (etRow.Implementation.TokenType != TokenType.ExportedType)
816                                         continue;
817
818                                 TypeReference owner = buffer [etRow.Implementation.RID - 1];
819                                 string name = m_root.Streams.StringsHeap [etRow.TypeName];
820                                 buffer [i] = m_module.TypeReferences [string.Concat (owner.FullName, '/', name)];
821                         }
822
823                         for (int i = 0; i < buffer.Length; i++) {
824                                 TypeReference curs = buffer [i];
825                                 if (curs != null)
826                                         ext.Add (curs);
827                         }
828                 }
829
830                 static object GetFixedArgValue (CustomAttrib.FixedArg fa)
831                 {
832                         if (fa.SzArray) {
833                                 object [] vals = new object [fa.NumElem];
834                                 for (int j = 0; j < vals.Length; j++)
835                                         vals [j] = fa.Elems [j].Value;
836                                 return vals;
837                         } else
838                                 return fa.Elems [0].Value;
839                 }
840
841                 TypeReference GetFixedArgType (CustomAttrib.FixedArg fa)
842                 {
843                         if (fa.SzArray) {
844                                 if (fa.NumElem == 0)
845                                         return new ArrayType (SearchCoreType (Constants.Object));
846                                 else
847                                         return new ArrayType (fa.Elems [0].ElemType);
848                         } else
849                                 return fa.Elems [0].ElemType;
850                 }
851
852                 TypeReference GetNamedArgType (CustomAttrib.NamedArg na)
853                 {
854                         if (na.FieldOrPropType == ElementType.Boxed)
855                                 return SearchCoreType (Constants.Object);
856
857                         return GetFixedArgType (na.FixedArg);
858                 }
859
860                 protected CustomAttribute BuildCustomAttribute (MethodReference ctor, byte [] data, CustomAttrib sig)
861                 {
862                         CustomAttribute cattr = new CustomAttribute (ctor);
863                         if (!sig.Read) {
864                                 cattr.Resolved = false;
865                                 cattr.Blob = data;
866                                 return cattr;
867                         }
868
869                         foreach (CustomAttrib.FixedArg fa in sig.FixedArgs)
870                                 cattr.ConstructorParameters.Add (GetFixedArgValue (fa));
871
872                         foreach (CustomAttrib.NamedArg na in sig.NamedArgs) {
873                                 object value = GetFixedArgValue (na.FixedArg);
874                                 if (na.Field) {
875                                         cattr.Fields [na.FieldOrPropName] = value;
876                                         cattr.SetFieldType (na.FieldOrPropName, GetNamedArgType (na));
877                                 } else if (na.Property) {
878                                         cattr.Properties [na.FieldOrPropName] = value;
879                                         cattr.SetPropertyType (na.FieldOrPropName, GetNamedArgType (na));
880                                 } else
881                                         throw new ReflectionException ("Non valid named arg");
882                         }
883
884                         return cattr;
885                 }
886
887                 void CompleteParameter (ParameterDefinition parameter, Param signature, GenericContext context)
888                 {
889                         TypeReference paramType;
890
891                         if (signature.TypedByRef)
892                                 paramType = SearchCoreType (Constants.TypedReference);
893                         else
894                                 paramType = GetTypeRefFromSig (signature.Type, context);
895
896                         paramType = GetModifierType (signature.CustomMods, paramType);
897
898                         if (signature.ByRef)
899                                 paramType = new ReferenceType (paramType);
900
901                         parameter.ParameterType = paramType;
902                 }
903
904                 public ParameterDefinition BuildParameterDefinition (int sequence, Param psig, GenericContext context)
905                 {
906                         ParameterDefinition parameter = new ParameterDefinition (null);
907                         parameter.Sequence = sequence;
908
909                         CompleteParameter (parameter, psig, context);
910
911                         return parameter;
912                 }
913
914                 public ParameterDefinition BuildParameterDefinition (string name, int sequence, ParameterAttributes attrs, Param psig, GenericContext context)
915                 {
916                         ParameterDefinition parameter = new ParameterDefinition (name, sequence, attrs, null);
917
918                         CompleteParameter (parameter, psig, context);
919
920                         return parameter;
921                 }
922
923                 protected SecurityDeclaration BuildSecurityDeclaration (DeclSecurityRow dsRow)
924                 {
925                         return BuildSecurityDeclaration (dsRow.Action, m_root.Streams.BlobHeap.Read (dsRow.PermissionSet));
926                 }
927
928                 public SecurityDeclaration BuildSecurityDeclaration (SecurityAction action, byte [] permset)
929                 {
930                         if (m_secReader == null)
931                                 m_secReader = new SecurityDeclarationReader (m_root, this);
932
933                         return m_secReader.FromByteArray (action, permset);
934                 }
935
936                 protected MarshalSpec BuildMarshalDesc (MarshalSig ms, IHasMarshalSpec container)
937                 {
938                         if (ms.Spec is MarshalSig.Array) {
939                                 ArrayMarshalSpec amd = new ArrayMarshalSpec (container);
940                                 MarshalSig.Array ar = (MarshalSig.Array) ms.Spec;
941                                 amd.ElemType = ar.ArrayElemType;
942                                 amd.NumElem = ar.NumElem;
943                                 amd.ParamNum = ar.ParamNum;
944                                 amd.ElemMult = ar.ElemMult;
945                                 return amd;
946                         } else if (ms.Spec is MarshalSig.CustomMarshaler) {
947                                 CustomMarshalerSpec cmd = new CustomMarshalerSpec (container);
948                                 MarshalSig.CustomMarshaler cmsig = (MarshalSig.CustomMarshaler) ms.Spec;
949                                 cmd.Guid = cmsig.Guid.Length > 0 ? new Guid (cmsig.Guid) : new Guid ();
950                                 cmd.UnmanagedType = cmsig.UnmanagedType;
951                                 cmd.ManagedType = cmsig.ManagedType;
952                                 cmd.Cookie = cmsig.Cookie;
953                                 return cmd;
954                         } else if (ms.Spec is MarshalSig.FixedArray) {
955                                 FixedArraySpec fad = new FixedArraySpec (container);
956                                 MarshalSig.FixedArray fasig = (MarshalSig.FixedArray) ms.Spec;
957                                 fad.ElemType = fasig.ArrayElemType;
958                                 fad.NumElem = fasig.NumElem;
959                                 return fad;
960                         } else if (ms.Spec is MarshalSig.FixedSysString) {
961                                 FixedSysStringSpec fssc = new FixedSysStringSpec (container);
962                                 fssc.Size = ((MarshalSig.FixedSysString) ms.Spec).Size;
963                                 return fssc;
964                         } else if (ms.Spec is MarshalSig.SafeArray) {
965                                 SafeArraySpec sad = new SafeArraySpec (container);
966                                 sad.ElemType = ((MarshalSig.SafeArray) ms.Spec).ArrayElemType;
967                                 return sad;
968                         } else {
969                                 return new MarshalSpec (ms.NativeInstrinsic, container);
970                         }
971                 }
972
973                 public TypeReference GetModifierType (CustomMod [] cmods, TypeReference type)
974                 {
975                         if (cmods == null || cmods.Length == 0)
976                                 return type;
977
978                         TypeReference ret = type;
979                         for (int i = cmods.Length - 1; i >= 0; i--) {
980                                 CustomMod cmod = cmods [i];
981                                 TypeReference modType;
982
983                                 if (cmod.TypeDefOrRef.RID == 0)
984                                         continue;
985
986                                 if (cmod.TypeDefOrRef.TokenType == TokenType.TypeDef)
987                                         modType = GetTypeDefAt (cmod.TypeDefOrRef.RID);
988                                 else
989                                         modType = GetTypeRefAt (cmod.TypeDefOrRef.RID);
990
991                                 if (cmod.CMOD == CustomMod.CMODType.OPT)
992                                         ret = new ModifierOptional (ret, modType);
993                                 else if (cmod.CMOD == CustomMod.CMODType.REQD)
994                                         ret = new ModifierRequired (ret, modType);
995                         }
996                         return ret;
997                 }
998
999                 public MethodReturnType GetMethodReturnType (MethodSig msig, GenericContext context)
1000                 {
1001                         TypeReference retType;
1002                         if (msig.RetType.Void)
1003                                 retType = SearchCoreType (Constants.Void);
1004                         else if (msig.RetType.TypedByRef)
1005                                 retType = SearchCoreType (Constants.TypedReference);
1006                         else
1007                                 retType = GetTypeRefFromSig (msig.RetType.Type, context);
1008
1009                         retType = GetModifierType (msig.RetType.CustomMods, retType);
1010
1011                         if (msig.RetType.ByRef)
1012                                 retType = new ReferenceType (retType);
1013
1014                         return new MethodReturnType (retType);
1015                 }
1016
1017                 public TypeReference GetTypeRefFromSig (SigType t, GenericContext context)
1018                 {
1019                         switch (t.ElementType) {
1020                         case ElementType.Class :
1021                                 CLASS c = t as CLASS;
1022                                 return GetTypeDefOrRef (c.Type, context);
1023                         case ElementType.ValueType :
1024                                 VALUETYPE vt = t as VALUETYPE;
1025                                 TypeReference vtr = GetTypeDefOrRef (vt.Type, context);
1026                                 vtr.IsValueType = true;
1027                                 return vtr;
1028                         case ElementType.String :
1029                                 return SearchCoreType (Constants.String);
1030                         case ElementType.Object :
1031                                 return SearchCoreType (Constants.Object);
1032                         case ElementType.Void :
1033                                 return SearchCoreType (Constants.Void);
1034                         case ElementType.Boolean :
1035                                 return SearchCoreType (Constants.Boolean);
1036                         case ElementType.Char :
1037                                 return SearchCoreType (Constants.Char);
1038                         case ElementType.I1 :
1039                                 return SearchCoreType (Constants.SByte);
1040                         case ElementType.U1 :
1041                                 return SearchCoreType (Constants.Byte);
1042                         case ElementType.I2 :
1043                                 return SearchCoreType (Constants.Int16);
1044                         case ElementType.U2 :
1045                                 return SearchCoreType (Constants.UInt16);
1046                         case ElementType.I4 :
1047                                 return SearchCoreType (Constants.Int32);
1048                         case ElementType.U4 :
1049                                 return SearchCoreType (Constants.UInt32);
1050                         case ElementType.I8 :
1051                                 return SearchCoreType (Constants.Int64);
1052                         case ElementType.U8 :
1053                                 return SearchCoreType (Constants.UInt64);
1054                         case ElementType.R4 :
1055                                 return SearchCoreType (Constants.Single);
1056                         case ElementType.R8 :
1057                                 return SearchCoreType (Constants.Double);
1058                         case ElementType.I :
1059                                 return SearchCoreType (Constants.IntPtr);
1060                         case ElementType.U :
1061                                 return SearchCoreType (Constants.UIntPtr);
1062                         case ElementType.TypedByRef :
1063                                 return SearchCoreType (Constants.TypedReference);
1064                         case ElementType.Array :
1065                                 ARRAY ary = t as ARRAY;
1066                                 return new ArrayType (GetTypeRefFromSig (ary.Type, context), ary.Shape);
1067                         case ElementType.SzArray :
1068                                 SZARRAY szary = t as SZARRAY;
1069                                 ArrayType at = new ArrayType (GetTypeRefFromSig (szary.Type, context));
1070                                 return at;
1071                         case ElementType.Ptr :
1072                                 PTR pointer = t as PTR;
1073                                 if (pointer.Void)
1074                                         return new PointerType (SearchCoreType (Constants.Void));
1075                                 return new PointerType (GetTypeRefFromSig (pointer.PtrType, context));
1076                         case ElementType.FnPtr :
1077                                 FNPTR funcptr = t as FNPTR;
1078                                 FunctionPointerType fnptr = new FunctionPointerType (funcptr.Method.HasThis, funcptr.Method.ExplicitThis,
1079                                         funcptr.Method.MethCallConv, GetMethodReturnType (funcptr.Method, context));
1080
1081                                 for (int i = 0; i < funcptr.Method.ParamCount; i++) {
1082                                         Param p = funcptr.Method.Parameters [i];
1083                                         fnptr.Parameters.Add (BuildParameterDefinition (i, p, context));
1084                                 }
1085
1086                                 CreateSentinelIfNeeded (fnptr, funcptr.Method);
1087
1088                                 return fnptr;
1089                         case ElementType.Var:
1090                                 VAR var = t as VAR;
1091                                 context.CheckProvider (context.Type, var.Index + 1);
1092
1093                                 if (context.Type is GenericInstanceType)
1094                                         return (context.Type as GenericInstanceType).GenericArguments [var.Index];
1095                                 else
1096                                         return context.Type.GenericParameters [var.Index];
1097                         case ElementType.MVar:
1098                                 MVAR mvar = t as MVAR;
1099                                 context.CheckProvider (context.Method, mvar.Index + 1);
1100
1101                                 if (context.Method is GenericInstanceMethod)
1102                                         return (context.Method as GenericInstanceMethod).GenericArguments [mvar.Index];
1103                                 else
1104                                         return context.Method.GenericParameters [mvar.Index];
1105                         case ElementType.GenericInst:
1106                                 GENERICINST ginst = t as GENERICINST;
1107                                 GenericInstanceType instance = new GenericInstanceType (GetTypeDefOrRef (ginst.Type, context));
1108                                 instance.IsValueType = ginst.ValueType;
1109                                 context.CheckProvider (instance.GetOriginalType (), ginst.Signature.Arity);
1110
1111                                 for (int i = 0; i < ginst.Signature.Arity; i++)
1112                                         instance.GenericArguments.Add (GetGenericArg (
1113                                                 ginst.Signature.Types [i], context));
1114
1115                                 return instance;
1116                         default:
1117                                 break;
1118                         }
1119                         return null;
1120                 }
1121
1122                 TypeReference GetGenericArg (GenericArg arg, GenericContext context)
1123                 {
1124                         TypeReference type = GetTypeRefFromSig (arg.Type, context);
1125                         type = GetModifierType (arg.CustomMods, type);
1126                         return type;
1127                 }
1128
1129                 static bool IsOdd (int i)
1130                 {
1131                         return (i & 1) == 1;
1132                 }
1133
1134                 protected object GetConstant (uint pos, ElementType elemType)
1135                 {
1136                         if (elemType == ElementType.Class)
1137                                 return null;
1138
1139                         byte [] constant = m_root.Streams.BlobHeap.Read (pos);
1140
1141                         if (elemType == ElementType.String) {
1142                                 int length = constant.Length;
1143                                 if (IsOdd (length))
1144                                         length--;
1145
1146                                 return Encoding.Unicode.GetString (constant, 0, length);
1147                         }
1148
1149                         // One byte types can always be read using BitConverter. However it can't be used
1150                         // elsewhere since it behaves differently in Mono compared to CF on BE architectures
1151                         switch (elemType) {
1152                         case ElementType.Boolean :
1153                                 return BitConverter.ToBoolean (constant, 0);
1154                         case ElementType.I1 :
1155                                 return (sbyte) constant [0];
1156                         case ElementType.U1 :
1157                                 return (byte) constant [0];
1158                         case ElementType.Object: // illegal, but foundable
1159                                 return null;
1160                         default :
1161                                 if (BitConverter.IsLittleEndian)
1162                                         return GetConstantLittleEndian (elemType, constant);
1163                                 else
1164                                         return GetConstantBigEndian (elemType, constant);
1165                         }
1166                 }
1167
1168                 static object GetConstantLittleEndian (ElementType elemType, byte [] constant)
1169                 {
1170                         switch (elemType) {
1171                         case ElementType.Char :
1172                                 return BitConverter.ToChar (constant, 0);
1173                         case ElementType.I2 :
1174                                 return BitConverter.ToInt16 (constant, 0);
1175                         case ElementType.I4 :
1176                                 return BitConverter.ToInt32 (constant, 0);
1177                         case ElementType.I8 :
1178                                 return BitConverter.ToInt64 (constant, 0);
1179                         case ElementType.U2 :
1180                                 return BitConverter.ToUInt16 (constant, 0);
1181                         case ElementType.U4 :
1182                                 return BitConverter.ToUInt32 (constant, 0);
1183                         case ElementType.U8 :
1184                                 return BitConverter.ToUInt64 (constant, 0);
1185                         case ElementType.R4 :
1186                                 return BitConverter.ToSingle (constant, 0);
1187                         case ElementType.R8 :
1188                                 return BitConverter.ToDouble (constant, 0);
1189                         default:
1190                                 throw new ReflectionException ("Non valid element in constant table");
1191                         }
1192                 }
1193
1194                 static object GetConstantBigEndian (ElementType elemType, byte [] constant)
1195                 {
1196                         // BinaryReader always read it's data in LE format
1197                         // note: this could be further optimized (even without unsafe code)
1198                         BinaryReader br = new BinaryReader (new MemoryStream (constant));
1199                         switch (elemType) {
1200                         case ElementType.Char :
1201                                 return (char) br.ReadUInt16 ();
1202                         case ElementType.I2 :
1203                                 return br.ReadInt16 ();
1204                         case ElementType.I4 :
1205                                 return br.ReadInt32 ();
1206                         case ElementType.I8 :
1207                                 return br.ReadInt64 ();
1208                         case ElementType.U2 :
1209                                 return br.ReadUInt16 ();
1210                         case ElementType.U4 :
1211                                 return br.ReadUInt32 ();
1212                         case ElementType.U8 :
1213                                 return br.ReadUInt64 ();
1214                         case ElementType.R4 :
1215                                 return br.ReadSingle ();
1216                         case ElementType.R8 :
1217                                 return br.ReadDouble ();
1218                         default:
1219                                 throw new ReflectionException ("Non valid element in constant table");
1220                         }
1221                 }
1222
1223                 protected void SetInitialValue (FieldDefinition field)
1224                 {
1225                         int size = 0;
1226                         TypeReference fieldType = field.FieldType;
1227                         switch (fieldType.FullName) {
1228                         case Constants.Boolean:
1229                         case Constants.Byte:
1230                         case Constants.SByte:
1231                                 size = 1;
1232                                 break;
1233                         case Constants.Int16:
1234                         case Constants.UInt16:
1235                         case Constants.Char:
1236                                 size = 2;
1237                                 break;
1238                         case Constants.Int32:
1239                         case Constants.UInt32:
1240                         case Constants.Single:
1241                                 size = 4;
1242                                 break;
1243                         case Constants.Int64:
1244                         case Constants.UInt64:
1245                         case Constants.Double:
1246                                 size = 8;
1247                                 break;
1248                         default:
1249                                 fieldType = fieldType.GetOriginalType ();
1250
1251                                 TypeDefinition fieldTypeDef = fieldType as TypeDefinition;
1252
1253                                 if (fieldTypeDef != null)
1254                                         size = (int) fieldTypeDef.ClassSize;
1255                                 break;
1256                         }
1257
1258                         if (size > 0 && field.RVA != RVA.Zero) {
1259                                 byte [] data = new byte [size];
1260                                 Section sect = m_reader.Image.GetSectionAtVirtualAddress (field.RVA);
1261                                 if (sect != null)
1262                                         Buffer.BlockCopy (sect.Data, (int) (long) (field.RVA - sect.VirtualAddress), data, 0, size);
1263                                 field.InitialValue = data;
1264                         } else
1265                                 field.InitialValue = new byte [0];
1266                 }
1267         }
1268 }