Move few more methods to shared RuntimeType (#46383)
authorMarek Safar <marek.safar@gmail.com>
Fri, 25 Dec 2020 04:56:36 +0000 (05:56 +0100)
committerGitHub <noreply@github.com>
Fri, 25 Dec 2020 04:56:36 +0000 (20:56 -0800)
src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs
src/libraries/System.Private.CoreLib/src/System/RuntimeType.cs
src/mono/netcore/System.Private.CoreLib/src/System/RuntimeType.Mono.cs

index 7b4f322..26bc4e1 100644 (file)
@@ -1935,31 +1935,6 @@ namespace System
             throw new SystemException();
         }
 
-        private static void ThrowIfTypeNeverValidGenericArgument(RuntimeType type)
-        {
-            if (type.IsPointer || type.IsByRef || type == typeof(void))
-                throw new ArgumentException(
-                    SR.Format(SR.Argument_NeverValidGenericArgument, type));
-        }
-
-        internal static void SanityCheckGenericArguments(RuntimeType[] genericArguments, RuntimeType[] genericParamters)
-        {
-            if (genericArguments == null)
-                throw new ArgumentNullException();
-
-            for (int i = 0; i < genericArguments.Length; i++)
-            {
-                if (genericArguments[i] == null)
-                    throw new ArgumentNullException();
-
-                ThrowIfTypeNeverValidGenericArgument(genericArguments[i]);
-            }
-
-            if (genericArguments.Length != genericParamters.Length)
-                throw new ArgumentException(
-                    SR.Format(SR.Argument_NotEnoughGenArguments, genericArguments.Length, genericParamters.Length));
-        }
-
         internal static void ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception? e)
         {
             RuntimeType[]? typeContext = null;
@@ -3348,12 +3323,6 @@ namespace System
 
         #region Invoke Member
 
-        private const BindingFlags MemberBindingMask = (BindingFlags)0x000000FF;
-        private const BindingFlags InvocationMask = (BindingFlags)0x0000FF00;
-        private const BindingFlags BinderNonCreateInstance = BindingFlags.InvokeMethod | BinderGetSetField | BinderGetSetProperty;
-        private const BindingFlags BinderGetSetProperty = BindingFlags.GetProperty | BindingFlags.SetProperty;
-        private const BindingFlags BinderGetSetField = BindingFlags.GetField | BindingFlags.SetField;
-        private const BindingFlags BinderNonFieldGetSet = (BindingFlags)0x00FFF300;
         private static readonly RuntimeType s_typedRef = (RuntimeType)typeof(TypedReference);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
@@ -3469,373 +3438,6 @@ namespace System
             throw new ArgumentException(SR.Format(SR.Arg_ObjObjEx, value.GetType(), this));
         }
 
