summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Reflection/RuntimeConstructorInfo.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/Reflection/RuntimeConstructorInfo.cs')
-rw-r--r--src/mscorlib/src/System/Reflection/RuntimeConstructorInfo.cs481
1 files changed, 481 insertions, 0 deletions
diff --git a/src/mscorlib/src/System/Reflection/RuntimeConstructorInfo.cs b/src/mscorlib/src/System/Reflection/RuntimeConstructorInfo.cs
new file mode 100644
index 0000000000..8c3b1fce98
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/RuntimeConstructorInfo.cs
@@ -0,0 +1,481 @@
+// 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.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Runtime.Serialization;
+using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
+
+namespace System.Reflection
+{
+ [Serializable]
+ internal sealed class RuntimeConstructorInfo : ConstructorInfo, ISerializable, IRuntimeMethodInfo
+ {
+ #region Private Data Members
+ private volatile RuntimeType m_declaringType;
+ private RuntimeTypeCache m_reflectedTypeCache;
+ private string m_toString;
+ private ParameterInfo[] m_parameters = null; // Created lazily when GetParameters() is called.
+#pragma warning disable 169
+ private object _empty1; // These empties are used to ensure that RuntimeConstructorInfo and RuntimeMethodInfo are have a layout which is sufficiently similar
+ private object _empty2;
+ private object _empty3;
+#pragma warning restore 169
+ private IntPtr m_handle;
+ private MethodAttributes m_methodAttributes;
+ private BindingFlags m_bindingFlags;
+ private volatile Signature m_signature;
+ private INVOCATION_FLAGS m_invocationFlags;
+
+ internal INVOCATION_FLAGS InvocationFlags
+ {
+ get
+ {
+ if ((m_invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED) == 0)
+ {
+ INVOCATION_FLAGS invocationFlags = INVOCATION_FLAGS.INVOCATION_FLAGS_IS_CTOR; // this is a given
+
+ Type declaringType = DeclaringType;
+
+ //
+ // first take care of all the NO_INVOKE cases.
+ if (declaringType == typeof(void) ||
+ (declaringType != null && declaringType.ContainsGenericParameters) ||
+ ((CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs) ||
+ ((Attributes & MethodAttributes.RequireSecObject) == MethodAttributes.RequireSecObject))
+ {
+ // We don't need other flags if this method cannot be invoked
+ invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE;
+ }
+ else if (IsStatic || declaringType != null && declaringType.IsAbstract)
+ {
+ invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NO_CTOR_INVOKE;
+ }
+ else
+ {
+ // this should be an invocable method, determine the other flags that participate in invocation
+ invocationFlags |= RuntimeMethodHandle.GetSecurityFlags(this);
+
+ if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY) == 0 &&
+ ((Attributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public ||
+ (declaringType != null && declaringType.NeedsReflectionSecurityCheck)))
+ {
+ // If method is non-public, or declaring type is not visible
+ invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY;
+ }
+
+ // Check for attempt to create a delegate class, we demand unmanaged
+ // code permission for this since it's hard to validate the target address.
+ if (typeof(Delegate).IsAssignableFrom(DeclaringType))
+ invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_IS_DELEGATE_CTOR;
+ }
+
+ m_invocationFlags = invocationFlags | INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED;
+ }
+
+ return m_invocationFlags;
+ }
+ }
+ #endregion
+
+ #region Constructor
+ internal RuntimeConstructorInfo(
+ RuntimeMethodHandleInternal handle, RuntimeType declaringType, RuntimeTypeCache reflectedTypeCache,
+ MethodAttributes methodAttributes, BindingFlags bindingFlags)
+ {
+ Contract.Ensures(methodAttributes == RuntimeMethodHandle.GetAttributes(handle));
+
+ m_bindingFlags = bindingFlags;
+ m_reflectedTypeCache = reflectedTypeCache;
+ m_declaringType = declaringType;
+ m_handle = handle.Value;
+ m_methodAttributes = methodAttributes;
+ }
+ #endregion
+
+ #region NonPublic Methods
+ RuntimeMethodHandleInternal IRuntimeMethodInfo.Value
+ {
+ get
+ {
+ return new RuntimeMethodHandleInternal(m_handle);
+ }
+ }
+
+ internal override bool CacheEquals(object o)
+ {
+ RuntimeConstructorInfo m = o as RuntimeConstructorInfo;
+
+ if ((object)m == null)
+ return false;
+
+ return m.m_handle == m_handle;
+ }
+
+ private Signature Signature
+ {
+ get
+ {
+ if (m_signature == null)
+ m_signature = new Signature(this, m_declaringType);
+
+ return m_signature;
+ }
+ }
+
+ private RuntimeType ReflectedTypeInternal
+ {
+ get
+ {
+ return m_reflectedTypeCache.GetRuntimeType();
+ }
+ }
+
+ private void CheckConsistency(Object target)
+ {
+ if (target == null && IsStatic)
+ return;
+
+ if (!m_declaringType.IsInstanceOfType(target))
+ {
+ if (target == null)
+ throw new TargetException(SR.RFLCT_Targ_StatMethReqTarg);
+
+ throw new TargetException(SR.RFLCT_Targ_ITargMismatch);
+ }
+ }
+
+ internal BindingFlags BindingFlags { get { return m_bindingFlags; } }
+ #endregion
+
+ #region Object Overrides
+ public override String ToString()
+ {
+ // "Void" really doesn't make sense here. But we'll keep it for compat reasons.
+ if (m_toString == null)
+ m_toString = "Void " + FormatNameAndSig();
+
+ return m_toString;
+ }
+ #endregion
+
+ #region ICustomAttributeProvider
+ 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 MemberInfo Overrides
+ public override String Name
+ {
+ get { return RuntimeMethodHandle.GetName(this); }
+ }
+ public override MemberTypes MemberType { get { return MemberTypes.Constructor; } }
+
+ public override Type DeclaringType
+ {
+ get
+ {
+ return m_reflectedTypeCache.IsGlobal ? null : m_declaringType;
+ }
+ }
+
+ public override Type ReflectedType
+ {
+ get
+ {
+ return m_reflectedTypeCache.IsGlobal ? null : ReflectedTypeInternal;
+ }
+ }
+
+ public override int MetadataToken
+ {
+ get { return RuntimeMethodHandle.GetMethodDef(this); }
+ }
+ public override Module Module
+ {
+ get { return GetRuntimeModule(); }
+ }
+
+ internal RuntimeType GetRuntimeType() { return m_declaringType; }
+ internal RuntimeModule GetRuntimeModule() { return RuntimeTypeHandle.GetModule(m_declaringType); }
+ internal RuntimeAssembly GetRuntimeAssembly() { return GetRuntimeModule().GetRuntimeAssembly(); }
+ #endregion
+
+ #region MethodBase Overrides
+
+ // This seems to always returns System.Void.
+ internal override Type GetReturnType() { return Signature.ReturnType; }
+
+ internal override ParameterInfo[] GetParametersNoCopy()
+ {
+ if (m_parameters == null)
+ m_parameters = RuntimeParameterInfo.GetParameters(this, this, Signature);
+
+ return m_parameters;
+ }
+
+ [Pure]
+ public override ParameterInfo[] GetParameters()
+ {
+ ParameterInfo[] parameters = GetParametersNoCopy();
+
+ if (parameters.Length == 0)
+ return parameters;
+
+ ParameterInfo[] ret = new ParameterInfo[parameters.Length];
+ Array.Copy(parameters, ret, parameters.Length);
+ return ret;
+ }
+
+ public override MethodImplAttributes GetMethodImplementationFlags()
+ {
+ return RuntimeMethodHandle.GetImplAttributes(this);
+ }
+
+ public override RuntimeMethodHandle MethodHandle
+ {
+ get
+ {
+ Type declaringType = DeclaringType;
+ if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType)
+ throw new InvalidOperationException(SR.InvalidOperation_NotAllowedInReflectionOnly);
+ return new RuntimeMethodHandle(this);
+ }
+ }
+
+ public override MethodAttributes Attributes
+ {
+ get
+ {
+ return m_methodAttributes;
+ }
+ }
+
+ public override CallingConventions CallingConvention
+ {
+ get
+ {
+ return Signature.CallingConvention;
+ }
+ }
+
+ internal static void CheckCanCreateInstance(Type declaringType, bool isVarArg)
+ {
+ if (declaringType == null)
+ throw new ArgumentNullException(nameof(declaringType));
+ Contract.EndContractBlock();
+
+ // ctor is ReflectOnly
+ if (declaringType is ReflectionOnlyType)
+ throw new InvalidOperationException(SR.Arg_ReflectionOnlyInvoke);
+
+ // ctor is declared on interface class
+ else if (declaringType.IsInterface)
+ throw new MemberAccessException(
+ String.Format(CultureInfo.CurrentUICulture, SR.Acc_CreateInterfaceEx, declaringType));
+
+ // ctor is on an abstract class
+ else if (declaringType.IsAbstract)
+ throw new MemberAccessException(
+ String.Format(CultureInfo.CurrentUICulture, SR.Acc_CreateAbstEx, declaringType));
+
+ // ctor is on a class that contains stack pointers
+ else if (declaringType.GetRootElementType() == typeof(ArgIterator))
+ throw new NotSupportedException();
+
+ // ctor is vararg
+ else if (isVarArg)
+ throw new NotSupportedException();
+
+ // ctor is generic or on a generic class
+ else if (declaringType.ContainsGenericParameters)
+ {
+ throw new MemberAccessException(
+ String.Format(CultureInfo.CurrentUICulture, SR.Acc_CreateGenericEx, declaringType));
+ }
+
+ // ctor is declared on System.Void
+ else if (declaringType == typeof(void))
+ throw new MemberAccessException(SR.Access_Void);
+ }
+
+ internal void ThrowNoInvokeException()
+ {
+ CheckCanCreateInstance(DeclaringType, (CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs);
+
+ // ctor is .cctor
+ if ((Attributes & MethodAttributes.Static) == MethodAttributes.Static)
+ throw new MemberAccessException(SR.Acc_NotClassInit);
+
+ throw new TargetException();
+ }
+
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public override Object Invoke(
+ Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
+ {
+ INVOCATION_FLAGS invocationFlags = InvocationFlags;
+
+ if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE) != 0)
+ ThrowNoInvokeException();
+
+ // check basic method consistency. This call will throw if there are problems in the target/method relationship
+ CheckConsistency(obj);
+
+ if (obj != null)
+ {
+ // For unverifiable code, we require the caller to be critical.
+ // Adding the INVOCATION_FLAGS_NEED_SECURITY flag makes that check happen
+ invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY;
+ }
+
+ Signature sig = Signature;
+
+ // get the signature
+ int formalCount = sig.Arguments.Length;
+ int actualCount = (parameters != null) ? parameters.Length : 0;
+ if (formalCount != actualCount)
+ throw new TargetParameterCountException(SR.Arg_ParmCnt);
+
+ // if we are here we passed all the previous checks. Time to look at the arguments
+ if (actualCount > 0)
+ {
+ Object[] arguments = CheckArguments(parameters, binder, invokeAttr, culture, sig);
+ Object retValue = RuntimeMethodHandle.InvokeMethod(obj, arguments, sig, false);
+ // copy out. This should be made only if ByRef are present.
+ for (int index = 0; index < arguments.Length; index++)
+ parameters[index] = arguments[index];
+ return retValue;
+ }
+ return RuntimeMethodHandle.InvokeMethod(obj, null, sig, false);
+ }
+
+ public override MethodBody GetMethodBody()
+ {
+ MethodBody mb = RuntimeMethodHandle.GetMethodBody(this, ReflectedTypeInternal);
+ if (mb != null)
+ mb.m_methodBase = this;
+ return mb;
+ }
+
+ public override bool IsSecurityCritical
+ {
+ get { return true; }
+ }
+
+ public override bool IsSecuritySafeCritical
+ {
+ get { return false; }
+ }
+
+ public override bool IsSecurityTransparent
+ {
+ get { return false; }
+ }
+
+ public override bool ContainsGenericParameters
+ {
+ get
+ {
+ return (DeclaringType != null && DeclaringType.ContainsGenericParameters);
+ }
+ }
+ #endregion
+
+ #region ConstructorInfo Overrides
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public override Object Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
+ {
+ INVOCATION_FLAGS invocationFlags = InvocationFlags;
+
+ // get the declaring TypeHandle early for consistent exceptions in IntrospectionOnly context
+ RuntimeTypeHandle declaringTypeHandle = m_declaringType.TypeHandle;
+
+ if ((invocationFlags & (INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE | INVOCATION_FLAGS.INVOCATION_FLAGS_CONTAINS_STACK_POINTERS | INVOCATION_FLAGS.INVOCATION_FLAGS_NO_CTOR_INVOKE)) != 0)
+ ThrowNoInvokeException();
+
+ // get the signature
+ Signature sig = Signature;
+
+ int formalCount = sig.Arguments.Length;
+ int actualCount = (parameters != null) ? parameters.Length : 0;
+ if (formalCount != actualCount)
+ throw new TargetParameterCountException(SR.Arg_ParmCnt);
+
+ // We don't need to explicitly invoke the class constructor here,
+ // JIT/NGen will insert the call to .cctor in the instance ctor.
+
+ // if we are here we passed all the previous checks. Time to look at the arguments
+ if (actualCount > 0)
+ {
+ Object[] arguments = CheckArguments(parameters, binder, invokeAttr, culture, sig);
+ Object retValue = RuntimeMethodHandle.InvokeMethod(null, arguments, sig, true);
+ // copy out. This should be made only if ByRef are present.
+ for (int index = 0; index < arguments.Length; index++)
+ parameters[index] = arguments[index];
+ return retValue;
+ }
+ return RuntimeMethodHandle.InvokeMethod(null, null, sig, true);
+ }
+ #endregion
+
+ #region ISerializable Implementation
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ throw new ArgumentNullException(nameof(info));
+ Contract.EndContractBlock();
+ MemberInfoSerializationHolder.GetSerializationInfo(info, this);
+ }
+
+ internal string SerializationToString()
+ {
+ // We don't need the return type for constructors.
+ return FormatNameAndSig(true);
+ }
+ #endregion
+ }
+}