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);
1890 public VariableDefinitionCollection ReadVariables (MetadataToken local_var_token)
1892 if (!MoveTo (Table.StandAloneSig, local_var_token.RID))
1895 var reader = ReadSignature (ReadBlobIndex ());
1896 const byte local_sig = 0x7;
1898 if (reader.ReadByte () != local_sig)
1899 throw new NotSupportedException ();
1901 var count = reader.ReadCompressedUInt32 ();
1905 var variables = new VariableDefinitionCollection ((int) count);
1907 for (int i = 0; i < count; i++)
1908 variables.Add (new VariableDefinition (reader.ReadTypeSignature ()));
1913 public IMetadataTokenProvider LookupToken (MetadataToken token)
1915 var rid = token.RID;
1920 IMetadataTokenProvider element;
1921 var position = this.position;
1922 var context = this.context;
1924 switch (token.TokenType) {
1925 case TokenType.TypeDef:
1926 element = GetTypeDefinition (rid);
1928 case TokenType.TypeRef:
1929 element = GetTypeReference (rid);
1931 case TokenType.TypeSpec:
1932 element = GetTypeSpecification (rid);
1934 case TokenType.Field:
1935 element = GetFieldDefinition (rid);
1937 case TokenType.Method:
1938 element = GetMethodDefinition (rid);
1940 case TokenType.MemberRef:
1941 element = GetMemberReference (rid);
1943 case TokenType.MethodSpec:
1944 element = GetMethodSpecification (rid);
1950 this.position = position;
1951 this.context = context;
1956 public FieldDefinition GetFieldDefinition (uint rid)
1958 InitializeTypeDefinitions ();
1960 var field = metadata.GetFieldDefinition (rid);
1964 return LookupField (rid);
1967 FieldDefinition LookupField (uint rid)
1969 var type = metadata.GetFieldDeclaringType (rid);
1973 InitializeCollection (type.Fields);
1975 return metadata.GetFieldDefinition (rid);
1978 public MethodDefinition GetMethodDefinition (uint rid)
1980 InitializeTypeDefinitions ();
1982 var method = metadata.GetMethodDefinition (rid);
1986 return LookupMethod (rid);
1989 MethodDefinition LookupMethod (uint rid)
1991 var type = metadata.GetMethodDeclaringType (rid);
1995 InitializeCollection (type.Methods);
1997 return metadata.GetMethodDefinition (rid);
2000 MethodSpecification GetMethodSpecification (uint rid)
2002 if (!MoveTo (Table.MethodSpec, rid))
2005 var element_method = (MethodReference) LookupToken (
2006 ReadMetadataToken (CodedIndex.MethodDefOrRef));
2007 var signature = ReadBlobIndex ();
2009 var method_spec = ReadMethodSpecSignature (signature, element_method);
2010 method_spec.token = new MetadataToken (TokenType.MethodSpec, rid);
2014 MethodSpecification ReadMethodSpecSignature (uint signature, MethodReference method)
2016 var reader = ReadSignature (signature);
2017 const byte methodspec_sig = 0x0a;
2019 var call_conv = reader.ReadByte ();
2021 if (call_conv != methodspec_sig)
2022 throw new NotSupportedException ();
2024 var instance = new GenericInstanceMethod (method);
2026 reader.ReadGenericInstanceSignature (method, instance);
2031 MemberReference GetMemberReference (uint rid)
2033 InitializeMemberReferences ();
2035 var member = metadata.GetMemberReference (rid);
2039 member = ReadMemberReference (rid);
2040 if (member != null && !member.ContainsGenericParameter)
2041 metadata.AddMemberReference (member);
2045 MemberReference ReadMemberReference (uint rid)
2047 if (!MoveTo (Table.MemberRef, rid))
2050 var token = ReadMetadataToken (CodedIndex.MemberRefParent);
2051 var name = ReadString ();
2052 var signature = ReadBlobIndex ();
2054 MemberReference member;
2056 switch (token.TokenType) {
2057 case TokenType.TypeDef:
2058 case TokenType.TypeRef:
2059 case TokenType.TypeSpec:
2060 member = ReadTypeMemberReference (token, name, signature);
2062 case TokenType.Method:
2063 member = ReadMethodMemberReference (token, name, signature);
2066 throw new NotSupportedException ();
2069 member.token = new MetadataToken (TokenType.MemberRef, rid);
2074 MemberReference ReadTypeMemberReference (MetadataToken type, string name, uint signature)
2076 var declaring_type = GetTypeDefOrRef (type);
2078 this.context = declaring_type;
2080 var member = ReadMemberReferenceSignature (signature, declaring_type);
2086 MemberReference ReadMemberReferenceSignature (uint signature, TypeReference declaring_type)
2088 var reader = ReadSignature (signature);
2089 const byte field_sig = 0x6;
2091 if (reader.buffer [reader.position] == field_sig) {
2093 var field = new FieldReference ();
2094 field.DeclaringType = declaring_type;
2095 field.FieldType = reader.ReadTypeSignature ();
2098 var method = new MethodReference ();
2099 method.DeclaringType = declaring_type;
2100 reader.ReadMethodSignature (method);
2105 MemberReference ReadMethodMemberReference (MetadataToken token, string name, uint signature)
2107 var method = GetMethodDefinition (token.RID);
2109 this.context = method;
2111 var member = ReadMemberReferenceSignature (signature, method.DeclaringType);
2117 void InitializeMemberReferences ()
2119 if (metadata.MemberReferences != null)
2122 metadata.MemberReferences = new MemberReference [image.GetTableLength (Table.MemberRef)];
2125 public IEnumerable<MemberReference> GetMemberReferences ()
2127 InitializeMemberReferences ();
2129 var length = image.GetTableLength (Table.MemberRef);
2131 var type_system = module.TypeSystem;
2133 var context = new MethodReference (string.Empty, type_system.Void);
2134 context.DeclaringType = new TypeReference (string.Empty, string.Empty, module, type_system.Corlib);
2136 var member_references = new MemberReference [length];
2138 for (uint i = 1; i <= length; i++) {
2139 this.context = context;
2140 member_references [i - 1] = GetMemberReference (i);
2143 return member_references;
2146 void InitializeConstants ()
2148 if (metadata.Constants != null)
2151 var length = MoveTo (Table.Constant);
2153 var constants = metadata.Constants = new Dictionary<MetadataToken, Row<ElementType, uint>> (length);
2155 for (uint i = 1; i <= length; i++) {
2156 var type = (ElementType) ReadUInt16 ();
2157 var owner = ReadMetadataToken (CodedIndex.HasConstant);
2158 var signature = ReadBlobIndex ();
2160 constants.Add (owner, new Row<ElementType, uint> (type, signature));
2164 public object ReadConstant (IConstantProvider owner)
2166 InitializeConstants ();
2168 Row<ElementType, uint> row;
2169 if (!metadata.Constants.TryGetValue (owner.MetadataToken, out row))
2170 return Mixin.NoValue;
2172 metadata.Constants.Remove (owner.MetadataToken);
2175 case ElementType.Class:
2176 case ElementType.Object:
2178 case ElementType.String:
2179 return ReadConstantString (ReadBlob (row.Col2));
2181 return ReadConstantPrimitive (row.Col1, row.Col2);
2185 static string ReadConstantString (byte [] blob)
2187 var length = blob.Length;
2188 if ((length & 1) == 1)
2191 return Encoding.Unicode.GetString (blob, 0, length);
2194 object ReadConstantPrimitive (ElementType type, uint signature)
2196 var reader = ReadSignature (signature);
2197 return reader.ReadConstantSignature (type);
2200 void InitializeCustomAttributes ()
2202 if (metadata.CustomAttributes != null)
2205 metadata.CustomAttributes = InitializeRanges (
2206 Table.CustomAttribute, () => {
2207 var next = ReadMetadataToken (CodedIndex.HasCustomAttribute);
2208 ReadMetadataToken (CodedIndex.CustomAttributeType);
2214 public bool HasCustomAttributes (ICustomAttributeProvider owner)
2216 InitializeCustomAttributes ();
2219 if (!metadata.TryGetCustomAttributeRange (owner, out range))
2222 return range.Length > 0;
2225 public Collection<CustomAttribute> ReadCustomAttributes (ICustomAttributeProvider owner)
2227 InitializeCustomAttributes ();
2230 if (!metadata.TryGetCustomAttributeRange (owner, out range)
2231 || !MoveTo (Table.CustomAttribute, range.Start))
2232 return new Collection<CustomAttribute> ();
2234 var custom_attributes = new Collection<CustomAttribute> ((int) range.Length);
2236 for (int i = 0; i < range.Length; i++) {
2237 ReadMetadataToken (CodedIndex.HasCustomAttribute);
2239 var constructor = (MethodReference) LookupToken (
2240 ReadMetadataToken (CodedIndex.CustomAttributeType));
2242 var signature = ReadBlobIndex ();
2244 custom_attributes.Add (new CustomAttribute (signature, constructor));
2247 metadata.RemoveCustomAttributeRange (owner);
2249 return custom_attributes;
2252 public byte [] ReadCustomAttributeBlob (uint signature)
2254 return ReadBlob (signature);
2257 public void ReadCustomAttributeSignature (CustomAttribute attribute)
2259 var reader = ReadSignature (attribute.signature);
2260 if (reader.ReadUInt16 () != 0x0001)
2261 throw new InvalidOperationException ();
2263 var constructor = attribute.Constructor;
2264 if (constructor.HasParameters)
2265 reader.ReadCustomAttributeConstructorArguments (attribute, constructor.Parameters);
2267 if (!reader.CanReadMore ())
2270 var named = reader.ReadUInt16 ();
2275 reader.ReadCustomAttributeNamedArguments (named, ref attribute.fields, ref attribute.properties);
2278 void InitializeMarshalInfos ()
2280 if (metadata.FieldMarshals != null)
2283 var length = MoveTo (Table.FieldMarshal);
2285 var marshals = metadata.FieldMarshals = new Dictionary<MetadataToken, uint> (length);
2287 for (int i = 0; i < length; i++) {
2288 var token = ReadMetadataToken (CodedIndex.HasFieldMarshal);
2289 var signature = ReadBlobIndex ();
2293 marshals.Add (token, signature);
2297 public bool HasMarshalInfo (IMarshalInfoProvider owner)
2299 InitializeMarshalInfos ();
2301 return metadata.FieldMarshals.ContainsKey (owner.MetadataToken);
2304 public MarshalInfo ReadMarshalInfo (IMarshalInfoProvider owner)
2306 InitializeMarshalInfos ();
2309 if (!metadata.FieldMarshals.TryGetValue (owner.MetadataToken, out signature))
2312 var reader = ReadSignature (signature);
2314 metadata.FieldMarshals.Remove (owner.MetadataToken);
2316 return reader.ReadMarshalInfo ();
2319 void InitializeSecurityDeclarations ()
2321 if (metadata.SecurityDeclarations != null)
2324 metadata.SecurityDeclarations = InitializeRanges (
2325 Table.DeclSecurity, () => {
2327 var next = ReadMetadataToken (CodedIndex.HasDeclSecurity);
2333 public bool HasSecurityDeclarations (ISecurityDeclarationProvider owner)
2335 InitializeSecurityDeclarations ();
2338 if (!metadata.TryGetSecurityDeclarationRange (owner, out range))
2341 return range.Length > 0;
2344 public Collection<SecurityDeclaration> ReadSecurityDeclarations (ISecurityDeclarationProvider owner)
2346 InitializeSecurityDeclarations ();
2349 if (!metadata.TryGetSecurityDeclarationRange (owner, out range)
2350 || !MoveTo (Table.DeclSecurity, range.Start))
2351 return new Collection<SecurityDeclaration> ();
2353 var security_declarations = new Collection<SecurityDeclaration> ((int) range.Length);
2355 for (int i = 0; i < range.Length; i++) {
2356 var action = (SecurityAction) ReadUInt16 ();
2357 ReadMetadataToken (CodedIndex.HasDeclSecurity);
2358 var signature = ReadBlobIndex ();
2360 security_declarations.Add (new SecurityDeclaration (action, signature, module));
2363 metadata.RemoveSecurityDeclarationRange (owner);
2365 return security_declarations;
2368 public byte [] ReadSecurityDeclarationBlob (uint signature)
2370 return ReadBlob (signature);
2373 public void ReadSecurityDeclarationSignature (SecurityDeclaration declaration)
2375 var signature = declaration.signature;
2376 var reader = ReadSignature (signature);
2378 if (reader.buffer [reader.position] != '.') {
2379 ReadXmlSecurityDeclaration (signature, declaration);
2384 var count = reader.ReadCompressedUInt32 ();
2385 var attributes = new Collection<SecurityAttribute> ((int) count);
2387 for (int i = 0; i < count; i++)
2388 attributes.Add (reader.ReadSecurityAttribute ());
2390 declaration.security_attributes = attributes;
2393 void ReadXmlSecurityDeclaration (uint signature, SecurityDeclaration declaration)
2395 var blob = ReadBlob (signature);
2396 var attributes = new Collection<SecurityAttribute> (1);
2398 var attribute = new SecurityAttribute (
2399 module.TypeSystem.LookupType ("System.Security.Permissions", "PermissionSetAttribute"));
2401 attribute.properties = new Collection<CustomAttributeNamedArgument> (1);
2402 attribute.properties.Add (
2403 new CustomAttributeNamedArgument (
2405 new CustomAttributeArgument (
2406 module.TypeSystem.String,
2407 Encoding.Unicode.GetString (blob, 0, blob.Length))));
2409 attributes.Add (attribute);
2411 declaration.security_attributes = attributes;
2414 public Collection<ExportedType> ReadExportedTypes ()
2416 var length = MoveTo (Table.ExportedType);
2418 return new Collection<ExportedType> ();
2420 var exported_types = new Collection<ExportedType> (length);
2422 for (int i = 1; i <= length; i++) {
2423 var attributes = (TypeAttributes) ReadUInt32 ();
2424 var identifier = ReadUInt32 ();
2425 var name = ReadString ();
2426 var @namespace = ReadString ();
2427 var implementation = ReadMetadataToken (CodedIndex.Implementation);
2429 ExportedType declaring_type = null;
2430 IMetadataScope scope = null;
2432 switch (implementation.TokenType) {
2433 case TokenType.AssemblyRef:
2434 case TokenType.File:
2435 scope = GetExportedTypeScope (implementation);
2437 case TokenType.ExportedType:
2438 // FIXME: if the table is not properly sorted
2439 declaring_type = exported_types [(int) implementation.RID - 1];
2443 var exported_type = new ExportedType (@namespace, name, scope) {
2444 Attributes = attributes,
2445 Identifier = (int) identifier,
2446 DeclaringType = declaring_type,
2448 exported_type.token = new MetadataToken (TokenType.ExportedType, i);
2450 exported_types.Add (exported_type);
2453 return exported_types;
2456 IMetadataScope GetExportedTypeScope (MetadataToken token)
2458 switch (token.TokenType) {
2459 case TokenType.AssemblyRef:
2460 return module.AssemblyReferences [(int) token.RID - 1];
2461 case TokenType.File:
2462 var position = this.position;
2463 var reference = GetModuleReferenceFromFile (token);
2464 this.position = position;
2466 if (reference == null)
2467 throw new NotSupportedException ();
2471 throw new NotSupportedException ();
2475 ModuleReference GetModuleReferenceFromFile (MetadataToken token)
2477 if (!MoveTo (Table.File, token.RID))
2481 var file_name = ReadString ();
2482 var modules = module.ModuleReferences;
2484 ModuleReference reference = null;
2485 for (int i = 0; i < modules.Count; i++) {
2486 var module_reference = modules [i];
2487 if (module_reference.Name != file_name)
2490 reference = module_reference;
2497 static void InitializeCollection (object o)
2502 sealed class SignatureReader : ByteBuffer {
2504 readonly MetadataReader reader;
2505 readonly uint start, sig_length;
2507 TypeSystem TypeSystem {
2508 get { return reader.module.TypeSystem; }
2511 public SignatureReader (uint blob, MetadataReader reader)
2512 : base (reader.buffer)
2514 this.reader = reader;
2518 this.sig_length = ReadCompressedUInt32 ();
2519 this.start = (uint) position;
2522 void MoveToBlob (uint blob)
2524 position = (int) (reader.image.BlobHeap.Offset + blob);
2527 MetadataToken ReadTypeTokenSignature ()
2529 return CodedIndex.TypeDefOrRef.GetMetadataToken (ReadCompressedUInt32 ());
2532 GenericParameter GetGenericParameter (GenericParameterType type, uint var)
2534 var context = reader.context;
2536 if (context == null)
2537 throw new NotSupportedException ();
2539 IGenericParameterProvider provider;
2542 case GenericParameterType.Type:
2543 provider = context.Type;
2545 case GenericParameterType.Method:
2546 provider = context.Method;
2549 throw new NotSupportedException ();
2552 int index = (int) var;
2554 if (!context.IsDefinition)
2555 CheckGenericContext (provider, index);
2557 return provider.GenericParameters [index];
2560 static void CheckGenericContext (IGenericParameterProvider owner, int index)
2562 var owner_parameters = owner.GenericParameters;
2564 for (int i = owner_parameters.Count; i <= index; i++)
2565 owner_parameters.Add (new GenericParameter (owner));
2568 public void ReadGenericInstanceSignature (IGenericParameterProvider provider, IGenericInstance instance)
2570 var arity = ReadCompressedUInt32 ();
2572 if (!provider.IsDefinition)
2573 CheckGenericContext (provider, (int) arity - 1);
2575 var instance_arguments = instance.GenericArguments;
2577 for (int i = 0; i < arity; i++)
2578 instance_arguments.Add (ReadTypeSignature ());
2581 ArrayType ReadArrayTypeSignature ()
2583 var array = new ArrayType (ReadTypeSignature ());
2585 var rank = ReadCompressedUInt32 ();
2587 var sizes = new uint [ReadCompressedUInt32 ()];
2588 for (int i = 0; i < sizes.Length; i++)
2589 sizes [i] = ReadCompressedUInt32 ();
2591 var low_bounds = new int [ReadCompressedUInt32 ()];
2592 for (int i = 0; i < low_bounds.Length; i++)
2593 low_bounds [i] = ReadCompressedInt32 ();
2595 array.Dimensions.Clear ();
2597 for (int i = 0; i < rank; i++) {
2598 int? lower = null, upper = null;
2600 if (i < low_bounds.Length)
2601 lower = low_bounds [i];
2603 if (i < sizes.Length)
2604 upper = lower + (int) sizes [i] - 1;
2606 array.Dimensions.Add (new ArrayDimension (lower, upper));
2612 TypeReference GetTypeDefOrRef (MetadataToken token)
2614 return reader.GetTypeDefOrRef (token);
2617 public TypeReference ReadTypeSignature ()
2619 return ReadTypeSignature ((ElementType) ReadByte ());
2622 TypeReference ReadTypeSignature (ElementType etype)
2625 case ElementType.ValueType: {
2626 var value_type = GetTypeDefOrRef (ReadTypeTokenSignature ());
2627 value_type.IsValueType = true;
2630 case ElementType.Class:
2631 return GetTypeDefOrRef (ReadTypeTokenSignature ());
2632 case ElementType.Ptr:
2633 return new PointerType (ReadTypeSignature ());
2634 case ElementType.FnPtr: {
2635 var fptr = new FunctionPointerType ();
2636 ReadMethodSignature (fptr);
2639 case ElementType.ByRef:
2640 return new ByReferenceType (ReadTypeSignature ());
2641 case ElementType.Pinned:
2642 return new PinnedType (ReadTypeSignature ());
2643 case ElementType.SzArray:
2644 return new ArrayType (ReadTypeSignature ());
2645 case ElementType.Array:
2646 return ReadArrayTypeSignature ();
2647 case ElementType.CModOpt:
2648 return new OptionalModifierType (
2649 GetTypeDefOrRef (ReadTypeTokenSignature ()), ReadTypeSignature ());
2650 case ElementType.CModReqD:
2651 return new RequiredModifierType (
2652 GetTypeDefOrRef (ReadTypeTokenSignature ()), ReadTypeSignature ());
2653 case ElementType.Sentinel:
2654 return new SentinelType (ReadTypeSignature ());
2655 case ElementType.Var:
2656 return GetGenericParameter (GenericParameterType.Type, ReadCompressedUInt32 ());
2657 case ElementType.MVar:
2658 return GetGenericParameter (GenericParameterType.Method, ReadCompressedUInt32 ());
2659 case ElementType.GenericInst: {
2660 var is_value_type = ReadByte () == (byte) ElementType.ValueType;
2661 var element_type = GetTypeDefOrRef (ReadTypeTokenSignature ());
2662 var generic_instance = new GenericInstanceType (element_type);
2664 ReadGenericInstanceSignature (element_type, generic_instance);
2666 if (is_value_type) {
2667 generic_instance.IsValueType = true;
2668 element_type.GetElementType ().IsValueType = true;
2671 return generic_instance;
2673 case ElementType.Object: return TypeSystem.Object;
2674 case ElementType.Void: return TypeSystem.Void;
2675 case ElementType.TypedByRef: return TypeSystem.TypedReference;
2676 case ElementType.I: return TypeSystem.IntPtr;
2677 case ElementType.U: return TypeSystem.UIntPtr;
2678 default: return GetPrimitiveType (etype);
2682 public void ReadMethodSignature (IMethodSignature method)
2684 var calling_convention = ReadByte ();
2685 method.CallingConvention = (MethodCallingConvention) calling_convention;
2686 method.HasThis = (calling_convention & 0x20) != 0;
2687 method.ExplicitThis = (calling_convention & 0x40) != 0;
2689 var generic_context = method as MethodReference;
2690 if (generic_context != null)
2691 reader.context = generic_context;
2693 if ((calling_convention & 0x10) != 0) {
2694 var arity = ReadCompressedUInt32 ();
2696 if (generic_context != null && !generic_context.IsDefinition)
2697 CheckGenericContext (generic_context, (int) arity -1 );
2700 // TODO: more call_conv
2702 var param_count = ReadCompressedUInt32 ();
2704 method.MethodReturnType.ReturnType = ReadTypeSignature ();
2706 if (param_count == 0)
2709 Collection<ParameterDefinition> parameters;
2711 var method_ref = method as MethodReference;
2712 if (method_ref != null)
2713 parameters = method_ref.parameters = new ParameterDefinitionCollection (method, (int) param_count);
2715 parameters = method.Parameters;
2717 for (int i = 0; i < param_count; i++)
2718 parameters.Add (new ParameterDefinition (ReadTypeSignature ()));
2721 public object ReadConstantSignature (ElementType type)
2723 return ReadPrimitiveValue (type);
2726 public void ReadCustomAttributeConstructorArguments (CustomAttribute attribute, Collection<ParameterDefinition> parameters)
2728 var count = parameters.Count;
2732 attribute.arguments = new Collection<CustomAttributeArgument> (count);
2734 for (int i = 0; i < count; i++)
2735 attribute.arguments.Add (
2736 ReadCustomAttributeFixedArgument (parameters [i].ParameterType));
2739 CustomAttributeArgument ReadCustomAttributeFixedArgument (TypeReference type)
2742 return ReadCustomAttributeFixedArrayArgument ((ArrayType) type);
2744 return ReadCustomAttributeElement (type);
2747 public void ReadCustomAttributeNamedArguments (ushort count, ref Collection<CustomAttributeNamedArgument> fields, ref Collection<CustomAttributeNamedArgument> properties)
2749 for (int i = 0; i < count; i++)
2750 ReadCustomAttributeNamedArgument (ref fields, ref properties);
2753 void ReadCustomAttributeNamedArgument (ref Collection<CustomAttributeNamedArgument> fields, ref Collection<CustomAttributeNamedArgument> properties)
2755 var kind = ReadByte ();
2756 var type = ReadCustomAttributeFieldOrPropType ();
2757 var name = ReadUTF8String ();
2759 Collection<CustomAttributeNamedArgument> container;
2762 container = GetCustomAttributeNamedArgumentCollection (ref fields);
2765 container = GetCustomAttributeNamedArgumentCollection (ref properties);
2768 throw new NotSupportedException ();
2771 container.Add (new CustomAttributeNamedArgument (name, ReadCustomAttributeFixedArgument (type)));
2774 static Collection<CustomAttributeNamedArgument> GetCustomAttributeNamedArgumentCollection (ref Collection<CustomAttributeNamedArgument> collection)
2776 if (collection != null)
2779 return collection = new Collection<CustomAttributeNamedArgument> ();
2782 CustomAttributeArgument ReadCustomAttributeFixedArrayArgument (ArrayType type)
2784 var length = ReadUInt32 ();
2786 if (length == 0xffffffff)
2787 return new CustomAttributeArgument (type, null);
2790 return new CustomAttributeArgument (type, Empty<CustomAttributeArgument>.Array);
2792 var arguments = new CustomAttributeArgument [length];
2793 var element_type = type.ElementType;
2795 for (int i = 0; i < length; i++)
2796 arguments [i] = ReadCustomAttributeElement (element_type);
2798 return new CustomAttributeArgument (type, arguments);
2801 CustomAttributeArgument ReadCustomAttributeElement (TypeReference type)
2804 return ReadCustomAttributeFixedArrayArgument ((ArrayType) type);
2806 if (type.etype == ElementType.Object)
2807 return ReadCustomAttributeElement (ReadCustomAttributeFieldOrPropType ());
2809 return new CustomAttributeArgument (type, ReadCustomAttributeElementValue (type));
2812 object ReadCustomAttributeElementValue (TypeReference type)
2814 var etype = type.etype;
2817 case ElementType.String:
2818 return ReadUTF8String ();
2819 case ElementType.None:
2820 if (type.IsTypeOf ("System", "Type"))
2821 return ReadTypeReference ();
2823 return ReadCustomAttributeEnum (type);
2825 return ReadPrimitiveValue (etype);
2829 object ReadPrimitiveValue (ElementType type)
2832 case ElementType.Boolean:
2833 return ReadByte () == 1;
2834 case ElementType.I1:
2835 return (sbyte) ReadByte ();
2836 case ElementType.U1:
2838 case ElementType.Char:
2839 return (char) ReadUInt16 ();
2840 case ElementType.I2:
2841 return ReadInt16 ();
2842 case ElementType.U2:
2843 return ReadUInt16 ();
2844 case ElementType.I4:
2845 return ReadInt32 ();
2846 case ElementType.U4:
2847 return ReadUInt32 ();
2848 case ElementType.I8:
2849 return ReadInt64 ();
2850 case ElementType.U8:
2851 return ReadUInt64 ();
2852 case ElementType.R4:
2853 return ReadSingle ();
2854 case ElementType.R8:
2855 return ReadDouble ();
2857 throw new NotImplementedException (type.ToString ());
2861 TypeReference GetPrimitiveType (ElementType etype)
2864 case ElementType.Boolean:
2865 return TypeSystem.Boolean;
2866 case ElementType.Char:
2867 return TypeSystem.Char;
2868 case ElementType.I1:
2869 return TypeSystem.SByte;
2870 case ElementType.U1:
2871 return TypeSystem.Byte;
2872 case ElementType.I2:
2873 return TypeSystem.Int16;
2874 case ElementType.U2:
2875 return TypeSystem.UInt16;
2876 case ElementType.I4:
2877 return TypeSystem.Int32;
2878 case ElementType.U4:
2879 return TypeSystem.UInt32;
2880 case ElementType.I8:
2881 return TypeSystem.Int64;
2882 case ElementType.U8:
2883 return TypeSystem.UInt64;
2884 case ElementType.R4:
2885 return TypeSystem.Single;
2886 case ElementType.R8:
2887 return TypeSystem.Double;
2888 case ElementType.String:
2889 return TypeSystem.String;
2891 throw new NotImplementedException (etype.ToString ());
2895 TypeReference ReadCustomAttributeFieldOrPropType ()
2897 var etype = (ElementType) ReadByte ();
2900 case ElementType.Boxed:
2901 return TypeSystem.Object;
2902 case ElementType.SzArray:
2903 return new ArrayType (ReadCustomAttributeFieldOrPropType ());
2904 case ElementType.Enum:
2905 return ReadTypeReference ();
2906 case ElementType.Type:
2907 return TypeSystem.LookupType ("System", "Type");
2909 return GetPrimitiveType (etype);
2913 public TypeReference ReadTypeReference ()
2915 return TypeParser.ParseType (reader.module, ReadUTF8String ());
2918 object ReadCustomAttributeEnum (TypeReference enum_type)
2920 var type = enum_type.CheckedResolve ();
2922 throw new ArgumentException ();
2924 return ReadCustomAttributeElementValue (type.GetEnumUnderlyingType ());
2927 public SecurityAttribute ReadSecurityAttribute ()
2929 var attribute = new SecurityAttribute (ReadTypeReference ());
2931 ReadCompressedUInt32 ();
2933 ReadCustomAttributeNamedArguments (
2934 (ushort) ReadCompressedUInt32 (),
2935 ref attribute.fields,
2936 ref attribute.properties);
2941 public MarshalInfo ReadMarshalInfo ()
2943 var native = ReadNativeType ();
2945 case NativeType.Array: {
2946 var array = new ArrayMarshalInfo ();
2948 array.element_type = ReadNativeType ();
2950 array.size_parameter_index = (int) ReadCompressedUInt32 ();
2952 array.size = (int) ReadCompressedUInt32 ();
2954 array.size_parameter_multiplier = (int) ReadCompressedUInt32 ();
2957 case NativeType.SafeArray: {
2958 var array = new SafeArrayMarshalInfo ();
2960 array.element_type = ReadVariantType ();
2963 case NativeType.FixedArray: {
2964 var array = new FixedArrayMarshalInfo ();
2966 array.size = (int) ReadCompressedUInt32 ();
2968 array.element_type = ReadNativeType ();
2971 case NativeType.FixedSysString: {
2972 var sys_string = new FixedSysStringMarshalInfo ();
2974 sys_string.size = (int) ReadCompressedUInt32 ();
2977 case NativeType.CustomMarshaler: {
2978 var marshaler = new CustomMarshalInfo ();
2979 var guid_value = ReadUTF8String ();
2980 marshaler.guid = !string.IsNullOrEmpty (guid_value) ? new Guid (guid_value) : Guid.Empty;
2981 marshaler.unmanaged_type = ReadUTF8String ();
2982 marshaler.managed_type = ReadTypeReference ();
2983 marshaler.cookie = ReadUTF8String ();
2987 return new MarshalInfo (native);
2991 NativeType ReadNativeType ()
2993 return (NativeType) ReadByte ();
2996 VariantType ReadVariantType ()
2998 return (VariantType) ReadByte ();
3001 string ReadUTF8String ()
3003 if (buffer [position] == 0xff) {
3008 var length = (int) ReadCompressedUInt32 ();
3010 return string.Empty;
3012 var @string = Encoding.UTF8.GetString (buffer, position,
3013 buffer [position + length - 1] == 0 ? length - 1 : length);
3019 public bool CanReadMore ()
3021 return position - start < sig_length;