-        [DebuggerStepThrough]
-        [DebuggerHidden]
-        [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
-        public override object? InvokeMember(
-            string name, BindingFlags bindingFlags, Binder? binder, object? target,
-            object?[]? providedArgs, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParams)
-        {
-            if (IsGenericParameter)
-                throw new InvalidOperationException(SR.Arg_GenericParameter);
-
-            if ((bindingFlags & InvocationMask) == 0)
-                // "Must specify binding flags describing the invoke operation required."
-                throw new ArgumentException(SR.Arg_NoAccessSpec, nameof(bindingFlags));
-
-            // Provide a default binding mask if none is provided
-            if ((bindingFlags & MemberBindingMask) == 0)
-            {
-                bindingFlags |= BindingFlags.Instance | BindingFlags.Public;
-
-                if ((bindingFlags & BindingFlags.CreateInstance) == 0)
-                    bindingFlags |= BindingFlags.Static;
-            }
-
-            // There must not be more named parameters than provided arguments
-            if (namedParams != null)
-            {
-                if (providedArgs != null)
-                {
-                    if (namedParams.Length > providedArgs.Length)
-                        throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams));
-                }
-                else
-                {
-                    if (namedParams.Length != 0)
-                        throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams));
-                }
-            }
-
-#if FEATURE_COMINTEROP
-            if (target != null && target.GetType().IsCOMObject)
-            {
-                const BindingFlags ClassicBindingMask =
-                    BindingFlags.InvokeMethod | BindingFlags.GetProperty | BindingFlags.SetProperty |
-                    BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty;
-
-                if ((bindingFlags & ClassicBindingMask) == 0)
-                    throw new ArgumentException(SR.Arg_COMAccess, nameof(bindingFlags));
-
-                if ((bindingFlags & BindingFlags.GetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
-                    throw new ArgumentException(SR.Arg_PropSetGet, nameof(bindingFlags));
-
-                if ((bindingFlags & BindingFlags.InvokeMethod) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
-                    throw new ArgumentException(SR.Arg_PropSetInvoke, nameof(bindingFlags));
-
-                if ((bindingFlags & BindingFlags.SetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.SetProperty) != 0)
-                    throw new ArgumentException(SR.Arg_COMPropSetPut, nameof(bindingFlags));
-
-                if ((bindingFlags & BindingFlags.PutDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutDispProperty) != 0)
-                    throw new ArgumentException(SR.Arg_COMPropSetPut, nameof(bindingFlags));
-
-                if ((bindingFlags & BindingFlags.PutRefDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutRefDispProperty) != 0)
-                    throw new ArgumentException(SR.Arg_COMPropSetPut, nameof(bindingFlags));
-
-                if (name == null)
-                    throw new ArgumentNullException(nameof(name));
-
-                bool[]? isByRef = modifiers?[0].IsByRefArray;
-
-                // pass LCID_ENGLISH_US if no explicit culture is specified to match the behavior of VB
-                int lcid = (culture == null ? 0x0409 : culture.LCID);
-
-                // If a request to not wrap exceptions was made, we will unwrap
-                // the TargetInvocationException since that is what will be thrown.
-                bool unwrapExceptions = (bindingFlags & BindingFlags.DoNotWrapExceptions) != 0;
-                try
-                {
-                    return InvokeDispMethod(name, bindingFlags, target, providedArgs, isByRef, lcid, namedParams);
-                }
-                catch (TargetInvocationException e) when (unwrapExceptions)
-                {
-                    // For target invocation exceptions, we need to unwrap the inner exception and
-                    // re-throw it.
-                    throw e.InnerException!;
-                }
-            }
-#endif // FEATURE_COMINTEROP
-
-            if (namedParams != null && Array.IndexOf(namedParams, null!) != -1)
-                throw new ArgumentException(SR.Arg_NamedParamNull, nameof(namedParams));
-
-            int argCnt = (providedArgs != null) ? providedArgs.Length : 0;
-
-            binder ??= DefaultBinder;
-
-            // Delegate to Activator.CreateInstance
-            if ((bindingFlags & BindingFlags.CreateInstance) != 0)
-            {
-                if ((bindingFlags & BindingFlags.CreateInstance) != 0 && (bindingFlags & BinderNonCreateInstance) != 0)
-                    // "Can not specify both CreateInstance and another access type."
-                    throw new ArgumentException(SR.Arg_CreatInstAccess, nameof(bindingFlags));
-
-                return Activator.CreateInstance(this, bindingFlags, binder, providedArgs, culture);
-            }
-
-            // PutDispProperty and\or PutRefDispProperty ==> SetProperty.
-            if ((bindingFlags & (BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty)) != 0)
-                bindingFlags |= BindingFlags.SetProperty;
-
-            if (name == null)
-                throw new ArgumentNullException(nameof(name));
-
-            if (name.Length == 0 || name.Equals("[DISPID=0]"))
-            {
-                // in InvokeMember we always pretend there is a default member if none is provided and we make it ToString
-                name = GetDefaultMemberName()! ?? "ToString";
-            }
-
-            // GetField or SetField
-            bool IsGetField = (bindingFlags & BindingFlags.GetField) != 0;
-            bool IsSetField = (bindingFlags & BindingFlags.SetField) != 0;
-
-            if (IsGetField || IsSetField)
-            {
-                if (IsGetField)
-                {
-                    if (IsSetField)
-                        throw new ArgumentException(SR.Arg_FldSetGet, nameof(bindingFlags));
-
-                    if ((bindingFlags & BindingFlags.SetProperty) != 0)
-                        throw new ArgumentException(SR.Arg_FldGetPropSet, nameof(bindingFlags));
-                }
-                else
-                {
-                    Debug.Assert(IsSetField);
-
-                    if (providedArgs == null)
-                        throw new ArgumentNullException(nameof(providedArgs));
-
-                    if ((bindingFlags & BindingFlags.GetProperty) != 0)
-                        throw new ArgumentException(SR.Arg_FldSetPropGet, nameof(bindingFlags));
-
-                    if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
-                        throw new ArgumentException(SR.Arg_FldSetInvoke, nameof(bindingFlags));
-                }
-
-                // Lookup Field
-                FieldInfo? selFld = null;
-                FieldInfo[]? flds = GetMember(name, MemberTypes.Field, bindingFlags) as FieldInfo[];
-
-                Debug.Assert(flds != null);
-
-                if (flds.Length == 1)
-                {
-                    selFld = flds[0];
-                }
-                else if (flds.Length > 0)
-                {
-                    selFld = binder.BindToField(bindingFlags, flds, IsGetField ? Empty.Value : providedArgs![0]!, culture);
-                }
-
-                if (selFld != null)
-                {
-                    // Invocation on a field
-                    if (selFld.FieldType.IsArray || ReferenceEquals(selFld.FieldType, typeof(Array)))
-                    {
-                        // Invocation of an array Field
-                        int idxCnt;
-                        if ((bindingFlags & BindingFlags.GetField) != 0)
-                        {
-                            idxCnt = argCnt;
-                        }
-                        else
-                        {
-                            idxCnt = argCnt - 1;
-                        }
-
-                        if (idxCnt > 0)
-                        {
-                            // Verify that all of the index values are ints
-                            int[] idx = new int[idxCnt];
-                            for (int i = 0; i < idxCnt; i++)
-                            {
-                                try
-                                {
-                                    idx[i] = ((IConvertible)providedArgs![i]!).ToInt32(null);
-                                }
-                                catch (InvalidCastException)
-                                {
-                                    throw new ArgumentException(SR.Arg_IndexMustBeInt);
-                                }
-                            }
-
-                            // Set or get the value...
-                            Array a = (Array)selFld.GetValue(target)!;
-
-                            // Set or get the value in the array
-                            if ((bindingFlags & BindingFlags.GetField) != 0)
-                            {
-                                return a.GetValue(idx);
-                            }
-                            else
-                            {
-                                a.SetValue(providedArgs![idxCnt], idx);
-                                return null;
-                            }
-                        }
-                    }
-
-                    if (IsGetField)
-                    {
-                        if (argCnt != 0)
-                            throw new ArgumentException(SR.Arg_FldGetArgErr, nameof(bindingFlags));
-
-                        return selFld.GetValue(target);
-                    }
-                    else
-                    {
-                        if (argCnt != 1)
-                            throw new ArgumentException(SR.Arg_FldSetArgErr, nameof(bindingFlags));
-
-                        selFld.SetValue(target, providedArgs![0], bindingFlags, binder, culture);
-                        return null;
-                    }
-                }
-
-                if ((bindingFlags & BinderNonFieldGetSet) == 0)
-                    throw new MissingFieldException(FullName, name);
-            }
-
-            // @Legacy - This is RTM behavior
-            bool isGetProperty = (bindingFlags & BindingFlags.GetProperty) != 0;
-            bool isSetProperty = (bindingFlags & BindingFlags.SetProperty) != 0;
-
-            if (isGetProperty || isSetProperty)
-            {
-                if (isGetProperty)
-                {
-                    Debug.Assert(!IsSetField);
-
-                    if (isSetProperty)
-                        throw new ArgumentException(SR.Arg_PropSetGet, nameof(bindingFlags));
-                }
-                else
-                {
-                    Debug.Assert(isSetProperty);
-
-                    Debug.Assert(!IsGetField);
-
-                    if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
-                        throw new ArgumentException(SR.Arg_PropSetInvoke, nameof(bindingFlags));
-                }
-            }
-
-            MethodInfo[]? finalists = null;
-            MethodInfo? finalist = null;
-
-            if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
-            {
-                // Lookup Methods
-                MethodInfo[] semiFinalists = (GetMember(name, MemberTypes.Method, bindingFlags) as MethodInfo[])!;
-                List<MethodInfo>? results = null;
-
-                for (int i = 0; i < semiFinalists.Length; i++)
-                {
-                    MethodInfo semiFinalist = semiFinalists[i];
-                    Debug.Assert(semiFinalist != null);
-
-                    if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
-                        continue;
-
-                    if (finalist == null)
-                    {
-                        finalist = semiFinalist;
-                    }
-                    else
-                    {
-                        results ??= new List<MethodInfo>(semiFinalists.Length) { finalist };
-                        results.Add(semiFinalist);
-                    }
-                }
-
-                if (results != null)
-                {
-                    Debug.Assert(results.Count > 1);
-                    finalists = results.ToArray();
-                }
-            }
-
-            Debug.Assert(finalists == null || finalist != null);
-
-            // BindingFlags.GetProperty or BindingFlags.SetProperty
-            if (finalist == null && isGetProperty || isSetProperty)
-            {
-                // Lookup Property
-                PropertyInfo[] semiFinalists = (GetMember(name, MemberTypes.Property, bindingFlags) as PropertyInfo[])!;
-                List<MethodInfo>? results = null;
-
-                for (int i = 0; i < semiFinalists.Length; i++)
-                {
-                    MethodInfo? semiFinalist = null;
-
-                    if (isSetProperty)
-                    {
-                        semiFinalist = semiFinalists[i].GetSetMethod(true);
-                    }
-                    else
-                    {
-                        semiFinalist = semiFinalists[i].GetGetMethod(true);
-                    }
-
-                    if (semiFinalist == null)
-                        continue;
-
-                    if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
-                        continue;
-
-                    if (finalist == null)
-                    {
-                        finalist = semiFinalist;
-                    }
-                    else
-                    {
-                        results ??= new List<MethodInfo>(semiFinalists.Length) { finalist };
-                        results.Add(semiFinalist);
-                    }
-                }
-
-                if (results != null)
-                {
-                    Debug.Assert(results.Count > 1);
-                    finalists = results.ToArray();
-                }
-            }
-
-            if (finalist != null)
-            {
-                // Invoke
-                if (finalists == null &&
-                    argCnt == 0 &&
-                    finalist.GetParametersNoCopy().Length == 0 &&
-                    (bindingFlags & BindingFlags.OptionalParamBinding) == 0)
-                {
-                    return finalist.Invoke(target, bindingFlags, binder, providedArgs, culture);
-                }
-
-                finalists ??= new MethodInfo[] { finalist };
-                providedArgs ??= Array.Empty<object>();
-                object? state = null;
-                MethodBase? invokeMethod = null;
-
-                try { invokeMethod = binder.BindToMethod(bindingFlags, finalists, ref providedArgs!, modifiers, culture, namedParams, out state); }
-                catch (MissingMethodException) { }
-
-                if (invokeMethod == null)
-                    throw new MissingMethodException(FullName, name);
-
-                object? result = ((MethodInfo)invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture);
-
-                if (state != null)
-                    binder.ReorderArgumentArray(ref providedArgs, state);
-
-                return result;
-            }
-
-            throw new MissingMethodException(FullName, name);
-        }
-
         #endregion
 
         #endregion
index 6bc3ddf..88c593c 100644 (file)
@@ -2,7 +2,9 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
 using System.Reflection;
 using System.Runtime.CompilerServices;
 
@@ -367,6 +369,380 @@ namespace System
             return false;
         }
 
+        [DebuggerStepThrough]
+        [DebuggerHidden]
+        [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
+        public override object? InvokeMember(
+            string name, BindingFlags bindingFlags, Binder? binder, object? target,
+            object?[]? providedArgs, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParams)
+        {
+            const BindingFlags MemberBindingMask = (BindingFlags)0x000000FF;
+            const BindingFlags InvocationMask = (BindingFlags)0x0000FF00;
+            const BindingFlags BinderGetSetField = BindingFlags.GetField | BindingFlags.SetField;
+            const BindingFlags BinderGetSetProperty = BindingFlags.GetProperty | BindingFlags.SetProperty;
+            const BindingFlags BinderNonCreateInstance = BindingFlags.InvokeMethod | BinderGetSetField | BinderGetSetProperty;
+            const BindingFlags BinderNonFieldGetSet = (BindingFlags)0x00FFF300;
+
+            if (IsGenericParameter)
+                throw new InvalidOperationException(SR.Arg_GenericParameter);
+
+            if ((bindingFlags & InvocationMask) == 0)
+                // "Must specify binding flags describing the invoke operation required."
+                throw new ArgumentException(SR.Arg_NoAccessSpec, nameof(bindingFlags));
+
+            // Provide a default binding mask if none is provided
+            if ((bindingFlags & MemberBindingMask) == 0)
+            {
+                bindingFlags |= BindingFlags.Instance | BindingFlags.Public;
+
+                if ((bindingFlags & BindingFlags.CreateInstance) == 0)
+                    bindingFlags |= BindingFlags.Static;
+            }
+
+            // There must not be more named parameters than provided arguments
+            if (namedParams != null)
+            {
+                if (providedArgs != null)
+                {
+                    if (namedParams.Length > providedArgs.Length)
+                        throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams));
+                }
+                else
+                {
+                    if (namedParams.Length != 0)
+                        throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams));
+                }
+            }
+
+#if FEATURE_COMINTEROP
+            if (target != null && target.GetType().IsCOMObject)
+            {
+                const BindingFlags ClassicBindingMask =
+                    BindingFlags.InvokeMethod | BindingFlags.GetProperty | BindingFlags.SetProperty |
+                    BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty;
+
+                if ((bindingFlags & ClassicBindingMask) == 0)
+                    throw new ArgumentException(SR.Arg_COMAccess, nameof(bindingFlags));
+
+                if ((bindingFlags & BindingFlags.GetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
+                    throw new ArgumentException(SR.Arg_PropSetGet, nameof(bindingFlags));
+
+                if ((bindingFlags & BindingFlags.InvokeMethod) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
+                    throw new ArgumentException(SR.Arg_PropSetInvoke, nameof(bindingFlags));
+
+                if ((bindingFlags & BindingFlags.SetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.SetProperty) != 0)
+                    throw new ArgumentException(SR.Arg_COMPropSetPut, nameof(bindingFlags));
+
+                if ((bindingFlags & BindingFlags.PutDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutDispProperty) != 0)
+                    throw new ArgumentException(SR.Arg_COMPropSetPut, nameof(bindingFlags));
+
+                if ((bindingFlags & BindingFlags.PutRefDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutRefDispProperty) != 0)
+                    throw new ArgumentException(SR.Arg_COMPropSetPut, nameof(bindingFlags));
+
+                if (name == null)
+                    throw new ArgumentNullException(nameof(name));
+
+                bool[]? isByRef = modifiers?[0].IsByRefArray;
+
+                // pass LCID_ENGLISH_US if no explicit culture is specified to match the behavior of VB
+                int lcid = (culture == null ? 0x0409 : culture.LCID);
+
+                // If a request to not wrap exceptions was made, we will unwrap
+                // the TargetInvocationException since that is what will be thrown.
+                bool unwrapExceptions = (bindingFlags & BindingFlags.DoNotWrapExceptions) != 0;
+                try
+                {
+                    return InvokeDispMethod(name, bindingFlags, target, providedArgs, isByRef, lcid, namedParams);
+                }
+                catch (TargetInvocationException e) when (unwrapExceptions)
+                {
+                    // For target invocation exceptions, we need to unwrap the inner exception and
+                    // re-throw it.
+                    throw e.InnerException!;
+                }
+            }
+#endif // FEATURE_COMINTEROP
+
+            if (namedParams != null && Array.IndexOf(namedParams, null!) != -1)
+                throw new ArgumentException(SR.Arg_NamedParamNull, nameof(namedParams));
+
+            int argCnt = (providedArgs != null) ? providedArgs.Length : 0;
+
+            binder ??= DefaultBinder;
+
+            // Delegate to Activator.CreateInstance
+            if ((bindingFlags & BindingFlags.CreateInstance) != 0)
+            {
+                if ((bindingFlags & BindingFlags.CreateInstance) != 0 && (bindingFlags & BinderNonCreateInstance) != 0)
+                    // "Can not specify both CreateInstance and another access type."
+                    throw new ArgumentException(SR.Arg_CreatInstAccess, nameof(bindingFlags));
+
+                return Activator.CreateInstance(this, bindingFlags, binder, providedArgs, culture);
+            }
+
+            // PutDispProperty and\or PutRefDispProperty ==> SetProperty.
+            if ((bindingFlags & (BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty)) != 0)
+                bindingFlags |= BindingFlags.SetProperty;
+
+            if (name == null)
+                throw new ArgumentNullException(nameof(name));
+
+            if (name.Length == 0 || name.Equals("[DISPID=0]"))
+            {
+                // in InvokeMember we always pretend there is a default member if none is provided and we make it ToString
+                name = GetDefaultMemberName()! ?? "ToString";
+            }
+
+            // GetField or SetField
+            bool IsGetField = (bindingFlags & BindingFlags.GetField) != 0;
+            bool IsSetField = (bindingFlags & BindingFlags.SetField) != 0;
+
+            if (IsGetField || IsSetField)
+            {
+                if (IsGetField)
+                {
+                    if (IsSetField)
+                        throw new ArgumentException(SR.Arg_FldSetGet, nameof(bindingFlags));
+
+                    if ((bindingFlags & BindingFlags.SetProperty) != 0)
+                        throw new ArgumentException(SR.Arg_FldGetPropSet, nameof(bindingFlags));
+                }
+                else
+                {
+                    Debug.Assert(IsSetField);
+
+                    if (providedArgs == null)
+                        throw new ArgumentNullException(nameof(providedArgs));
+
+                    if ((bindingFlags & BindingFlags.GetProperty) != 0)
+                        throw new ArgumentException(SR.Arg_FldSetPropGet, nameof(bindingFlags));
+
+                    if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
+                        throw new ArgumentException(SR.Arg_FldSetInvoke, nameof(bindingFlags));
+                }
+
+                // Lookup Field
+                FieldInfo? selFld = null;
+                FieldInfo[]? flds = GetMember(name, MemberTypes.Field, bindingFlags) as FieldInfo[];
+
+                Debug.Assert(flds != null);
+
+                if (flds.Length == 1)
+                {
+                    selFld = flds[0];
+                }
+                else if (flds.Length > 0)
+                {
+                    selFld = binder.BindToField(bindingFlags, flds, IsGetField ? Empty.Value : providedArgs![0]!, culture);
+                }
+
+                if (selFld != null)
+                {
+                    // Invocation on a field
+                    if (selFld.FieldType.IsArray || ReferenceEquals(selFld.FieldType, typeof(Array)))
+                    {
+                        // Invocation of an array Field
+                        int idxCnt;
+                        if ((bindingFlags & BindingFlags.GetField) != 0)
+                        {
+                            idxCnt = argCnt;
+                        }
+                        else
+                        {
+                            idxCnt = argCnt - 1;
+                        }
+
+                        if (idxCnt > 0)
+                        {
+                            // Verify that all of the index values are ints
+                            int[] idx = new int[idxCnt];
+                            for (int i = 0; i < idxCnt; i++)
+                            {
+                                try
+                                {
+                                    idx[i] = ((IConvertible)providedArgs![i]!).ToInt32(null);
+                                }
+                                catch (InvalidCastException)
+                                {
+                                    throw new ArgumentException(SR.Arg_IndexMustBeInt);
+                                }
+                            }
+
+                            // Set or get the value...
+                            Array a = (Array)selFld.GetValue(target)!;
+
+                            // Set or get the value in the array
+                            if ((bindingFlags & BindingFlags.GetField) != 0)
+                            {
+                                return a.GetValue(idx);
+                            }
+                            else
+                            {
+                                a.SetValue(providedArgs![idxCnt], idx);
+                                return null;
+                            }
+                        }
+                    }
+
+                    if (IsGetField)
+                    {
+                        if (argCnt != 0)
+                            throw new ArgumentException(SR.Arg_FldGetArgErr, nameof(bindingFlags));
+
+                        return selFld.GetValue(target);
+                    }
+                    else
+                    {
+                        if (argCnt != 1)
+                            throw new ArgumentException(SR.Arg_FldSetArgErr, nameof(bindingFlags));
+
+                        selFld.SetValue(target, providedArgs![0], bindingFlags, binder, culture);
+                        return null;
+                    }
+                }
+
+                if ((bindingFlags & BinderNonFieldGetSet) == 0)
+                    throw new MissingFieldException(FullName, name);
+            }
+
+            // @Legacy - This is RTM behavior
+            bool isGetProperty = (bindingFlags & BindingFlags.GetProperty) != 0;
+            bool isSetProperty = (bindingFlags & BindingFlags.SetProperty) != 0;
+
+            if (isGetProperty || isSetProperty)
+            {
+                if (isGetProperty)
+                {
+                    Debug.Assert(!IsSetField);
+
+                    if (isSetProperty)
+                        throw new ArgumentException(SR.Arg_PropSetGet, nameof(bindingFlags));
+                }
+                else
+                {
+                    Debug.Assert(isSetProperty);
+
+                    Debug.Assert(!IsGetField);
+
+                    if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
+                        throw new ArgumentException(SR.Arg_PropSetInvoke, nameof(bindingFlags));
+                }
+            }
+
+            MethodInfo[]? finalists = null;
+            MethodInfo? finalist = null;
+
+            if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
+            {
+                // Lookup Methods
+                MethodInfo[] semiFinalists = (GetMember(name, MemberTypes.Method, bindingFlags) as MethodInfo[])!;
+                List<MethodInfo>? results = null;
+
+                for (int i = 0; i < semiFinalists.Length; i++)
+                {
+                    MethodInfo semiFinalist = semiFinalists[i];
+                    Debug.Assert(semiFinalist != null);
+
+                    if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
+                        continue;
+
+                    if (finalist == null)
+                    {
+                        finalist = semiFinalist;
+                    }
+                    else
+                    {
+                        results ??= new List<MethodInfo>(semiFinalists.Length) { finalist };
+                        results.Add(semiFinalist);
+                    }
+                }
+
+                if (results != null)
+                {
+                    Debug.Assert(results.Count > 1);
+                    finalists = results.ToArray();
+                }
+            }
+
+            Debug.Assert(finalists == null || finalist != null);
+
+            // BindingFlags.GetProperty or BindingFlags.SetProperty
+            if (finalist == null && isGetProperty || isSetProperty)
+            {
+                // Lookup Property
+                PropertyInfo[] semiFinalists = (GetMember(name, MemberTypes.Property, bindingFlags) as PropertyInfo[])!;
+                List<MethodInfo>? results = null;
+
+                for (int i = 0; i < semiFinalists.Length; i++)
+                {
+                    MethodInfo? semiFinalist = null;
+
+                    if (isSetProperty)
+                    {
+                        semiFinalist = semiFinalists[i].GetSetMethod(true);
+                    }
+                    else
+                    {
+                        semiFinalist = semiFinalists[i].GetGetMethod(true);
+                    }
+
+                    if (semiFinalist == null)
+                        continue;
+
+                    if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
+                        continue;
+
+                    if (finalist == null)
+                    {
+                        finalist = semiFinalist;
+                    }
+                    else
+                    {
+                        results ??= new List<MethodInfo>(semiFinalists.Length) { finalist };
+                        results.Add(semiFinalist);
+                    }
+                }
+
+                if (results != null)
+                {
+                    Debug.Assert(results.Count > 1);
+                    finalists = results.ToArray();
+                }
+            }
+
+            if (finalist != null)
+            {
+                // Invoke
+                if (finalists == null &&
+                    argCnt == 0 &&
+                    finalist.GetParametersNoCopy().Length == 0 &&
+                    (bindingFlags & BindingFlags.OptionalParamBinding) == 0)
+                {
+                    return finalist.Invoke(target, bindingFlags, binder, providedArgs, culture);
+                }
+
+                finalists ??= new MethodInfo[] { finalist };
+                providedArgs ??= Array.Empty<object>();
+                object? state = null;
+                MethodBase? invokeMethod = null;
+
+                try { invokeMethod = binder.BindToMethod(bindingFlags, finalists, ref providedArgs!, modifiers, culture, namedParams, out state); }
+                catch (MissingMethodException) { }
+
+                if (invokeMethod == null)
+                    throw new MissingMethodException(FullName, name);
+
+                object? result = ((MethodInfo)invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture);
+
+                if (state != null)
+                    binder.ReorderArgumentArray(ref providedArgs, state);
+
+                return result;
+            }
+
+            throw new MissingMethodException(FullName, name);
+        }
+
         private RuntimeType? GetBaseType()
         {
             if (IsInterface)
@@ -409,5 +785,30 @@ namespace System
 
             return RuntimeTypeHandle.GetBaseType(this);
         }
+
+        private static void ThrowIfTypeNeverValidGenericArgument(RuntimeType type)
+        {
+            if (type.IsPointer || type.IsByRef || type == typeof(void))
+                throw new ArgumentException(
+                    SR.Format(SR.Argument_NeverValidGenericArgument, type));
+        }
+
+        internal static void SanityCheckGenericArguments(RuntimeType[] genericArguments, RuntimeType[] genericParamters)
+        {
+            if (genericArguments == null)
+                throw new ArgumentNullException();
+
+            for (int i = 0; i < genericArguments.Length; i++)
+            {
+                if (genericArguments[i] == null)
+                    throw new ArgumentNullException();
+
+                ThrowIfTypeNeverValidGenericArgument(genericArguments[i]);
+            }
+
+            if (genericArguments.Length != genericParamters.Length)
+                throw new ArgumentException(
+                    SR.Format(SR.Argument_NotEnoughGenArguments, genericArguments.Length, genericParamters.Length));
+        }
     }
 }
