5 // Jb Evain (jbevain@gmail.com)
7 // Copyright (c) 2008 - 2010 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.
30 using System.Collections.Generic;
34 using Mono.Collections.Generic;
36 using Mono.Cecil.Metadata;
39 using RVA = System.UInt32;
41 namespace Mono.Cecil {
43 abstract class ModuleReader {
45 readonly protected Image image;
46 readonly protected ModuleDefinition module;
48 protected ModuleReader (Image image, ReadingMode mode)
51 this.module = new ModuleDefinition (image);
52 this.module.ReadingMode = mode;
55 protected abstract void ReadModule ();
57 protected void ReadModuleManifest (MetadataReader reader)
59 reader.Populate (module);
61 ReadAssembly (reader);
64 void ReadAssembly (MetadataReader reader)
66 var name = reader.ReadAssemblyNameDefinition ();
68 module.kind = ModuleKind.NetModule;
72 var assembly = new AssemblyDefinition ();
75 module.assembly = assembly;
76 assembly.main_module = module;
79 public static ModuleDefinition CreateModuleFrom (Image image, ReaderParameters parameters)
81 var module = ReadModule (image, parameters);
83 ReadSymbols (module, parameters);
85 if (parameters.AssemblyResolver != null)
86 module.assembly_resolver = parameters.AssemblyResolver;
91 static void ReadSymbols (ModuleDefinition module, ReaderParameters parameters)
93 var symbol_reader_provider = parameters.SymbolReaderProvider;
95 if (symbol_reader_provider == null && parameters.ReadSymbols)
96 symbol_reader_provider = SymbolProvider.GetPlatformReaderProvider ();
98 if (symbol_reader_provider != null) {
99 module.SymbolReaderProvider = symbol_reader_provider;
101 var reader = parameters.SymbolStream != null
102 ? symbol_reader_provider.GetSymbolReader (module, parameters.SymbolStream)
103 : symbol_reader_provider.GetSymbolReader (module, module.FullyQualifiedName);
105 module.ReadSymbols (reader);
109 static ModuleDefinition ReadModule (Image image, ReaderParameters parameters)
111 var reader = CreateModuleReader (image, parameters.ReadingMode);
112 reader.ReadModule ();
113 return reader.module;
116 static ModuleReader CreateModuleReader (Image image, ReadingMode mode)
119 case ReadingMode.Immediate:
120 return new ImmediateModuleReader (image);
121 case ReadingMode.Deferred:
122 return new DeferredModuleReader (image);
124 throw new ArgumentException ();
129 sealed class ImmediateModuleReader : ModuleReader {
131 public ImmediateModuleReader (Image image)
132 : base (image, ReadingMode.Immediate)
136 protected override void ReadModule ()
138 this.module.Read (this.module, (module, reader) => {
139 ReadModuleManifest (reader);
145 public static void ReadModule (ModuleDefinition module)
147 if (module.HasAssemblyReferences)
148 Read (module.AssemblyReferences);
149 if (module.HasResources)
150 Read (module.Resources);
151 if (module.HasModuleReferences)
152 Read (module.ModuleReferences);
154 ReadTypes (module.Types);
155 if (module.HasExportedTypes)
156 Read (module.ExportedTypes);
157 if (module.HasCustomAttributes)
158 Read (module.CustomAttributes);
160 var assembly = module.Assembly;
161 if (assembly == null)
164 if (assembly.HasCustomAttributes)
165 Read (assembly.CustomAttributes);
166 if (assembly.HasSecurityDeclarations)
167 Read (assembly.SecurityDeclarations);
170 static void ReadTypes (Collection<TypeDefinition> types)
172 for (int i = 0; i < types.Count; i++)
173 ReadType (types [i]);
176 static void ReadType (TypeDefinition type)
178 ReadGenericParameters (type);
180 if (type.HasInterfaces)
181 Read (type.Interfaces);
183 if (type.HasNestedTypes)
184 ReadTypes (type.NestedTypes);
186 if (type.HasLayoutInfo)
187 Read (type.ClassSize);
195 if (type.HasProperties)
196 ReadProperties (type);
201 ReadSecurityDeclarations (type);
202 ReadCustomAttributes (type);
205 static void ReadGenericParameters (IGenericParameterProvider provider)
207 if (!provider.HasGenericParameters)
210 var parameters = provider.GenericParameters;
212 for (int i = 0; i < parameters.Count; i++) {
213 var parameter = parameters [i];
215 if (parameter.HasConstraints)
216 Read (parameter.Constraints);
218 if (parameter.HasCustomAttributes)
219 Read (parameter.CustomAttributes);
223 static void ReadSecurityDeclarations (ISecurityDeclarationProvider provider)
225 if (provider.HasSecurityDeclarations)
226 Read (provider.SecurityDeclarations);
229 static void ReadCustomAttributes (ICustomAttributeProvider provider)
231 if (provider.HasCustomAttributes)
232 Read (provider.CustomAttributes);
235 static void ReadFields (TypeDefinition type)
237 var fields = type.Fields;
239 for (int i = 0; i < fields.Count; i++) {
240 var field = fields [i];
242 if (field.HasConstant)
243 Read (field.Constant);
245 if (field.HasLayoutInfo)
249 Read (field.InitialValue);
251 if (field.HasMarshalInfo)
252 Read (field.MarshalInfo);
254 ReadCustomAttributes (field);
258 static void ReadMethods (TypeDefinition type)
260 var methods = type.Methods;
262 for (int i = 0; i < methods.Count; i++) {
263 var method = methods [i];
265 ReadGenericParameters (method);
267 if (method.HasParameters)
268 ReadParameters (method);
270 if (method.HasOverrides)
271 Read (method.Overrides);
273 if (method.IsPInvokeImpl)
274 Read (method.PInvokeInfo);
276 ReadSecurityDeclarations (method);
277 ReadCustomAttributes (method);
279 var return_type = method.MethodReturnType;
280 if (return_type.HasConstant)
281 Read (return_type.Constant);
283 if (return_type.HasMarshalInfo)
284 Read (return_type.MarshalInfo);
286 ReadCustomAttributes (return_type);
290 static void ReadParameters (MethodDefinition method)
292 var parameters = method.Parameters;
294 for (int i = 0; i < parameters.Count; i++) {
295 var parameter = parameters [i];
297 if (parameter.HasConstant)
298 Read (parameter.Constant);
300 if (parameter.HasMarshalInfo)
301 Read (parameter.MarshalInfo);
303 ReadCustomAttributes (parameter);
307 static void ReadProperties (TypeDefinition type)
309 var properties = type.Properties;
311 for (int i = 0; i < properties.Count; i++) {
312 var property = properties [i];
314 Read (property.GetMethod);
316 if (property.HasConstant)
317 Read (property.Constant);
319 ReadCustomAttributes (property);
323 static void ReadEvents (TypeDefinition type)
325 var events = type.Events;
327 for (int i = 0; i < events.Count; i++) {
328 var @event = events [i];
330 Read (@event.AddMethod);
332 ReadCustomAttributes (@event);
336 static void Read (object collection)
341 sealed class DeferredModuleReader : ModuleReader {
343 public DeferredModuleReader (Image image)
344 : base (image, ReadingMode.Deferred)
348 protected override void ReadModule ()
350 this.module.Read (this.module, (module, reader) => {
351 ReadModuleManifest (reader);
357 sealed class MetadataReader : ByteBuffer {
359 readonly internal Image image;
360 readonly internal ModuleDefinition module;
361 readonly internal MetadataSystem metadata;
363 internal IGenericContext context;
364 internal CodeReader code;
367 get { return (uint) base.position; }
368 set { base.position = (int) value; }
371 public MetadataReader (ModuleDefinition module)
372 : base (module.Image.MetadataSection.Data)
374 this.image = module.Image;
375 this.module = module;
376 this.metadata = module.MetadataSystem;
377 this.code = CodeReader.CreateCodeReader (this);
380 int GetCodedIndexSize (CodedIndex index)
382 return image.GetCodedIndexSize (index);
385 uint ReadByIndexSize (int size)
388 return ReadUInt32 ();
390 return ReadUInt16 ();
395 var blob_heap = image.BlobHeap;
396 if (blob_heap == null) {
398 return Empty<byte>.Array;
401 return blob_heap.Read (ReadBlobIndex ());
404 byte [] ReadBlob (uint signature)
406 var blob_heap = image.BlobHeap;
407 if (blob_heap == null)
408 return Empty<byte>.Array;
410 return blob_heap.Read (signature);
413 uint ReadBlobIndex ()
415 var blob_heap = image.BlobHeap;
416 return ReadByIndexSize (blob_heap != null ? blob_heap.IndexSize : 2);
421 return image.StringHeap.Read (ReadByIndexSize (image.StringHeap.IndexSize));
424 uint ReadStringIndex ()
426 return ReadByIndexSize (image.StringHeap.IndexSize);
429 uint ReadTableIndex (Table table)
431 return ReadByIndexSize (image.GetTableIndexSize (table));
434 MetadataToken ReadMetadataToken (CodedIndex index)
436 return index.GetMetadataToken (ReadByIndexSize (GetCodedIndexSize (index)));
439 int MoveTo (Table table)
441 var info = image.TableHeap [table];
442 if (info.Length != 0)
443 Position = info.Offset;
445 return (int) info.Length;
448 bool MoveTo (Table table, uint row)
450 var info = image.TableHeap [table];
451 var length = info.Length;
452 if (length == 0 || row > length)
455 Position = info.Offset + (info.RowSize * (row - 1));
459 public AssemblyNameDefinition ReadAssemblyNameDefinition ()
461 if (MoveTo (Table.Assembly) == 0)
464 var name = new AssemblyNameDefinition ();
466 name.HashAlgorithm = (AssemblyHashAlgorithm) ReadUInt32 ();
468 PopulateVersionAndFlags (name);
470 name.PublicKey = ReadBlob ();
472 PopulateNameAndCulture (name);
477 public ModuleDefinition Populate (ModuleDefinition module)
479 if (MoveTo (Table.Module) == 0)
482 Advance (2); // Generation
484 module.Name = ReadString ();
485 module.Mvid = image.GuidHeap.Read (ReadByIndexSize (image.GuidHeap.IndexSize));
490 public Collection<AssemblyNameReference> ReadAssemblyReferences ()
492 int length = MoveTo (Table.AssemblyRef);
493 var references = new Collection<AssemblyNameReference> (length);
495 for (uint i = 1; i <= length; i++) {
496 var reference = new AssemblyNameReference ();
497 reference.token = new MetadataToken (TokenType.AssemblyRef, i);
499 PopulateVersionAndFlags (reference);
501 reference.PublicKeyToken = ReadBlob ();
503 PopulateNameAndCulture (reference);
505 reference.Hash = ReadBlob ();
507 references.Add (reference);
513 public MethodDefinition ReadEntryPoint ()
515 if (module.Kind != ModuleKind.Console && module.Kind != ModuleKind.Windows)
518 var token = new MetadataToken (module.Image.EntryPointToken);
520 return GetMethodDefinition (token.RID);
523 public Collection<ModuleDefinition> ReadModules ()
525 var modules = new Collection<ModuleDefinition> (1);
526 modules.Add (this.module);
528 int length = MoveTo (Table.File);
529 for (uint i = 1; i <= length; i++) {
530 var attributes = (FileAttributes) ReadUInt32 ();
531 var name = ReadString ();
534 if (attributes != FileAttributes.ContainsMetaData)
537 var parameters = new ReaderParameters {
538 ReadingMode = module.ReadingMode,
539 SymbolReaderProvider = module.SymbolReaderProvider,
542 modules.Add (ModuleDefinition.ReadModule (
543 GetModuleFileName (name), parameters));
549 string GetModuleFileName (string name)
551 if (module.FullyQualifiedName == null)
552 throw new NotSupportedException ();
554 var path = Path.GetDirectoryName (module.FullyQualifiedName);
555 return Path.Combine (path, name);
558 public Collection<ModuleReference> ReadModuleReferences ()
560 int length = MoveTo (Table.ModuleRef);
561 var references = new Collection<ModuleReference> (length);
563 for (uint i = 1; i <= length; i++) {
564 var reference = new ModuleReference (ReadString ());
565 reference.token = new MetadataToken (TokenType.ModuleRef, i);
567 references.Add (reference);
573 public bool HasFileResource ()
575 int length = MoveTo (Table.File);
579 for (uint i = 1; i <= length; i++)
580 if (ReadFileRecord (i).Col1 == FileAttributes.ContainsNoMetaData)
586 public Collection<Resource> ReadResources ()
588 int length = MoveTo (Table.ManifestResource);
589 var resources = new Collection<Resource> (length);
591 for (int i = 1; i <= length; i++) {
592 var offset = ReadUInt32 ();
593 var flags = (ManifestResourceAttributes) ReadUInt32 ();
594 var name = ReadString ();
595 var implementation = ReadMetadataToken (CodedIndex.Implementation);
599 if (implementation.RID == 0) {
600 resource = new EmbeddedResource (name, flags, offset, this);
601 } else if (implementation.TokenType == TokenType.AssemblyRef) {
602 resource = new AssemblyLinkedResource (name, flags) {
603 Assembly = (AssemblyNameReference) GetTypeReferenceScope (implementation),
605 } else if (implementation.TokenType == TokenType.File) {
606 var file_record = ReadFileRecord (implementation.RID);
608 resource = new LinkedResource (name, flags) {
609 File = file_record.Col2,
610 hash = ReadBlob (file_record.Col3)
613 throw new NotSupportedException ();
615 resources.Add (resource);
621 Row<FileAttributes, string, uint> ReadFileRecord (uint rid)
623 var position = this.position;
625 if (!MoveTo (Table.File, rid))
626 throw new ArgumentException ();
628 var record = new Row<FileAttributes, string, uint> (
629 (FileAttributes) ReadUInt32 (),
633 this.position = position;
638 public MemoryStream GetManagedResourceStream (uint offset)
640 var rva = image.Resources.VirtualAddress;
641 var section = image.GetSectionAtVirtualAddress (rva);
642 var position = (rva - section.VirtualAddress) + offset;
643 var buffer = section.Data;
645 var length = buffer [position]
646 | (buffer [position + 1] << 8)
647 | (buffer [position + 2] << 16)
648 | (buffer [position + 3] << 24);
650 return new MemoryStream (buffer, (int) position + 4, length);
653 void PopulateVersionAndFlags (AssemblyNameReference name)
655 name.Version = new Version (
661 name.Attributes = (AssemblyAttributes) ReadUInt32 ();
664 void PopulateNameAndCulture (AssemblyNameReference name)
666 name.Name = ReadString ();
667 name.Culture = ReadString ();
670 public TypeDefinitionCollection ReadTypes ()
672 InitializeTypeDefinitions ();
673 var mtypes = metadata.Types;
674 var type_count = mtypes.Length - metadata.NestedTypes.Count;
675 var types = new TypeDefinitionCollection (module, type_count);
677 for (int i = 0; i < mtypes.Length; i++) {
678 var type = mtypes [i];
679 if (IsNested (type.Attributes))
688 void InitializeTypeDefinitions ()
690 if (metadata.Types != null)
693 InitializeNestedTypes ();
695 InitializeMethods ();
697 int length = MoveTo (Table.TypeDef);
698 var types = metadata.Types = new TypeDefinition [length];
700 for (uint i = 0; i < length; i++) {
701 if (types [i] != null)
704 types [i] = ReadType (i + 1);
708 static bool IsNested (TypeAttributes attributes)
710 switch (attributes & TypeAttributes.VisibilityMask) {
711 case TypeAttributes.NestedAssembly:
712 case TypeAttributes.NestedFamANDAssem:
713 case TypeAttributes.NestedFamily:
714 case TypeAttributes.NestedFamORAssem:
715 case TypeAttributes.NestedPrivate:
716 case TypeAttributes.NestedPublic:
723 public bool HasNestedTypes (TypeDefinition type)
726 InitializeNestedTypes ();
728 if (!metadata.TryGetNestedTypeMapping (type, out mapping))
731 return mapping.Length > 0;
734 public Collection<TypeDefinition> ReadNestedTypes (TypeDefinition type)
736 InitializeNestedTypes ();
738 if (!metadata.TryGetNestedTypeMapping (type, out mapping))
739 return new MemberDefinitionCollection<TypeDefinition> (type);
741 var nested_types = new MemberDefinitionCollection<TypeDefinition> (type, mapping.Length);
743 for (int i = 0; i < mapping.Length; i++)
744 nested_types.Add (GetTypeDefinition (mapping [i]));
746 metadata.RemoveNestedTypeMapping (type);
751 void InitializeNestedTypes ()
753 if (metadata.NestedTypes != null)
756 var length = MoveTo (Table.NestedClass);
758 metadata.NestedTypes = new Dictionary<uint, uint []> (length);
759 metadata.ReverseNestedTypes = new Dictionary<uint, uint> (length);
764 for (int i = 1; i <= length; i++) {
765 var nested = ReadTableIndex (Table.TypeDef);
766 var declaring = ReadTableIndex (Table.TypeDef);
768 AddNestedMapping (declaring, nested);
772 void AddNestedMapping (uint declaring, uint nested)
774 metadata.SetNestedTypeMapping (declaring, AddMapping (metadata.NestedTypes, declaring, nested));
775 metadata.SetReverseNestedTypeMapping (nested, declaring);
778 static TValue [] AddMapping<TKey, TValue> (Dictionary<TKey, TValue []> cache, TKey key, TValue value)
781 if (!cache.TryGetValue (key, out mapped)) {
782 mapped = new [] { value };
786 var new_mapped = new TValue [mapped.Length + 1];
787 Array.Copy (mapped, new_mapped, mapped.Length);
788 new_mapped [mapped.Length] = value;
792 TypeDefinition ReadType (uint rid)
794 if (!MoveTo (Table.TypeDef, rid))
797 var attributes = (TypeAttributes) ReadUInt32 ();
798 var name = ReadString ();
799 var @namespace = ReadString ();
800 var type = new TypeDefinition (@namespace, name, attributes);
801 type.token = new MetadataToken (TokenType.TypeDef, rid);
803 type.module = module;
805 metadata.AddTypeDefinition (type);
809 type.BaseType = GetTypeDefOrRef (ReadMetadataToken (CodedIndex.TypeDefOrRef));
811 type.fields_range = ReadFieldsRange (rid);
812 type.methods_range = ReadMethodsRange (rid);
814 if (IsNested (attributes))
815 type.DeclaringType = GetNestedTypeDeclaringType (type);
820 TypeDefinition GetNestedTypeDeclaringType (TypeDefinition type)
823 if (!metadata.TryGetReverseNestedTypeMapping (type, out declaring_rid))
826 metadata.RemoveReverseNestedTypeMapping (type);
827 return GetTypeDefinition (declaring_rid);
830 Range ReadFieldsRange (uint type_index)
832 return ReadListRange (type_index, Table.TypeDef, Table.Field);
835 Range ReadMethodsRange (uint type_index)
837 return ReadListRange (type_index, Table.TypeDef, Table.Method);
840 Range ReadListRange (uint current_index, Table current, Table target)
842 var list = new Range ();
844 list.Start = ReadTableIndex (target);
847 var current_table = image.TableHeap [current];
849 if (current_index == current_table.Length)
850 next_index = image.TableHeap [target].Length + 1;
852 var position = Position;
853 Position += (uint) (current_table.RowSize - image.GetTableIndexSize (target));
854 next_index = ReadTableIndex (target);
858 list.Length = next_index - list.Start;
863 public Row<short, int> ReadTypeLayout (TypeDefinition type)
865 InitializeTypeLayouts ();
866 Row<ushort, uint> class_layout;
867 var rid = type.token.RID;
868 if (!metadata.ClassLayouts.TryGetValue (rid, out class_layout))
869 return new Row<short, int> (Mixin.NoDataMarker, Mixin.NoDataMarker);
871 type.PackingSize = (short) class_layout.Col1;
872 type.ClassSize = (int) class_layout.Col2;
874 metadata.ClassLayouts.Remove (rid);
876 return new Row<short, int> ((short) class_layout.Col1, (int) class_layout.Col2);
879 void InitializeTypeLayouts ()
881 if (metadata.ClassLayouts != null)
884 int length = MoveTo (Table.ClassLayout);
886 var class_layouts = metadata.ClassLayouts = new Dictionary<uint, Row<ushort, uint>> (length);
888 for (uint i = 0; i < length; i++) {
889 var packing_size = ReadUInt16 ();
890 var class_size = ReadUInt32 ();
892 var parent = ReadTableIndex (Table.TypeDef);
894 class_layouts.Add (parent, new Row<ushort, uint> (packing_size, class_size));
898 public TypeReference GetTypeDefOrRef (MetadataToken token)
900 return (TypeReference) LookupToken (token);
903 public TypeDefinition GetTypeDefinition (uint rid)
905 InitializeTypeDefinitions ();
907 var type = metadata.GetTypeDefinition (rid);
911 return ReadTypeDefinition (rid);
914 TypeDefinition ReadTypeDefinition (uint rid)
916 if (!MoveTo (Table.TypeDef, rid))
919 return ReadType (rid);
922 void InitializeTypeReferences ()
924 if (metadata.TypeReferences != null)
927 metadata.TypeReferences = new TypeReference [image.GetTableLength (Table.TypeRef)];
930 public TypeReference GetTypeReference (string scope, string full_name)
932 InitializeTypeReferences ();
934 var length = metadata.TypeReferences.Length;
936 for (uint i = 1; i <= length; i++) {
937 var type = GetTypeReference (i);
939 if (type.FullName != full_name)
942 if (string.IsNullOrEmpty (scope))
945 if (type.Scope.Name == scope)
952 TypeReference GetTypeReference (uint rid)
954 InitializeTypeReferences ();
956 var type = metadata.GetTypeReference (rid);
960 return ReadTypeReference (rid);
963 TypeReference ReadTypeReference (uint rid)
965 if (!MoveTo (Table.TypeRef, rid))
968 TypeReference declaring_type = null;
969 IMetadataScope scope;
971 var scope_token = ReadMetadataToken (CodedIndex.ResolutionScope);
973 var name = ReadString ();
974 var @namespace = ReadString ();
976 var type = new TypeReference (
982 type.token = new MetadataToken (TokenType.TypeRef, rid);
984 metadata.AddTypeReference (type);
986 if (scope_token.TokenType == TokenType.TypeRef) {
987 declaring_type = GetTypeDefOrRef (scope_token);
989 scope = declaring_type != null
990 ? declaring_type.Scope
993 scope = GetTypeReferenceScope (scope_token);
996 type.DeclaringType = declaring_type;
998 MetadataSystem.TryProcessPrimitiveType (type);
1003 IMetadataScope GetTypeReferenceScope (MetadataToken scope)
1005 switch (scope.TokenType) {
1006 // FIXME: both assembly refs and module refs should be in their
1007 // own arrays, in case of someone modify the collections before
1008 // this code is called
1009 case TokenType.AssemblyRef:
1010 return module.AssemblyReferences [(int) scope.RID - 1];
1011 case TokenType.ModuleRef:
1012 return module.ModuleReferences [(int) scope.RID - 1];
1013 case TokenType.Module:
1016 throw new NotSupportedException ();
1020 public IEnumerable<TypeReference> GetTypeReferences ()
1022 InitializeTypeReferences ();
1024 var length = image.GetTableLength (Table.TypeRef);
1026 var type_references = new TypeReference [length];
1028 for (uint i = 1; i <= length; i++)
1029 type_references [i - 1] = GetTypeReference (i);
1031 return type_references;
1034 TypeReference GetTypeSpecification (uint rid)
1036 if (!MoveTo (Table.TypeSpec, rid))
1039 var reader = ReadSignature (ReadBlobIndex ());
1040 var type = reader.ReadTypeSignature ();
1041 if (type.token.RID == 0)
1042 type.token = new MetadataToken (TokenType.TypeSpec, rid);
1047 SignatureReader ReadSignature (uint signature)
1049 return new SignatureReader (signature, this);
1052 public bool HasInterfaces (TypeDefinition type)
1054 InitializeInterfaces ();
1055 MetadataToken [] mapping;
1057 return metadata.TryGetInterfaceMapping (type, out mapping);
1060 public Collection<TypeReference> ReadInterfaces (TypeDefinition type)
1062 InitializeInterfaces ();
1063 MetadataToken [] mapping;
1065 if (!metadata.TryGetInterfaceMapping (type, out mapping))
1066 return new Collection<TypeReference> ();
1068 var interfaces = new Collection<TypeReference> (mapping.Length);
1070 this.context = type;
1072 for (int i = 0; i < mapping.Length; i++)
1073 interfaces.Add (GetTypeDefOrRef (mapping [i]));
1075 metadata.RemoveInterfaceMapping (type);
1080 void InitializeInterfaces ()
1082 if (metadata.Interfaces != null)
1085 int length = MoveTo (Table.InterfaceImpl);
1087 metadata.Interfaces = new Dictionary<uint, MetadataToken []> (length);
1089 for (int i = 0; i < length; i++) {
1090 var type = ReadTableIndex (Table.TypeDef);
1091 var @interface = ReadMetadataToken (CodedIndex.TypeDefOrRef);
1093 AddInterfaceMapping (type, @interface);
1097 void AddInterfaceMapping (uint type, MetadataToken @interface)
1099 metadata.SetInterfaceMapping (type, AddMapping (metadata.Interfaces, type, @interface));
1102 public Collection<FieldDefinition> ReadFields (TypeDefinition type)
1104 var fields_range = type.fields_range;
1105 if (fields_range.Length == 0)
1106 return new MemberDefinitionCollection<FieldDefinition> (type);
1108 var fields = new MemberDefinitionCollection<FieldDefinition> (type, (int) fields_range.Length);
1109 this.context = type;
1111 MoveTo (Table.Field, fields_range.Start);
1112 for (uint i = 0; i < fields_range.Length; i++)
1113 fields.Add (ReadField (fields_range.Start + i));
1118 FieldDefinition ReadField (uint field_rid)
1120 var attributes = (FieldAttributes) ReadUInt16 ();
1121 var name = ReadString ();
1122 var signature = ReadBlobIndex ();
1124 var field = new FieldDefinition (name, attributes, ReadFieldType (signature));
1125 field.token = new MetadataToken (TokenType.Field, field_rid);
1126 metadata.AddFieldDefinition (field);
1131 void InitializeFields ()
1133 if (metadata.Fields != null)
1136 metadata.Fields = new FieldDefinition [image.GetTableLength (Table.Field)];
1139 TypeReference ReadFieldType (uint signature)
1141 var reader = ReadSignature (signature);
1143 const byte field_sig = 0x6;
1145 if (reader.ReadByte () != field_sig)
1146 throw new NotSupportedException ();
1148 return reader.ReadTypeSignature ();
1151 public int ReadFieldRVA (FieldDefinition field)
1153 InitializeFieldRVAs ();
1154 var rid = field.token.RID;
1157 if (!metadata.FieldRVAs.TryGetValue (rid, out rva))
1160 var size = GetFieldTypeSize (field.FieldType);
1162 if (size == 0 || rva == 0)
1165 metadata.FieldRVAs.Remove (rid);
1167 field.InitialValue = GetFieldInitializeValue (size, rva);
1172 byte [] GetFieldInitializeValue (int size, RVA rva)
1174 var section = image.GetSectionAtVirtualAddress (rva);
1175 if (section == null)
1176 return Empty<byte>.Array;
1178 var value = new byte [size];
1179 Buffer.BlockCopy (section.Data, (int) (rva - section.VirtualAddress), value, 0, size);
1183 static int GetFieldTypeSize (TypeReference type)
1187 switch (type.etype) {
1188 case ElementType.Boolean:
1189 case ElementType.U1:
1190 case ElementType.I1:
1193 case ElementType.U2:
1194 case ElementType.I2:
1195 case ElementType.Char:
1198 case ElementType.U4:
1199 case ElementType.I4:
1200 case ElementType.R4:
1203 case ElementType.U8:
1204 case ElementType.I8:
1205 case ElementType.R8:
1208 case ElementType.Ptr:
1209 case ElementType.FnPtr:
1212 case ElementType.CModOpt:
1213 case ElementType.CModReqD:
1214 return GetFieldTypeSize (((IModifierType) type).ElementType);
1216 var field_type = type.CheckedResolve ();
1217 if (field_type.HasLayoutInfo)
1218 size = field_type.ClassSize;
1226 void InitializeFieldRVAs ()
1228 if (metadata.FieldRVAs != null)
1231 int length = MoveTo (Table.FieldRVA);
1233 var field_rvas = metadata.FieldRVAs = new Dictionary<uint, uint> (length);
1235 for (int i = 0; i < length; i++) {
1236 var rva = ReadUInt32 ();
1237 var field = ReadTableIndex (Table.Field);
1239 field_rvas.Add (field, rva);
1243 public int ReadFieldLayout (FieldDefinition field)
1245 InitializeFieldLayouts ();
1246 var rid = field.token.RID;
1248 if (!metadata.FieldLayouts.TryGetValue (rid, out offset))
1249 return Mixin.NoDataMarker;
1251 metadata.FieldLayouts.Remove (rid);
1253 return (int) offset;
1256 void InitializeFieldLayouts ()
1258 if (metadata.FieldLayouts != null)
1261 int length = MoveTo (Table.FieldLayout);
1263 var field_layouts = metadata.FieldLayouts = new Dictionary<uint, uint> (length);
1265 for (int i = 0; i < length; i++) {
1266 var offset = ReadUInt32 ();
1267 var field = ReadTableIndex (Table.Field);
1269 field_layouts.Add (field, offset);
1273 public bool HasEvents (TypeDefinition type)
1275 InitializeEvents ();
1278 if (!metadata.TryGetEventsRange (type, out range))
1281 return range.Length > 0;
1284 public Collection<EventDefinition> ReadEvents (TypeDefinition type)
1286 InitializeEvents ();
1289 if (!metadata.TryGetEventsRange (type, out range))
1290 return new MemberDefinitionCollection<EventDefinition> (type);
1292 var events = new MemberDefinitionCollection<EventDefinition> (type, (int) range.Length);
1294 metadata.RemoveEventsRange (type);
1296 if (range.Length == 0 || !MoveTo (Table.Event, range.Start))
1299 this.context = type;
1301 for (uint i = 0; i < range.Length; i++)
1302 events.Add (ReadEvent (range.Start + i));
1307 EventDefinition ReadEvent (uint event_rid)
1309 var attributes = (EventAttributes) ReadUInt16 ();
1310 var name = ReadString ();
1311 var event_type = GetTypeDefOrRef (ReadMetadataToken (CodedIndex.TypeDefOrRef));
1313 var @event = new EventDefinition (name, attributes, event_type);
1314 @event.token = new MetadataToken (TokenType.Event, event_rid);
1318 void InitializeEvents ()
1320 if (metadata.Events != null)
1323 int length = MoveTo (Table.EventMap);
1325 metadata.Events = new Dictionary<uint, Range> (length);
1327 for (uint i = 1; i <= length; i++) {
1328 var type_rid = ReadTableIndex (Table.TypeDef);
1329 Range events_range = ReadEventsRange (i);
1330 metadata.AddEventsRange (type_rid, events_range);
1334 Range ReadEventsRange (uint rid)
1336 return ReadListRange (rid, Table.EventMap, Table.Event);
1339 public bool HasProperties (TypeDefinition type)
1341 InitializeProperties ();
1344 if (!metadata.TryGetPropertiesRange (type, out range))
1347 return range.Length > 0;
1350 public Collection<PropertyDefinition> ReadProperties (TypeDefinition type)
1352 InitializeProperties ();
1356 if (!metadata.TryGetPropertiesRange (type, out range))
1357 return new MemberDefinitionCollection<PropertyDefinition> (type);
1359 metadata.RemovePropertiesRange (type);
1361 var properties = new MemberDefinitionCollection<PropertyDefinition> (type, (int) range.Length);
1363 if (range.Length == 0 || !MoveTo (Table.Property, range.Start))
1366 this.context = type;
1368 for (uint i = 0; i < range.Length; i++)
1369 properties.Add (ReadProperty (range.Start + i));
1374 PropertyDefinition ReadProperty (uint property_rid)
1376 var attributes = (PropertyAttributes) ReadUInt16 ();
1377 var name = ReadString ();
1378 var signature = ReadBlobIndex ();
1380 var reader = ReadSignature (signature);
1381 const byte property_signature = 0x8;
1383 var calling_convention = reader.ReadByte ();
1385 if ((calling_convention & property_signature) == 0)
1386 throw new NotSupportedException ();
1388 var has_this = (calling_convention & 0x20) != 0;
1390 reader.ReadCompressedUInt32 (); // count
1392 var property = new PropertyDefinition (name, attributes, reader.ReadTypeSignature ());
1393 property.HasThis = has_this;
1394 property.token = new MetadataToken (TokenType.Property, property_rid);
1399 void InitializeProperties ()
1401 if (metadata.Properties != null)
1404 int length = MoveTo (Table.PropertyMap);
1406 metadata.Properties = new Dictionary<uint, Range> (length);
1408 for (uint i = 1; i <= length; i++) {
1409 var type_rid = ReadTableIndex (Table.TypeDef);
1410 var properties_range = ReadPropertiesRange (i);
1411 metadata.AddPropertiesRange (type_rid, properties_range);
1415 Range ReadPropertiesRange (uint rid)
1417 return ReadListRange (rid, Table.PropertyMap, Table.Property);
1420 MethodSemanticsAttributes ReadMethodSemantics (MethodDefinition method)
1422 InitializeMethodSemantics ();
1423 Row<MethodSemanticsAttributes, MetadataToken> row;
1424 if (!metadata.Semantics.TryGetValue (method.token.RID, out row))
1425 return MethodSemanticsAttributes.None;
1427 var type = method.DeclaringType;
1430 case MethodSemanticsAttributes.AddOn:
1431 GetEvent (type, row.Col2).add_method = method;
1433 case MethodSemanticsAttributes.Fire:
1434 GetEvent (type, row.Col2).invoke_method = method;
1436 case MethodSemanticsAttributes.RemoveOn:
1437 GetEvent (type, row.Col2).remove_method = method;
1439 case MethodSemanticsAttributes.Getter:
1440 GetProperty (type, row.Col2).get_method = method;
1442 case MethodSemanticsAttributes.Setter:
1443 GetProperty (type, row.Col2).set_method = method;
1445 case MethodSemanticsAttributes.Other:
1446 switch (row.Col2.TokenType) {
1447 case TokenType.Event: {
1448 var @event = GetEvent (type, row.Col2);
1449 if (@event.other_methods == null)
1450 @event.other_methods = new Collection<MethodDefinition> ();
1452 @event.other_methods.Add (method);
1455 case TokenType.Property: {
1456 var property = GetProperty (type, row.Col2);
1457 if (property.other_methods == null)
1458 property.other_methods = new Collection<MethodDefinition> ();
1460 property.other_methods.Add (method);
1465 throw new NotSupportedException ();
1469 throw new NotSupportedException ();
1472 metadata.Semantics.Remove (method.token.RID);
1477 static EventDefinition GetEvent (TypeDefinition type, MetadataToken token)
1479 if (token.TokenType != TokenType.Event)
1480 throw new ArgumentException ();
1482 return GetMember (type.Events, token);
1485 static PropertyDefinition GetProperty (TypeDefinition type, MetadataToken token)
1487 if (token.TokenType != TokenType.Property)
1488 throw new ArgumentException ();
1490 return GetMember (type.Properties, token);
1493 static TMember GetMember<TMember> (Collection<TMember> members, MetadataToken token) where TMember : IMemberDefinition
1495 for (int i = 0; i < members.Count; i++) {
1496 var member = members [i];
1497 if (member.MetadataToken == token)
1501 throw new ArgumentException ();
1504 void InitializeMethodSemantics ()
1506 if (metadata.Semantics != null)
1509 int length = MoveTo (Table.MethodSemantics);
1511 var semantics = metadata.Semantics = new Dictionary<uint, Row<MethodSemanticsAttributes, MetadataToken>> (0);
1513 for (uint i = 0; i < length; i++) {
1514 var attributes = (MethodSemanticsAttributes) ReadUInt16 ();
1515 var method_rid = ReadTableIndex (Table.Method);
1516 var association = ReadMetadataToken (CodedIndex.HasSemantics);
1518 semantics [method_rid] = new Row<MethodSemanticsAttributes, MetadataToken> (attributes, association);
1522 public PropertyDefinition ReadMethods (PropertyDefinition property)
1524 ReadAllSemantics (property.DeclaringType);
1528 public EventDefinition ReadMethods (EventDefinition @event)
1530 ReadAllSemantics (@event.DeclaringType);
1534 public MethodSemanticsAttributes ReadAllSemantics (MethodDefinition method)
1536 ReadAllSemantics (method.DeclaringType);
1538 return method.SemanticsAttributes;
1541 void ReadAllSemantics (TypeDefinition type)
1543 var methods = type.Methods;
1544 for (int i = 0; i < methods.Count; i++) {
1545 var method = methods [i];
1546 if (method.sem_attrs.HasValue)
1549 method.sem_attrs = ReadMethodSemantics (method);
1553 Range ReadParametersRange (uint method_rid)
1555 return ReadListRange (method_rid, Table.Method, Table.Param);
1558 public Collection<MethodDefinition> ReadMethods (TypeDefinition type)
1560 var methods_range = type.methods_range;
1561 if (methods_range.Length == 0)
1562 return new MemberDefinitionCollection<MethodDefinition> (type);
1564 var methods = new MemberDefinitionCollection<MethodDefinition> (type, (int) methods_range.Length);
1566 MoveTo (Table.Method, methods_range.Start);
1567 for (uint i = 0; i < methods_range.Length; i++)
1568 ReadMethod (methods_range.Start + i, methods);
1573 void InitializeMethods ()
1575 if (metadata.Methods != null)
1578 metadata.Methods = new MethodDefinition [image.GetTableLength (Table.Method)];
1581 void ReadMethod (uint method_rid, Collection<MethodDefinition> methods)
1583 var method = new MethodDefinition ();
1584 method.rva = ReadUInt32 ();
1585 method.ImplAttributes = (MethodImplAttributes) ReadUInt16 ();
1586 method.Attributes = (MethodAttributes) ReadUInt16 ();
1587 method.Name = ReadString ();
1588 method.token = new MetadataToken (TokenType.Method, method_rid);
1590 methods.Add (method); // attach method
1592 var signature = ReadBlobIndex ();
1593 var param_range = ReadParametersRange (method_rid);
1595 this.context = method;
1597 ReadMethodSignature (signature, method);
1598 metadata.AddMethodDefinition (method);
1600 if (param_range.Length == 0)
1603 var position = base.position;
1604 ReadParameters (method, param_range);
1605 base.position = position;
1608 void ReadParameters (MethodDefinition method, Range param_range)
1610 MoveTo (Table.Param, param_range.Start);
1611 for (uint i = 0; i < param_range.Length; i++) {
1612 var attributes = (ParameterAttributes) ReadUInt16 ();
1613 var sequence = ReadUInt16 ();
1614 var name = ReadString ();
1616 var parameter = sequence == 0
1617 ? method.MethodReturnType.Parameter
1618 : method.Parameters [sequence - 1];
1620 parameter.token = new MetadataToken (TokenType.Param, param_range.Start + i);
1621 parameter.Name = name;
1622 parameter.Attributes = attributes;
1626 void ReadMethodSignature (uint signature, IMethodSignature method)
1628 var reader = ReadSignature (signature);
1629 reader.ReadMethodSignature (method);
1632 public PInvokeInfo ReadPInvokeInfo (MethodDefinition method)
1634 InitializePInvokes ();
1635 Row<PInvokeAttributes, uint, uint> row;
1637 var rid = method.token.RID;
1639 if (!metadata.PInvokes.TryGetValue (rid, out row))
1642 metadata.PInvokes.Remove (rid);
1644 return new PInvokeInfo (
1646 image.StringHeap.Read (row.Col2),
1647 module.ModuleReferences [(int) row.Col3 - 1]);
1650 void InitializePInvokes ()
1652 if (metadata.PInvokes != null)
1655 int length = MoveTo (Table.ImplMap);
1657 var pinvokes = metadata.PInvokes = new Dictionary<uint, Row<PInvokeAttributes, uint, uint>> (length);
1659 for (int i = 1; i <= length; i++) {
1660 var attributes = (PInvokeAttributes) ReadUInt16 ();
1661 var method = ReadMetadataToken (CodedIndex.MemberForwarded);
1662 var name = ReadStringIndex ();
1663 var scope = ReadTableIndex (Table.File);
1665 if (method.TokenType != TokenType.Method)
1668 pinvokes.Add (method.RID, new Row<PInvokeAttributes, uint, uint> (attributes, name, scope));
1672 public bool HasGenericParameters (IGenericParameterProvider provider)
1674 InitializeGenericParameters ();
1677 if (!metadata.TryGetGenericParameterRange (provider, out range))
1680 return range.Length > 0;
1683 public Collection<GenericParameter> ReadGenericParameters (IGenericParameterProvider provider)
1685 InitializeGenericParameters ();
1688 if (!metadata.TryGetGenericParameterRange (provider, out range)
1689 || !MoveTo (Table.GenericParam, range.Start))
1690 return new Collection<GenericParameter> ();
1692 metadata.RemoveGenericParameterRange (provider);
1694 var generic_parameters = new Collection<GenericParameter> ((int) range.Length);
1696 for (uint i = 0; i < range.Length; i++) {
1697 ReadUInt16 (); // index
1698 var flags = (GenericParameterAttributes) ReadUInt16 ();
1699 ReadMetadataToken (CodedIndex.TypeOrMethodDef);
1700 var name = ReadString ();
1702 var parameter = new GenericParameter (name, provider);
1703 parameter.token = new MetadataToken (TokenType.GenericParam, range.Start + i);
1704 parameter.Attributes = flags;
1706 generic_parameters.Add (parameter);
1709 return generic_parameters;
1712 void InitializeGenericParameters ()
1714 if (metadata.GenericParameters != null)
1717 metadata.GenericParameters = InitializeRanges (
1718 Table.GenericParam, () => {
1720 var next = ReadMetadataToken (CodedIndex.TypeOrMethodDef);
1726 Dictionary<MetadataToken, Range> InitializeRanges (Table table, Func<MetadataToken> get_next)
1728 int length = MoveTo (table);
1729 var ranges = new Dictionary<MetadataToken, Range> (length);
1734 MetadataToken owner = MetadataToken.Zero;
1735 Range range = new Range (1, 0);
1737 for (uint i = 1; i <= length; i++) {
1738 var next = get_next ();
1743 } else if (next != owner) {
1745 ranges.Add (owner, range);
1746 range = new Range (i, 1);
1752 if (owner != MetadataToken.Zero)
1753 ranges.Add (owner, range);
1758 public bool HasGenericConstraints (GenericParameter generic_parameter)
1760 InitializeGenericConstraints ();
1762 MetadataToken [] mapping;
1763 if (!metadata.TryGetGenericConstraintMapping (generic_parameter, out mapping))
1766 return mapping.Length > 0;
1769 public Collection<TypeReference> ReadGenericConstraints (GenericParameter generic_parameter)
1771 InitializeGenericConstraints ();
1773 MetadataToken [] mapping;
1774 if (!metadata.TryGetGenericConstraintMapping (generic_parameter, out mapping))
1775 return new Collection<TypeReference> ();
1777 var constraints = new Collection<TypeReference> (mapping.Length);
1779 this.context = (IGenericContext) generic_parameter.Owner;
1781 for (int i = 0; i < mapping.Length; i++)
1782 constraints.Add (GetTypeDefOrRef (mapping [i]));
1784 metadata.RemoveGenericConstraintMapping (generic_parameter);
1789 void InitializeGenericConstraints ()
1791 if (metadata.GenericConstraints != null)
1794 var length = MoveTo (Table.GenericParamConstraint);
1796 metadata.GenericConstraints = new Dictionary<uint, MetadataToken []> (length);
1798 for (int i = 1; i <= length; i++)
1799 AddGenericConstraintMapping (
1800 ReadTableIndex (Table.GenericParam),
1801 ReadMetadataToken (CodedIndex.TypeDefOrRef));
1804 void AddGenericConstraintMapping (uint generic_parameter, MetadataToken constraint)
1806 metadata.SetGenericConstraintMapping (
1808 AddMapping (metadata.GenericConstraints, generic_parameter, constraint));
1811 public bool HasOverrides (MethodDefinition method)
1813 InitializeOverrides ();
1814 MetadataToken [] mapping;
1816 if (!metadata.TryGetOverrideMapping (method, out mapping))
1819 return mapping.Length > 0;
1822 public Collection<MethodReference> ReadOverrides (MethodDefinition method)
1824 InitializeOverrides ();
1826 MetadataToken [] mapping;
1827 if (!metadata.TryGetOverrideMapping (method, out mapping))
1828 return new Collection<MethodReference> ();
1830 var overrides = new Collection<MethodReference> (mapping.Length);
1832 this.context = method;
1834 for (int i = 0; i < mapping.Length; i++)
1835 overrides.Add ((MethodReference) LookupToken (mapping [i]));
1837 metadata.RemoveOverrideMapping (method);
1842 void InitializeOverrides ()
1844 if (metadata.Overrides != null)
1847 var length = MoveTo (Table.MethodImpl);
1849 metadata.Overrides = new Dictionary<uint, MetadataToken []> (length);
1851 for (int i = 1; i <= length; i++) {
1852 ReadTableIndex (Table.TypeDef);
1854 var method = ReadMetadataToken (CodedIndex.MethodDefOrRef);
1855 if (method.TokenType != TokenType.Method)
1856 throw new NotSupportedException ();
1858 var @override = ReadMetadataToken (CodedIndex.MethodDefOrRef);
1860 AddOverrideMapping (method.RID, @override);
1864 void AddOverrideMapping (uint method_rid, MetadataToken @override)
1866 metadata.SetOverrideMapping (
1868 AddMapping (metadata.Overrides, method_rid, @override));
1871 public MethodBody ReadMethodBody (MethodDefinition method)
1873 return code.ReadMethodBody (method);
1876 public CallSite ReadCallSite (MetadataToken token)
1878 if (!MoveTo (Table.StandAloneSig, token.RID))
1881 var signature = ReadBlobIndex ();
1883 var call_site = new CallSite ();
1885 ReadMethodSignature (signature, call_site);
1887 call_site.MetadataToken = token;
1892 public VariableDefinitionCollection ReadVariables (MetadataToken local_var_token)
1894 if (!MoveTo (Table.StandAloneSig, local_var_token.RID))
1897 var reader = ReadSignature (ReadBlobIndex ());
1898 const byte local_sig = 0x7;
1900 if (reader.ReadByte () != local_sig)
1901 throw new NotSupportedException ();
1903 var count = reader.ReadCompressedUInt32 ();
1907 var variables = new VariableDefinitionCollection ((int) count);
1909 for (int i = 0; i < count; i++)
1910 variables.Add (new VariableDefinition (reader.ReadTypeSignature ()));
1915 public IMetadataTokenProvider LookupToken (MetadataToken token)
1917 var rid = token.RID;
1922 IMetadataTokenProvider element;
1923 var position = this.position;
1924 var context = this.context;
1926 switch (token.TokenType) {
1927 case TokenType.TypeDef:
1928 element = GetTypeDefinition (rid);
1930 case TokenType.TypeRef:
1931 element = GetTypeReference (rid);
1933 case TokenType.TypeSpec:
1934 element = GetTypeSpecification (rid);
1936 case TokenType.Field:
1937 element = GetFieldDefinition (rid);
1939 case TokenType.Method:
1940 element = GetMethodDefinition (rid);
1942 case TokenType.MemberRef:
1943 element = GetMemberReference (rid);
1945 case TokenType.MethodSpec:
1946 element = GetMethodSpecification (rid);
1952 this.position = position;
1953 this.context = context;
1958 public FieldDefinition GetFieldDefinition (uint rid)
1960 InitializeTypeDefinitions ();
1962 var field = metadata.GetFieldDefinition (rid);
1966 return LookupField (rid);
1969 FieldDefinition LookupField (uint rid)
1971 var type = metadata.GetFieldDeclaringType (rid);
1975 InitializeCollection (type.Fields);
1977 return metadata.GetFieldDefinition (rid);
1980 public MethodDefinition GetMethodDefinition (uint rid)
1982 InitializeTypeDefinitions ();
1984 var method = metadata.GetMethodDefinition (rid);
1988 return LookupMethod (rid);
1991 MethodDefinition LookupMethod (uint rid)
1993 var type = metadata.GetMethodDeclaringType (rid);
1997 InitializeCollection (type.Methods);
1999 return metadata.GetMethodDefinition (rid);
2002 MethodSpecification GetMethodSpecification (uint rid)
2004 if (!MoveTo (Table.MethodSpec, rid))
2007 var element_method = (MethodReference) LookupToken (
2008 ReadMetadataToken (CodedIndex.MethodDefOrRef));
2009 var signature = ReadBlobIndex ();
2011 var method_spec = ReadMethodSpecSignature (signature, element_method);
2012 method_spec.token = new MetadataToken (TokenType.MethodSpec, rid);
2016 MethodSpecification ReadMethodSpecSignature (uint signature, MethodReference method)
2018 var reader = ReadSignature (signature);
2019 const byte methodspec_sig = 0x0a;
2021 var call_conv = reader.ReadByte ();
2023 if (call_conv != methodspec_sig)
2024 throw new NotSupportedException ();
2026 var instance = new GenericInstanceMethod (method);
2028 reader.ReadGenericInstanceSignature (method, instance);
2033 MemberReference GetMemberReference (uint rid)
2035 InitializeMemberReferences ();
2037 var member = metadata.GetMemberReference (rid);
2041 member = ReadMemberReference (rid);
2042 if (member != null && !member.ContainsGenericParameter)
2043 metadata.AddMemberReference (member);
2047 MemberReference ReadMemberReference (uint rid)
2049 if (!MoveTo (Table.MemberRef, rid))
2052 var token = ReadMetadataToken (CodedIndex.MemberRefParent);
2053 var name = ReadString ();
2054 var signature = ReadBlobIndex ();
2056 MemberReference member;
2058 switch (token.TokenType) {
2059 case TokenType.TypeDef:
2060 case TokenType.TypeRef:
2061 case TokenType.TypeSpec:
2062 member = ReadTypeMemberReference (token, name, signature);
2064 case TokenType.Method:
2065 member = ReadMethodMemberReference (token, name, signature);
2068 throw new NotSupportedException ();
2071 member.token = new MetadataToken (TokenType.MemberRef, rid);
2076 MemberReference ReadTypeMemberReference (MetadataToken type, string name, uint signature)
2078 var declaring_type = GetTypeDefOrRef (type);
2080 this.context = declaring_type;
2082 var member = ReadMemberReferenceSignature (signature, declaring_type);
2088 MemberReference ReadMemberReferenceSignature (uint signature, TypeReference declaring_type)
2090 var reader = ReadSignature (signature);
2091 const byte field_sig = 0x6;
2093 if (reader.buffer [reader.position] == field_sig) {
2095 var field = new FieldReference ();
2096 field.DeclaringType = declaring_type;
2097 field.FieldType = reader.ReadTypeSignature ();
2100 var method = new MethodReference ();
2101 method.DeclaringType = declaring_type;
2102 reader.ReadMethodSignature (method);
2107 MemberReference ReadMethodMemberReference (MetadataToken token, string name, uint signature)
2109 var method = GetMethodDefinition (token.RID);
2111 this.context = method;
2113 var member = ReadMemberReferenceSignature (signature, method.DeclaringType);
2119 void InitializeMemberReferences ()
2121 if (metadata.MemberReferences != null)
2124 metadata.MemberReferences = new MemberReference [image.GetTableLength (Table.MemberRef)];
2127 public IEnumerable<MemberReference> GetMemberReferences ()
2129 InitializeMemberReferences ();
2131 var length = image.GetTableLength (Table.MemberRef);
2133 var type_system = module.TypeSystem;
2135 var context = new MethodReference (string.Empty, type_system.Void);
2136 context.DeclaringType = new TypeReference (string.Empty, string.Empty, module, type_system.Corlib);
2138 var member_references = new MemberReference [length];
2140 for (uint i = 1; i <= length; i++) {
2141 this.context = context;
2142 member_references [i - 1] = GetMemberReference (i);
2145 return member_references;
2148 void InitializeConstants ()
2150 if (metadata.Constants != null)
2153 var length = MoveTo (Table.Constant);
2155 var constants = metadata.Constants = new Dictionary<MetadataToken, Row<ElementType, uint>> (length);
2157 for (uint i = 1; i <= length; i++) {
2158 var type = (ElementType) ReadUInt16 ();
2159 var owner = ReadMetadataToken (CodedIndex.HasConstant);
2160 var signature = ReadBlobIndex ();
2162 constants.Add (owner, new Row<ElementType, uint> (type, signature));
2166 public object ReadConstant (IConstantProvider owner)
2168 InitializeConstants ();
2170 Row<ElementType, uint> row;
2171 if (!metadata.Constants.TryGetValue (owner.MetadataToken, out row))
2172 return Mixin.NoValue;
2174 metadata.Constants.Remove (owner.MetadataToken);
2177 case ElementType.Class:
2178 case ElementType.Object:
2180 case ElementType.String:
2181 return ReadConstantString (ReadBlob (row.Col2));
2183 return ReadConstantPrimitive (row.Col1, row.Col2);
2187 static string ReadConstantString (byte [] blob)
2189 var length = blob.Length;
2190 if ((length & 1) == 1)
2193 return Encoding.Unicode.GetString (blob, 0, length);
2196 object ReadConstantPrimitive (ElementType type, uint signature)
2198 var reader = ReadSignature (signature);
2199 return reader.ReadConstantSignature (type);
2202 void InitializeCustomAttributes ()
2204 if (metadata.CustomAttributes != null)
2207 metadata.CustomAttributes = InitializeRanges (
2208 Table.CustomAttribute, () => {
2209 var next = ReadMetadataToken (CodedIndex.HasCustomAttribute);
2210 ReadMetadataToken (CodedIndex.CustomAttributeType);
2216 public bool HasCustomAttributes (ICustomAttributeProvider owner)
2218 InitializeCustomAttributes ();
2221 if (!metadata.TryGetCustomAttributeRange (owner, out range))
2224 return range.Length > 0;
2227 public Collection<CustomAttribute> ReadCustomAttributes (ICustomAttributeProvider owner)
2229 InitializeCustomAttributes ();
2232 if (!metadata.TryGetCustomAttributeRange (owner, out range)
2233 || !MoveTo (Table.CustomAttribute, range.Start))
2234 return new Collection<CustomAttribute> ();
2236 var custom_attributes = new Collection<CustomAttribute> ((int) range.Length);
2238 for (int i = 0; i < range.Length; i++) {
2239 ReadMetadataToken (CodedIndex.HasCustomAttribute);
2241 var constructor = (MethodReference) LookupToken (
2242 ReadMetadataToken (CodedIndex.CustomAttributeType));
2244 var signature = ReadBlobIndex ();
2246 custom_attributes.Add (new CustomAttribute (signature, constructor));
2249 metadata.RemoveCustomAttributeRange (owner);
2251 return custom_attributes;
2254 public byte [] ReadCustomAttributeBlob (uint signature)
2256 return ReadBlob (signature);
2259 public void ReadCustomAttributeSignature (CustomAttribute attribute)
2261 var reader = ReadSignature (attribute.signature);
2262 if (reader.ReadUInt16 () != 0x0001)
2263 throw new InvalidOperationException ();
2265 var constructor = attribute.Constructor;
2266 if (constructor.HasParameters)
2267 reader.ReadCustomAttributeConstructorArguments (attribute, constructor.Parameters);
2269 if (!reader.CanReadMore ())
2272 var named = reader.ReadUInt16 ();
2277 reader.ReadCustomAttributeNamedArguments (named, ref attribute.fields, ref attribute.properties);
2280 void InitializeMarshalInfos ()
2282 if (metadata.FieldMarshals != null)
2285 var length = MoveTo (Table.FieldMarshal);
2287 var marshals = metadata.FieldMarshals = new Dictionary<MetadataToken, uint> (length);
2289 for (int i = 0; i < length; i++) {
2290 var token = ReadMetadataToken (CodedIndex.HasFieldMarshal);
2291 var signature = ReadBlobIndex ();
2295 marshals.Add (token, signature);
2299 public bool HasMarshalInfo (IMarshalInfoProvider owner)
2301 InitializeMarshalInfos ();
2303 return metadata.FieldMarshals.ContainsKey (owner.MetadataToken);
2306 public MarshalInfo ReadMarshalInfo (IMarshalInfoProvider owner)
2308 InitializeMarshalInfos ();
2311 if (!metadata.FieldMarshals.TryGetValue (owner.MetadataToken, out signature))
2314 var reader = ReadSignature (signature);
2316 metadata.FieldMarshals.Remove (owner.MetadataToken);
2318 return reader.ReadMarshalInfo ();
2321 void InitializeSecurityDeclarations ()
2323 if (metadata.SecurityDeclarations != null)
2326 metadata.SecurityDeclarations = InitializeRanges (
2327 Table.DeclSecurity, () => {
2329 var next = ReadMetadataToken (CodedIndex.HasDeclSecurity);
2335 public bool HasSecurityDeclarations (ISecurityDeclarationProvider owner)
2337 InitializeSecurityDeclarations ();
2340 if (!metadata.TryGetSecurityDeclarationRange (owner, out range))
2343 return range.Length > 0;
2346 public Collection<SecurityDeclaration> ReadSecurityDeclarations (ISecurityDeclarationProvider owner)
2348 InitializeSecurityDeclarations ();
2351 if (!metadata.TryGetSecurityDeclarationRange (owner, out range)
2352 || !MoveTo (Table.DeclSecurity, range.Start))
2353 return new Collection<SecurityDeclaration> ();
2355 var security_declarations = new Collection<SecurityDeclaration> ((int) range.Length);
2357 for (int i = 0; i < range.Length; i++) {
2358 var action = (SecurityAction) ReadUInt16 ();
2359 ReadMetadataToken (CodedIndex.HasDeclSecurity);
2360 var signature = ReadBlobIndex ();
2362 security_declarations.Add (new SecurityDeclaration (action, signature, module));
2365 metadata.RemoveSecurityDeclarationRange (owner);
2367 return security_declarations;
2370 public byte [] ReadSecurityDeclarationBlob (uint signature)
2372 return ReadBlob (signature);
2375 public void ReadSecurityDeclarationSignature (SecurityDeclaration declaration)
2377 var signature = declaration.signature;
2378 var reader = ReadSignature (signature);
2380 if (reader.buffer [reader.position] != '.') {
2381 ReadXmlSecurityDeclaration (signature, declaration);
2386 var count = reader.ReadCompressedUInt32 ();
2387 var attributes = new Collection<SecurityAttribute> ((int) count);
2389 for (int i = 0; i < count; i++)
2390 attributes.Add (reader.ReadSecurityAttribute ());
2392 declaration.security_attributes = attributes;
2395 void ReadXmlSecurityDeclaration (uint signature, SecurityDeclaration declaration)
2397 var blob = ReadBlob (signature);
2398 var attributes = new Collection<SecurityAttribute> (1);
2400 var attribute = new SecurityAttribute (
2401 module.TypeSystem.LookupType ("System.Security.Permissions", "PermissionSetAttribute"));
2403 attribute.properties = new Collection<CustomAttributeNamedArgument> (1);
2404 attribute.properties.Add (
2405 new CustomAttributeNamedArgument (
2407 new CustomAttributeArgument (
2408 module.TypeSystem.String,
2409 Encoding.Unicode.GetString (blob, 0, blob.Length))));
2411 attributes.Add (attribute);
2413 declaration.security_attributes = attributes;
2416 public Collection<ExportedType> ReadExportedTypes ()
2418 var length = MoveTo (Table.ExportedType);
2420 return new Collection<ExportedType> ();
2422 var exported_types = new Collection<ExportedType> (length);
2424 for (int i = 1; i <= length; i++) {
2425 var attributes = (TypeAttributes) ReadUInt32 ();
2426 var identifier = ReadUInt32 ();
2427 var name = ReadString ();
2428 var @namespace = ReadString ();
2429 var implementation = ReadMetadataToken (CodedIndex.Implementation);
2431 ExportedType declaring_type = null;
2432 IMetadataScope scope = null;
2434 switch (implementation.TokenType) {
2435 case TokenType.AssemblyRef:
2436 case TokenType.File:
2437 scope = GetExportedTypeScope (implementation);
2439 case TokenType.ExportedType:
2440 // FIXME: if the table is not properly sorted
2441 declaring_type = exported_types [(int) implementation.RID - 1];
2445 var exported_type = new ExportedType (@namespace, name, scope) {
2446 Attributes = attributes,
2447 Identifier = (int) identifier,
2448 DeclaringType = declaring_type,
2450 exported_type.token = new MetadataToken (TokenType.ExportedType, i);
2452 exported_types.Add (exported_type);
2455 return exported_types;
2458 IMetadataScope GetExportedTypeScope (MetadataToken token)
2460 switch (token.TokenType) {
2461 case TokenType.AssemblyRef:
2462 return module.AssemblyReferences [(int) token.RID - 1];
2463 case TokenType.File:
2464 var position = this.position;
2465 var reference = GetModuleReferenceFromFile (token);
2466 this.position = position;
2468 if (reference == null)
2469 throw new NotSupportedException ();
2473 throw new NotSupportedException ();
2477 ModuleReference GetModuleReferenceFromFile (MetadataToken token)
2479 if (!MoveTo (Table.File, token.RID))
2483 var file_name = ReadString ();
2484 var modules = module.ModuleReferences;
2486 ModuleReference reference = null;
2487 for (int i = 0; i < modules.Count; i++) {
2488 var module_reference = modules [i];
2489 if (module_reference.Name != file_name)
2492 reference = module_reference;
2499 static void InitializeCollection (object o)
2504 sealed class SignatureReader : ByteBuffer {
2506 readonly MetadataReader reader;
2507 readonly uint start, sig_length;
2509 TypeSystem TypeSystem {
2510 get { return reader.module.TypeSystem; }
2513 public SignatureReader (uint blob, MetadataReader reader)
2514 : base (reader.buffer)
2516 this.reader = reader;
2520 this.sig_length = ReadCompressedUInt32 ();
2521 this.start = (uint) position;
2524 void MoveToBlob (uint blob)
2526 position = (int) (reader.image.BlobHeap.Offset + blob);
2529 MetadataToken ReadTypeTokenSignature ()
2531 return CodedIndex.TypeDefOrRef.GetMetadataToken (ReadCompressedUInt32 ());
2534 GenericParameter GetGenericParameter (GenericParameterType type, uint var)
2536 var context = reader.context;
2538 if (context == null)
2539 throw new NotSupportedException ();
2541 IGenericParameterProvider provider;
2544 case GenericParameterType.Type:
2545 provider = context.Type;
2547 case GenericParameterType.Method:
2548 provider = context.Method;
2551 throw new NotSupportedException ();
2554 int index = (int) var;
2556 if (!context.IsDefinition)
2557 CheckGenericContext (provider, index);
2559 return provider.GenericParameters [index];
2562 static void CheckGenericContext (IGenericParameterProvider owner, int index)
2564 var owner_parameters = owner.GenericParameters;
2566 for (int i = owner_parameters.Count; i <= index; i++)
2567 owner_parameters.Add (new GenericParameter (owner));
2570 public void ReadGenericInstanceSignature (IGenericParameterProvider provider, IGenericInstance instance)
2572 var arity = ReadCompressedUInt32 ();
2574 if (!provider.IsDefinition)
2575 CheckGenericContext (provider, (int) arity - 1);
2577 var instance_arguments = instance.GenericArguments;
2579 for (int i = 0; i < arity; i++)
2580 instance_arguments.Add (ReadTypeSignature ());
2583 ArrayType ReadArrayTypeSignature ()
2585 var array = new ArrayType (ReadTypeSignature ());
2587 var rank = ReadCompressedUInt32 ();
2589 var sizes = new uint [ReadCompressedUInt32 ()];
2590 for (int i = 0; i < sizes.Length; i++)
2591 sizes [i] = ReadCompressedUInt32 ();
2593 var low_bounds = new int [ReadCompressedUInt32 ()];
2594 for (int i = 0; i < low_bounds.Length; i++)
2595 low_bounds [i] = ReadCompressedInt32 ();
2597 array.Dimensions.Clear ();
2599 for (int i = 0; i < rank; i++) {
2600 int? lower = null, upper = null;
2602 if (i < low_bounds.Length)
2603 lower = low_bounds [i];
2605 if (i < sizes.Length)
2606 upper = lower + (int) sizes [i] - 1;
2608 array.Dimensions.Add (new ArrayDimension (lower, upper));
2614 TypeReference GetTypeDefOrRef (MetadataToken token)
2616 return reader.GetTypeDefOrRef (token);
2619 public TypeReference ReadTypeSignature ()
2621 return ReadTypeSignature ((ElementType) ReadByte ());
2624 TypeReference ReadTypeSignature (ElementType etype)
2627 case ElementType.ValueType: {
2628 var value_type = GetTypeDefOrRef (ReadTypeTokenSignature ());
2629 value_type.IsValueType = true;
2632 case ElementType.Class:
2633 return GetTypeDefOrRef (ReadTypeTokenSignature ());
2634 case ElementType.Ptr:
2635 return new PointerType (ReadTypeSignature ());
2636 case ElementType.FnPtr: {
2637 var fptr = new FunctionPointerType ();
2638 ReadMethodSignature (fptr);
2641 case ElementType.ByRef:
2642 return new ByReferenceType (ReadTypeSignature ());
2643 case ElementType.Pinned:
2644 return new PinnedType (ReadTypeSignature ());
2645 case ElementType.SzArray:
2646 return new ArrayType (ReadTypeSignature ());
2647 case ElementType.Array:
2648 return ReadArrayTypeSignature ();
2649 case ElementType.CModOpt:
2650 return new OptionalModifierType (
2651 GetTypeDefOrRef (ReadTypeTokenSignature ()), ReadTypeSignature ());
2652 case ElementType.CModReqD:
2653 return new RequiredModifierType (
2654 GetTypeDefOrRef (ReadTypeTokenSignature ()), ReadTypeSignature ());
2655 case ElementType.Sentinel:
2656 return new SentinelType (ReadTypeSignature ());
2657 case ElementType.Var:
2658 return GetGenericParameter (GenericParameterType.Type, ReadCompressedUInt32 ());
2659 case ElementType.MVar:
2660 return GetGenericParameter (GenericParameterType.Method, ReadCompressedUInt32 ());
2661 case ElementType.GenericInst: {
2662 var is_value_type = ReadByte () == (byte) ElementType.ValueType;
2663 var element_type = GetTypeDefOrRef (ReadTypeTokenSignature ());
2664 var generic_instance = new GenericInstanceType (element_type);
2666 ReadGenericInstanceSignature (element_type, generic_instance);
2668 if (is_value_type) {
2669 generic_instance.IsValueType = true;
2670 element_type.GetElementType ().IsValueType = true;
2673 return generic_instance;
2675 case ElementType.Object: return TypeSystem.Object;
2676 case ElementType.Void: return TypeSystem.Void;
2677 case ElementType.TypedByRef: return TypeSystem.TypedReference;
2678 case ElementType.I: return TypeSystem.IntPtr;
2679 case ElementType.U: return TypeSystem.UIntPtr;
2680 default: return GetPrimitiveType (etype);
2684 public void ReadMethodSignature (IMethodSignature method)
2686 var calling_convention = ReadByte ();
2687 method.CallingConvention = (MethodCallingConvention) calling_convention;
2688 method.HasThis = (calling_convention & 0x20) != 0;
2689 method.ExplicitThis = (calling_convention & 0x40) != 0;
2691 var generic_context = method as MethodReference;
2692 if (generic_context != null)
2693 reader.context = generic_context;
2695 if ((calling_convention & 0x10) != 0) {
2696 var arity = ReadCompressedUInt32 ();
2698 if (generic_context != null && !generic_context.IsDefinition)
2699 CheckGenericContext (generic_context, (int) arity -1 );
2702 // TODO: more call_conv
2704 var param_count = ReadCompressedUInt32 ();
2706 method.MethodReturnType.ReturnType = ReadTypeSignature ();
2708 if (param_count == 0)
2711 Collection<ParameterDefinition> parameters;
2713 var method_ref = method as MethodReference;
2714 if (method_ref != null)
2715 parameters = method_ref.parameters = new ParameterDefinitionCollection (method, (int) param_count);
2717 parameters = method.Parameters;
2719 for (int i = 0; i < param_count; i++)
2720 parameters.Add (new ParameterDefinition (ReadTypeSignature ()));
2723 public object ReadConstantSignature (ElementType type)
2725 return ReadPrimitiveValue (type);
2728 public void ReadCustomAttributeConstructorArguments (CustomAttribute attribute, Collection<ParameterDefinition> parameters)
2730 var count = parameters.Count;
2734 attribute.arguments = new Collection<CustomAttributeArgument> (count);
2736 for (int i = 0; i < count; i++)
2737 attribute.arguments.Add (
2738 ReadCustomAttributeFixedArgument (parameters [i].ParameterType));
2741 CustomAttributeArgument ReadCustomAttributeFixedArgument (TypeReference type)
2744 return ReadCustomAttributeFixedArrayArgument ((ArrayType) type);
2746 return ReadCustomAttributeElement (type);
2749 public void ReadCustomAttributeNamedArguments (ushort count, ref Collection<CustomAttributeNamedArgument> fields, ref Collection<CustomAttributeNamedArgument> properties)
2751 for (int i = 0; i < count; i++)
2752 ReadCustomAttributeNamedArgument (ref fields, ref properties);
2755 void ReadCustomAttributeNamedArgument (ref Collection<CustomAttributeNamedArgument> fields, ref Collection<CustomAttributeNamedArgument> properties)
2757 var kind = ReadByte ();
2758 var type = ReadCustomAttributeFieldOrPropType ();
2759 var name = ReadUTF8String ();
2761 Collection<CustomAttributeNamedArgument> container;
2764 container = GetCustomAttributeNamedArgumentCollection (ref fields);
2767 container = GetCustomAttributeNamedArgumentCollection (ref properties);
2770 throw new NotSupportedException ();
2773 container.Add (new CustomAttributeNamedArgument (name, ReadCustomAttributeFixedArgument (type)));
2776 static Collection<CustomAttributeNamedArgument> GetCustomAttributeNamedArgumentCollection (ref Collection<CustomAttributeNamedArgument> collection)
2778 if (collection != null)
2781 return collection = new Collection<CustomAttributeNamedArgument> ();
2784 CustomAttributeArgument ReadCustomAttributeFixedArrayArgument (ArrayType type)
2786 var length = ReadUInt32 ();
2788 if (length == 0xffffffff)
2789 return new CustomAttributeArgument (type, null);
2792 return new CustomAttributeArgument (type, Empty<CustomAttributeArgument>.Array);
2794 var arguments = new CustomAttributeArgument [length];
2795 var element_type = type.ElementType;
2797 for (int i = 0; i < length; i++)
2798 arguments [i] = ReadCustomAttributeElement (element_type);
2800 return new CustomAttributeArgument (type, arguments);
2803 CustomAttributeArgument ReadCustomAttributeElement (TypeReference type)
2806 return ReadCustomAttributeFixedArrayArgument ((ArrayType) type);
2808 return new CustomAttributeArgument (
2810 type.etype == ElementType.Object
2811 ? ReadCustomAttributeElement (ReadCustomAttributeFieldOrPropType ())
2812 : ReadCustomAttributeElementValue (type));
2815 object ReadCustomAttributeElementValue (TypeReference type)
2817 var etype = type.etype;
2820 case ElementType.String:
2821 return ReadUTF8String ();
2822 case ElementType.None:
2823 if (type.IsTypeOf ("System", "Type"))
2824 return ReadTypeReference ();
2826 return ReadCustomAttributeEnum (type);
2828 return ReadPrimitiveValue (etype);
2832 object ReadPrimitiveValue (ElementType type)
2835 case ElementType.Boolean:
2836 return ReadByte () == 1;
2837 case ElementType.I1:
2838 return (sbyte) ReadByte ();
2839 case ElementType.U1:
2841 case ElementType.Char:
2842 return (char) ReadUInt16 ();
2843 case ElementType.I2:
2844 return ReadInt16 ();
2845 case ElementType.U2:
2846 return ReadUInt16 ();
2847 case ElementType.I4:
2848 return ReadInt32 ();
2849 case ElementType.U4:
2850 return ReadUInt32 ();
2851 case ElementType.I8:
2852 return ReadInt64 ();
2853 case ElementType.U8:
2854 return ReadUInt64 ();
2855 case ElementType.R4:
2856 return ReadSingle ();
2857 case ElementType.R8:
2858 return ReadDouble ();
2860 throw new NotImplementedException (type.ToString ());
2864 TypeReference GetPrimitiveType (ElementType etype)
2867 case ElementType.Boolean:
2868 return TypeSystem.Boolean;
2869 case ElementType.Char:
2870 return TypeSystem.Char;
2871 case ElementType.I1:
2872 return TypeSystem.SByte;
2873 case ElementType.U1:
2874 return TypeSystem.Byte;
2875 case ElementType.I2:
2876 return TypeSystem.Int16;
2877 case ElementType.U2:
2878 return TypeSystem.UInt16;
2879 case ElementType.I4:
2880 return TypeSystem.Int32;
2881 case ElementType.U4:
2882 return TypeSystem.UInt32;
2883 case ElementType.I8:
2884 return TypeSystem.Int64;
2885 case ElementType.U8:
2886 return TypeSystem.UInt64;
2887 case ElementType.R4:
2888 return TypeSystem.Single;
2889 case ElementType.R8:
2890 return TypeSystem.Double;
2891 case ElementType.String:
2892 return TypeSystem.String;
2894 throw new NotImplementedException (etype.ToString ());
2898 TypeReference ReadCustomAttributeFieldOrPropType ()
2900 var etype = (ElementType) ReadByte ();
2903 case ElementType.Boxed:
2904 return TypeSystem.Object;
2905 case ElementType.SzArray:
2906 return new ArrayType (ReadCustomAttributeFieldOrPropType ());
2907 case ElementType.Enum:
2908 return ReadTypeReference ();
2909 case ElementType.Type:
2910 return TypeSystem.LookupType ("System", "Type");
2912 return GetPrimitiveType (etype);
2916 public TypeReference ReadTypeReference ()
2918 return TypeParser.ParseType (reader.module, ReadUTF8String ());
2921 object ReadCustomAttributeEnum (TypeReference enum_type)
2923 var type = enum_type.CheckedResolve ();
2925 throw new ArgumentException ();
2927 return ReadCustomAttributeElementValue (type.GetEnumUnderlyingType ());
2930 public SecurityAttribute ReadSecurityAttribute ()
2932 var attribute = new SecurityAttribute (ReadTypeReference ());
2934 ReadCompressedUInt32 ();
2936 ReadCustomAttributeNamedArguments (
2937 (ushort) ReadCompressedUInt32 (),
2938 ref attribute.fields,
2939 ref attribute.properties);
2944 public MarshalInfo ReadMarshalInfo ()
2946 var native = ReadNativeType ();
2948 case NativeType.Array: {
2949 var array = new ArrayMarshalInfo ();
2951 array.element_type = ReadNativeType ();
2953 array.size_parameter_index = (int) ReadCompressedUInt32 ();
2955 array.size = (int) ReadCompressedUInt32 ();
2957 array.size_parameter_multiplier = (int) ReadCompressedUInt32 ();
2960 case NativeType.SafeArray: {
2961 var array = new SafeArrayMarshalInfo ();
2963 array.element_type = ReadVariantType ();
2966 case NativeType.FixedArray: {
2967 var array = new FixedArrayMarshalInfo ();
2969 array.size = (int) ReadCompressedUInt32 ();
2971 array.element_type = ReadNativeType ();
2974 case NativeType.FixedSysString: {
2975 var sys_string = new FixedSysStringMarshalInfo ();
2977 sys_string.size = (int) ReadCompressedUInt32 ();
2980 case NativeType.CustomMarshaler: {
2981 var marshaler = new CustomMarshalInfo ();
2982 var guid_value = ReadUTF8String ();
2983 marshaler.guid = !string.IsNullOrEmpty (guid_value) ? new Guid (guid_value) : Guid.Empty;
2984 marshaler.unmanaged_type = ReadUTF8String ();
2985 marshaler.managed_type = ReadTypeReference ();
2986 marshaler.cookie = ReadUTF8String ();
2990 return new MarshalInfo (native);
2994 NativeType ReadNativeType ()
2996 return (NativeType) ReadByte ();
2999 VariantType ReadVariantType ()
3001 return (VariantType) ReadByte ();
3004 string ReadUTF8String ()
3006 if (buffer [position] == 0xff) {
3011 var length = (int) ReadCompressedUInt32 ();
3013 return string.Empty;
3015 var @string = Encoding.UTF8.GetString (buffer, position,
3016 buffer [position + length - 1] == 0 ? length - 1 : length);
3022 public bool CanReadMore ()
3024 return position - start < sig_length;