2 Copyright (C) 2009-2012 Jeroen Frijters
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
25 using System.Collections.Generic;
26 using IKVM.Reflection.Metadata;
27 using IKVM.Reflection.Reader;
29 namespace IKVM.Reflection
31 public sealed class RawModule : IDisposable
33 private readonly ModuleReader module;
34 private readonly bool isManifestModule;
35 private bool imported;
37 internal RawModule(ModuleReader module)
40 this.isManifestModule = module.Assembly != null;
43 public string Location
45 get { return module.FullyQualifiedName; }
48 public bool IsManifestModule
50 get { return isManifestModule; }
53 public Guid ModuleVersionId
55 get { return module.ModuleVersionId; }
58 private void CheckManifestModule()
60 if (!IsManifestModule)
62 throw new BadImageFormatException("Module does not contain a manifest");
66 public AssemblyName GetAssemblyName()
68 CheckManifestModule();
69 return module.Assembly.GetName();
72 public AssemblyName[] GetReferencedAssemblies()
74 return module.__GetReferencedAssemblies();
81 module.stream.Dispose();
85 internal AssemblyReader ToAssembly()
89 throw new InvalidOperationException();
92 return (AssemblyReader)module.Assembly;
95 internal Module ToModule(Assembly assembly)
97 if (module.Assembly != null)
99 throw new InvalidOperationException();
102 module.SetAssembly(assembly);
107 public abstract class Module : ICustomAttributeProvider
109 internal readonly Universe universe;
110 internal readonly ModuleTable ModuleTable = new ModuleTable();
111 internal readonly TypeRefTable TypeRef = new TypeRefTable();
112 internal readonly TypeDefTable TypeDef = new TypeDefTable();
113 internal readonly FieldPtrTable FieldPtr = new FieldPtrTable();
114 internal readonly FieldTable Field = new FieldTable();
115 internal readonly MemberRefTable MemberRef = new MemberRefTable();
116 internal readonly ConstantTable Constant = new ConstantTable();
117 internal readonly CustomAttributeTable CustomAttribute = new CustomAttributeTable();
118 internal readonly FieldMarshalTable FieldMarshal = new FieldMarshalTable();
119 internal readonly DeclSecurityTable DeclSecurity = new DeclSecurityTable();
120 internal readonly ClassLayoutTable ClassLayout = new ClassLayoutTable();
121 internal readonly FieldLayoutTable FieldLayout = new FieldLayoutTable();
122 internal readonly ParamPtrTable ParamPtr = new ParamPtrTable();
123 internal readonly ParamTable Param = new ParamTable();
124 internal readonly InterfaceImplTable InterfaceImpl = new InterfaceImplTable();
125 internal readonly StandAloneSigTable StandAloneSig = new StandAloneSigTable();
126 internal readonly EventMapTable EventMap = new EventMapTable();
127 internal readonly EventPtrTable EventPtr = new EventPtrTable();
128 internal readonly EventTable Event = new EventTable();
129 internal readonly PropertyMapTable PropertyMap = new PropertyMapTable();
130 internal readonly PropertyPtrTable PropertyPtr = new PropertyPtrTable();
131 internal readonly PropertyTable Property = new PropertyTable();
132 internal readonly MethodSemanticsTable MethodSemantics = new MethodSemanticsTable();
133 internal readonly MethodImplTable MethodImpl = new MethodImplTable();
134 internal readonly ModuleRefTable ModuleRef = new ModuleRefTable();
135 internal readonly TypeSpecTable TypeSpec = new TypeSpecTable();
136 internal readonly ImplMapTable ImplMap = new ImplMapTable();
137 internal readonly FieldRVATable FieldRVA = new FieldRVATable();
138 internal readonly AssemblyTable AssemblyTable = new AssemblyTable();
139 internal readonly AssemblyRefTable AssemblyRef = new AssemblyRefTable();
140 internal readonly MethodPtrTable MethodPtr = new MethodPtrTable();
141 internal readonly MethodDefTable MethodDef = new MethodDefTable();
142 internal readonly NestedClassTable NestedClass = new NestedClassTable();
143 internal readonly FileTable File = new FileTable();
144 internal readonly ExportedTypeTable ExportedType = new ExportedTypeTable();
145 internal readonly ManifestResourceTable ManifestResource = new ManifestResourceTable();
146 internal readonly GenericParamTable GenericParam = new GenericParamTable();
147 internal readonly MethodSpecTable MethodSpec = new MethodSpecTable();
148 internal readonly GenericParamConstraintTable GenericParamConstraint = new GenericParamConstraintTable();
149 protected ulong sortedTableMask;
151 protected Module(Universe universe)
153 this.universe = universe;
156 internal Table[] GetTables()
158 Table[] tables = new Table[64];
159 tables[ModuleTable.Index] = ModuleTable;
160 tables[TypeRefTable.Index] = TypeRef;
161 tables[TypeDefTable.Index] = TypeDef;
162 tables[FieldPtrTable.Index] = FieldPtr;
163 tables[FieldTable.Index] = Field;
164 tables[MemberRefTable.Index] = MemberRef;
165 tables[ConstantTable.Index] = Constant;
166 tables[CustomAttributeTable.Index] = CustomAttribute;
167 tables[FieldMarshalTable.Index] = FieldMarshal;
168 tables[DeclSecurityTable.Index] = DeclSecurity;
169 tables[ClassLayoutTable.Index] = ClassLayout;
170 tables[FieldLayoutTable.Index] = FieldLayout;
171 tables[ParamPtrTable.Index] = ParamPtr;
172 tables[ParamTable.Index] = Param;
173 tables[InterfaceImplTable.Index] = InterfaceImpl;
174 tables[StandAloneSigTable.Index] = StandAloneSig;
175 tables[EventMapTable.Index] = EventMap;
176 tables[EventPtrTable.Index] = EventPtr;
177 tables[EventTable.Index] = Event;
178 tables[PropertyMapTable.Index] = PropertyMap;
179 tables[PropertyPtrTable.Index] = PropertyPtr;
180 tables[PropertyTable.Index] = Property;
181 tables[MethodSemanticsTable.Index] = MethodSemantics;
182 tables[MethodImplTable.Index] = MethodImpl;
183 tables[ModuleRefTable.Index] = ModuleRef;
184 tables[TypeSpecTable.Index] = TypeSpec;
185 tables[ImplMapTable.Index] = ImplMap;
186 tables[FieldRVATable.Index] = FieldRVA;
187 tables[AssemblyTable.Index] = AssemblyTable;
188 tables[AssemblyRefTable.Index] = AssemblyRef;
189 tables[MethodPtrTable.Index] = MethodPtr;
190 tables[MethodDefTable.Index] = MethodDef;
191 tables[NestedClassTable.Index] = NestedClass;
192 tables[FileTable.Index] = File;
193 tables[ExportedTypeTable.Index] = ExportedType;
194 tables[ManifestResourceTable.Index] = ManifestResource;
195 tables[GenericParamTable.Index] = GenericParam;
196 tables[MethodSpecTable.Index] = MethodSpec;
197 tables[GenericParamConstraintTable.Index] = GenericParamConstraint;
201 public virtual void __GetDataDirectoryEntry(int index, out int rva, out int length)
203 throw new NotSupportedException();
206 public virtual long __RelativeVirtualAddressToFileOffset(int rva)
208 throw new NotSupportedException();
211 public virtual bool __GetSectionInfo(int rva, out string name, out int characteristics)
213 throw new NotSupportedException();
216 public virtual int __ReadDataFromRVA(int rva, byte[] data, int offset, int length)
218 throw new NotSupportedException();
221 public virtual void GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine)
223 throw new NotSupportedException();
226 public virtual int __Subsystem
228 get { throw new NotSupportedException(); }
231 public FieldInfo GetField(string name)
233 return GetField(name, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
236 public FieldInfo GetField(string name, BindingFlags bindingFlags)
238 return IsResource() ? null : GetModuleType().GetField(name, bindingFlags | BindingFlags.DeclaredOnly);
241 public FieldInfo[] GetFields()
243 return GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
246 public FieldInfo[] GetFields(BindingFlags bindingFlags)
248 return IsResource() ? Empty<FieldInfo>.Array : GetModuleType().GetFields(bindingFlags | BindingFlags.DeclaredOnly);
251 public MethodInfo GetMethod(string name)
253 return IsResource() ? null : GetModuleType().GetMethod(name, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
256 public MethodInfo GetMethod(string name, Type[] types)
258 return IsResource() ? null : GetModuleType().GetMethod(name, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, types, null);
261 public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConv, Type[] types, ParameterModifier[] modifiers)
263 return IsResource() ? null : GetModuleType().GetMethod(name, bindingAttr | BindingFlags.DeclaredOnly, binder, callConv, types, modifiers);
266 public MethodInfo[] GetMethods()
268 return GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
271 public MethodInfo[] GetMethods(BindingFlags bindingFlags)
273 return IsResource() ? Empty<MethodInfo>.Array : GetModuleType().GetMethods(bindingFlags | BindingFlags.DeclaredOnly);
276 public ConstructorInfo __ModuleInitializer
278 get { return IsResource() ? null : GetModuleType().TypeInitializer; }
281 public virtual byte[] ResolveSignature(int metadataToken)
283 throw new NotSupportedException();
286 public virtual __StandAloneMethodSig __ResolveStandAloneMethodSig(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
288 throw new NotSupportedException();
291 public int MetadataToken
293 get { return IsResource() ? 0 : 1; }
296 public abstract int MDStreamVersion { get ;}
297 public abstract Assembly Assembly { get; }
298 public abstract string FullyQualifiedName { get; }
299 public abstract string Name { get; }
300 public abstract Guid ModuleVersionId { get; }
301 public abstract Type ResolveType(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments);
302 public abstract MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments);
303 public abstract FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments);
304 public abstract MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments);
306 public abstract string ResolveString(int metadataToken);
307 public abstract Type[] __ResolveOptionalParameterTypes(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments, out CustomModifiers[] customModifiers);
308 public abstract string ScopeName { get; }
310 internal abstract void GetTypesImpl(List<Type> list);
312 internal abstract Type FindType(TypeName name);
314 [Obsolete("Please use __ResolveOptionalParameterTypes(int, Type[], Type[], out CustomModifiers[]) instead.")]
315 public Type[] __ResolveOptionalParameterTypes(int metadataToken)
317 CustomModifiers[] dummy;
318 return __ResolveOptionalParameterTypes(metadataToken, null, null, out dummy);
321 public Type GetType(string className)
323 return GetType(className, false, false);
326 public Type GetType(string className, bool ignoreCase)
328 return GetType(className, false, ignoreCase);
331 public Type GetType(string className, bool throwOnError, bool ignoreCase)
335 throw new NotImplementedException();
337 TypeNameParser parser = TypeNameParser.Parse(className, throwOnError);
342 if (parser.AssemblyName != null)
346 throw new ArgumentException("Type names passed to Module.GetType() must not specify an assembly.");
353 Type type = FindType(TypeName.Split(TypeNameParser.Unescape(parser.FirstNamePart)));
354 if (type == null && __IsMissing)
356 throw new MissingModuleException((MissingModule)this);
358 return parser.Expand(type, this.Assembly, throwOnError, className, false);
361 public Type[] GetTypes()
363 List<Type> list = new List<Type>();
365 return list.ToArray();
368 public Type[] FindTypes(TypeFilter filter, object filterCriteria)
370 List<Type> list = new List<Type>();
371 foreach (Type type in GetTypes())
373 if (filter(type, filterCriteria))
378 return list.ToArray();
381 public virtual bool IsResource()
386 public Type ResolveType(int metadataToken)
388 return ResolveType(metadataToken, null, null);
391 public MethodBase ResolveMethod(int metadataToken)
393 return ResolveMethod(metadataToken, null, null);
396 public FieldInfo ResolveField(int metadataToken)
398 return ResolveField(metadataToken, null, null);
401 public MemberInfo ResolveMember(int metadataToken)
403 return ResolveMember(metadataToken, null, null);
406 public bool IsDefined(Type attributeType, bool inherit)
408 return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit).Count != 0;
411 public IList<CustomAttributeData> __GetCustomAttributes(Type attributeType, bool inherit)
413 return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit);
416 public virtual IList<CustomAttributeData> __GetPlaceholderAssemblyCustomAttributes(bool multiple, bool security)
418 return Empty<CustomAttributeData>.Array;
421 public abstract AssemblyName[] __GetReferencedAssemblies();
423 public virtual void __ResolveReferencedAssemblies(Assembly[] assemblies)
425 throw new NotSupportedException();
428 public abstract string[] __GetReferencedModules();
430 public abstract Type[] __GetReferencedTypes();
432 public abstract Type[] __GetExportedTypes();
434 public virtual bool __IsMissing
436 get { return false; }
439 public long __ImageBase
441 get { return GetImageBaseImpl(); }
444 protected abstract long GetImageBaseImpl();
446 public virtual long __StackReserve
448 get { throw new NotSupportedException(); }
451 public virtual int __FileAlignment
453 get { throw new NotSupportedException(); }
456 public virtual byte[] __ModuleHash
458 get { throw new NotSupportedException(); }
461 public virtual int __EntryPointRVA
463 get { throw new NotSupportedException(); }
466 public virtual int __EntryPointToken
468 get { throw new NotSupportedException(); }
471 public virtual string __ImageRuntimeVersion
473 get { throw new NotSupportedException(); }
476 public IEnumerable<CustomAttributeData> __EnumerateCustomAttributeTable()
478 List<CustomAttributeData> list = new List<CustomAttributeData>(CustomAttribute.RowCount);
479 for (int i = 0; i < CustomAttribute.RowCount; i++)
481 list.Add(new CustomAttributeData(this, i));
487 public List<CustomAttributeData> __GetCustomAttributesFor(int token)
489 return GetCustomAttributes(token, null);
492 internal abstract Type GetModuleType();
494 internal abstract ByteReader GetBlob(int blobIndex);
496 internal virtual IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
498 return GetCustomAttributes(0x00000001, attributeType);
501 internal List<CustomAttributeData> GetCustomAttributes(int metadataToken, Type attributeType)
503 List<CustomAttributeData> list = new List<CustomAttributeData>();
504 if ((sortedTableMask & (1UL << CustomAttributeTable.Index)) == 0)
506 for (int i = 0; i < CustomAttribute.RowCount; i++)
508 if (CustomAttribute.records[i].Parent == metadataToken)
510 if (attributeType == null)
512 list.Add(new CustomAttributeData(this, i));
516 ConstructorInfo constructor = (ConstructorInfo)ResolveMethod(CustomAttribute.records[i].Type);
517 if (attributeType.IsAssignableFrom(constructor.DeclaringType))
519 list.Add(new CustomAttributeData(this, i));
527 // do a binary search (on the rid part of the token)
528 CustomAttributeTable.Record rec = new CustomAttributeTable.Record();
529 rec.Parent = metadataToken;
530 int index = Array.BinarySearch(CustomAttribute.records, 0, CustomAttribute.RowCount, rec, BinarySearch.Comparer);
533 while (index > 0 && (CustomAttribute.records[index - 1].Parent & 0xFFFFFF) == (metadataToken & 0xFFFFFF))
537 for (; index < CustomAttribute.RowCount && (CustomAttribute.records[index].Parent & 0xFFFFFF) == (metadataToken & 0xFFFFFF); index++)
539 if (CustomAttribute.records[index].Parent == metadataToken)
541 if (attributeType == null)
543 list.Add(new CustomAttributeData(this, index));
547 ConstructorInfo constructor = (ConstructorInfo)ResolveMethod(CustomAttribute.records[index].Type);
548 if (attributeType.IsAssignableFrom(constructor.DeclaringType))
550 list.Add(new CustomAttributeData(this, index));
560 private sealed class BinarySearch : IComparer<CustomAttributeTable.Record>
562 internal static readonly BinarySearch Comparer = new BinarySearch();
564 public int Compare(CustomAttributeTable.Record x, CustomAttributeTable.Record y)
566 return (x.Parent & 0xFFFFFF).CompareTo(y.Parent & 0xFFFFFF);
570 internal IList<CustomAttributeData> GetDeclarativeSecurity(int metadataToken)
572 List<CustomAttributeData> list = new List<CustomAttributeData>();
573 // TODO use binary search?
574 for (int i = 0; i < DeclSecurity.records.Length; i++)
576 if (DeclSecurity.records[i].Parent == metadataToken)
578 CustomAttributeData.ReadDeclarativeSecurity(this, i, list);
584 internal virtual void Dispose()
588 internal virtual void ExportTypes(int fileToken, IKVM.Reflection.Emit.ModuleBuilder manifestModule)
593 abstract class NonPEModule : Module
595 protected NonPEModule(Universe universe)
600 protected virtual Exception InvalidOperationException()
602 return new InvalidOperationException();
605 protected virtual Exception NotSupportedException()
607 return new NotSupportedException();
610 protected virtual Exception ArgumentOutOfRangeException()
612 return new ArgumentOutOfRangeException();
615 internal sealed override Type GetModuleType()
617 throw InvalidOperationException();
620 internal sealed override ByteReader GetBlob(int blobIndex)
622 throw InvalidOperationException();
625 public sealed override AssemblyName[] __GetReferencedAssemblies()
627 throw NotSupportedException();
630 public sealed override string[] __GetReferencedModules()
632 throw NotSupportedException();
635 public override Type[] __GetReferencedTypes()
637 throw NotSupportedException();
640 public override Type[] __GetExportedTypes()
642 throw NotSupportedException();
645 protected sealed override long GetImageBaseImpl()
647 throw NotSupportedException();
650 public sealed override Type ResolveType(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
652 throw ArgumentOutOfRangeException();
655 public sealed override MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
657 throw ArgumentOutOfRangeException();
660 public sealed override FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
662 throw ArgumentOutOfRangeException();
665 public sealed override MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
667 throw ArgumentOutOfRangeException();
670 public sealed override string ResolveString(int metadataToken)
672 throw ArgumentOutOfRangeException();
675 public sealed override Type[] __ResolveOptionalParameterTypes(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments, out CustomModifiers[] customModifiers)
677 throw ArgumentOutOfRangeException();
681 public delegate bool TypeFilter(Type m, object filterCriteria);
682 public delegate bool MemberFilter(MemberInfo m, object filterCriteria);