index a703fc8..bb71ef1 100644 (file)
@@ -163,31 +163,6 @@ namespace System
                 typeName, throwOnError, ignoreCase, reflectionOnly, ref stackMark, false);
         }
 
-        private static void ThrowIfTypeNeverValidGenericArgument(RuntimeType type)
-        {
-            if (type.IsPointer || type.IsByRef || type == typeof(void))
-                throw new ArgumentException(
-                    SR.Format(SR.Argument_NeverValidGenericArgument, type));
-        }
-
-        internal static void SanityCheckGenericArguments(RuntimeType[] genericArguments, RuntimeType[] genericParamters)
-        {
-            if (genericArguments == null)
-                throw new ArgumentNullException();
-
-            for (int i = 0; i < genericArguments.Length; i++)
-            {
-                if (genericArguments[i] == null)
-                    throw new ArgumentNullException();
-
-                ThrowIfTypeNeverValidGenericArgument(genericArguments[i]);
-            }
-
-            if (genericArguments.Length != genericParamters.Length)
-                throw new ArgumentException(
-                    SR.Format(SR.Argument_NotEnoughGenArguments, genericArguments.Length, genericParamters.Length));
-        }
-
         private static void SplitName(string? fullname, out string? name, out string? ns)
         {
             name = null;
@@ -1270,406 +1245,6 @@ namespace System
 
         #endregion
 
-        #region Invoke Member
-        private const BindingFlags MemberBindingMask = (BindingFlags)0x000000FF;
-        private const BindingFlags InvocationMask = (BindingFlags)0x0000FF00;
-        private const BindingFlags BinderNonCreateInstance = BindingFlags.InvokeMethod | BinderGetSetField | BinderGetSetProperty;
-        private const BindingFlags BinderGetSetProperty = BindingFlags.GetProperty | BindingFlags.SetProperty;
-        private const BindingFlags BinderGetSetField = BindingFlags.GetField | BindingFlags.SetField;
-        private const BindingFlags BinderNonFieldGetSet = (BindingFlags)0x00FFF300;
-
-        [DebuggerStepThroughAttribute]
-        [Diagnostics.DebuggerHidden]
-        [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
-        public override object? InvokeMember(
-            string name, BindingFlags bindingFlags, Binder? binder, object? target,
-            object?[]? providedArgs, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParams)
-        {
-            if (IsGenericParameter)
-                throw new InvalidOperationException(SR.Arg_GenericParameter);
-
-            #region Preconditions
-            if ((bindingFlags & InvocationMask) == 0)
-                // "Must specify binding flags describing the invoke operation required."
-                throw new ArgumentException(SR.Arg_NoAccessSpec, nameof(bindingFlags));
-
-            // Provide a default binding mask if none is provided
-            if ((bindingFlags & MemberBindingMask) == 0)
-            {
-                bindingFlags |= BindingFlags.Instance | BindingFlags.Public;
-
-                if ((bindingFlags & BindingFlags.CreateInstance) == 0)
-                    bindingFlags |= BindingFlags.Static;
-            }
-
-            // There must not be more named parameters than provided arguments
-            if (namedParams != null)
-            {
-                if (providedArgs != null)
-                {
-                    if (namedParams.Length > providedArgs.Length)
-                        // "Named parameter array can not be bigger than argument array."
-                        throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams));
-                }
-                else
-                {
-                    if (namedParams.Length != 0)
-                        // "Named parameter array can not be bigger than argument array."
-                        throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams));
-                }
-            }
-            #endregion
-
-            #region Check that any named paramters are not null
-            if (namedParams != null && Array.IndexOf<string?>(namedParams, null) != -1)
-                // "Named parameter value must not be null."
-                throw new ArgumentException(SR.Arg_NamedParamNull, nameof(namedParams));
-            #endregion
-
-            int argCnt = (providedArgs != null) ? providedArgs.Length : 0;
-
-            #region Get a Binder
-            if (binder == null)
-                binder = DefaultBinder;
-
-            #endregion
-
-            #region Delegate to Activator.CreateInstance
-            if ((bindingFlags & BindingFlags.CreateInstance) != 0)
-            {
-                if ((bindingFlags & BindingFlags.CreateInstance) != 0 && (bindingFlags & BinderNonCreateInstance) != 0)
-                    // "Can not specify both CreateInstance and another access type."
-                    throw new ArgumentException(SR.Arg_CreatInstAccess, nameof(bindingFlags));
-
-                return Activator.CreateInstance(this, bindingFlags, binder, providedArgs, culture);
-            }
-            #endregion
-
-            // PutDispProperty and\or PutRefDispProperty ==> SetProperty.
-            if ((bindingFlags & (BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty)) != 0)
-                bindingFlags |= BindingFlags.SetProperty;
-
-            #region Name
-            if (name == null)
-                throw new ArgumentNullException(nameof(name));
-
-            if (name.Length == 0 || name.Equals(@"[DISPID=0]"))
-            {
-                name = GetDefaultMemberName() ?? "ToString"; // in InvokeMember we always pretend there is a default member if none is provided and we make it ToString
-            }
-            #endregion
-
-            #region GetField or SetField
-            bool IsGetField = (bindingFlags & BindingFlags.GetField) != 0;
-            bool IsSetField = (bindingFlags & BindingFlags.SetField) != 0;
-
-            if (IsGetField || IsSetField)
-            {
-                #region Preconditions
-                if (IsGetField)
-                {
-                    if (IsSetField)
-                        // "Can not specify both Get and Set on a field."
-                        throw new ArgumentException(SR.Arg_FldSetGet, nameof(bindingFlags));
-
-                    if ((bindingFlags & BindingFlags.SetProperty) != 0)
-                        // "Can not specify both GetField and SetProperty."
-                        throw new ArgumentException(SR.Arg_FldGetPropSet, nameof(bindingFlags));
-                }
-                else
-                {
-                    Debug.Assert(IsSetField);
-
-                    if (providedArgs == null)
-                        throw new ArgumentNullException(nameof(providedArgs));
-
-                    if ((bindingFlags & BindingFlags.GetProperty) != 0)
-                        // "Can not specify both SetField and GetProperty."
-                        throw new ArgumentException(SR.Arg_FldSetPropGet, nameof(bindingFlags));
-
-                    if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
-                        // "Can not specify Set on a Field and Invoke on a method."
-                        throw new ArgumentException(SR.Arg_FldSetInvoke, nameof(bindingFlags));
-                }
-                #endregion
-
-                #region Lookup Field
-                FieldInfo? selFld = null;
-                FieldInfo[]? flds = GetMember(name, MemberTypes.Field, bindingFlags) as FieldInfo[];
-
-                Debug.Assert(flds != null);
-
-                if (flds.Length == 1)
-                {
-                    selFld = flds[0];
-                }
-                else if (flds.Length > 0)
-                {
-                    selFld = binder.BindToField(bindingFlags, flds, IsGetField ? Empty.Value : providedArgs![0]!, culture);
-                }
-                #endregion
-
-                if (selFld != null)
-                {
-                    #region Invocation on a field
-                    if (selFld.FieldType.IsArray || ReferenceEquals(selFld.FieldType, typeof(System.Array)))
-                    {
-                        #region Invocation of an array Field
-                        int idxCnt;
-
-                        if ((bindingFlags & BindingFlags.GetField) != 0)
-                        {
-                            idxCnt = argCnt;
-                        }
-                        else
-                        {
-                            idxCnt = argCnt - 1;
-                        }
-
-                        if (idxCnt > 0)
-                        {
-                            // Verify that all of the index values are ints
-                            int[] idx = new int[idxCnt];
-                            for (int i = 0; i < idxCnt; i++)
-                            {
-                                try
-                                {
-                                    idx[i] = ((IConvertible)providedArgs![i]!).ToInt32(null);
-                                }
-                                catch (InvalidCastException)
-                                {
-                                    throw new ArgumentException(SR.Arg_IndexMustBeInt);
-                                }
-                            }
-
-                            // Set or get the value...
-                            Array a = (Array)selFld.GetValue(target)!;
-
-                            // Set or get the value in the array
-                            if ((bindingFlags & BindingFlags.GetField) != 0)
-                            {
-                                return a.GetValue(idx);
-                            }
-                            else
-                            {
-                                a.SetValue(providedArgs![idxCnt], idx);
-                                return null;
-                            }
-                        }
-                        #endregion
-                    }
-
-                    if (IsGetField)
-                    {
-                        #region Get the field value
-                        if (argCnt != 0)
-                            throw new ArgumentException(SR.Arg_FldGetArgErr, nameof(bindingFlags));
-
-                        return selFld.GetValue(target);
-                        #endregion
-                    }
-                    else
-                    {
-                        #region Set the field Value
-                        if (argCnt != 1)
-                            throw new ArgumentException(SR.Arg_FldSetArgErr, nameof(bindingFlags));
-
-                        selFld.SetValue(target, providedArgs![0], bindingFlags, binder, culture);
-
-                        return null;
-                        #endregion
-                    }
-                    #endregion
-                }
-
-                if ((bindingFlags & BinderNonFieldGetSet) == 0)
-                    throw new MissingFieldException(FullName, name);
-            }
-            #endregion
-
-            #region Caching Logic
-            /*
-            bool useCache = false;
-
-            // Note that when we add something to the cache, we are careful to ensure
-            // that the actual providedArgs matches the parameters of the method.  Otherwise,
-            // some default argument processing has occurred.  We don't want anyone
-            // else with the same (insufficient) number of actual arguments to get a
-            // cache hit because then they would bypass the default argument processing
-            // and the invocation would fail.
-            if (bDefaultBinder && namedParams == null && argCnt < 6)
-                useCache = true;
-
-            if (useCache)
-            {
-                MethodBase invokeMethod = GetMethodFromCache (name, bindingFlags, argCnt, providedArgs);
-
-                if (invokeMethod != null)
-                    return ((MethodInfo) invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture);
-            }
-            */
-            #endregion
-
-            #region Property PreConditions
-            // @Legacy - This is RTM behavior
-            bool isGetProperty = (bindingFlags & BindingFlags.GetProperty) != 0;
-            bool isSetProperty = (bindingFlags & BindingFlags.SetProperty) != 0;
-
-            if (isGetProperty || isSetProperty)
-            {
-                #region Preconditions
-                if (isGetProperty)
-                {
-                    Debug.Assert(!IsSetField);
-
-                    if (isSetProperty)
-                        throw new ArgumentException(SR.Arg_PropSetGet, nameof(bindingFlags));
-                }
-                else
-                {
-                    Debug.Assert(isSetProperty);
-
-                    Debug.Assert(!IsGetField);
-
-                    if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
-                        throw new ArgumentException(SR.Arg_PropSetInvoke, nameof(bindingFlags));
-                }
-                #endregion
-            }
-            #endregion
-
-            MethodInfo[]? finalists = null;
-            MethodInfo? finalist = null;
-
-            #region BindingFlags.InvokeMethod
-            if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
-            {
-                #region Lookup Methods
-                MethodInfo[] semiFinalists = (GetMember(name, MemberTypes.Method, bindingFlags) as MethodInfo[])!;
-                List<MethodInfo>? results = null;
-
-                for (int i = 0; i < semiFinalists.Length; i++)
-                {
-                    MethodInfo semiFinalist = semiFinalists[i];
-                    Debug.Assert(semiFinalist != null);
-
-                    if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
-                        continue;
-
-                    if (finalist == null)
-                    {
-                        finalist = semiFinalist;
-                    }
-                    else
-                    {
-                        results ??= new List<MethodInfo>(semiFinalists.Length) { finalist };
-                        results.Add(semiFinalist);
-                    }
-                }
-
-                if (results != null)
-                {
-                    Debug.Assert(results.Count > 1);
-                    finalists = new MethodInfo[results.Count];
-                    results.CopyTo(finalists);
-                }
-                #endregion
-            }
-            #endregion
-
-            Debug.Assert(finalists == null || finalist != null);
-
-            #region BindingFlags.GetProperty or BindingFlags.SetProperty
-            if (finalist == null && isGetProperty || isSetProperty)
-            {
-                #region Lookup Property
-                PropertyInfo[] semiFinalists = (GetMember(name, MemberTypes.Property, bindingFlags) as PropertyInfo[])!;
-                List<MethodInfo>? results = null;
-
-                for (int i = 0; i < semiFinalists.Length; i++)
-                {
-                    MethodInfo? semiFinalist = null;
-
-                    if (isSetProperty)
-                    {
-                        semiFinalist = semiFinalists[i].GetSetMethod(true);
-                    }
-                    else
-                    {
-                        semiFinalist = semiFinalists[i].GetGetMethod(true);
-                    }
-
-                    if (semiFinalist == null)
-                        continue;
-
-                    if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
-                        continue;
-
-                    if (finalist == null)
-                    {
-                        finalist = semiFinalist;
-                    }
-                    else
-                    {
-                        results ??= new List<MethodInfo>(semiFinalists.Length) { finalist };
-                        results.Add(semiFinalist);
-                    }
-                }
-
-                if (results != null)
-                {
-                    Debug.Assert(results.Count > 1);
-                    finalists = new MethodInfo[results.Count];
-                    results.CopyTo(finalists);
-                }
-                #endregion
-            }
-            #endregion
-
-            if (finalist != null)
-            {
-                #region Invoke
-                if (finalists == null &&
-                    argCnt == 0 &&
-                    finalist.GetParametersNoCopy().Length == 0 &&
-                    (bindingFlags & BindingFlags.OptionalParamBinding) == 0)
-                {
-                    //if (useCache && argCnt == props[0].GetParameters().Length)
-                    //    AddMethodToCache(name, bindingFlags, argCnt, providedArgs, props[0]);
-
-                    return finalist.Invoke(target, bindingFlags, binder, providedArgs, culture);
-                }
-
-                finalists ??= new MethodInfo[] { finalist };
-                providedArgs ??= Array.Empty<object>();
-
-                object? state = null;
-
-
-                MethodBase? invokeMethod = null;
-
-                try { invokeMethod = binder.BindToMethod(bindingFlags, finalists, ref providedArgs, modifiers, culture, namedParams, out state); }
-                catch (MissingMethodException) { }
-
-                if (invokeMethod == null)
-                    throw new MissingMethodException(FullName, name);
-
-                //if (useCache && argCnt == invokeMethod.GetParameters().Length)
-                //    AddMethodToCache(name, bindingFlags, argCnt, providedArgs, invokeMethod);
-
-                object? result = ((MethodInfo)invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture);
-
-                if (state != null)
-                    binder.ReorderArgumentArray(ref providedArgs, state);
-
-                return result;
-                #endregion
-            }
-
-            throw new MissingMethodException(FullName, name);
-        }
-        #endregion
-
         public static bool operator ==(RuntimeType? left, RuntimeType? right)
         {
             return ReferenceEquals(left, right);