summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Reflection/RuntimeModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/Reflection/RuntimeModule.cs')
-rw-r--r--src/mscorlib/src/System/Reflection/RuntimeModule.cs602
1 files changed, 602 insertions, 0 deletions
diff --git a/src/mscorlib/src/System/Reflection/RuntimeModule.cs b/src/mscorlib/src/System/Reflection/RuntimeModule.cs
new file mode 100644
index 0000000000..75809cba01
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/RuntimeModule.cs
@@ -0,0 +1,602 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using System.Security;
+using System.Globalization;
+using System.Diagnostics.Contracts;
+
+namespace System.Reflection
+{
+ [Serializable]
+ internal class RuntimeModule : Module
+ {
+ internal RuntimeModule() { throw new NotSupportedException(); }
+
+ #region FCalls
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private extern static void GetType(RuntimeModule module, String className, bool throwOnError, bool ignoreCase, ObjectHandleOnStack type, ObjectHandleOnStack keepAlive);
+
+ [DllImport(JitHelpers.QCall)]
+ [SuppressUnmanagedCodeSecurity]
+ private static extern bool nIsTransientInternal(RuntimeModule module);
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private extern static void GetScopeName(RuntimeModule module, StringHandleOnStack retString);
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private extern static void GetFullyQualifiedName(RuntimeModule module, StringHandleOnStack retString);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private extern static RuntimeType[] GetTypes(RuntimeModule module);
+
+ internal RuntimeType[] GetDefinedTypes()
+ {
+ return GetTypes(GetNativeHandle());
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private extern static bool IsResource(RuntimeModule module);
+ #endregion
+
+ #region Module overrides
+ private static RuntimeTypeHandle[] ConvertToTypeHandleArray(Type[] genericArguments)
+ {
+ if (genericArguments == null)
+ return null;
+
+ int size = genericArguments.Length;
+ RuntimeTypeHandle[] typeHandleArgs = new RuntimeTypeHandle[size];
+ for (int i = 0; i < size; i++)
+ {
+ Type typeArg = genericArguments[i];
+ if (typeArg == null)
+ throw new ArgumentException(SR.Argument_InvalidGenericInstArray);
+ typeArg = typeArg.UnderlyingSystemType;
+ if (typeArg == null)
+ throw new ArgumentException(SR.Argument_InvalidGenericInstArray);
+ if (!(typeArg is RuntimeType))
+ throw new ArgumentException(SR.Argument_InvalidGenericInstArray);
+ typeHandleArgs[i] = typeArg.GetTypeHandleInternal();
+ }
+ return typeHandleArgs;
+ }
+
+ public override byte[] ResolveSignature(int metadataToken)
+ {
+ MetadataToken tk = new MetadataToken(metadataToken);
+
+ if (!MetadataImport.IsValidToken(tk))
+ throw new ArgumentOutOfRangeException(nameof(metadataToken),
+ SR.Format(SR.Argument_InvalidToken, tk, this));
+
+ if (!tk.IsMemberRef && !tk.IsMethodDef && !tk.IsTypeSpec && !tk.IsSignature && !tk.IsFieldDef)
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidToken, tk, this),
+ nameof(metadataToken));
+
+ ConstArray signature;
+ if (tk.IsMemberRef)
+ signature = MetadataImport.GetMemberRefProps(metadataToken);
+ else
+ signature = MetadataImport.GetSignatureFromToken(metadataToken);
+
+ byte[] sig = new byte[signature.Length];
+
+ for (int i = 0; i < signature.Length; i++)
+ sig[i] = signature[i];
+
+ return sig;
+ }
+
+ public override MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
+ {
+ MetadataToken tk = new MetadataToken(metadataToken);
+
+ if (!MetadataImport.IsValidToken(tk))
+ throw new ArgumentOutOfRangeException(nameof(metadataToken),
+ SR.Format(SR.Argument_InvalidToken, tk, this));
+
+ RuntimeTypeHandle[] typeArgs = ConvertToTypeHandleArray(genericTypeArguments);
+ RuntimeTypeHandle[] methodArgs = ConvertToTypeHandleArray(genericMethodArguments);
+
+ try
+ {
+ if (!tk.IsMethodDef && !tk.IsMethodSpec)
+ {
+ if (!tk.IsMemberRef)
+ throw new ArgumentException(SR.Format(SR.Argument_ResolveMethod, tk, this),
+ nameof(metadataToken));
+
+ unsafe
+ {
+ ConstArray sig = MetadataImport.GetMemberRefProps(tk);
+
+ if (*(MdSigCallingConvention*)sig.Signature.ToPointer() == MdSigCallingConvention.Field)
+ throw new ArgumentException(SR.Format(SR.Argument_ResolveMethod, tk, this),
+ nameof(metadataToken));
+ }
+ }
+
+ IRuntimeMethodInfo methodHandle = ModuleHandle.ResolveMethodHandleInternal(GetNativeHandle(), tk, typeArgs, methodArgs);
+ Type declaringType = RuntimeMethodHandle.GetDeclaringType(methodHandle);
+
+ if (declaringType.IsGenericType || declaringType.IsArray)
+ {
+ MetadataToken tkDeclaringType = new MetadataToken(MetadataImport.GetParentToken(tk));
+
+ if (tk.IsMethodSpec)
+ tkDeclaringType = new MetadataToken(MetadataImport.GetParentToken(tkDeclaringType));
+
+ declaringType = ResolveType(tkDeclaringType, genericTypeArguments, genericMethodArguments);
+ }
+
+ return System.RuntimeType.GetMethodBase(declaringType as RuntimeType, methodHandle);
+ }
+ catch (BadImageFormatException e)
+ {
+ throw new ArgumentException(SR.Argument_BadImageFormatExceptionResolve, e);
+ }
+ }
+
+ private FieldInfo ResolveLiteralField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
+ {
+ MetadataToken tk = new MetadataToken(metadataToken);
+
+ if (!MetadataImport.IsValidToken(tk) || !tk.IsFieldDef)
+ throw new ArgumentOutOfRangeException(nameof(metadataToken),
+ String.Format(CultureInfo.CurrentUICulture, SR.Format(SR.Argument_InvalidToken, tk, this)));
+
+ int tkDeclaringType;
+ string fieldName;
+
+ fieldName = MetadataImport.GetName(tk).ToString();
+ tkDeclaringType = MetadataImport.GetParentToken(tk);
+
+ Type declaringType = ResolveType(tkDeclaringType, genericTypeArguments, genericMethodArguments);
+
+ declaringType.GetFields();
+
+ try
+ {
+ return declaringType.GetField(fieldName,
+ BindingFlags.Static | BindingFlags.Instance |
+ BindingFlags.Public | BindingFlags.NonPublic |
+ BindingFlags.DeclaredOnly);
+ }
+ catch
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_ResolveField, tk, this), nameof(metadataToken));
+ }
+ }
+
+ public override FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
+ {
+ MetadataToken tk = new MetadataToken(metadataToken);
+
+ if (!MetadataImport.IsValidToken(tk))
+ throw new ArgumentOutOfRangeException(nameof(metadataToken),
+ SR.Format(SR.Argument_InvalidToken, tk, this));
+
+ RuntimeTypeHandle[] typeArgs = ConvertToTypeHandleArray(genericTypeArguments);
+ RuntimeTypeHandle[] methodArgs = ConvertToTypeHandleArray(genericMethodArguments);
+
+ try
+ {
+ IRuntimeFieldInfo fieldHandle = null;
+
+ if (!tk.IsFieldDef)
+ {
+ if (!tk.IsMemberRef)
+ throw new ArgumentException(SR.Format(SR.Argument_ResolveField, tk, this),
+ nameof(metadataToken));
+
+ unsafe
+ {
+ ConstArray sig = MetadataImport.GetMemberRefProps(tk);
+
+ if (*(MdSigCallingConvention*)sig.Signature.ToPointer() != MdSigCallingConvention.Field)
+ throw new ArgumentException(SR.Format(SR.Argument_ResolveField, tk, this),
+ nameof(metadataToken));
+ }
+
+ fieldHandle = ModuleHandle.ResolveFieldHandleInternal(GetNativeHandle(), tk, typeArgs, methodArgs);
+ }
+
+ fieldHandle = ModuleHandle.ResolveFieldHandleInternal(GetNativeHandle(), metadataToken, typeArgs, methodArgs);
+ RuntimeType declaringType = RuntimeFieldHandle.GetApproxDeclaringType(fieldHandle.Value);
+
+ if (declaringType.IsGenericType || declaringType.IsArray)
+ {
+ int tkDeclaringType = ModuleHandle.GetMetadataImport(GetNativeHandle()).GetParentToken(metadataToken);
+ declaringType = (RuntimeType)ResolveType(tkDeclaringType, genericTypeArguments, genericMethodArguments);
+ }
+
+ return System.RuntimeType.GetFieldInfo(declaringType, fieldHandle);
+ }
+ catch (MissingFieldException)
+ {
+ return ResolveLiteralField(tk, genericTypeArguments, genericMethodArguments);
+ }
+ catch (BadImageFormatException e)
+ {
+ throw new ArgumentException(SR.Argument_BadImageFormatExceptionResolve, e);
+ }
+ }
+
+ public override Type ResolveType(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
+ {
+ MetadataToken tk = new MetadataToken(metadataToken);
+
+ if (tk.IsGlobalTypeDefToken)
+ throw new ArgumentException(SR.Format(SR.Argument_ResolveModuleType, tk), nameof(metadataToken));
+
+ if (!MetadataImport.IsValidToken(tk))
+ throw new ArgumentOutOfRangeException(nameof(metadataToken),
+ SR.Format(SR.Argument_InvalidToken, tk, this));
+
+ if (!tk.IsTypeDef && !tk.IsTypeSpec && !tk.IsTypeRef)
+ throw new ArgumentException(SR.Format(SR.Argument_ResolveType, tk, this), nameof(metadataToken));
+
+ RuntimeTypeHandle[] typeArgs = ConvertToTypeHandleArray(genericTypeArguments);
+ RuntimeTypeHandle[] methodArgs = ConvertToTypeHandleArray(genericMethodArguments);
+
+ try
+ {
+ Type t = GetModuleHandleImpl().ResolveTypeHandle(metadataToken, typeArgs, methodArgs).GetRuntimeType();
+
+ if (t == null)
+ throw new ArgumentException(SR.Format(SR.Argument_ResolveType, tk, this), nameof(metadataToken));
+
+ return t;
+ }
+ catch (BadImageFormatException e)
+ {
+ throw new ArgumentException(SR.Argument_BadImageFormatExceptionResolve, e);
+ }
+ }
+
+ public override MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
+ {
+ MetadataToken tk = new MetadataToken(metadataToken);
+
+ if (tk.IsProperty)
+ throw new ArgumentException(SR.InvalidOperation_PropertyInfoNotAvailable);
+
+ if (tk.IsEvent)
+ throw new ArgumentException(SR.InvalidOperation_EventInfoNotAvailable);
+
+ if (tk.IsMethodSpec || tk.IsMethodDef)
+ return ResolveMethod(metadataToken, genericTypeArguments, genericMethodArguments);
+
+ if (tk.IsFieldDef)
+ return ResolveField(metadataToken, genericTypeArguments, genericMethodArguments);
+
+ if (tk.IsTypeRef || tk.IsTypeDef || tk.IsTypeSpec)
+ return ResolveType(metadataToken, genericTypeArguments, genericMethodArguments);
+
+ if (tk.IsMemberRef)
+ {
+ if (!MetadataImport.IsValidToken(tk))
+ throw new ArgumentOutOfRangeException(nameof(metadataToken),
+ SR.Format(SR.Argument_InvalidToken, tk, this));
+
+ ConstArray sig = MetadataImport.GetMemberRefProps(tk);
+
+ unsafe
+ {
+ if (*(MdSigCallingConvention*)sig.Signature.ToPointer() == MdSigCallingConvention.Field)
+ {
+ return ResolveField(tk, genericTypeArguments, genericMethodArguments);
+ }
+ else
+ {
+ return ResolveMethod(tk, genericTypeArguments, genericMethodArguments);
+ }
+ }
+ }
+
+ throw new ArgumentException(SR.Format(SR.Argument_ResolveMember, tk, this),
+ nameof(metadataToken));
+ }
+
+ public override string ResolveString(int metadataToken)
+ {
+ MetadataToken tk = new MetadataToken(metadataToken);
+ if (!tk.IsString)
+ throw new ArgumentException(
+ String.Format(CultureInfo.CurrentUICulture, SR.Argument_ResolveString, metadataToken, ToString()));
+
+ if (!MetadataImport.IsValidToken(tk))
+ throw new ArgumentOutOfRangeException(nameof(metadataToken),
+ String.Format(CultureInfo.CurrentUICulture, SR.Format(SR.Argument_InvalidToken, tk, this)));
+
+ string str = MetadataImport.GetUserString(metadataToken);
+
+ if (str == null)
+ throw new ArgumentException(
+ String.Format(CultureInfo.CurrentUICulture, SR.Argument_ResolveString, metadataToken, ToString()));
+
+ return str;
+ }
+
+ public override void GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine)
+ {
+ ModuleHandle.GetPEKind(GetNativeHandle(), out peKind, out machine);
+ }
+
+ public override int MDStreamVersion
+ {
+ get
+ {
+ return ModuleHandle.GetMDStreamVersion(GetNativeHandle());
+ }
+ }
+ #endregion
+
+ #region Data Members
+#pragma warning disable 169
+ // If you add any data members, you need to update the native declaration ReflectModuleBaseObject.
+ private RuntimeType m_runtimeType;
+ private RuntimeAssembly m_runtimeAssembly;
+ private IntPtr m_pRefClass;
+ private IntPtr m_pData;
+ private IntPtr m_pGlobals;
+ private IntPtr m_pFields;
+#pragma warning restore 169
+ #endregion
+
+ #region Protected Virtuals
+ protected override MethodInfo GetMethodImpl(String name, BindingFlags bindingAttr, Binder binder,
+ CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
+ {
+ return GetMethodInternal(name, bindingAttr, binder, callConvention, types, modifiers);
+ }
+
+ internal MethodInfo GetMethodInternal(String name, BindingFlags bindingAttr, Binder binder,
+ CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
+ {
+ if (RuntimeType == null)
+ return null;
+
+ if (types == null)
+ {
+ return RuntimeType.GetMethod(name, bindingAttr);
+ }
+ else
+ {
+ return RuntimeType.GetMethod(name, bindingAttr, binder, callConvention, types, modifiers);
+ }
+ }
+ #endregion
+
+ #region Internal Members
+ internal RuntimeType RuntimeType
+ {
+ get
+ {
+ if (m_runtimeType == null)
+ m_runtimeType = ModuleHandle.GetModuleType(GetNativeHandle());
+
+ return m_runtimeType;
+ }
+ }
+
+ internal bool IsTransientInternal()
+ {
+ return RuntimeModule.nIsTransientInternal(this.GetNativeHandle());
+ }
+
+ internal MetadataImport MetadataImport
+ {
+ get
+ {
+ unsafe
+ {
+ return ModuleHandle.GetMetadataImport(GetNativeHandle());
+ }
+ }
+ }
+ #endregion
+
+ #region ICustomAttributeProvider Members
+ public override Object[] GetCustomAttributes(bool inherit)
+ {
+ return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType);
+ }
+
+ public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException(nameof(attributeType));
+ Contract.EndContractBlock();
+
+ RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
+
+ return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
+ }
+
+ public override bool IsDefined(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException(nameof(attributeType));
+ Contract.EndContractBlock();
+
+ RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
+
+ return CustomAttribute.IsDefined(this, attributeRuntimeType);
+ }
+
+ public override IList<CustomAttributeData> GetCustomAttributesData()
+ {
+ return CustomAttributeData.GetCustomAttributesInternal(this);
+ }
+ #endregion
+
+ #region Public Virtuals
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
+ throw new ArgumentNullException(nameof(info));
+ }
+ Contract.EndContractBlock();
+ UnitySerializationHolder.GetUnitySerializationInfo(info, UnitySerializationHolder.ModuleUnity, this.ScopeName, this.GetRuntimeAssembly());
+ }
+
+ public override Type GetType(String className, bool throwOnError, bool ignoreCase)
+ {
+ // throw on null strings regardless of the value of "throwOnError"
+ if (className == null)
+ throw new ArgumentNullException(nameof(className));
+
+ RuntimeType retType = null;
+ Object keepAlive = null;
+ GetType(GetNativeHandle(), className, throwOnError, ignoreCase, JitHelpers.GetObjectHandleOnStack(ref retType), JitHelpers.GetObjectHandleOnStack(ref keepAlive));
+ GC.KeepAlive(keepAlive);
+ return retType;
+ }
+
+ internal string GetFullyQualifiedName()
+ {
+ String fullyQualifiedName = null;
+ GetFullyQualifiedName(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref fullyQualifiedName));
+ return fullyQualifiedName;
+ }
+
+ public override String FullyQualifiedName
+ {
+ get
+ {
+ return GetFullyQualifiedName();
+ }
+ }
+
+ public override Type[] GetTypes()
+ {
+ return GetTypes(GetNativeHandle());
+ }
+
+ #endregion
+
+ #region Public Members
+
+ public override Guid ModuleVersionId
+ {
+ get
+ {
+ unsafe
+ {
+ Guid mvid;
+ MetadataImport.GetScopeProps(out mvid);
+ return mvid;
+ }
+ }
+ }
+
+ public override int MetadataToken
+ {
+ get
+ {
+ return ModuleHandle.GetToken(GetNativeHandle());
+ }
+ }
+
+ public override bool IsResource()
+ {
+ return IsResource(GetNativeHandle());
+ }
+
+ public override FieldInfo[] GetFields(BindingFlags bindingFlags)
+ {
+ if (RuntimeType == null)
+ return new FieldInfo[0];
+
+ return RuntimeType.GetFields(bindingFlags);
+ }
+
+ public override FieldInfo GetField(String name, BindingFlags bindingAttr)
+ {
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+
+ if (RuntimeType == null)
+ return null;
+
+ return RuntimeType.GetField(name, bindingAttr);
+ }
+
+ public override MethodInfo[] GetMethods(BindingFlags bindingFlags)
+ {
+ if (RuntimeType == null)
+ return new MethodInfo[0];
+
+ return RuntimeType.GetMethods(bindingFlags);
+ }
+
+ public override String ScopeName
+ {
+ get
+ {
+ string scopeName = null;
+ GetScopeName(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref scopeName));
+ return scopeName;
+ }
+ }
+
+ public override String Name
+ {
+ get
+ {
+ String s = GetFullyQualifiedName();
+
+#if !FEATURE_PAL
+ int i = s.LastIndexOf('\\');
+#else
+ int i = s.LastIndexOf(System.IO.Path.DirectorySeparatorChar);
+#endif
+ if (i == -1)
+ return s;
+
+ return s.Substring(i + 1);
+ }
+ }
+
+ public override Assembly Assembly
+ {
+ [Pure]
+ get
+ {
+ return GetRuntimeAssembly();
+ }
+ }
+
+ internal RuntimeAssembly GetRuntimeAssembly()
+ {
+ return m_runtimeAssembly;
+ }
+
+ protected override ModuleHandle GetModuleHandleImpl()
+ {
+ return new ModuleHandle(this);
+ }
+
+ internal RuntimeModule GetNativeHandle()
+ {
+ return this;
+ }
+ #endregion
+ }
+}