2 Copyright (C) 2009-2011 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 private void CheckManifestModule()
55 if (!IsManifestModule)
57 throw new BadImageFormatException("Module does not contain a manifest");
61 public AssemblyName GetAssemblyName()
63 CheckManifestModule();
64 return module.Assembly.GetName();
67 public AssemblyName[] GetReferencedAssemblies()
69 return module.__GetReferencedAssemblies();
76 module.stream.Dispose();
80 internal Assembly ToAssembly()
84 throw new InvalidOperationException();
87 return module.Assembly;
90 internal Module ToModule(Assembly assembly)
92 if (module.Assembly != null)
94 throw new InvalidOperationException();
97 module.SetAssembly(assembly);
102 public abstract class Module : ICustomAttributeProvider
104 internal readonly Universe universe;
105 internal readonly ModuleTable ModuleTable = new ModuleTable();
106 internal readonly TypeRefTable TypeRef = new TypeRefTable();
107 internal readonly TypeDefTable TypeDef = new TypeDefTable();
108 internal readonly FieldPtrTable FieldPtr = new FieldPtrTable();
109 internal readonly FieldTable Field = new FieldTable();
110 internal readonly MemberRefTable MemberRef = new MemberRefTable();
111 internal readonly ConstantTable Constant = new ConstantTable();
112 internal readonly CustomAttributeTable CustomAttribute = new CustomAttributeTable();
113 internal readonly FieldMarshalTable FieldMarshal = new FieldMarshalTable();
114 internal readonly DeclSecurityTable DeclSecurity = new DeclSecurityTable();
115 internal readonly ClassLayoutTable ClassLayout = new ClassLayoutTable();
116 internal readonly FieldLayoutTable FieldLayout = new FieldLayoutTable();
117 internal readonly ParamPtrTable ParamPtr = new ParamPtrTable();
118 internal readonly ParamTable Param = new ParamTable();
119 internal readonly InterfaceImplTable InterfaceImpl = new InterfaceImplTable();
120 internal readonly StandAloneSigTable StandAloneSig = new StandAloneSigTable();
121 internal readonly EventMapTable EventMap = new EventMapTable();
122 internal readonly EventPtrTable EventPtr = new EventPtrTable();
123 internal readonly EventTable Event = new EventTable();
124 internal readonly PropertyMapTable PropertyMap = new PropertyMapTable();
125 internal readonly PropertyPtrTable PropertyPtr = new PropertyPtrTable();
126 internal readonly PropertyTable Property = new PropertyTable();
127 internal readonly MethodSemanticsTable MethodSemantics = new MethodSemanticsTable();
128 internal readonly MethodImplTable MethodImpl = new MethodImplTable();
129 internal readonly ModuleRefTable ModuleRef = new ModuleRefTable();
130 internal readonly TypeSpecTable TypeSpec = new TypeSpecTable();
131 internal readonly ImplMapTable ImplMap = new ImplMapTable();
132 internal readonly FieldRVATable FieldRVA = new FieldRVATable();
133 internal readonly AssemblyTable AssemblyTable = new AssemblyTable();
134 internal readonly AssemblyRefTable AssemblyRef = new AssemblyRefTable();
135 internal readonly MethodPtrTable MethodPtr = new MethodPtrTable();
136 internal readonly MethodDefTable MethodDef = new MethodDefTable();
137 internal readonly NestedClassTable NestedClass = new NestedClassTable();
138 internal readonly FileTable File = new FileTable();
139 internal readonly ExportedTypeTable ExportedType = new ExportedTypeTable();
140 internal readonly ManifestResourceTable ManifestResource = new ManifestResourceTable();
141 internal readonly GenericParamTable GenericParam = new GenericParamTable();
142 internal readonly MethodSpecTable MethodSpec = new MethodSpecTable();
143 internal readonly GenericParamConstraintTable GenericParamConstraint = new GenericParamConstraintTable();
145 protected Module(Universe universe)
147 this.universe = universe;
150 internal Table[] GetTables()
152 Table[] tables = new Table[64];
153 tables[ModuleTable.Index] = ModuleTable;
154 tables[TypeRefTable.Index] = TypeRef;
155 tables[TypeDefTable.Index] = TypeDef;
156 tables[FieldPtrTable.Index] = FieldPtr;
157 tables[FieldTable.Index] = Field;
158 tables[MemberRefTable.Index] = MemberRef;
159 tables[ConstantTable.Index] = Constant;
160 tables[CustomAttributeTable.Index] = CustomAttribute;
161 tables[FieldMarshalTable.Index] = FieldMarshal;
162 tables[DeclSecurityTable.Index] = DeclSecurity;
163 tables[ClassLayoutTable.Index] = ClassLayout;
164 tables[FieldLayoutTable.Index] = FieldLayout;
165 tables[ParamPtrTable.Index] = ParamPtr;
166 tables[ParamTable.Index] = Param;
167 tables[InterfaceImplTable.Index] = InterfaceImpl;
168 tables[StandAloneSigTable.Index] = StandAloneSig;
169 tables[EventMapTable.Index] = EventMap;
170 tables[EventPtrTable.Index] = EventPtr;
171 tables[EventTable.Index] = Event;
172 tables[PropertyMapTable.Index] = PropertyMap;
173 tables[PropertyPtrTable.Index] = PropertyPtr;
174 tables[PropertyTable.Index] = Property;
175 tables[MethodSemanticsTable.Index] = MethodSemantics;
176 tables[MethodImplTable.Index] = MethodImpl;
177 tables[ModuleRefTable.Index] = ModuleRef;
178 tables[TypeSpecTable.Index] = TypeSpec;
179 tables[ImplMapTable.Index] = ImplMap;
180 tables[FieldRVATable.Index] = FieldRVA;
181 tables[AssemblyTable.Index] = AssemblyTable;
182 tables[AssemblyRefTable.Index] = AssemblyRef;
183 tables[MethodPtrTable.Index] = MethodPtr;
184 tables[MethodDefTable.Index] = MethodDef;
185 tables[NestedClassTable.Index] = NestedClass;
186 tables[FileTable.Index] = File;
187 tables[ExportedTypeTable.Index] = ExportedType;
188 tables[ManifestResourceTable.Index] = ManifestResource;
189 tables[GenericParamTable.Index] = GenericParam;
190 tables[MethodSpecTable.Index] = MethodSpec;
191 tables[GenericParamConstraintTable.Index] = GenericParamConstraint;
195 public virtual void __GetDataDirectoryEntry(int index, out int rva, out int length)
197 throw new NotSupportedException();
200 public virtual long __RelativeVirtualAddressToFileOffset(int rva)
202 throw new NotSupportedException();
205 public virtual bool __GetSectionInfo(int rva, out string name, out int characteristics)
207 throw new NotSupportedException();
210 public virtual int __ReadDataFromRVA(int rva, byte[] data, int offset, int length)
212 throw new NotSupportedException();
215 public virtual void GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine)
217 throw new NotSupportedException();
220 public virtual int __Subsystem
222 get { throw new NotSupportedException(); }
225 public FieldInfo GetField(string name)
227 return GetField(name, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
230 public FieldInfo GetField(string name, BindingFlags bindingFlags)
232 return IsResource() ? null : GetModuleType().GetField(name, bindingFlags | BindingFlags.DeclaredOnly);
235 public FieldInfo[] GetFields()
237 return GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
240 public FieldInfo[] GetFields(BindingFlags bindingFlags)
242 return IsResource() ? Empty<FieldInfo>.Array : GetModuleType().GetFields(bindingFlags | BindingFlags.DeclaredOnly);
245 public MethodInfo GetMethod(string name)
247 return IsResource() ? null : GetModuleType().GetMethod(name, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
250 public MethodInfo GetMethod(string name, Type[] types)
252 return IsResource() ? null : GetModuleType().GetMethod(name, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, types, null);
255 public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConv, Type[] types, ParameterModifier[] modifiers)
257 return IsResource() ? null : GetModuleType().GetMethod(name, bindingAttr | BindingFlags.DeclaredOnly, binder, callConv, types, modifiers);
260 public MethodInfo[] GetMethods()
262 return GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
265 public MethodInfo[] GetMethods(BindingFlags bindingFlags)
267 return IsResource() ? Empty<MethodInfo>.Array : GetModuleType().GetMethods(bindingFlags | BindingFlags.DeclaredOnly);
270 public ConstructorInfo __ModuleInitializer
272 get { return IsResource() ? null : GetModuleType().TypeInitializer; }
275 public byte[] ResolveSignature(int metadataToken)
277 ModuleReader rdr = this as ModuleReader;
280 ByteReader br = rdr.ResolveSignature(metadataToken);
281 return br.ReadBytes(br.Length);
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);
308 public abstract string ScopeName { get; }
310 internal abstract void GetTypesImpl(List<Type> list);
312 internal abstract Type FindType(TypeName name);
314 public Type GetType(string className)
316 return GetType(className, false, false);
319 public Type GetType(string className, bool ignoreCase)
321 return GetType(className, false, ignoreCase);
324 public Type GetType(string className, bool throwOnError, bool ignoreCase)
328 throw new NotImplementedException();
330 TypeNameParser parser = TypeNameParser.Parse(className, throwOnError);
335 if (parser.AssemblyName != null)
339 throw new ArgumentException("Type names passed to Module.GetType() must not specify an assembly.");
346 Type type = FindType(TypeName.Split(TypeNameParser.Unescape(parser.FirstNamePart)));
347 if (type == null && __IsMissing)
349 throw new MissingModuleException((MissingModule)this);
351 return parser.Expand(type, this.Assembly, throwOnError, className, false);
354 public Type[] GetTypes()
356 List<Type> list = new List<Type>();
358 return list.ToArray();
361 public Type[] FindTypes(TypeFilter filter, object filterCriteria)
363 List<Type> list = new List<Type>();
364 foreach (Type type in GetTypes())
366 if (filter(type, filterCriteria))
371 return list.ToArray();
374 public virtual bool IsResource()
379 public Type ResolveType(int metadataToken)
381 return ResolveType(metadataToken, null, null);
384 public MethodBase ResolveMethod(int metadataToken)
386 return ResolveMethod(metadataToken, null, null);
389 public FieldInfo ResolveField(int metadataToken)
391 return ResolveField(metadataToken, null, null);
394 public MemberInfo ResolveMember(int metadataToken)
396 return ResolveMember(metadataToken, null, null);
399 public bool IsDefined(Type attributeType, bool inherit)
401 return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit).Count != 0;
404 public IList<CustomAttributeData> __GetCustomAttributes(Type attributeType, bool inherit)
406 return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit);
409 public virtual IList<CustomAttributeData> __GetPlaceholderAssemblyCustomAttributes(bool multiple, bool security)
411 return Empty<CustomAttributeData>.Array;
414 public abstract AssemblyName[] __GetReferencedAssemblies();
416 public virtual void __ResolveReferencedAssemblies(Assembly[] assemblies)
418 throw new NotSupportedException();
421 public abstract string[] __GetReferencedModules();
423 public abstract Type[] __GetReferencedTypes();
425 public abstract Type[] __GetExportedTypes();
427 public virtual bool __IsMissing
429 get { return false; }
432 public long __ImageBase
434 get { return GetImageBaseImpl(); }
437 protected abstract long GetImageBaseImpl();
439 public virtual long __StackReserve
441 get { throw new NotSupportedException(); }
444 public virtual byte[] __ModuleHash
446 get { throw new NotSupportedException(); }
449 public List<CustomAttributeData> __GetCustomAttributesFor(int token)
451 return GetCustomAttributes(token, null);
454 internal Type CanonicalizeType(Type type)
457 if (!universe.canonicalizedTypes.TryGetValue(type, out canon))
460 universe.canonicalizedTypes.Add(canon, canon);
465 internal abstract Type GetModuleType();
467 internal abstract ByteReader GetBlob(int blobIndex);
469 internal virtual IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
471 return GetCustomAttributes(0x00000001, attributeType);
474 internal List<CustomAttributeData> GetCustomAttributes(int metadataToken, Type attributeType)
476 List<CustomAttributeData> list = new List<CustomAttributeData>();
477 // TODO use binary search?
478 for (int i = 0; i < CustomAttribute.records.Length; i++)
480 if (CustomAttribute.records[i].Parent == metadataToken)
482 if (attributeType == null)
484 list.Add(new CustomAttributeData(this, i));
488 ConstructorInfo constructor = (ConstructorInfo)ResolveMethod(CustomAttribute.records[i].Type);
489 if (attributeType.IsAssignableFrom(constructor.DeclaringType))
491 list.Add(new CustomAttributeData(this.Assembly, constructor, GetBlob(CustomAttribute.records[i].Value)));
499 internal IList<CustomAttributeData> GetDeclarativeSecurity(int metadataToken)
501 List<CustomAttributeData> list = new List<CustomAttributeData>();
502 // TODO use binary search?
503 for (int i = 0; i < DeclSecurity.records.Length; i++)
505 if (DeclSecurity.records[i].Parent == metadataToken)
507 int action = DeclSecurity.records[i].Action;
508 int permissionSet = DeclSecurity.records[i].PermissionSet;
509 CustomAttributeData.ReadDeclarativeSecurity(this.Assembly, list, action, GetBlob(permissionSet));
515 internal virtual void Dispose()
519 internal virtual void ExportTypes(int fileToken, IKVM.Reflection.Emit.ModuleBuilder manifestModule)
524 abstract class NonPEModule : Module
526 protected NonPEModule(Universe universe)
531 protected virtual Exception InvalidOperationException()
533 return new InvalidOperationException();
536 protected virtual Exception NotSupportedException()
538 return new NotSupportedException();
541 protected virtual Exception ArgumentOutOfRangeException()
543 return new ArgumentOutOfRangeException();
546 internal sealed override Type GetModuleType()
548 throw InvalidOperationException();
551 internal sealed override ByteReader GetBlob(int blobIndex)
553 throw InvalidOperationException();
556 public sealed override AssemblyName[] __GetReferencedAssemblies()
558 throw NotSupportedException();
561 public sealed override string[] __GetReferencedModules()
563 throw NotSupportedException();
566 public override Type[] __GetReferencedTypes()
568 throw NotSupportedException();
571 public override Type[] __GetExportedTypes()
573 throw NotSupportedException();
576 protected sealed override long GetImageBaseImpl()
578 throw NotSupportedException();
581 public sealed override Type ResolveType(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
583 throw ArgumentOutOfRangeException();
586 public sealed override MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
588 throw ArgumentOutOfRangeException();
591 public sealed override FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
593 throw ArgumentOutOfRangeException();
596 public sealed override MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
598 throw ArgumentOutOfRangeException();
601 public sealed override string ResolveString(int metadataToken)
603 throw ArgumentOutOfRangeException();
606 public sealed override Type[] __ResolveOptionalParameterTypes(int metadataToken)
608 throw ArgumentOutOfRangeException();
612 public delegate bool TypeFilter(Type m, object filterCriteria);
613 public delegate bool MemberFilter(MemberInfo m, object filterCriteria);