5 // Jb Evain (jbevain@gmail.com)
7 // (C) 2005 - 2007 Jb Evain
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
29 namespace Mono.Cecil {
35 using Mono.Cecil.Binary;
37 using Mono.Cecil.Metadata;
38 using Mono.Cecil.Signatures;
40 internal abstract class ReflectionReader : BaseReflectionReader {
42 ModuleDefinition m_module;
44 SecurityDeclarationReader m_secReader;
45 protected MetadataTableReader m_tableReader;
46 protected MetadataRoot m_root;
47 protected TablesHeap m_tHeap;
48 protected bool m_checkDeleted;
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;
63 AssemblyNameReference m_corlib;
65 protected SignatureReader m_sigReader;
66 protected CodeReader m_codeReader;
67 protected ISymbolReader m_symbolReader;
69 internal AssemblyNameReference Corlib {
74 foreach (AssemblyNameReference ar in m_module.AssemblyReferences) {
75 if (ar.Name == Constants.Corlib) {
85 public ModuleDefinition Module {
86 get { return m_module; }
89 public SignatureReader SigReader {
90 get { return m_sigReader; }
93 public MetadataTableReader TableReader {
94 get { return m_tableReader; }
97 public CodeReader Code {
98 get { return m_codeReader; }
101 public ISymbolReader SymbolReader {
102 get { return m_symbolReader; }
103 set { m_symbolReader = value; }
106 public MetadataRoot MetadataRoot {
107 get { return m_root; }
110 public ReflectionReader (ModuleDefinition 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;
124 public TypeDefinition GetTypeDefAt (uint rid)
126 return m_typeDefs [rid - 1];
129 public TypeReference GetTypeRefAt (uint rid)
131 return m_typeRefs [rid - 1];
134 public TypeReference GetTypeSpecAt (uint rid, GenericContext context)
136 int index = (int) rid - 1;
137 TypeReference tspec = m_typeSpecs [index];
141 TypeSpecTable tsTable = m_tableReader.GetTypeSpecTable ();
142 TypeSpecRow tsRow = tsTable [index];
143 TypeSpec ts = m_sigReader.GetTypeSpec (tsRow.Signature);
144 tspec = GetTypeRefFromSig (ts.Type, context);
145 tspec.MetadataToken = MetadataToken.FromMetadataRow (TokenType.TypeSpec, index);
146 m_typeSpecs [index] = tspec;
151 public FieldDefinition GetFieldDefAt (uint rid)
153 return m_fields [rid - 1];
156 public MethodDefinition GetMethodDefAt (uint rid)
158 return m_meths [rid - 1];
161 protected bool IsDeleted (IMemberDefinition member)
166 if (!member.IsSpecialName || !member.IsRuntimeSpecialName)
169 return member.Name.StartsWith (Constants.Deleted);
172 public MemberReference GetMemberRefAt (uint rid, GenericContext context)
174 int index = (int) rid - 1;
175 MemberReference member = m_memberRefs [rid - 1];
179 MemberRefTable mrTable = m_tableReader.GetMemberRefTable ();
180 MemberRefRow mrefRow = mrTable [index];
182 Signature sig = m_sigReader.GetMemberRefSig (mrefRow.Class.TokenType, mrefRow.Signature);
183 switch (mrefRow.Class.TokenType) {
184 case TokenType.TypeDef :
185 case TokenType.TypeRef :
186 case TokenType.TypeSpec :
187 TypeReference declaringType = GetTypeDefOrRef (mrefRow.Class, context);
188 GenericContext nc = context.Clone ();
190 if (declaringType is GenericInstanceType) {
191 TypeReference ct = declaringType;
192 while (ct is GenericInstanceType)
193 ct = (ct as GenericInstanceType).ElementType;
196 nc.AllowCreation = ct.GetType () == typeof (TypeReference);
199 if (sig is FieldSig) {
200 FieldSig fs = sig as FieldSig;
201 TypeReference fieldType = GetTypeRefFromSig (fs.Type, nc);
202 if (fs.CustomMods.Length > 0)
203 fieldType = GetModifierType (fs.CustomMods, fieldType);
205 member = new FieldReference (
206 m_root.Streams.StringsHeap [mrefRow.Name],
210 string name = m_root.Streams.StringsHeap [mrefRow.Name];
211 MethodSig ms = (MethodSig) sig;
213 member = CreateMethodReferenceFromSig (ms, name, declaringType, nc);
216 case TokenType.Method :
217 // really not sure about this
218 MethodDefinition methdef = GetMethodDefAt (mrefRow.Class.RID);
220 member = CreateMethodReferenceFromSig ((MethodSig) sig, methdef.Name, methdef.DeclaringType, new GenericContext ());
222 case TokenType.ModuleRef :
223 break; // TODO, implement that, or not
226 member.MetadataToken = MetadataToken.FromMetadataRow (TokenType.MemberRef, index);
227 m_module.MemberReferences.Add (member);
228 m_memberRefs [index] = member;
233 MethodReference CreateMethodReferenceFromSig (MethodSig ms, string name, TypeReference declaringType, GenericContext context)
235 MethodReference methref = new MethodReference (
236 name, ms.HasThis, ms.ExplicitThis, ms.MethCallConv);
237 methref.DeclaringType = declaringType;
239 if (ms is MethodDefSig) {
240 int arity = (ms as MethodDefSig).GenericParameterCount;
241 for (int i = 0; i < arity; i++)
242 methref.GenericParameters.Add (new GenericParameter (i, methref));
245 if (methref.GenericParameters.Count > 0)
246 context.Method = methref;
248 methref.ReturnType = GetMethodReturnType (ms, context);
250 methref.ReturnType.Method = methref;
251 for (int j = 0; j < ms.ParamCount; j++) {
252 Param p = ms.Parameters [j];
253 ParameterDefinition pdef = BuildParameterDefinition (j, p, context);
254 pdef.Method = methref;
255 methref.Parameters.Add (pdef);
258 CreateSentinelIfNeeded (methref, ms);
263 public static void CreateSentinelIfNeeded (IMethodSignature meth, MethodSig signature)
265 MethodDefSig sig = signature as MethodDefSig;
269 int sentinel = sig.Sentinel;
271 if (sig.Sentinel < 0 || sig.Sentinel >= meth.Parameters.Count)
274 ParameterDefinition param = meth.Parameters [sentinel];
275 param.ParameterType = new SentinelType (param.ParameterType);
278 public PropertyDefinition GetPropertyDefAt (uint rid)
280 return m_properties [rid - 1];
283 public EventDefinition GetEventDefAt (uint rid)
285 return m_events [rid - 1];
288 public ParameterDefinition GetParamDefAt (uint rid)
290 return m_parameters [rid - 1];
293 public GenericParameter GetGenericParameterAt (uint rid)
295 return m_genericParameters [rid - 1];
298 public GenericInstanceMethod GetMethodSpecAt (uint rid, GenericContext context)
300 int index = (int) rid - 1;
301 GenericInstanceMethod gim = m_methodSpecs [index];
305 MethodSpecTable msTable = m_tableReader.GetMethodSpecTable ();
306 MethodSpecRow msRow = msTable [index];
308 MethodSpec sig = m_sigReader.GetMethodSpec (msRow.Instantiation);
310 MethodReference meth;
311 if (msRow.Method.TokenType == TokenType.Method)
312 meth = GetMethodDefAt (msRow.Method.RID);
313 else if (msRow.Method.TokenType == TokenType.MemberRef)
314 meth = (MethodReference) GetMemberRefAt (msRow.Method.RID, context);
316 throw new ReflectionException ("Unknown method type for method spec");
318 gim = new GenericInstanceMethod (meth);
319 foreach (GenericArg arg in sig.Signature.Types)
320 gim.GenericArguments.Add (GetGenericArg (arg, context));
322 m_methodSpecs [index] = gim;
327 public TypeReference GetTypeDefOrRef (MetadataToken token, GenericContext context)
332 switch (token.TokenType) {
333 case TokenType.TypeDef :
334 return GetTypeDefAt (token.RID);
335 case TokenType.TypeRef :
336 return GetTypeRefAt (token.RID);
337 case TokenType.TypeSpec :
338 return GetTypeSpecAt (token.RID, context);
344 public TypeReference SearchCoreType (string fullName)
347 return m_module.Types [fullName];
349 TypeReference coreType = m_module.TypeReferences [fullName];
350 if (coreType == null) {
352 string [] parts = fullName.Split ('.');
353 if (parts.Length != 2)
354 throw new ReflectionException ("Unvalid core type name");
355 coreType = new TypeReference (parts [1], parts [0], Corlib);
356 m_module.TypeReferences.Add (coreType);
358 if (!coreType.IsValueType) {
359 switch (coreType.FullName) {
360 case Constants.Boolean :
361 case Constants.Char :
362 case Constants.Single :
363 case Constants.Double :
364 case Constants.SByte :
365 case Constants.Byte :
366 case Constants.Int16 :
367 case Constants.UInt16 :
368 case Constants.Int32 :
369 case Constants.UInt32 :
370 case Constants.Int64 :
371 case Constants.UInt64 :
372 case Constants.IntPtr :
373 case Constants.UIntPtr :
374 coreType.IsValueType = true;
381 public IMetadataTokenProvider LookupByToken (MetadataToken token)
383 switch (token.TokenType) {
384 case TokenType.TypeDef :
385 return GetTypeDefAt (token.RID);
386 case TokenType.TypeRef :
387 return GetTypeRefAt (token.RID);
388 case TokenType.Method :
389 return GetMethodDefAt (token.RID);
390 case TokenType.Field :
391 return GetFieldDefAt (token.RID);
392 case TokenType.Event :
393 return GetEventDefAt (token.RID);
394 case TokenType.Property :
395 return GetPropertyDefAt (token.RID);
396 case TokenType.Param :
397 return GetParamDefAt (token.RID);
399 throw new NotSupportedException ("Lookup is not allowed on this kind of token");
403 public CustomAttribute GetCustomAttribute (MethodReference ctor, byte [] data, bool resolve)
405 CustomAttrib sig = m_sigReader.GetCustomAttrib (data, ctor, resolve);
406 return BuildCustomAttribute (ctor, sig);
409 public CustomAttribute GetCustomAttribute (MethodReference ctor, byte [] data)
411 return GetCustomAttribute (ctor, data, false);
414 public override void VisitModuleDefinition (ModuleDefinition mod)
416 VisitTypeDefinitionCollection (mod.Types);
419 public override void VisitTypeDefinitionCollection (TypeDefinitionCollection types)
422 TypeDefTable typesTable = m_tableReader.GetTypeDefTable ();
423 m_typeDefs = new TypeDefinition [typesTable.Rows.Count];
424 for (int i = 0; i < typesTable.Rows.Count; i++) {
425 TypeDefRow type = typesTable [i];
426 TypeDefinition t = new TypeDefinition (
427 m_root.Streams.StringsHeap [type.Name],
428 m_root.Streams.StringsHeap [type.Namespace],
430 t.MetadataToken = MetadataToken.FromMetadataRow (TokenType.TypeDef, i);
436 if (m_tHeap.HasTable (NestedClassTable.RId)) {
437 NestedClassTable nested = m_tableReader.GetNestedClassTable ();
438 for (int i = 0; i < nested.Rows.Count; i++) {
439 NestedClassRow row = nested [i];
441 TypeDefinition parent = GetTypeDefAt (row.EnclosingClass);
442 TypeDefinition child = GetTypeDefAt (row.NestedClass);
444 if (!IsDeleted (child))
445 parent.NestedTypes.Add (child);
449 foreach (TypeDefinition type in m_typeDefs)
450 if (!IsDeleted (type))
454 if (m_tHeap.HasTable (TypeRefTable.RId)) {
455 TypeRefTable typesRef = m_tableReader.GetTypeRefTable ();
457 m_typeRefs = new TypeReference [typesRef.Rows.Count];
459 for (int i = 0; i < typesRef.Rows.Count; i++)
460 AddTypeRef (typesRef, i);
462 m_typeRefs = new TypeReference [0];
468 ReadGenericParameters ();
471 for (int i = 0; i < typesTable.Rows.Count; i++) {
472 TypeDefRow type = typesTable [i];
473 TypeDefinition child = m_typeDefs [i];
474 child.BaseType = GetTypeDefOrRef (type.Extends, new GenericContext (child));
479 ReadMemberReferences ();
482 void AddTypeRef (TypeRefTable typesRef, int i)
484 // Check if index has been already added.
485 if (m_typeRefs [i] != null)
488 TypeRefRow type = typesRef [i];
489 IMetadataScope scope = null;
490 TypeReference parent = null;
492 if (type.ResolutionScope.RID != 0) {
493 int rid = (int) type.ResolutionScope.RID - 1;
494 switch (type.ResolutionScope.TokenType) {
495 case TokenType.AssemblyRef:
496 scope = m_module.AssemblyReferences [rid];
498 case TokenType.ModuleRef:
499 scope = m_module.ModuleReferences [rid];
501 case TokenType.Module:
502 scope = m_module.Assembly.Modules [rid];
504 case TokenType.TypeRef:
505 AddTypeRef (typesRef, rid);
506 parent = GetTypeRefAt (type.ResolutionScope.RID);
507 scope = parent.Scope;
512 TypeReference t = new TypeReference (
513 m_root.Streams.StringsHeap [type.Name],
514 m_root.Streams.StringsHeap [type.Namespace],
516 t.MetadataToken = MetadataToken.FromMetadataRow (TokenType.TypeRef, i);
519 t.DeclaringType = parent;
522 m_module.TypeReferences.Add (t);
525 void ReadTypeSpecs ()
527 if (!m_tHeap.HasTable (TypeSpecTable.RId))
530 TypeSpecTable tsTable = m_tableReader.GetTypeSpecTable ();
531 m_typeSpecs = new TypeReference [tsTable.Rows.Count];
534 void ReadMethodSpecs ()
536 if (!m_tHeap.HasTable (MethodSpecTable.RId))
539 MethodSpecTable msTable = m_tableReader.GetMethodSpecTable ();
540 m_methodSpecs = new GenericInstanceMethod [msTable.Rows.Count];
543 void ReadGenericParameters ()
545 if (!m_tHeap.HasTable (GenericParamTable.RId))
548 GenericParamTable gpTable = m_tableReader.GetGenericParamTable ();
549 m_genericParameters = new GenericParameter [gpTable.Rows.Count];
550 for (int i = 0; i < gpTable.Rows.Count; i++) {
551 GenericParamRow gpRow = gpTable [i];
552 IGenericParameterProvider owner;
553 if (gpRow.Owner.TokenType == TokenType.Method)
554 owner = GetMethodDefAt (gpRow.Owner.RID);
555 else if (gpRow.Owner.TokenType == TokenType.TypeDef)
556 owner = GetTypeDefAt (gpRow.Owner.RID);
558 throw new ReflectionException ("Unknown owner type for generic parameter");
560 GenericParameter gp = new GenericParameter (gpRow.Number, owner);
561 gp.Attributes = gpRow.Flags;
562 gp.Name = MetadataRoot.Streams.StringsHeap [gpRow.Name];
563 gp.MetadataToken = MetadataToken.FromMetadataRow (TokenType.GenericParam, i);
565 owner.GenericParameters.Add (gp);
566 m_genericParameters [i] = gp;
570 void ReadAllFields ()
572 TypeDefTable tdefTable = m_tableReader.GetTypeDefTable ();
574 if (!m_tHeap.HasTable(FieldTable.RId)) {
575 m_fields = new FieldDefinition [0];
579 FieldTable fldTable = m_tableReader.GetFieldTable ();
580 m_fields = new FieldDefinition [fldTable.Rows.Count];
582 for (int i = 0; i < m_typeDefs.Length; i++) {
583 TypeDefinition dec = m_typeDefs [i];
584 GenericContext context = new GenericContext (dec);
588 if (index == tdefTable.Rows.Count - 1)
589 next = fldTable.Rows.Count + 1;
591 next = (int) (tdefTable [index + 1]).FieldList;
593 for (int j = (int) tdefTable [index].FieldList; j < next; j++) {
594 FieldRow frow = fldTable [j - 1];
595 FieldSig fsig = m_sigReader.GetFieldSig (frow.Signature);
597 FieldDefinition fdef = new FieldDefinition (
598 m_root.Streams.StringsHeap [frow.Name],
599 GetTypeRefFromSig (fsig.Type, context), frow.Flags);
600 fdef.MetadataToken = MetadataToken.FromMetadataRow (TokenType.Field, j - 1);
602 if (fsig.CustomMods.Length > 0)
603 fdef.FieldType = GetModifierType (fsig.CustomMods, fdef.FieldType);
605 if (!IsDeleted (fdef))
606 dec.Fields.Add (fdef);
608 m_fields [j - 1] = fdef;
615 if (!m_tHeap.HasTable (MethodTable.RId)) {
616 m_meths = new MethodDefinition [0];
620 MethodTable mTable = m_tableReader.GetMethodTable ();
621 m_meths = new MethodDefinition [mTable.Rows.Count];
622 for (int i = 0; i < mTable.Rows.Count; i++) {
623 MethodRow mRow = mTable [i];
624 MethodDefinition meth = new MethodDefinition (
625 m_root.Streams.StringsHeap [mRow.Name],
628 meth.ImplAttributes = mRow.ImplFlags;
630 meth.MetadataToken = MetadataToken.FromMetadataRow (TokenType.Method, i);
636 void CompleteMethods ()
638 TypeDefTable tdefTable = m_tableReader.GetTypeDefTable ();
640 if (!m_tHeap.HasTable (MethodTable.RId)) {
641 m_meths = new MethodDefinition [0];
645 MethodTable methTable = m_tableReader.GetMethodTable ();
646 ParamTable paramTable = m_tableReader.GetParamTable ();
647 if (!m_tHeap.HasTable (ParamTable.RId))
648 m_parameters = new ParameterDefinition [0];
650 m_parameters = new ParameterDefinition [paramTable.Rows.Count];
652 for (int i = 0; i < m_typeDefs.Length; i++) {
653 TypeDefinition dec = m_typeDefs [i];
657 if (index == tdefTable.Rows.Count - 1)
658 next = methTable.Rows.Count + 1;
660 next = (int) (tdefTable [index + 1]).MethodList;
662 for (int j = (int) tdefTable [index].MethodList; j < next; j++) {
663 MethodRow methRow = methTable [j - 1];
664 MethodDefinition mdef = m_meths [j - 1];
666 if (!IsDeleted(mdef)) {
667 if (mdef.IsConstructor)
668 dec.Constructors.Add (mdef);
670 dec.Methods.Add (mdef);
673 GenericContext context = new GenericContext (mdef);
675 MethodDefSig msig = m_sigReader.GetMethodDefSig (methRow.Signature);
676 mdef.HasThis = msig.HasThis;
677 mdef.ExplicitThis = msig.ExplicitThis;
678 mdef.CallingConvention = msig.MethCallConv;
681 if (j == methTable.Rows.Count)
682 prms = m_parameters.Length + 1;
684 prms = (int) (methTable [j]).ParamList;
686 ParameterDefinition retparam = null;
688 //TODO: optimize this
689 int start = (int) methRow.ParamList - 1;
691 if (paramTable != null && start < prms - 1) {
693 ParamRow pRetRow = paramTable [start];
695 if (pRetRow != null && pRetRow.Sequence == 0) { // ret type
697 retparam = new ParameterDefinition (
698 m_root.Streams.StringsHeap [pRetRow.Name],
703 retparam.Method = mdef;
704 m_parameters [start] = retparam;
709 for (int k = 0; k < msig.ParamCount; k++) {
711 int pointer = start + k;
713 ParamRow pRow = null;
715 if (paramTable != null && pointer < prms - 1)
716 pRow = paramTable [pointer];
718 Param psig = msig.Parameters [k];
720 ParameterDefinition pdef;
722 pdef = BuildParameterDefinition (
723 m_root.Streams.StringsHeap [pRow.Name],
724 pRow.Sequence, pRow.Flags, psig, context);
725 pdef.MetadataToken = MetadataToken.FromMetadataRow (TokenType.Param, pointer);
726 m_parameters [pointer] = pdef;
728 pdef = BuildParameterDefinition (k + 1, psig, context);
731 mdef.Parameters.Add (pdef);
734 mdef.ReturnType = GetMethodReturnType (msig, context);
735 MethodReturnType mrt = mdef.ReturnType;
737 if (retparam != null) {
738 mrt.Parameter = retparam;
739 mrt.Parameter.ParameterType = mrt.ReturnType;
744 uint eprid = CodeReader.GetRid ((int) m_reader.Image.CLIHeader.EntryPointToken);
745 if (eprid > 0 && eprid <= m_meths.Length)
746 m_module.Assembly.EntryPoint = GetMethodDefAt (eprid);
749 void ReadMemberReferences ()
751 if (!m_tHeap.HasTable (MemberRefTable.RId))
754 MemberRefTable mrefTable = m_tableReader.GetMemberRefTable ();
755 m_memberRefs = new MemberReference [mrefTable.Rows.Count];
758 public override void VisitExternTypeCollection (ExternTypeCollection externs)
760 ExternTypeCollection ext = externs;
762 if (!m_tHeap.HasTable (ExportedTypeTable.RId))
765 ExportedTypeTable etTable = m_tableReader.GetExportedTypeTable ();
766 TypeReference [] buffer = new TypeReference [etTable.Rows.Count];
768 for (int i = 0; i < etTable.Rows.Count; i++) {
769 ExportedTypeRow etRow = etTable [i];
770 if (etRow.Implementation.TokenType != TokenType.File)
773 string name = m_root.Streams.StringsHeap [etRow.TypeName];
774 string ns = m_root.Streams.StringsHeap [etRow.TypeNamespace];
776 buffer [i] = m_module.TypeReferences [name];
778 buffer [i] = m_module.TypeReferences [string.Concat (ns, '.', name)];
781 for (int i = 0; i < etTable.Rows.Count; i++) {
782 ExportedTypeRow etRow = etTable [i];
783 if (etRow.Implementation.TokenType != TokenType.ExportedType)
786 TypeReference owner = buffer [etRow.Implementation.RID - 1];
787 string name = m_root.Streams.StringsHeap [etRow.TypeName];
788 buffer [i] = m_module.TypeReferences [string.Concat (owner.FullName, '/', name)];
791 for (int i = 0; i < buffer.Length; i++) {
792 TypeReference curs = buffer [i];
798 static object GetFixedArgValue (CustomAttrib.FixedArg fa)
801 object [] vals = new object [fa.NumElem];
802 for (int j = 0; j < vals.Length; j++)
803 vals [j] = fa.Elems [j].Value;
806 return fa.Elems [0].Value;
809 TypeReference GetFixedArgType (CustomAttrib.FixedArg fa)
813 return new ArrayType (SearchCoreType (Constants.Object));
815 return new ArrayType (fa.Elems [0].ElemType);
817 return fa.Elems [0].ElemType;
820 TypeReference GetNamedArgType (CustomAttrib.NamedArg na)
822 if (na.FieldOrPropType == ElementType.Boxed)
823 return SearchCoreType (Constants.Object);
825 return GetFixedArgType (na.FixedArg);
828 protected CustomAttribute BuildCustomAttribute (MethodReference ctor, CustomAttrib sig)
830 CustomAttribute cattr = new CustomAttribute (ctor);
832 foreach (CustomAttrib.FixedArg fa in sig.FixedArgs)
833 cattr.ConstructorParameters.Add (GetFixedArgValue (fa));
835 foreach (CustomAttrib.NamedArg na in sig.NamedArgs) {
836 object value = GetFixedArgValue (na.FixedArg);
838 cattr.Fields [na.FieldOrPropName] = value;
839 cattr.SetFieldType (na.FieldOrPropName, GetNamedArgType (na));
840 } else if (na.Property) {
841 cattr.Properties [na.FieldOrPropName] = value;
842 cattr.SetPropertyType (na.FieldOrPropName, GetNamedArgType (na));
844 throw new ReflectionException ("Non valid named arg");
850 void CompleteParameter (ParameterDefinition parameter, Param signature, GenericContext context)
852 TypeReference paramType;
855 paramType = new ReferenceType (GetTypeRefFromSig (signature.Type, context));
856 else if (signature.TypedByRef)
857 paramType = SearchCoreType (Constants.TypedReference);
859 paramType = GetTypeRefFromSig (signature.Type, context);
861 if (signature.CustomMods.Length > 0)
862 paramType = GetModifierType (signature.CustomMods, paramType);
864 parameter.ParameterType = paramType;
867 public ParameterDefinition BuildParameterDefinition (int sequence, Param psig, GenericContext context)
869 ParameterDefinition parameter = new ParameterDefinition (null);
870 parameter.Sequence = sequence;
872 CompleteParameter (parameter, psig, context);
877 public ParameterDefinition BuildParameterDefinition (string name, int sequence, ParameterAttributes attrs, Param psig, GenericContext context)
879 ParameterDefinition parameter = new ParameterDefinition (name, sequence, attrs, null);
881 CompleteParameter (parameter, psig, context);
886 protected SecurityDeclaration BuildSecurityDeclaration (DeclSecurityRow dsRow)
888 return BuildSecurityDeclaration (dsRow.Action, m_root.Streams.BlobHeap.Read (dsRow.PermissionSet));
891 public SecurityDeclaration BuildSecurityDeclaration (SecurityAction action, byte [] permset)
893 if (m_secReader == null)
894 m_secReader = new SecurityDeclarationReader (m_root, this);
896 return m_secReader.FromByteArray (action, permset);
899 protected MarshalSpec BuildMarshalDesc (MarshalSig ms, IHasMarshalSpec container)
901 if (ms.Spec is MarshalSig.Array) {
902 ArrayMarshalSpec amd = new ArrayMarshalSpec (container);
903 MarshalSig.Array ar = (MarshalSig.Array) ms.Spec;
904 amd.ElemType = ar.ArrayElemType;
905 amd.NumElem = ar.NumElem;
906 amd.ParamNum = ar.ParamNum;
907 amd.ElemMult = ar.ElemMult;
909 } else if (ms.Spec is MarshalSig.CustomMarshaler) {
910 CustomMarshalerSpec cmd = new CustomMarshalerSpec (container);
911 MarshalSig.CustomMarshaler cmsig = (MarshalSig.CustomMarshaler) ms.Spec;
912 cmd.Guid = cmsig.Guid.Length > 0 ? new Guid (cmsig.Guid) : new Guid ();
913 cmd.UnmanagedType = cmsig.UnmanagedType;
914 cmd.ManagedType = cmsig.ManagedType;
915 cmd.Cookie = cmsig.Cookie;
917 } else if (ms.Spec is MarshalSig.FixedArray) {
918 FixedArraySpec fad = new FixedArraySpec (container);
919 MarshalSig.FixedArray fasig = (MarshalSig.FixedArray) ms.Spec;
920 fad.ElemType = fasig.ArrayElemType;
921 fad.NumElem = fasig.NumElem;
923 } else if (ms.Spec is MarshalSig.FixedSysString) {
924 FixedSysStringSpec fssc = new FixedSysStringSpec (container);
925 fssc.Size = ((MarshalSig.FixedSysString) ms.Spec).Size;
927 } else if (ms.Spec is MarshalSig.SafeArray) {
928 SafeArraySpec sad = new SafeArraySpec (container);
929 sad.ElemType = ((MarshalSig.SafeArray) ms.Spec).ArrayElemType;
932 return new MarshalSpec (ms.NativeInstrinsic, container);
936 public TypeReference GetModifierType (CustomMod [] cmods, TypeReference type)
938 TypeReference ret = type;
939 for (int i = cmods.Length - 1; i >= 0; i--) {
940 CustomMod cmod = cmods [i];
941 TypeReference modType;
943 if (cmod.TypeDefOrRef.TokenType == TokenType.TypeDef)
944 modType = GetTypeDefAt (cmod.TypeDefOrRef.RID);
946 modType = GetTypeRefAt (cmod.TypeDefOrRef.RID);
948 if (cmod.CMOD == CustomMod.CMODType.OPT)
949 ret = new ModifierOptional (ret, modType);
950 else if (cmod.CMOD == CustomMod.CMODType.REQD)
951 ret = new ModifierRequired (ret, modType);
956 public MethodReturnType GetMethodReturnType (MethodSig msig, GenericContext context)
958 TypeReference retType;
959 if (msig.RetType.Void)
960 retType = SearchCoreType (Constants.Void);
961 else if (msig.RetType.ByRef)
962 retType = new ReferenceType (GetTypeRefFromSig (msig.RetType.Type, context));
963 else if (msig.RetType.TypedByRef)
964 retType = SearchCoreType (Constants.TypedReference);
966 retType = GetTypeRefFromSig (msig.RetType.Type, context);
968 if (msig.RetType.CustomMods.Length > 0)
969 retType = GetModifierType (msig.RetType.CustomMods, retType);
971 return new MethodReturnType (retType);
974 public TypeReference GetTypeRefFromSig (SigType t, GenericContext context)
976 switch (t.ElementType) {
977 case ElementType.Class :
978 CLASS c = t as CLASS;
979 return GetTypeDefOrRef (c.Type, context);
980 case ElementType.ValueType :
981 VALUETYPE vt = t as VALUETYPE;
982 TypeReference vtr = GetTypeDefOrRef (vt.Type, context);
983 vtr.IsValueType = true;
985 case ElementType.String :
986 return SearchCoreType (Constants.String);
987 case ElementType.Object :
988 return SearchCoreType (Constants.Object);
989 case ElementType.Void :
990 return SearchCoreType (Constants.Void);
991 case ElementType.Boolean :
992 return SearchCoreType (Constants.Boolean);
993 case ElementType.Char :
994 return SearchCoreType (Constants.Char);
995 case ElementType.I1 :
996 return SearchCoreType (Constants.SByte);
997 case ElementType.U1 :
998 return SearchCoreType (Constants.Byte);
999 case ElementType.I2 :
1000 return SearchCoreType (Constants.Int16);
1001 case ElementType.U2 :
1002 return SearchCoreType (Constants.UInt16);
1003 case ElementType.I4 :
1004 return SearchCoreType (Constants.Int32);
1005 case ElementType.U4 :
1006 return SearchCoreType (Constants.UInt32);
1007 case ElementType.I8 :
1008 return SearchCoreType (Constants.Int64);
1009 case ElementType.U8 :
1010 return SearchCoreType (Constants.UInt64);
1011 case ElementType.R4 :
1012 return SearchCoreType (Constants.Single);
1013 case ElementType.R8 :
1014 return SearchCoreType (Constants.Double);
1015 case ElementType.I :
1016 return SearchCoreType (Constants.IntPtr);
1017 case ElementType.U :
1018 return SearchCoreType (Constants.UIntPtr);
1019 case ElementType.TypedByRef :
1020 return SearchCoreType (Constants.TypedReference);
1021 case ElementType.Array :
1022 ARRAY ary = t as ARRAY;
1023 return new ArrayType (GetTypeRefFromSig (ary.Type, context), ary.Shape);
1024 case ElementType.SzArray :
1025 SZARRAY szary = t as SZARRAY;
1026 ArrayType at = new ArrayType (GetTypeRefFromSig (szary.Type, context));
1028 case ElementType.Ptr :
1029 PTR pointer = t as PTR;
1031 return new PointerType (SearchCoreType (Constants.Void));
1032 return new PointerType (GetTypeRefFromSig (pointer.PtrType, context));
1033 case ElementType.FnPtr :
1034 FNPTR funcptr = t as FNPTR;
1035 FunctionPointerType fnptr = new FunctionPointerType (funcptr.Method.HasThis, funcptr.Method.ExplicitThis,
1036 funcptr.Method.MethCallConv, GetMethodReturnType (funcptr.Method, context));
1038 for (int i = 0; i < funcptr.Method.ParamCount; i++) {
1039 Param p = funcptr.Method.Parameters [i];
1040 fnptr.Parameters.Add (BuildParameterDefinition (i, p, context));
1043 CreateSentinelIfNeeded (fnptr, funcptr.Method);
1046 case ElementType.Var:
1048 if (context.AllowCreation)
1049 CheckGenericParameters (context, var);
1051 if (context.Type is GenericInstanceType)
1052 return (context.Type as GenericInstanceType).GenericArguments [var.Index];
1054 return context.Type.GenericParameters [var.Index];
1055 case ElementType.MVar:
1056 MVAR mvar = t as MVAR;
1057 if (context.Method is GenericInstanceMethod)
1058 return (context.Method as GenericInstanceMethod).GenericArguments [mvar.Index];
1060 return context.Method.GenericParameters [mvar.Index];
1061 case ElementType.GenericInst:
1062 GENERICINST ginst = t as GENERICINST;
1063 GenericInstanceType instance = new GenericInstanceType (GetTypeDefOrRef (ginst.Type, context));
1064 instance.IsValueType = ginst.ValueType;
1066 for (int i = 0; i < ginst.Signature.Arity; i++)
1067 instance.GenericArguments.Add (GetGenericArg (
1068 ginst.Signature.Types [i], context));
1077 TypeReference GetGenericArg (GenericArg arg, GenericContext context)
1079 TypeReference type = GetTypeRefFromSig (arg.Type, context);
1080 if (arg.CustomMods != null && arg.CustomMods.Length > 0)
1081 type = GetModifierType (arg.CustomMods, type);
1085 static void CheckGenericParameters (GenericContext context, VAR v)
1087 for (int i = context.Type.GenericParameters.Count; i <= v.Index; i++)
1088 context.Type.GenericParameters.Add (new GenericParameter (i, context.Type));
1091 protected object GetConstant (uint pos, ElementType elemType)
1093 byte [] constant = m_root.Streams.BlobHeap.Read (pos);
1094 BinaryReader br = new BinaryReader (new MemoryStream (constant));
1097 case ElementType.Boolean :
1098 return br.ReadByte () == 1;
1099 case ElementType.Char :
1100 return (char) br.ReadUInt16 ();
1101 case ElementType.I1 :
1102 return br.ReadSByte ();
1103 case ElementType.I2 :
1104 return br.ReadInt16 ();
1105 case ElementType.I4 :
1106 return br.ReadInt32 ();
1107 case ElementType.I8 :
1108 return br.ReadInt64 ();
1109 case ElementType.U1 :
1110 return br.ReadByte ();
1111 case ElementType.U2 :
1112 return br.ReadUInt16 ();
1113 case ElementType.U4 :
1114 return br.ReadUInt32 ();
1115 case ElementType.U8 :
1116 return br.ReadUInt64 ();
1117 case ElementType.R4 :
1118 return br.ReadSingle ();
1119 case ElementType.R8 :
1120 return br.ReadDouble ();
1121 case ElementType.String :
1122 byte [] bytes = br.ReadBytes (constant.Length);
1123 string str = Encoding.Unicode.GetString (bytes, 0, bytes.Length);
1125 case ElementType.Class :
1128 throw new ReflectionException ("Non valid element in constant table");
1132 protected void SetInitialValue (FieldDefinition field)
1135 TypeReference fieldType = field.FieldType;
1136 switch (fieldType.FullName) {
1137 case Constants.Byte:
1138 case Constants.SByte:
1141 case Constants.Int16:
1142 case Constants.UInt16:
1143 case Constants.Char:
1146 case Constants.Int32:
1147 case Constants.UInt32:
1148 case Constants.Single:
1151 case Constants.Int64:
1152 case Constants.UInt64:
1153 case Constants.Double:
1157 fieldType = fieldType.GetOriginalType ();
1159 TypeDefinition fieldTypeDef = fieldType as TypeDefinition;
1161 if (fieldTypeDef != null)
1162 size = (int) fieldTypeDef.ClassSize;
1166 if (size > 0 && field.RVA != RVA.Zero) {
1167 BinaryReader br = m_reader.MetadataReader.GetDataReader (field.RVA);
1168 field.InitialValue = br == null ? new byte [size] : br.ReadBytes (size);
1170 field.InitialValue = new byte [0];