5 // Jb Evain (jbevain@gmail.com)
7 // Copyright (c) 2008 - 2011 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 = new CodeReader (image.MetadataSection, 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 void InitializeAssemblyReferences ()
492 if (metadata.AssemblyReferences != null)
495 int length = MoveTo (Table.AssemblyRef);
496 var references = metadata.AssemblyReferences = new AssemblyNameReference [length];
498 for (uint i = 0; i < length; i++) {
499 var reference = new AssemblyNameReference ();
500 reference.token = new MetadataToken (TokenType.AssemblyRef, i + 1);
502 PopulateVersionAndFlags (reference);
504 var key_or_token = ReadBlob ();
506 if (reference.HasPublicKey)
507 reference.PublicKey = key_or_token;
509 reference.PublicKeyToken = key_or_token;
511 PopulateNameAndCulture (reference);
513 reference.Hash = ReadBlob ();
515 references [i] = reference;
519 public Collection<AssemblyNameReference> ReadAssemblyReferences ()
521 InitializeAssemblyReferences ();
523 return new Collection<AssemblyNameReference> (metadata.AssemblyReferences);
526 public MethodDefinition ReadEntryPoint ()
528 if (module.Kind != ModuleKind.Console && module.Kind != ModuleKind.Windows)
531 var token = new MetadataToken (module.Image.EntryPointToken);
533 return GetMethodDefinition (token.RID);
536 public Collection<ModuleDefinition> ReadModules ()
538 var modules = new Collection<ModuleDefinition> (1);
539 modules.Add (this.module);
541 int length = MoveTo (Table.File);
542 for (uint i = 1; i <= length; i++) {
543 var attributes = (FileAttributes) ReadUInt32 ();
544 var name = ReadString ();
547 if (attributes != FileAttributes.ContainsMetaData)
550 var parameters = new ReaderParameters {
551 ReadingMode = module.ReadingMode,
552 SymbolReaderProvider = module.SymbolReaderProvider,
555 modules.Add (ModuleDefinition.ReadModule (
556 GetModuleFileName (name), parameters));
562 string GetModuleFileName (string name)
564 if (module.FullyQualifiedName == null)
565 throw new NotSupportedException ();
567 var path = Path.GetDirectoryName (module.FullyQualifiedName);
568 return Path.Combine (path, name);
571 void InitializeModuleReferences ()
573 if (metadata.ModuleReferences != null)
576 int length = MoveTo (Table.ModuleRef);
577 var references = metadata.ModuleReferences = new ModuleReference [length];
579 for (uint i = 0; i < length; i++) {
580 var reference = new ModuleReference (ReadString ());
581 reference.token = new MetadataToken (TokenType.ModuleRef, i + 1);
583 references [i] = reference;
587 public Collection<ModuleReference> ReadModuleReferences ()
589 InitializeModuleReferences ();
591 return new Collection<ModuleReference> (metadata.ModuleReferences);
594 public bool HasFileResource ()
596 int length = MoveTo (Table.File);
600 for (uint i = 1; i <= length; i++)
601 if (ReadFileRecord (i).Col1 == FileAttributes.ContainsNoMetaData)
607 public Collection<Resource> ReadResources ()
609 int length = MoveTo (Table.ManifestResource);
610 var resources = new Collection<Resource> (length);
612 for (int i = 1; i <= length; i++) {
613 var offset = ReadUInt32 ();
614 var flags = (ManifestResourceAttributes) ReadUInt32 ();
615 var name = ReadString ();
616 var implementation = ReadMetadataToken (CodedIndex.Implementation);
620 if (implementation.RID == 0) {
621 resource = new EmbeddedResource (name, flags, offset, this);
622 } else if (implementation.TokenType == TokenType.AssemblyRef) {
623 resource = new AssemblyLinkedResource (name, flags) {
624 Assembly = (AssemblyNameReference) GetTypeReferenceScope (implementation),
626 } else if (implementation.TokenType == TokenType.File) {
627 var file_record = ReadFileRecord (implementation.RID);
629 resource = new LinkedResource (name, flags) {
630 File = file_record.Col2,
631 hash = ReadBlob (file_record.Col3)
634 throw new NotSupportedException ();
636 resources.Add (resource);
642 Row<FileAttributes, string, uint> ReadFileRecord (uint rid)
644 var position = this.position;
646 if (!MoveTo (Table.File, rid))
647 throw new ArgumentException ();
649 var record = new Row<FileAttributes, string, uint> (
650 (FileAttributes) ReadUInt32 (),
654 this.position = position;
659 public MemoryStream GetManagedResourceStream (uint offset)
661 var rva = image.Resources.VirtualAddress;
662 var section = image.GetSectionAtVirtualAddress (rva);
663 var position = (rva - section.VirtualAddress) + offset;
664 var buffer = section.Data;
666 var length = buffer [position]
667 | (buffer [position + 1] << 8)
668 | (buffer [position + 2] << 16)
669 | (buffer [position + 3] << 24);
671 return new MemoryStream (buffer, (int) position + 4, length);
674 void PopulateVersionAndFlags (AssemblyNameReference name)
676 name.Version = new Version (
682 name.Attributes = (AssemblyAttributes) ReadUInt32 ();
685 void PopulateNameAndCulture (AssemblyNameReference name)
687 name.Name = ReadString ();
688 name.Culture = ReadString ();
691 public TypeDefinitionCollection ReadTypes ()
693 InitializeTypeDefinitions ();
694 var mtypes = metadata.Types;
695 var type_count = mtypes.Length - metadata.NestedTypes.Count;
696 var types = new TypeDefinitionCollection (module, type_count);
698 for (int i = 0; i < mtypes.Length; i++) {
699 var type = mtypes [i];
700 if (IsNested (type.Attributes))
706 if (image.HasTable (Table.MethodPtr) || image.HasTable (Table.FieldPtr))
712 void CompleteTypes ()
714 var types = metadata.Types;
716 for (int i = 0; i < types.Length; i++) {
717 var type = types [i];
719 InitializeCollection (type.Fields);
720 InitializeCollection (type.Methods);
724 void InitializeTypeDefinitions ()
726 if (metadata.Types != null)
729 InitializeNestedTypes ();
731 InitializeMethods ();
733 int length = MoveTo (Table.TypeDef);
734 var types = metadata.Types = new TypeDefinition [length];
736 for (uint i = 0; i < length; i++) {
737 if (types [i] != null)
740 types [i] = ReadType (i + 1);
744 static bool IsNested (TypeAttributes attributes)
746 switch (attributes & TypeAttributes.VisibilityMask) {
747 case TypeAttributes.NestedAssembly:
748 case TypeAttributes.NestedFamANDAssem:
749 case TypeAttributes.NestedFamily:
750 case TypeAttributes.NestedFamORAssem:
751 case TypeAttributes.NestedPrivate:
752 case TypeAttributes.NestedPublic:
759 public bool HasNestedTypes (TypeDefinition type)
762 InitializeNestedTypes ();
764 if (!metadata.TryGetNestedTypeMapping (type, out mapping))
767 return mapping.Length > 0;
770 public Collection<TypeDefinition> ReadNestedTypes (TypeDefinition type)
772 InitializeNestedTypes ();
774 if (!metadata.TryGetNestedTypeMapping (type, out mapping))
775 return new MemberDefinitionCollection<TypeDefinition> (type);
777 var nested_types = new MemberDefinitionCollection<TypeDefinition> (type, mapping.Length);
779 for (int i = 0; i < mapping.Length; i++)
780 nested_types.Add (GetTypeDefinition (mapping [i]));
782 metadata.RemoveNestedTypeMapping (type);
787 void InitializeNestedTypes ()
789 if (metadata.NestedTypes != null)
792 var length = MoveTo (Table.NestedClass);
794 metadata.NestedTypes = new Dictionary<uint, uint []> (length);
795 metadata.ReverseNestedTypes = new Dictionary<uint, uint> (length);
800 for (int i = 1; i <= length; i++) {
801 var nested = ReadTableIndex (Table.TypeDef);
802 var declaring = ReadTableIndex (Table.TypeDef);
804 AddNestedMapping (declaring, nested);
808 void AddNestedMapping (uint declaring, uint nested)
810 metadata.SetNestedTypeMapping (declaring, AddMapping (metadata.NestedTypes, declaring, nested));
811 metadata.SetReverseNestedTypeMapping (nested, declaring);
814 static TValue [] AddMapping<TKey, TValue> (Dictionary<TKey, TValue []> cache, TKey key, TValue value)
817 if (!cache.TryGetValue (key, out mapped)) {
818 mapped = new [] { value };
822 var new_mapped = new TValue [mapped.Length + 1];
823 Array.Copy (mapped, new_mapped, mapped.Length);
824 new_mapped [mapped.Length] = value;
828 TypeDefinition ReadType (uint rid)
830 if (!MoveTo (Table.TypeDef, rid))
833 var attributes = (TypeAttributes) ReadUInt32 ();
834 var name = ReadString ();
835 var @namespace = ReadString ();
836 var type = new TypeDefinition (@namespace, name, attributes);
837 type.token = new MetadataToken (TokenType.TypeDef, rid);
839 type.module = module;
841 metadata.AddTypeDefinition (type);
845 type.BaseType = GetTypeDefOrRef (ReadMetadataToken (CodedIndex.TypeDefOrRef));
847 type.fields_range = ReadFieldsRange (rid);
848 type.methods_range = ReadMethodsRange (rid);
850 if (IsNested (attributes))
851 type.DeclaringType = GetNestedTypeDeclaringType (type);
856 TypeDefinition GetNestedTypeDeclaringType (TypeDefinition type)
859 if (!metadata.TryGetReverseNestedTypeMapping (type, out declaring_rid))
862 metadata.RemoveReverseNestedTypeMapping (type);
863 return GetTypeDefinition (declaring_rid);
866 Range ReadFieldsRange (uint type_index)
868 return ReadListRange (type_index, Table.TypeDef, Table.Field);
871 Range ReadMethodsRange (uint type_index)
873 return ReadListRange (type_index, Table.TypeDef, Table.Method);
876 Range ReadListRange (uint current_index, Table current, Table target)
878 var list = new Range ();
880 list.Start = ReadTableIndex (target);
883 var current_table = image.TableHeap [current];
885 if (current_index == current_table.Length)
886 next_index = image.TableHeap [target].Length + 1;
888 var position = Position;
889 Position += (uint) (current_table.RowSize - image.GetTableIndexSize (target));
890 next_index = ReadTableIndex (target);
894 list.Length = next_index - list.Start;
899 public Row<short, int> ReadTypeLayout (TypeDefinition type)
901 InitializeTypeLayouts ();
902 Row<ushort, uint> class_layout;
903 var rid = type.token.RID;
904 if (!metadata.ClassLayouts.TryGetValue (rid, out class_layout))
905 return new Row<short, int> (Mixin.NoDataMarker, Mixin.NoDataMarker);
907 type.PackingSize = (short) class_layout.Col1;
908 type.ClassSize = (int) class_layout.Col2;
910 metadata.ClassLayouts.Remove (rid);
912 return new Row<short, int> ((short) class_layout.Col1, (int) class_layout.Col2);
915 void InitializeTypeLayouts ()
917 if (metadata.ClassLayouts != null)
920 int length = MoveTo (Table.ClassLayout);
922 var class_layouts = metadata.ClassLayouts = new Dictionary<uint, Row<ushort, uint>> (length);
924 for (uint i = 0; i < length; i++) {
925 var packing_size = ReadUInt16 ();
926 var class_size = ReadUInt32 ();
928 var parent = ReadTableIndex (Table.TypeDef);
930 class_layouts.Add (parent, new Row<ushort, uint> (packing_size, class_size));
934 public TypeReference GetTypeDefOrRef (MetadataToken token)
936 return (TypeReference) LookupToken (token);
939 public TypeDefinition GetTypeDefinition (uint rid)
941 InitializeTypeDefinitions ();
943 var type = metadata.GetTypeDefinition (rid);
947 return ReadTypeDefinition (rid);
950 TypeDefinition ReadTypeDefinition (uint rid)
952 if (!MoveTo (Table.TypeDef, rid))
955 return ReadType (rid);
958 void InitializeTypeReferences ()
960 if (metadata.TypeReferences != null)
963 metadata.TypeReferences = new TypeReference [image.GetTableLength (Table.TypeRef)];
966 public TypeReference GetTypeReference (string scope, string full_name)
968 InitializeTypeReferences ();
970 var length = metadata.TypeReferences.Length;
972 for (uint i = 1; i <= length; i++) {
973 var type = GetTypeReference (i);
975 if (type.FullName != full_name)
978 if (string.IsNullOrEmpty (scope))
981 if (type.Scope.Name == scope)
988 TypeReference GetTypeReference (uint rid)
990 InitializeTypeReferences ();
992 var type = metadata.GetTypeReference (rid);
996 return ReadTypeReference (rid);
999 TypeReference ReadTypeReference (uint rid)
1001 if (!MoveTo (Table.TypeRef, rid))
1004 TypeReference declaring_type = null;
1005 IMetadataScope scope;
1007 var scope_token = ReadMetadataToken (CodedIndex.ResolutionScope);
1009 var name = ReadString ();
1010 var @namespace = ReadString ();
1012 var type = new TypeReference (
1018 type.token = new MetadataToken (TokenType.TypeRef, rid);
1020 metadata.AddTypeReference (type);
1022 if (scope_token.TokenType == TokenType.TypeRef) {
1023 declaring_type = GetTypeDefOrRef (scope_token);
1025 scope = declaring_type != null
1026 ? declaring_type.Scope
1029 scope = GetTypeReferenceScope (scope_token);
1032 type.DeclaringType = declaring_type;
1034 MetadataSystem.TryProcessPrimitiveType (type);
1039 IMetadataScope GetTypeReferenceScope (MetadataToken scope)
1041 switch (scope.TokenType) {
1042 case TokenType.AssemblyRef:
1043 InitializeAssemblyReferences ();
1044 return metadata.AssemblyReferences [(int) scope.RID - 1];
1045 case TokenType.ModuleRef:
1046 InitializeModuleReferences ();
1047 return metadata.ModuleReferences [(int) scope.RID - 1];
1048 case TokenType.Module:
1051 throw new NotSupportedException ();
1055 public IEnumerable<TypeReference> GetTypeReferences ()
1057 InitializeTypeReferences ();
1059 var length = image.GetTableLength (Table.TypeRef);
1061 var type_references = new TypeReference [length];
1063 for (uint i = 1; i <= length; i++)
1064 type_references [i - 1] = GetTypeReference (i);
1066 return type_references;
1069 TypeReference GetTypeSpecification (uint rid)
1071 if (!MoveTo (Table.TypeSpec, rid))
1074 var reader = ReadSignature (ReadBlobIndex ());
1075 var type = reader.ReadTypeSignature ();
1076 if (type.token.RID == 0)
1077 type.token = new MetadataToken (TokenType.TypeSpec, rid);
1082 SignatureReader ReadSignature (uint signature)
1084 return new SignatureReader (signature, this);
1087 public bool HasInterfaces (TypeDefinition type)
1089 InitializeInterfaces ();
1090 MetadataToken [] mapping;
1092 return metadata.TryGetInterfaceMapping (type, out mapping);
1095 public Collection<TypeReference> ReadInterfaces (TypeDefinition type)
1097 InitializeInterfaces ();
1098 MetadataToken [] mapping;
1100 if (!metadata.TryGetInterfaceMapping (type, out mapping))
1101 return new Collection<TypeReference> ();
1103 var interfaces = new Collection<TypeReference> (mapping.Length);
1105 this.context = type;
1107 for (int i = 0; i < mapping.Length; i++)
1108 interfaces.Add (GetTypeDefOrRef (mapping [i]));
1110 metadata.RemoveInterfaceMapping (type);
1115 void InitializeInterfaces ()
1117 if (metadata.Interfaces != null)
1120 int length = MoveTo (Table.InterfaceImpl);
1122 metadata.Interfaces = new Dictionary<uint, MetadataToken []> (length);
1124 for (int i = 0; i < length; i++) {
1125 var type = ReadTableIndex (Table.TypeDef);
1126 var @interface = ReadMetadataToken (CodedIndex.TypeDefOrRef);
1128 AddInterfaceMapping (type, @interface);
1132 void AddInterfaceMapping (uint type, MetadataToken @interface)
1134 metadata.SetInterfaceMapping (type, AddMapping (metadata.Interfaces, type, @interface));
1137 public Collection<FieldDefinition> ReadFields (TypeDefinition type)
1139 var fields_range = type.fields_range;
1140 if (fields_range.Length == 0)
1141 return new MemberDefinitionCollection<FieldDefinition> (type);
1143 var fields = new MemberDefinitionCollection<FieldDefinition> (type, (int) fields_range.Length);
1144 this.context = type;
1146 if (!MoveTo (Table.FieldPtr, fields_range.Start)) {
1147 if (!MoveTo (Table.Field, fields_range.Start))
1150 for (uint i = 0; i < fields_range.Length; i++)
1151 ReadField (fields_range.Start + i, fields);
1153 ReadPointers (Table.FieldPtr, Table.Field, fields_range, fields, ReadField);
1158 void ReadField (uint field_rid, Collection<FieldDefinition> fields)
1160 var attributes = (FieldAttributes) ReadUInt16 ();
1161 var name = ReadString ();
1162 var signature = ReadBlobIndex ();
1164 var field = new FieldDefinition (name, attributes, ReadFieldType (signature));
1165 field.token = new MetadataToken (TokenType.Field, field_rid);
1166 metadata.AddFieldDefinition (field);
1168 if (IsDeleted (field))
1174 void InitializeFields ()
1176 if (metadata.Fields != null)
1179 metadata.Fields = new FieldDefinition [image.GetTableLength (Table.Field)];
1182 TypeReference ReadFieldType (uint signature)
1184 var reader = ReadSignature (signature);
1186 const byte field_sig = 0x6;
1188 if (reader.ReadByte () != field_sig)
1189 throw new NotSupportedException ();
1191 return reader.ReadTypeSignature ();
1194 public int ReadFieldRVA (FieldDefinition field)
1196 InitializeFieldRVAs ();
1197 var rid = field.token.RID;
1200 if (!metadata.FieldRVAs.TryGetValue (rid, out rva))
1203 var size = GetFieldTypeSize (field.FieldType);
1205 if (size == 0 || rva == 0)
1208 metadata.FieldRVAs.Remove (rid);
1210 field.InitialValue = GetFieldInitializeValue (size, rva);
1215 byte [] GetFieldInitializeValue (int size, RVA rva)
1217 var section = image.GetSectionAtVirtualAddress (rva);
1218 if (section == null)
1219 return Empty<byte>.Array;
1221 var value = new byte [size];
1222 Buffer.BlockCopy (section.Data, (int) (rva - section.VirtualAddress), value, 0, size);
1226 static int GetFieldTypeSize (TypeReference type)
1230 switch (type.etype) {
1231 case ElementType.Boolean:
1232 case ElementType.U1:
1233 case ElementType.I1:
1236 case ElementType.U2:
1237 case ElementType.I2:
1238 case ElementType.Char:
1241 case ElementType.U4:
1242 case ElementType.I4:
1243 case ElementType.R4:
1246 case ElementType.U8:
1247 case ElementType.I8:
1248 case ElementType.R8:
1251 case ElementType.Ptr:
1252 case ElementType.FnPtr:
1255 case ElementType.CModOpt:
1256 case ElementType.CModReqD:
1257 return GetFieldTypeSize (((IModifierType) type).ElementType);
1259 var field_type = type.CheckedResolve ();
1260 if (field_type.HasLayoutInfo)
1261 size = field_type.ClassSize;
1269 void InitializeFieldRVAs ()
1271 if (metadata.FieldRVAs != null)
1274 int length = MoveTo (Table.FieldRVA);
1276 var field_rvas = metadata.FieldRVAs = new Dictionary<uint, uint> (length);
1278 for (int i = 0; i < length; i++) {
1279 var rva = ReadUInt32 ();
1280 var field = ReadTableIndex (Table.Field);
1282 field_rvas.Add (field, rva);
1286 public int ReadFieldLayout (FieldDefinition field)
1288 InitializeFieldLayouts ();
1289 var rid = field.token.RID;
1291 if (!metadata.FieldLayouts.TryGetValue (rid, out offset))
1292 return Mixin.NoDataMarker;
1294 metadata.FieldLayouts.Remove (rid);
1296 return (int) offset;
1299 void InitializeFieldLayouts ()
1301 if (metadata.FieldLayouts != null)
1304 int length = MoveTo (Table.FieldLayout);
1306 var field_layouts = metadata.FieldLayouts = new Dictionary<uint, uint> (length);
1308 for (int i = 0; i < length; i++) {
1309 var offset = ReadUInt32 ();
1310 var field = ReadTableIndex (Table.Field);
1312 field_layouts.Add (field, offset);
1316 public bool HasEvents (TypeDefinition type)
1318 InitializeEvents ();
1321 if (!metadata.TryGetEventsRange (type, out range))
1324 return range.Length > 0;
1327 public Collection<EventDefinition> ReadEvents (TypeDefinition type)
1329 InitializeEvents ();
1332 if (!metadata.TryGetEventsRange (type, out range))
1333 return new MemberDefinitionCollection<EventDefinition> (type);
1335 var events = new MemberDefinitionCollection<EventDefinition> (type, (int) range.Length);
1337 metadata.RemoveEventsRange (type);
1339 if (range.Length == 0)
1342 this.context = type;
1344 if (!MoveTo (Table.EventPtr, range.Start)) {
1345 if (!MoveTo (Table.Event, range.Start))
1348 for (uint i = 0; i < range.Length; i++)
1349 ReadEvent (range.Start + i, events);
1351 ReadPointers (Table.EventPtr, Table.Event, range, events, ReadEvent);
1356 void ReadEvent (uint event_rid, Collection<EventDefinition> events)
1358 var attributes = (EventAttributes) ReadUInt16 ();
1359 var name = ReadString ();
1360 var event_type = GetTypeDefOrRef (ReadMetadataToken (CodedIndex.TypeDefOrRef));
1362 var @event = new EventDefinition (name, attributes, event_type);
1363 @event.token = new MetadataToken (TokenType.Event, event_rid);
1365 if (IsDeleted (@event))
1368 events.Add (@event);
1371 void InitializeEvents ()
1373 if (metadata.Events != null)
1376 int length = MoveTo (Table.EventMap);
1378 metadata.Events = new Dictionary<uint, Range> (length);
1380 for (uint i = 1; i <= length; i++) {
1381 var type_rid = ReadTableIndex (Table.TypeDef);
1382 Range events_range = ReadEventsRange (i);
1383 metadata.AddEventsRange (type_rid, events_range);
1387 Range ReadEventsRange (uint rid)
1389 return ReadListRange (rid, Table.EventMap, Table.Event);
1392 public bool HasProperties (TypeDefinition type)
1394 InitializeProperties ();
1397 if (!metadata.TryGetPropertiesRange (type, out range))
1400 return range.Length > 0;
1403 public Collection<PropertyDefinition> ReadProperties (TypeDefinition type)
1405 InitializeProperties ();
1409 if (!metadata.TryGetPropertiesRange (type, out range))
1410 return new MemberDefinitionCollection<PropertyDefinition> (type);
1412 metadata.RemovePropertiesRange (type);
1414 var properties = new MemberDefinitionCollection<PropertyDefinition> (type, (int) range.Length);
1416 if (range.Length == 0)
1419 this.context = type;
1421 if (!MoveTo (Table.PropertyPtr, range.Start)) {
1422 if (!MoveTo (Table.Property, range.Start))
1424 for (uint i = 0; i < range.Length; i++)
1425 ReadProperty (range.Start + i, properties);
1427 ReadPointers (Table.PropertyPtr, Table.Property, range, properties, ReadProperty);
1432 void ReadProperty (uint property_rid, Collection<PropertyDefinition> properties)
1434 var attributes = (PropertyAttributes) ReadUInt16 ();
1435 var name = ReadString ();
1436 var signature = ReadBlobIndex ();
1438 var reader = ReadSignature (signature);
1439 const byte property_signature = 0x8;
1441 var calling_convention = reader.ReadByte ();
1443 if ((calling_convention & property_signature) == 0)
1444 throw new NotSupportedException ();
1446 var has_this = (calling_convention & 0x20) != 0;
1448 reader.ReadCompressedUInt32 (); // count
1450 var property = new PropertyDefinition (name, attributes, reader.ReadTypeSignature ());
1451 property.HasThis = has_this;
1452 property.token = new MetadataToken (TokenType.Property, property_rid);
1454 if (IsDeleted (property))
1457 properties.Add (property);
1460 void InitializeProperties ()
1462 if (metadata.Properties != null)
1465 int length = MoveTo (Table.PropertyMap);
1467 metadata.Properties = new Dictionary<uint, Range> (length);
1469 for (uint i = 1; i <= length; i++) {
1470 var type_rid = ReadTableIndex (Table.TypeDef);
1471 var properties_range = ReadPropertiesRange (i);
1472 metadata.AddPropertiesRange (type_rid, properties_range);
1476 Range ReadPropertiesRange (uint rid)
1478 return ReadListRange (rid, Table.PropertyMap, Table.Property);
1481 MethodSemanticsAttributes ReadMethodSemantics (MethodDefinition method)
1483 InitializeMethodSemantics ();
1484 Row<MethodSemanticsAttributes, MetadataToken> row;
1485 if (!metadata.Semantics.TryGetValue (method.token.RID, out row))
1486 return MethodSemanticsAttributes.None;
1488 var type = method.DeclaringType;
1491 case MethodSemanticsAttributes.AddOn:
1492 GetEvent (type, row.Col2).add_method = method;
1494 case MethodSemanticsAttributes.Fire:
1495 GetEvent (type, row.Col2).invoke_method = method;
1497 case MethodSemanticsAttributes.RemoveOn:
1498 GetEvent (type, row.Col2).remove_method = method;
1500 case MethodSemanticsAttributes.Getter:
1501 GetProperty (type, row.Col2).get_method = method;
1503 case MethodSemanticsAttributes.Setter:
1504 GetProperty (type, row.Col2).set_method = method;
1506 case MethodSemanticsAttributes.Other:
1507 switch (row.Col2.TokenType) {
1508 case TokenType.Event: {
1509 var @event = GetEvent (type, row.Col2);
1510 if (@event.other_methods == null)
1511 @event.other_methods = new Collection<MethodDefinition> ();
1513 @event.other_methods.Add (method);
1516 case TokenType.Property: {
1517 var property = GetProperty (type, row.Col2);
1518 if (property.other_methods == null)
1519 property.other_methods = new Collection<MethodDefinition> ();
1521 property.other_methods.Add (method);
1526 throw new NotSupportedException ();
1530 throw new NotSupportedException ();
1533 metadata.Semantics.Remove (method.token.RID);
1538 static EventDefinition GetEvent (TypeDefinition type, MetadataToken token)
1540 if (token.TokenType != TokenType.Event)
1541 throw new ArgumentException ();
1543 return GetMember (type.Events, token);
1546 static PropertyDefinition GetProperty (TypeDefinition type, MetadataToken token)
1548 if (token.TokenType != TokenType.Property)
1549 throw new ArgumentException ();
1551 return GetMember (type.Properties, token);
1554 static TMember GetMember<TMember> (Collection<TMember> members, MetadataToken token) where TMember : IMemberDefinition
1556 for (int i = 0; i < members.Count; i++) {
1557 var member = members [i];
1558 if (member.MetadataToken == token)
1562 throw new ArgumentException ();
1565 void InitializeMethodSemantics ()
1567 if (metadata.Semantics != null)
1570 int length = MoveTo (Table.MethodSemantics);
1572 var semantics = metadata.Semantics = new Dictionary<uint, Row<MethodSemanticsAttributes, MetadataToken>> (0);
1574 for (uint i = 0; i < length; i++) {
1575 var attributes = (MethodSemanticsAttributes) ReadUInt16 ();
1576 var method_rid = ReadTableIndex (Table.Method);
1577 var association = ReadMetadataToken (CodedIndex.HasSemantics);
1579 semantics [method_rid] = new Row<MethodSemanticsAttributes, MetadataToken> (attributes, association);
1583 public PropertyDefinition ReadMethods (PropertyDefinition property)
1585 ReadAllSemantics (property.DeclaringType);
1589 public EventDefinition ReadMethods (EventDefinition @event)
1591 ReadAllSemantics (@event.DeclaringType);
1595 public MethodSemanticsAttributes ReadAllSemantics (MethodDefinition method)
1597 ReadAllSemantics (method.DeclaringType);
1599 return method.SemanticsAttributes;
1602 void ReadAllSemantics (TypeDefinition type)
1604 var methods = type.Methods;
1605 for (int i = 0; i < methods.Count; i++) {
1606 var method = methods [i];
1607 if (method.sem_attrs.HasValue)
1610 method.sem_attrs = ReadMethodSemantics (method);
1614 Range ReadParametersRange (uint method_rid)
1616 return ReadListRange (method_rid, Table.Method, Table.Param);
1619 public Collection<MethodDefinition> ReadMethods (TypeDefinition type)
1621 var methods_range = type.methods_range;
1622 if (methods_range.Length == 0)
1623 return new MemberDefinitionCollection<MethodDefinition> (type);
1625 var methods = new MemberDefinitionCollection<MethodDefinition> (type, (int) methods_range.Length);
1626 if (!MoveTo (Table.MethodPtr, methods_range.Start)) {
1627 if (!MoveTo (Table.Method, methods_range.Start))
1630 for (uint i = 0; i < methods_range.Length; i++)
1631 ReadMethod (methods_range.Start + i, methods);
1633 ReadPointers (Table.MethodPtr, Table.Method, methods_range, methods, ReadMethod);
1638 void ReadPointers<TMember> (Table ptr, Table table, Range range, Collection<TMember> members, Action<uint, Collection<TMember>> reader)
1639 where TMember : IMemberDefinition
1641 for (uint i = 0; i < range.Length; i++) {
1642 MoveTo (ptr, range.Start + i);
1644 var rid = ReadTableIndex (table);
1645 MoveTo (table, rid);
1647 reader (rid, members);
1651 static bool IsDeleted (IMemberDefinition member)
1653 return member.IsSpecialName && member.Name == "_Deleted";
1656 void InitializeMethods ()
1658 if (metadata.Methods != null)
1661 metadata.Methods = new MethodDefinition [image.GetTableLength (Table.Method)];
1664 void ReadMethod (uint method_rid, Collection<MethodDefinition> methods)
1666 var method = new MethodDefinition ();
1667 method.rva = ReadUInt32 ();
1668 method.ImplAttributes = (MethodImplAttributes) ReadUInt16 ();
1669 method.Attributes = (MethodAttributes) ReadUInt16 ();
1670 method.Name = ReadString ();
1671 method.token = new MetadataToken (TokenType.Method, method_rid);
1673 if (IsDeleted (method))
1676 methods.Add (method); // attach method
1678 var signature = ReadBlobIndex ();
1679 var param_range = ReadParametersRange (method_rid);
1681 this.context = method;
1683 ReadMethodSignature (signature, method);
1684 metadata.AddMethodDefinition (method);
1686 if (param_range.Length == 0)
1689 var position = base.position;
1690 ReadParameters (method, param_range);
1691 base.position = position;
1694 void ReadParameters (MethodDefinition method, Range param_range)
1696 if (!MoveTo (Table.ParamPtr, param_range.Start)) {
1697 if (!MoveTo (Table.Param, param_range.Start))
1700 for (uint i = 0; i < param_range.Length; i++)
1701 ReadParameter (param_range.Start + i, method);
1703 ReadParameterPointers (method, param_range);
1706 void ReadParameterPointers (MethodDefinition method, Range range)
1708 for (uint i = 0; i < range.Length; i++) {
1709 MoveTo (Table.ParamPtr, range.Start + i);
1711 var rid = ReadTableIndex (Table.Param);
1713 MoveTo (Table.Param, rid);
1715 ReadParameter (rid, method);
1719 void ReadParameter (uint param_rid, MethodDefinition method)
1721 var attributes = (ParameterAttributes) ReadUInt16 ();
1722 var sequence = ReadUInt16 ();
1723 var name = ReadString ();
1725 var parameter = sequence == 0
1726 ? method.MethodReturnType.Parameter
1727 : method.Parameters [sequence - 1];
1729 parameter.token = new MetadataToken (TokenType.Param, param_rid);
1730 parameter.Name = name;
1731 parameter.Attributes = attributes;
1734 void ReadMethodSignature (uint signature, IMethodSignature method)
1736 var reader = ReadSignature (signature);
1737 reader.ReadMethodSignature (method);
1740 public PInvokeInfo ReadPInvokeInfo (MethodDefinition method)
1742 InitializePInvokes ();
1743 Row<PInvokeAttributes, uint, uint> row;
1745 var rid = method.token.RID;
1747 if (!metadata.PInvokes.TryGetValue (rid, out row))
1750 metadata.PInvokes.Remove (rid);
1752 return new PInvokeInfo (
1754 image.StringHeap.Read (row.Col2),
1755 module.ModuleReferences [(int) row.Col3 - 1]);
1758 void InitializePInvokes ()
1760 if (metadata.PInvokes != null)
1763 int length = MoveTo (Table.ImplMap);
1765 var pinvokes = metadata.PInvokes = new Dictionary<uint, Row<PInvokeAttributes, uint, uint>> (length);
1767 for (int i = 1; i <= length; i++) {
1768 var attributes = (PInvokeAttributes) ReadUInt16 ();
1769 var method = ReadMetadataToken (CodedIndex.MemberForwarded);
1770 var name = ReadStringIndex ();
1771 var scope = ReadTableIndex (Table.File);
1773 if (method.TokenType != TokenType.Method)
1776 pinvokes.Add (method.RID, new Row<PInvokeAttributes, uint, uint> (attributes, name, scope));
1780 public bool HasGenericParameters (IGenericParameterProvider provider)
1782 InitializeGenericParameters ();
1785 if (!metadata.TryGetGenericParameterRange (provider, out range))
1788 return range.Length > 0;
1791 public Collection<GenericParameter> ReadGenericParameters (IGenericParameterProvider provider)
1793 InitializeGenericParameters ();
1796 if (!metadata.TryGetGenericParameterRange (provider, out range)
1797 || !MoveTo (Table.GenericParam, range.Start))
1798 return new Collection<GenericParameter> ();
1800 metadata.RemoveGenericParameterRange (provider);
1802 var generic_parameters = new Collection<GenericParameter> ((int) range.Length);
1804 for (uint i = 0; i < range.Length; i++) {
1805 ReadUInt16 (); // index
1806 var flags = (GenericParameterAttributes) ReadUInt16 ();
1807 ReadMetadataToken (CodedIndex.TypeOrMethodDef);
1808 var name = ReadString ();
1810 var parameter = new GenericParameter (name, provider);
1811 parameter.token = new MetadataToken (TokenType.GenericParam, range.Start + i);
1812 parameter.Attributes = flags;
1814 generic_parameters.Add (parameter);
1817 return generic_parameters;
1820 void InitializeGenericParameters ()
1822 if (metadata.GenericParameters != null)
1825 metadata.GenericParameters = InitializeRanges (
1826 Table.GenericParam, () => {
1828 var next = ReadMetadataToken (CodedIndex.TypeOrMethodDef);
1834 Dictionary<MetadataToken, Range> InitializeRanges (Table table, Func<MetadataToken> get_next)
1836 int length = MoveTo (table);
1837 var ranges = new Dictionary<MetadataToken, Range> (length);
1842 MetadataToken owner = MetadataToken.Zero;
1843 Range range = new Range (1, 0);
1845 for (uint i = 1; i <= length; i++) {
1846 var next = get_next ();
1851 } else if (next != owner) {
1853 ranges.Add (owner, range);
1854 range = new Range (i, 1);
1860 if (owner != MetadataToken.Zero && !ranges.ContainsKey (owner))
1861 ranges.Add (owner, range);
1866 public bool HasGenericConstraints (GenericParameter generic_parameter)
1868 InitializeGenericConstraints ();
1870 MetadataToken [] mapping;
1871 if (!metadata.TryGetGenericConstraintMapping (generic_parameter, out mapping))
1874 return mapping.Length > 0;
1877 public Collection<TypeReference> ReadGenericConstraints (GenericParameter generic_parameter)
1879 InitializeGenericConstraints ();
1881 MetadataToken [] mapping;
1882 if (!metadata.TryGetGenericConstraintMapping (generic_parameter, out mapping))
1883 return new Collection<TypeReference> ();
1885 var constraints = new Collection<TypeReference> (mapping.Length);
1887 this.context = (IGenericContext) generic_parameter.Owner;
1889 for (int i = 0; i < mapping.Length; i++)
1890 constraints.Add (GetTypeDefOrRef (mapping [i]));
1892 metadata.RemoveGenericConstraintMapping (generic_parameter);
1897 void InitializeGenericConstraints ()
1899 if (metadata.GenericConstraints != null)
1902 var length = MoveTo (Table.GenericParamConstraint);
1904 metadata.GenericConstraints = new Dictionary<uint, MetadataToken []> (length);
1906 for (int i = 1; i <= length; i++)
1907 AddGenericConstraintMapping (
1908 ReadTableIndex (Table.GenericParam),
1909 ReadMetadataToken (CodedIndex.TypeDefOrRef));
1912 void AddGenericConstraintMapping (uint generic_parameter, MetadataToken constraint)
1914 metadata.SetGenericConstraintMapping (
1916 AddMapping (metadata.GenericConstraints, generic_parameter, constraint));
1919 public bool HasOverrides (MethodDefinition method)
1921 InitializeOverrides ();
1922 MetadataToken [] mapping;
1924 if (!metadata.TryGetOverrideMapping (method, out mapping))
1927 return mapping.Length > 0;
1930 public Collection<MethodReference> ReadOverrides (MethodDefinition method)
1932 InitializeOverrides ();
1934 MetadataToken [] mapping;
1935 if (!metadata.TryGetOverrideMapping (method, out mapping))
1936 return new Collection<MethodReference> ();
1938 var overrides = new Collection<MethodReference> (mapping.Length);
1940 this.context = method;
1942 for (int i = 0; i < mapping.Length; i++)
1943 overrides.Add ((MethodReference) LookupToken (mapping [i]));
1945 metadata.RemoveOverrideMapping (method);
1950 void InitializeOverrides ()
1952 if (metadata.Overrides != null)
1955 var length = MoveTo (Table.MethodImpl);
1957 metadata.Overrides = new Dictionary<uint, MetadataToken []> (length);
1959 for (int i = 1; i <= length; i++) {
1960 ReadTableIndex (Table.TypeDef);
1962 var method = ReadMetadataToken (CodedIndex.MethodDefOrRef);
1963 if (method.TokenType != TokenType.Method)
1964 throw new NotSupportedException ();
1966 var @override = ReadMetadataToken (CodedIndex.MethodDefOrRef);
1968 AddOverrideMapping (method.RID, @override);
1972 void AddOverrideMapping (uint method_rid, MetadataToken @override)
1974 metadata.SetOverrideMapping (
1976 AddMapping (metadata.Overrides, method_rid, @override));
1979 public MethodBody ReadMethodBody (MethodDefinition method)
1981 return code.ReadMethodBody (method);
1984 public CallSite ReadCallSite (MetadataToken token)
1986 if (!MoveTo (Table.StandAloneSig, token.RID))
1989 var signature = ReadBlobIndex ();
1991 var call_site = new CallSite ();
1993 ReadMethodSignature (signature, call_site);
1995 call_site.MetadataToken = token;
2000 public VariableDefinitionCollection ReadVariables (MetadataToken local_var_token)
2002 if (!MoveTo (Table.StandAloneSig, local_var_token.RID))
2005 var reader = ReadSignature (ReadBlobIndex ());
2006 const byte local_sig = 0x7;
2008 if (reader.ReadByte () != local_sig)
2009 throw new NotSupportedException ();
2011 var count = reader.ReadCompressedUInt32 ();
2015 var variables = new VariableDefinitionCollection ((int) count);
2017 for (int i = 0; i < count; i++)
2018 variables.Add (new VariableDefinition (reader.ReadTypeSignature ()));
2023 public IMetadataTokenProvider LookupToken (MetadataToken token)
2025 var rid = token.RID;
2030 IMetadataTokenProvider element;
2031 var position = this.position;
2032 var context = this.context;
2034 switch (token.TokenType) {
2035 case TokenType.TypeDef:
2036 element = GetTypeDefinition (rid);
2038 case TokenType.TypeRef:
2039 element = GetTypeReference (rid);
2041 case TokenType.TypeSpec:
2042 element = GetTypeSpecification (rid);
2044 case TokenType.Field:
2045 element = GetFieldDefinition (rid);
2047 case TokenType.Method:
2048 element = GetMethodDefinition (rid);
2050 case TokenType.MemberRef:
2051 element = GetMemberReference (rid);
2053 case TokenType.MethodSpec:
2054 element = GetMethodSpecification (rid);
2060 this.position = position;
2061 this.context = context;
2066 public FieldDefinition GetFieldDefinition (uint rid)
2068 InitializeTypeDefinitions ();
2070 var field = metadata.GetFieldDefinition (rid);
2074 return LookupField (rid);
2077 FieldDefinition LookupField (uint rid)
2079 var type = metadata.GetFieldDeclaringType (rid);
2083 InitializeCollection (type.Fields);
2085 return metadata.GetFieldDefinition (rid);
2088 public MethodDefinition GetMethodDefinition (uint rid)
2090 InitializeTypeDefinitions ();
2092 var method = metadata.GetMethodDefinition (rid);
2096 return LookupMethod (rid);
2099 MethodDefinition LookupMethod (uint rid)
2101 var type = metadata.GetMethodDeclaringType (rid);
2105 InitializeCollection (type.Methods);
2107 return metadata.GetMethodDefinition (rid);
2110 MethodSpecification GetMethodSpecification (uint rid)
2112 if (!MoveTo (Table.MethodSpec, rid))
2115 var element_method = (MethodReference) LookupToken (
2116 ReadMetadataToken (CodedIndex.MethodDefOrRef));
2117 var signature = ReadBlobIndex ();
2119 var method_spec = ReadMethodSpecSignature (signature, element_method);
2120 method_spec.token = new MetadataToken (TokenType.MethodSpec, rid);
2124 MethodSpecification ReadMethodSpecSignature (uint signature, MethodReference method)
2126 var reader = ReadSignature (signature);
2127 const byte methodspec_sig = 0x0a;
2129 var call_conv = reader.ReadByte ();
2131 if (call_conv != methodspec_sig)
2132 throw new NotSupportedException ();
2134 var instance = new GenericInstanceMethod (method);
2136 reader.ReadGenericInstanceSignature (method, instance);
2141 MemberReference GetMemberReference (uint rid)
2143 InitializeMemberReferences ();
2145 var member = metadata.GetMemberReference (rid);
2149 member = ReadMemberReference (rid);
2150 if (member != null && !member.ContainsGenericParameter)
2151 metadata.AddMemberReference (member);
2155 MemberReference ReadMemberReference (uint rid)
2157 if (!MoveTo (Table.MemberRef, rid))
2160 var token = ReadMetadataToken (CodedIndex.MemberRefParent);
2161 var name = ReadString ();
2162 var signature = ReadBlobIndex ();
2164 MemberReference member;
2166 switch (token.TokenType) {
2167 case TokenType.TypeDef:
2168 case TokenType.TypeRef:
2169 case TokenType.TypeSpec:
2170 member = ReadTypeMemberReference (token, name, signature);
2172 case TokenType.Method:
2173 member = ReadMethodMemberReference (token, name, signature);
2176 throw new NotSupportedException ();
2179 member.token = new MetadataToken (TokenType.MemberRef, rid);
2184 MemberReference ReadTypeMemberReference (MetadataToken type, string name, uint signature)
2186 var declaring_type = GetTypeDefOrRef (type);
2188 this.context = declaring_type;
2190 var member = ReadMemberReferenceSignature (signature, declaring_type);
2196 MemberReference ReadMemberReferenceSignature (uint signature, TypeReference declaring_type)
2198 var reader = ReadSignature (signature);
2199 const byte field_sig = 0x6;
2201 if (reader.buffer [reader.position] == field_sig) {
2203 var field = new FieldReference ();
2204 field.DeclaringType = declaring_type;
2205 field.FieldType = reader.ReadTypeSignature ();
2208 var method = new MethodReference ();
2209 method.DeclaringType = declaring_type;
2210 reader.ReadMethodSignature (method);
2215 MemberReference ReadMethodMemberReference (MetadataToken token, string name, uint signature)
2217 var method = GetMethodDefinition (token.RID);
2219 this.context = method;
2221 var member = ReadMemberReferenceSignature (signature, method.DeclaringType);
2227 void InitializeMemberReferences ()
2229 if (metadata.MemberReferences != null)
2232 metadata.MemberReferences = new MemberReference [image.GetTableLength (Table.MemberRef)];
2235 public IEnumerable<MemberReference> GetMemberReferences ()
2237 InitializeMemberReferences ();
2239 var length = image.GetTableLength (Table.MemberRef);
2241 var type_system = module.TypeSystem;
2243 var context = new MethodReference (string.Empty, type_system.Void);
2244 context.DeclaringType = new TypeReference (string.Empty, string.Empty, module, type_system.Corlib);
2246 var member_references = new MemberReference [length];
2248 for (uint i = 1; i <= length; i++) {
2249 this.context = context;
2250 member_references [i - 1] = GetMemberReference (i);
2253 return member_references;
2256 void InitializeConstants ()
2258 if (metadata.Constants != null)
2261 var length = MoveTo (Table.Constant);
2263 var constants = metadata.Constants = new Dictionary<MetadataToken, Row<ElementType, uint>> (length);
2265 for (uint i = 1; i <= length; i++) {
2266 var type = (ElementType) ReadUInt16 ();
2267 var owner = ReadMetadataToken (CodedIndex.HasConstant);
2268 var signature = ReadBlobIndex ();
2270 constants.Add (owner, new Row<ElementType, uint> (type, signature));
2274 public object ReadConstant (IConstantProvider owner)
2276 InitializeConstants ();
2278 Row<ElementType, uint> row;
2279 if (!metadata.Constants.TryGetValue (owner.MetadataToken, out row))
2280 return Mixin.NoValue;
2282 metadata.Constants.Remove (owner.MetadataToken);
2285 case ElementType.Class:
2286 case ElementType.Object:
2288 case ElementType.String:
2289 return ReadConstantString (ReadBlob (row.Col2));
2291 return ReadConstantPrimitive (row.Col1, row.Col2);
2295 static string ReadConstantString (byte [] blob)
2297 var length = blob.Length;
2298 if ((length & 1) == 1)
2301 return Encoding.Unicode.GetString (blob, 0, length);
2304 object ReadConstantPrimitive (ElementType type, uint signature)
2306 var reader = ReadSignature (signature);
2307 return reader.ReadConstantSignature (type);
2310 void InitializeCustomAttributes ()
2312 if (metadata.CustomAttributes != null)
2315 metadata.CustomAttributes = InitializeRanges (
2316 Table.CustomAttribute, () => {
2317 var next = ReadMetadataToken (CodedIndex.HasCustomAttribute);
2318 ReadMetadataToken (CodedIndex.CustomAttributeType);
2324 public bool HasCustomAttributes (ICustomAttributeProvider owner)
2326 InitializeCustomAttributes ();
2329 if (!metadata.TryGetCustomAttributeRange (owner, out range))
2332 return range.Length > 0;
2335 public Collection<CustomAttribute> ReadCustomAttributes (ICustomAttributeProvider owner)
2337 InitializeCustomAttributes ();
2340 if (!metadata.TryGetCustomAttributeRange (owner, out range)
2341 || !MoveTo (Table.CustomAttribute, range.Start))
2342 return new Collection<CustomAttribute> ();
2344 var custom_attributes = new Collection<CustomAttribute> ((int) range.Length);
2346 for (int i = 0; i < range.Length; i++) {
2347 ReadMetadataToken (CodedIndex.HasCustomAttribute);
2349 var constructor = (MethodReference) LookupToken (
2350 ReadMetadataToken (CodedIndex.CustomAttributeType));
2352 var signature = ReadBlobIndex ();
2354 custom_attributes.Add (new CustomAttribute (signature, constructor));
2357 metadata.RemoveCustomAttributeRange (owner);
2359 return custom_attributes;
2362 public byte [] ReadCustomAttributeBlob (uint signature)
2364 return ReadBlob (signature);
2367 public void ReadCustomAttributeSignature (CustomAttribute attribute)
2369 var reader = ReadSignature (attribute.signature);
2370 if (reader.ReadUInt16 () != 0x0001)
2371 throw new InvalidOperationException ();
2373 var constructor = attribute.Constructor;
2374 if (constructor.HasParameters)
2375 reader.ReadCustomAttributeConstructorArguments (attribute, constructor.Parameters);
2377 if (!reader.CanReadMore ())
2380 var named = reader.ReadUInt16 ();
2385 reader.ReadCustomAttributeNamedArguments (named, ref attribute.fields, ref attribute.properties);
2388 void InitializeMarshalInfos ()
2390 if (metadata.FieldMarshals != null)
2393 var length = MoveTo (Table.FieldMarshal);
2395 var marshals = metadata.FieldMarshals = new Dictionary<MetadataToken, uint> (length);
2397 for (int i = 0; i < length; i++) {
2398 var token = ReadMetadataToken (CodedIndex.HasFieldMarshal);
2399 var signature = ReadBlobIndex ();
2403 marshals.Add (token, signature);
2407 public bool HasMarshalInfo (IMarshalInfoProvider owner)
2409 InitializeMarshalInfos ();
2411 return metadata.FieldMarshals.ContainsKey (owner.MetadataToken);
2414 public MarshalInfo ReadMarshalInfo (IMarshalInfoProvider owner)
2416 InitializeMarshalInfos ();
2419 if (!metadata.FieldMarshals.TryGetValue (owner.MetadataToken, out signature))
2422 var reader = ReadSignature (signature);
2424 metadata.FieldMarshals.Remove (owner.MetadataToken);
2426 return reader.ReadMarshalInfo ();
2429 void InitializeSecurityDeclarations ()
2431 if (metadata.SecurityDeclarations != null)
2434 metadata.SecurityDeclarations = InitializeRanges (
2435 Table.DeclSecurity, () => {
2437 var next = ReadMetadataToken (CodedIndex.HasDeclSecurity);
2443 public bool HasSecurityDeclarations (ISecurityDeclarationProvider owner)
2445 InitializeSecurityDeclarations ();
2448 if (!metadata.TryGetSecurityDeclarationRange (owner, out range))
2451 return range.Length > 0;
2454 public Collection<SecurityDeclaration> ReadSecurityDeclarations (ISecurityDeclarationProvider owner)
2456 InitializeSecurityDeclarations ();
2459 if (!metadata.TryGetSecurityDeclarationRange (owner, out range)
2460 || !MoveTo (Table.DeclSecurity, range.Start))
2461 return new Collection<SecurityDeclaration> ();
2463 var security_declarations = new Collection<SecurityDeclaration> ((int) range.Length);
2465 for (int i = 0; i < range.Length; i++) {
2466 var action = (SecurityAction) ReadUInt16 ();
2467 ReadMetadataToken (CodedIndex.HasDeclSecurity);
2468 var signature = ReadBlobIndex ();
2470 security_declarations.Add (new SecurityDeclaration (action, signature, module));
2473 metadata.RemoveSecurityDeclarationRange (owner);
2475 return security_declarations;
2478 public byte [] ReadSecurityDeclarationBlob (uint signature)
2480 return ReadBlob (signature);
2483 public void ReadSecurityDeclarationSignature (SecurityDeclaration declaration)
2485 var signature = declaration.signature;
2486 var reader = ReadSignature (signature);
2488 if (reader.buffer [reader.position] != '.') {
2489 ReadXmlSecurityDeclaration (signature, declaration);
2494 var count = reader.ReadCompressedUInt32 ();
2495 var attributes = new Collection<SecurityAttribute> ((int) count);
2497 for (int i = 0; i < count; i++)
2498 attributes.Add (reader.ReadSecurityAttribute ());
2500 declaration.security_attributes = attributes;
2503 void ReadXmlSecurityDeclaration (uint signature, SecurityDeclaration declaration)
2505 var blob = ReadBlob (signature);
2506 var attributes = new Collection<SecurityAttribute> (1);
2508 var attribute = new SecurityAttribute (
2509 module.TypeSystem.LookupType ("System.Security.Permissions", "PermissionSetAttribute"));
2511 attribute.properties = new Collection<CustomAttributeNamedArgument> (1);
2512 attribute.properties.Add (
2513 new CustomAttributeNamedArgument (
2515 new CustomAttributeArgument (
2516 module.TypeSystem.String,
2517 Encoding.Unicode.GetString (blob, 0, blob.Length))));
2519 attributes.Add (attribute);
2521 declaration.security_attributes = attributes;
2524 public Collection<ExportedType> ReadExportedTypes ()
2526 var length = MoveTo (Table.ExportedType);
2528 return new Collection<ExportedType> ();
2530 var exported_types = new Collection<ExportedType> (length);
2532 for (int i = 1; i <= length; i++) {
2533 var attributes = (TypeAttributes) ReadUInt32 ();
2534 var identifier = ReadUInt32 ();
2535 var name = ReadString ();
2536 var @namespace = ReadString ();
2537 var implementation = ReadMetadataToken (CodedIndex.Implementation);
2539 ExportedType declaring_type = null;
2540 IMetadataScope scope = null;
2542 switch (implementation.TokenType) {
2543 case TokenType.AssemblyRef:
2544 case TokenType.File:
2545 scope = GetExportedTypeScope (implementation);
2547 case TokenType.ExportedType:
2548 // FIXME: if the table is not properly sorted
2549 declaring_type = exported_types [(int) implementation.RID - 1];
2553 var exported_type = new ExportedType (@namespace, name, module, scope) {
2554 Attributes = attributes,
2555 Identifier = (int) identifier,
2556 DeclaringType = declaring_type,
2558 exported_type.token = new MetadataToken (TokenType.ExportedType, i);
2560 exported_types.Add (exported_type);
2563 return exported_types;
2566 IMetadataScope GetExportedTypeScope (MetadataToken token)
2568 var position = this.position;
2569 IMetadataScope scope;
2571 switch (token.TokenType) {
2572 case TokenType.AssemblyRef:
2573 InitializeAssemblyReferences ();
2574 scope = metadata.AssemblyReferences [(int) token.RID - 1];
2576 case TokenType.File:
2577 InitializeModuleReferences ();
2578 scope = GetModuleReferenceFromFile (token);
2581 throw new NotSupportedException ();
2584 this.position = position;
2588 ModuleReference GetModuleReferenceFromFile (MetadataToken token)
2590 if (!MoveTo (Table.File, token.RID))
2594 var file_name = ReadString ();
2595 var modules = module.ModuleReferences;
2597 ModuleReference reference;
2598 for (int i = 0; i < modules.Count; i++) {
2599 reference = modules [i];
2600 if (reference.Name == file_name)
2604 reference = new ModuleReference (file_name);
2605 modules.Add (reference);
2609 static void InitializeCollection (object o)
2614 sealed class SignatureReader : ByteBuffer {
2616 readonly MetadataReader reader;
2617 readonly uint start, sig_length;
2619 TypeSystem TypeSystem {
2620 get { return reader.module.TypeSystem; }
2623 public SignatureReader (uint blob, MetadataReader reader)
2624 : base (reader.buffer)
2626 this.reader = reader;
2630 this.sig_length = ReadCompressedUInt32 ();
2631 this.start = (uint) position;
2634 void MoveToBlob (uint blob)
2636 position = (int) (reader.image.BlobHeap.Offset + blob);
2639 MetadataToken ReadTypeTokenSignature ()
2641 return CodedIndex.TypeDefOrRef.GetMetadataToken (ReadCompressedUInt32 ());
2644 GenericParameter GetGenericParameter (GenericParameterType type, uint var)
2646 var context = reader.context;
2648 if (context == null)
2649 throw new NotSupportedException ();
2651 IGenericParameterProvider provider;
2654 case GenericParameterType.Type:
2655 provider = context.Type;
2657 case GenericParameterType.Method:
2658 provider = context.Method;
2661 throw new NotSupportedException ();
2664 int index = (int) var;
2666 if (!context.IsDefinition)
2667 CheckGenericContext (provider, index);
2669 return provider.GenericParameters [index];
2672 static void CheckGenericContext (IGenericParameterProvider owner, int index)
2674 var owner_parameters = owner.GenericParameters;
2676 for (int i = owner_parameters.Count; i <= index; i++)
2677 owner_parameters.Add (new GenericParameter (owner));
2680 public void ReadGenericInstanceSignature (IGenericParameterProvider provider, IGenericInstance instance)
2682 var arity = ReadCompressedUInt32 ();
2684 if (!provider.IsDefinition)
2685 CheckGenericContext (provider, (int) arity - 1);
2687 var instance_arguments = instance.GenericArguments;
2689 for (int i = 0; i < arity; i++)
2690 instance_arguments.Add (ReadTypeSignature ());
2693 ArrayType ReadArrayTypeSignature ()
2695 var array = new ArrayType (ReadTypeSignature ());
2697 var rank = ReadCompressedUInt32 ();
2699 var sizes = new uint [ReadCompressedUInt32 ()];
2700 for (int i = 0; i < sizes.Length; i++)
2701 sizes [i] = ReadCompressedUInt32 ();
2703 var low_bounds = new int [ReadCompressedUInt32 ()];
2704 for (int i = 0; i < low_bounds.Length; i++)
2705 low_bounds [i] = ReadCompressedInt32 ();
2707 array.Dimensions.Clear ();
2709 for (int i = 0; i < rank; i++) {
2710 int? lower = null, upper = null;
2712 if (i < low_bounds.Length)
2713 lower = low_bounds [i];
2715 if (i < sizes.Length)
2716 upper = lower + (int) sizes [i] - 1;
2718 array.Dimensions.Add (new ArrayDimension (lower, upper));
2724 TypeReference GetTypeDefOrRef (MetadataToken token)
2726 return reader.GetTypeDefOrRef (token);
2729 public TypeReference ReadTypeSignature ()
2731 return ReadTypeSignature ((ElementType) ReadByte ());
2734 TypeReference ReadTypeSignature (ElementType etype)
2737 case ElementType.ValueType: {
2738 var value_type = GetTypeDefOrRef (ReadTypeTokenSignature ());
2739 value_type.IsValueType = true;
2742 case ElementType.Class:
2743 return GetTypeDefOrRef (ReadTypeTokenSignature ());
2744 case ElementType.Ptr:
2745 return new PointerType (ReadTypeSignature ());
2746 case ElementType.FnPtr: {
2747 var fptr = new FunctionPointerType ();
2748 ReadMethodSignature (fptr);
2751 case ElementType.ByRef:
2752 return new ByReferenceType (ReadTypeSignature ());
2753 case ElementType.Pinned:
2754 return new PinnedType (ReadTypeSignature ());
2755 case ElementType.SzArray:
2756 return new ArrayType (ReadTypeSignature ());
2757 case ElementType.Array:
2758 return ReadArrayTypeSignature ();
2759 case ElementType.CModOpt:
2760 return new OptionalModifierType (
2761 GetTypeDefOrRef (ReadTypeTokenSignature ()), ReadTypeSignature ());
2762 case ElementType.CModReqD:
2763 return new RequiredModifierType (
2764 GetTypeDefOrRef (ReadTypeTokenSignature ()), ReadTypeSignature ());
2765 case ElementType.Sentinel:
2766 return new SentinelType (ReadTypeSignature ());
2767 case ElementType.Var:
2768 return GetGenericParameter (GenericParameterType.Type, ReadCompressedUInt32 ());
2769 case ElementType.MVar:
2770 return GetGenericParameter (GenericParameterType.Method, ReadCompressedUInt32 ());
2771 case ElementType.GenericInst: {
2772 var is_value_type = ReadByte () == (byte) ElementType.ValueType;
2773 var element_type = GetTypeDefOrRef (ReadTypeTokenSignature ());
2774 var generic_instance = new GenericInstanceType (element_type);
2776 ReadGenericInstanceSignature (element_type, generic_instance);
2778 if (is_value_type) {
2779 generic_instance.IsValueType = true;
2780 element_type.GetElementType ().IsValueType = true;
2783 return generic_instance;
2785 case ElementType.Object: return TypeSystem.Object;
2786 case ElementType.Void: return TypeSystem.Void;
2787 case ElementType.TypedByRef: return TypeSystem.TypedReference;
2788 case ElementType.I: return TypeSystem.IntPtr;
2789 case ElementType.U: return TypeSystem.UIntPtr;
2790 default: return GetPrimitiveType (etype);
2794 public void ReadMethodSignature (IMethodSignature method)
2796 var calling_convention = ReadByte ();
2798 const byte has_this = 0x20;
2799 const byte explicit_this = 0x40;
2801 if ((calling_convention & has_this) != 0) {
2802 method.HasThis = true;
2803 calling_convention = (byte) (calling_convention & ~has_this);
2806 if ((calling_convention & explicit_this) != 0) {
2807 method.ExplicitThis = true;
2808 calling_convention = (byte) (calling_convention & ~explicit_this);
2811 method.CallingConvention = (MethodCallingConvention) calling_convention;
2813 var generic_context = method as MethodReference;
2814 if (generic_context != null)
2815 reader.context = generic_context;
2817 if ((calling_convention & 0x10) != 0) {
2818 var arity = ReadCompressedUInt32 ();
2820 if (generic_context != null && !generic_context.IsDefinition)
2821 CheckGenericContext (generic_context, (int) arity -1 );
2824 var param_count = ReadCompressedUInt32 ();
2826 method.MethodReturnType.ReturnType = ReadTypeSignature ();
2828 if (param_count == 0)
2831 Collection<ParameterDefinition> parameters;
2833 var method_ref = method as MethodReference;
2834 if (method_ref != null)
2835 parameters = method_ref.parameters = new ParameterDefinitionCollection (method, (int) param_count);
2837 parameters = method.Parameters;
2839 for (int i = 0; i < param_count; i++)
2840 parameters.Add (new ParameterDefinition (ReadTypeSignature ()));
2843 public object ReadConstantSignature (ElementType type)
2845 return ReadPrimitiveValue (type);
2848 public void ReadCustomAttributeConstructorArguments (CustomAttribute attribute, Collection<ParameterDefinition> parameters)
2850 var count = parameters.Count;
2854 attribute.arguments = new Collection<CustomAttributeArgument> (count);
2856 for (int i = 0; i < count; i++)
2857 attribute.arguments.Add (
2858 ReadCustomAttributeFixedArgument (parameters [i].ParameterType));
2861 CustomAttributeArgument ReadCustomAttributeFixedArgument (TypeReference type)
2864 return ReadCustomAttributeFixedArrayArgument ((ArrayType) type);
2866 return ReadCustomAttributeElement (type);
2869 public void ReadCustomAttributeNamedArguments (ushort count, ref Collection<CustomAttributeNamedArgument> fields, ref Collection<CustomAttributeNamedArgument> properties)
2871 for (int i = 0; i < count; i++)
2872 ReadCustomAttributeNamedArgument (ref fields, ref properties);
2875 void ReadCustomAttributeNamedArgument (ref Collection<CustomAttributeNamedArgument> fields, ref Collection<CustomAttributeNamedArgument> properties)
2877 var kind = ReadByte ();
2878 var type = ReadCustomAttributeFieldOrPropType ();
2879 var name = ReadUTF8String ();
2881 Collection<CustomAttributeNamedArgument> container;
2884 container = GetCustomAttributeNamedArgumentCollection (ref fields);
2887 container = GetCustomAttributeNamedArgumentCollection (ref properties);
2890 throw new NotSupportedException ();
2893 container.Add (new CustomAttributeNamedArgument (name, ReadCustomAttributeFixedArgument (type)));
2896 static Collection<CustomAttributeNamedArgument> GetCustomAttributeNamedArgumentCollection (ref Collection<CustomAttributeNamedArgument> collection)
2898 if (collection != null)
2901 return collection = new Collection<CustomAttributeNamedArgument> ();
2904 CustomAttributeArgument ReadCustomAttributeFixedArrayArgument (ArrayType type)
2906 var length = ReadUInt32 ();
2908 if (length == 0xffffffff)
2909 return new CustomAttributeArgument (type, null);
2912 return new CustomAttributeArgument (type, Empty<CustomAttributeArgument>.Array);
2914 var arguments = new CustomAttributeArgument [length];
2915 var element_type = type.ElementType;
2917 for (int i = 0; i < length; i++)
2918 arguments [i] = ReadCustomAttributeElement (element_type);
2920 return new CustomAttributeArgument (type, arguments);
2923 CustomAttributeArgument ReadCustomAttributeElement (TypeReference type)
2926 return ReadCustomAttributeFixedArrayArgument ((ArrayType) type);
2928 return new CustomAttributeArgument (
2930 type.etype == ElementType.Object
2931 ? ReadCustomAttributeElement (ReadCustomAttributeFieldOrPropType ())
2932 : ReadCustomAttributeElementValue (type));
2935 object ReadCustomAttributeElementValue (TypeReference type)
2937 var etype = type.etype;
2940 case ElementType.String:
2941 return ReadUTF8String ();
2942 case ElementType.None:
2943 if (type.IsTypeOf ("System", "Type"))
2944 return ReadTypeReference ();
2946 return ReadCustomAttributeEnum (type);
2948 return ReadPrimitiveValue (etype);
2952 object ReadPrimitiveValue (ElementType type)
2955 case ElementType.Boolean:
2956 return ReadByte () == 1;
2957 case ElementType.I1:
2958 return (sbyte) ReadByte ();
2959 case ElementType.U1:
2961 case ElementType.Char:
2962 return (char) ReadUInt16 ();
2963 case ElementType.I2:
2964 return ReadInt16 ();
2965 case ElementType.U2:
2966 return ReadUInt16 ();
2967 case ElementType.I4:
2968 return ReadInt32 ();
2969 case ElementType.U4:
2970 return ReadUInt32 ();
2971 case ElementType.I8:
2972 return ReadInt64 ();
2973 case ElementType.U8:
2974 return ReadUInt64 ();
2975 case ElementType.R4:
2976 return ReadSingle ();
2977 case ElementType.R8:
2978 return ReadDouble ();
2980 throw new NotImplementedException (type.ToString ());
2984 TypeReference GetPrimitiveType (ElementType etype)
2987 case ElementType.Boolean:
2988 return TypeSystem.Boolean;
2989 case ElementType.Char:
2990 return TypeSystem.Char;
2991 case ElementType.I1:
2992 return TypeSystem.SByte;
2993 case ElementType.U1:
2994 return TypeSystem.Byte;
2995 case ElementType.I2:
2996 return TypeSystem.Int16;
2997 case ElementType.U2:
2998 return TypeSystem.UInt16;
2999 case ElementType.I4:
3000 return TypeSystem.Int32;
3001 case ElementType.U4:
3002 return TypeSystem.UInt32;
3003 case ElementType.I8:
3004 return TypeSystem.Int64;
3005 case ElementType.U8:
3006 return TypeSystem.UInt64;
3007 case ElementType.R4:
3008 return TypeSystem.Single;
3009 case ElementType.R8:
3010 return TypeSystem.Double;
3011 case ElementType.String:
3012 return TypeSystem.String;
3014 throw new NotImplementedException (etype.ToString ());
3018 TypeReference ReadCustomAttributeFieldOrPropType ()
3020 var etype = (ElementType) ReadByte ();
3023 case ElementType.Boxed:
3024 return TypeSystem.Object;
3025 case ElementType.SzArray:
3026 return new ArrayType (ReadCustomAttributeFieldOrPropType ());
3027 case ElementType.Enum:
3028 return ReadTypeReference ();
3029 case ElementType.Type:
3030 return TypeSystem.LookupType ("System", "Type");
3032 return GetPrimitiveType (etype);
3036 public TypeReference ReadTypeReference ()
3038 return TypeParser.ParseType (reader.module, ReadUTF8String ());
3041 object ReadCustomAttributeEnum (TypeReference enum_type)
3043 var type = enum_type.CheckedResolve ();
3045 throw new ArgumentException ();
3047 return ReadCustomAttributeElementValue (type.GetEnumUnderlyingType ());
3050 public SecurityAttribute ReadSecurityAttribute ()
3052 var attribute = new SecurityAttribute (ReadTypeReference ());
3054 ReadCompressedUInt32 ();
3056 ReadCustomAttributeNamedArguments (
3057 (ushort) ReadCompressedUInt32 (),
3058 ref attribute.fields,
3059 ref attribute.properties);
3064 public MarshalInfo ReadMarshalInfo ()
3066 var native = ReadNativeType ();
3068 case NativeType.Array: {
3069 var array = new ArrayMarshalInfo ();
3071 array.element_type = ReadNativeType ();
3073 array.size_parameter_index = (int) ReadCompressedUInt32 ();
3075 array.size = (int) ReadCompressedUInt32 ();
3077 array.size_parameter_multiplier = (int) ReadCompressedUInt32 ();
3080 case NativeType.SafeArray: {
3081 var array = new SafeArrayMarshalInfo ();
3083 array.element_type = ReadVariantType ();
3086 case NativeType.FixedArray: {
3087 var array = new FixedArrayMarshalInfo ();
3089 array.size = (int) ReadCompressedUInt32 ();
3091 array.element_type = ReadNativeType ();
3094 case NativeType.FixedSysString: {
3095 var sys_string = new FixedSysStringMarshalInfo ();
3097 sys_string.size = (int) ReadCompressedUInt32 ();
3100 case NativeType.CustomMarshaler: {
3101 var marshaler = new CustomMarshalInfo ();
3102 var guid_value = ReadUTF8String ();
3103 marshaler.guid = !string.IsNullOrEmpty (guid_value) ? new Guid (guid_value) : Guid.Empty;
3104 marshaler.unmanaged_type = ReadUTF8String ();
3105 marshaler.managed_type = ReadTypeReference ();
3106 marshaler.cookie = ReadUTF8String ();
3110 return new MarshalInfo (native);
3114 NativeType ReadNativeType ()
3116 return (NativeType) ReadByte ();
3119 VariantType ReadVariantType ()
3121 return (VariantType) ReadByte ();
3124 string ReadUTF8String ()
3126 if (buffer [position] == 0xff) {
3131 var length = (int) ReadCompressedUInt32 ();
3133 return string.Empty;
3135 var @string = Encoding.UTF8.GetString (buffer, position,
3136 buffer [position + length - 1] == 0 ? length - 1 : length);
3142 public bool CanReadMore ()
3144 return position - start < sig_length;