Пример #1
0
        protected Delegate([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type target, string method)
        {
            if (target is null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            if (target.ContainsGenericParameters)
            {
                throw new ArgumentException(SR.Arg_UnboundGenParam, nameof(target));
            }

            if (method is null)
            {
                throw new ArgumentNullException(nameof(method));
            }

            if (!target.IsRuntimeImplemented())
            {
                throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(target));
            }

            this.data = new DelegateData()
            {
                method_name = method,
                target_type = target
            };
        }
Пример #2
0
        protected Delegate(object target, string method)
        {
            ArgumentNullException.ThrowIfNull(target);
            ArgumentNullException.ThrowIfNull(method);

            this._target = target;
            this.data    = new DelegateData()
            {
                method_name = method
            };
        }
Пример #3
0
#pragma warning restore 169, 414, 649
		#endregion

		protected Delegate (object target, string method)
		{
			if (target == null)
				throw new ArgumentNullException ("target");

			if (method == null)
				throw new ArgumentNullException ("method");

			this.m_target = target;
			this.data = new DelegateData ();
			this.data.method_name = method;
		}
Пример #4
0
        protected Delegate(Type target, string method)
        {
            if (target == null)
            {
                throw new ArgumentNullException("target");
            }

            if (method == null)
            {
                throw new ArgumentNullException("method");
            }

            this.data             = new DelegateData();
            this.data.method_name = method;
            this.data.target_type = target;
        }
Пример #5
0
        protected Delegate(object target, string method)
        {
            if (target is null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            if (method is null)
            {
                throw new ArgumentNullException(nameof(method));
            }

            this._target = target;
            this.data    = new DelegateData()
            {
                method_name = method
            };
        }
Пример #6
0
        void InitializeDelegateData()
        {
            DelegateData delegate_data = new DelegateData();

            if (method_info.IsStatic)
            {
                if (m_target != null)
                {
                    delegate_data.curried_first_arg = true;
                }
                else
                {
                    MethodInfo invoke = GetType().GetMethod("Invoke");
                    if (invoke.GetParametersCount() + 1 == method_info.GetParametersCount())
                    {
                        delegate_data.curried_first_arg = true;
                    }
                }
            }
            this.data = delegate_data;
        }
Пример #7
0
        private DelegateData CreateDelegateData()
        {
            DelegateData delegate_data = new DelegateData();

            if (method_info !.IsStatic)
            {
                if (_target != null)
                {
                    delegate_data.curried_first_arg = true;
                }
                else
                {
                    MethodInfo?invoke = GetType().GetMethod("Invoke");
                    if (invoke != null && invoke.GetParametersCount() + 1 == method_info.GetParametersCount())
                    {
                        delegate_data.curried_first_arg = true;
                    }
                }
            }

            return(delegate_data);
        }
Пример #8
0
        static Delegate CreateDelegate(Type type, object firstArgument, MethodInfo method, bool throwOnBindFailure, bool allowClosed)
        {
            // The name of the parameter changed in 2.0
            object target = firstArgument;

            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            if (method == null)
            {
                throw new ArgumentNullException("method");
            }

            if (!type.IsSubclassOf(typeof(MulticastDelegate)))
            {
                throw new ArgumentException("type is not a subclass of Multicastdelegate");
            }

            MethodInfo invoke = type.GetMethod("Invoke");

            if (!return_type_match(invoke.ReturnType, method.ReturnType))
            {
                if (throwOnBindFailure)
                {
                    throw new ArgumentException("method return type is incompatible");
                }
                else
                {
                    return(null);
                }
            }

            ParameterInfo[] delargs = invoke.GetParametersInternal();
            ParameterInfo[] args    = method.GetParametersInternal();

            bool argLengthMatch;

            if (target != null)
            {
                // delegate closed over target
                if (!method.IsStatic)
                {
                    // target is passed as this
                    argLengthMatch = (args.Length == delargs.Length);
                }
                else
                {
                    // target is passed as the first argument to the static method
                    argLengthMatch = (args.Length == delargs.Length + 1);
                }
            }
            else
            {
                if (!method.IsStatic)
                {
                    //
                    // Net 2.0 feature. The first argument of the delegate is passed
                    // as the 'this' argument to the method.
                    //
                    argLengthMatch = (args.Length + 1 == delargs.Length);

                    if (!argLengthMatch)
                    {
                        // closed over a null reference
                        argLengthMatch = (args.Length == delargs.Length);
                    }
                }
                else
                {
                    argLengthMatch = (args.Length == delargs.Length);

                    if (!argLengthMatch)
                    {
                        // closed over a null reference
                        argLengthMatch = args.Length == delargs.Length + 1;
                    }
                }
            }
            if (!argLengthMatch)
            {
                if (throwOnBindFailure)
                {
                    throw new ArgumentException("method argument length mismatch");
                }
                else
                {
                    return(null);
                }
            }

            bool         argsMatch;
            DelegateData delegate_data = new DelegateData();

            if (target != null)
            {
                if (!method.IsStatic)
                {
                    argsMatch = arg_type_match_this(target.GetType(), method.DeclaringType, true);
                    for (int i = 0; i < args.Length; i++)
                    {
                        argsMatch &= arg_type_match(delargs [i].ParameterType, args [i].ParameterType);
                    }
                }
                else
                {
                    argsMatch = arg_type_match(target.GetType(), args [0].ParameterType);
                    for (int i = 1; i < args.Length; i++)
                    {
                        argsMatch &= arg_type_match(delargs [i - 1].ParameterType, args [i].ParameterType);
                    }

                    delegate_data.curried_first_arg = true;
                }
            }
            else
            {
                if (!method.IsStatic)
                {
                    if (args.Length + 1 == delargs.Length)
                    {
                        // The first argument should match this
                        argsMatch = arg_type_match_this(delargs [0].ParameterType, method.DeclaringType, false);
                        for (int i = 0; i < args.Length; i++)
                        {
                            argsMatch &= arg_type_match(delargs [i + 1].ParameterType, args [i].ParameterType);
                        }
                    }
                    else
                    {
                        // closed over a null reference
                        argsMatch = allowClosed;
                        for (int i = 0; i < args.Length; i++)
                        {
                            argsMatch &= arg_type_match(delargs [i].ParameterType, args [i].ParameterType);
                        }
                    }
                }
                else
                {
                    if (delargs.Length + 1 == args.Length)
                    {
                        // closed over a null reference
                        argsMatch = !(args [0].ParameterType.IsValueType || args [0].ParameterType.IsByRef) && allowClosed;
                        for (int i = 0; i < delargs.Length; i++)
                        {
                            argsMatch &= arg_type_match(delargs [i].ParameterType, args [i + 1].ParameterType);
                        }

                        delegate_data.curried_first_arg = true;
                    }
                    else
                    {
                        argsMatch = true;
                        for (int i = 0; i < args.Length; i++)
                        {
                            argsMatch &= arg_type_match(delargs [i].ParameterType, args [i].ParameterType);
                        }
                    }
                }
            }

            if (!argsMatch)
            {
                if (throwOnBindFailure)
                {
                    throw new ArgumentException("method arguments are incompatible");
                }
                else
                {
                    return(null);
                }
            }

            Delegate d = CreateDelegate_internal(type, target, method, throwOnBindFailure);

            if (d != null)
            {
                d.original_method_info = method;
            }
            if (delegate_data != null)
            {
                d.data = delegate_data;
            }
            return(d);
        }
Пример #9
0
		static Delegate CreateDelegate (Type type, object firstArgument, MethodInfo method, bool throwOnBindFailure, bool allowClosed)
		{
			// The name of the parameter changed in 2.0
			object target = firstArgument;

			if (type == null)
				throw new ArgumentNullException ("type");

			if (method == null)
				throw new ArgumentNullException ("method");

			if (!type.IsSubclassOf (typeof (MulticastDelegate)))
				throw new ArgumentException ("type is not a subclass of Multicastdelegate");

			MethodInfo invoke = type.GetMethod ("Invoke");

			if (!return_type_match (invoke.ReturnType, method.ReturnType))
				if (throwOnBindFailure)
					throw new ArgumentException ("method return type is incompatible");
				else
					return null;

			ParameterInfo[] delargs = invoke.GetParametersInternal ();
			ParameterInfo[] args = method.GetParametersInternal ();

			bool argLengthMatch;

			if (target != null) {
				// delegate closed over target
				if (!method.IsStatic)
					// target is passed as this
					argLengthMatch = (args.Length == delargs.Length);
				else
					// target is passed as the first argument to the static method
					argLengthMatch = (args.Length == delargs.Length + 1);
			} else {
				if (!method.IsStatic) {
					//
					// Net 2.0 feature. The first argument of the delegate is passed
					// as the 'this' argument to the method.
					//
					argLengthMatch = (args.Length + 1 == delargs.Length);

					if (!argLengthMatch)
						// closed over a null reference
						argLengthMatch = (args.Length == delargs.Length);
				} else {
					argLengthMatch = (args.Length == delargs.Length);

					if (!argLengthMatch)
						// closed over a null reference
						argLengthMatch = args.Length == delargs.Length + 1;
				}
			}
			if (!argLengthMatch)
				if (throwOnBindFailure)
					throw new ArgumentException ("method argument length mismatch");
				else
					return null;

			bool argsMatch;
			DelegateData delegate_data = new DelegateData ();

			if (target != null) {
				if (!method.IsStatic) {
					argsMatch = arg_type_match_this (target.GetType (), method.DeclaringType, true);
					for (int i = 0; i < args.Length; i++)
						argsMatch &= arg_type_match (delargs [i].ParameterType, args [i].ParameterType);
				} else {
					argsMatch = arg_type_match (target.GetType (), args [0].ParameterType);
					for (int i = 1; i < args.Length; i++)
						argsMatch &= arg_type_match (delargs [i - 1].ParameterType, args [i].ParameterType);

					delegate_data.curried_first_arg = true;
				}
			} else {
				if (!method.IsStatic) {
					if (args.Length + 1 == delargs.Length) {
						// The first argument should match this
						argsMatch = arg_type_match_this (delargs [0].ParameterType, method.DeclaringType, false);
						for (int i = 0; i < args.Length; i++)
							argsMatch &= arg_type_match (delargs [i + 1].ParameterType, args [i].ParameterType);
					} else {
						// closed over a null reference
						argsMatch = allowClosed;
						for (int i = 0; i < args.Length; i++)
							argsMatch &= arg_type_match (delargs [i].ParameterType, args [i].ParameterType);
					}
				} else {
					if (delargs.Length + 1 == args.Length) {
						// closed over a null reference
						argsMatch = !(args [0].ParameterType.IsValueType || args [0].ParameterType.IsByRef) && allowClosed;
						for (int i = 0; i < delargs.Length; i++)
							argsMatch &= arg_type_match (delargs [i].ParameterType, args [i + 1].ParameterType);

						delegate_data.curried_first_arg = true;
					} else {
						argsMatch = true;
						for (int i = 0; i < args.Length; i++)
							argsMatch &= arg_type_match (delargs [i].ParameterType, args [i].ParameterType);
					}
				}
			}

			if (!argsMatch)
				if (throwOnBindFailure)
					throw new ArgumentException ("method arguments are incompatible");
				else
					return null;

			Delegate d = CreateDelegate_internal (type, target, method, throwOnBindFailure);
			throw new NotImplementedException();
			return d;
		}
Пример #10
0
        protected virtual object?DynamicInvokeImpl(object?[]?args)
        {
            MethodInfo _method = Method ?? throw new NullReferenceException("method_info is null");

            object?target = _target;

            if (data is null)
            {
                data = CreateDelegateData();
            }

            // replace all Type.Missing with default values defined on parameters of the delegate if any
            MethodInfo?invoke = GetType().GetMethod("Invoke");

            if (invoke != null && args != null)
            {
                ParameterInfo[] delegateParameters = invoke.GetParameters();
                for (int i = 0; i < args.Length; i++)
                {
                    if (args[i] == Type.Missing)
                    {
                        ParameterInfo dlgParam = delegateParameters[i];
                        if (dlgParam.HasDefaultValue)
                        {
                            args[i] = dlgParam.DefaultValue;
                        }
                    }
                }
            }

            if (_method.IsStatic)
            {
                //
                // The delegate is bound to _target
                //
                if (data.curried_first_arg)
                {
                    if (args is null)
                    {
                        args = new object?[] { target };
                    }
                    else
                    {
                        Array.Resize(ref args, args.Length + 1);
                        Array.Copy(args, 0, args, 1, args.Length - 1);
                        args[0] = target;
                    }

                    target = null;
                }
            }
            else
            {
                if (_target is null && args?.Length > 0)
                {
                    target = args[0];
                    Array.Copy(args, 1, args, 0, args.Length - 1);
                    Array.Resize(ref args, args.Length - 1);
                }
            }

            return(_method.Invoke(target, args));
        }
Пример #11
0
        private static bool IsMatchingCandidate(RuntimeType type, object?target, MethodInfo method, bool allowClosed, out DelegateData?delegateData)
        {
            MethodInfo?invoke = GetDelegateInvokeMethod(type);

            if (invoke == null || !IsReturnTypeMatch(invoke.ReturnType !, method.ReturnType !))
            {
                delegateData = null;
                return(false);
            }

            ParameterInfo[] delargs = invoke.GetParametersInternal();
            ParameterInfo[] args    = method.GetParametersInternal();

            bool argLengthMatch;

            if (target != null)
            {
                // delegate closed over target
                if (!method.IsStatic)
                {
                    // target is passed as this
                    argLengthMatch = (args.Length == delargs.Length);
                }
                else
                {
                    // target is passed as the first argument to the static method
                    argLengthMatch = (args.Length == delargs.Length + 1);
                }
            }
            else
            {
                if (!method.IsStatic)
                {
                    //
                    // Net 2.0 feature. The first argument of the delegate is passed
                    // as the 'this' argument to the method.
                    //
                    argLengthMatch = (args.Length + 1 == delargs.Length);

                    if (!argLengthMatch)
                    {
                        // closed over a null reference
                        argLengthMatch = (args.Length == delargs.Length);
                    }
                }
                else
                {
                    argLengthMatch = (args.Length == delargs.Length);

                    if (!argLengthMatch)
                    {
                        // closed over a null reference
                        argLengthMatch = args.Length == delargs.Length + 1;
                    }
                }
            }

            if (!argLengthMatch)
            {
                delegateData = null;
                return(false);
            }

            bool argsMatch;

            delegateData = new DelegateData();

            if (target != null)
            {
                if (!method.IsStatic)
                {
                    argsMatch = IsArgumentTypeMatchWithThis(target.GetType(), method.DeclaringType !, true);
                    for (int i = 0; i < args.Length; i++)
                    {
                        argsMatch &= IsArgumentTypeMatch(delargs[i].ParameterType, args[i].ParameterType);
                    }
                }
                else
                {
                    argsMatch = IsArgumentTypeMatch(target.GetType(), args[0].ParameterType);
                    for (int i = 1; i < args.Length; i++)
                    {
                        argsMatch &= IsArgumentTypeMatch(delargs[i - 1].ParameterType, args[i].ParameterType);
                    }

                    delegateData.curried_first_arg = true;
                }
            }
            else
            {
                if (!method.IsStatic)
                {
                    if (args.Length + 1 == delargs.Length)
                    {
                        // The first argument should match this
                        argsMatch = IsArgumentTypeMatchWithThis(delargs[0].ParameterType, method.DeclaringType !, false);
                        for (int i = 0; i < args.Length; i++)
                        {
                            argsMatch &= IsArgumentTypeMatch(delargs[i + 1].ParameterType, args[i].ParameterType);
                        }
                    }
                    else
                    {
                        // closed over a null reference
                        argsMatch = allowClosed;
                        for (int i = 0; i < args.Length; i++)
                        {
                            argsMatch &= IsArgumentTypeMatch(delargs[i].ParameterType, args[i].ParameterType);
                        }
                    }
                }
                else
                {
                    if (delargs.Length + 1 == args.Length)
                    {
                        // closed over a null reference
                        argsMatch = !(args[0].ParameterType.IsValueType || args[0].ParameterType.IsByRef) && allowClosed;
                        for (int i = 0; i < delargs.Length; i++)
                        {
                            argsMatch &= IsArgumentTypeMatch(delargs[i].ParameterType, args[i + 1].ParameterType);
                        }

                        delegateData.curried_first_arg = true;
                    }
                    else
                    {
                        argsMatch = true;
                        for (int i = 0; i < args.Length; i++)
                        {
                            argsMatch &= IsArgumentTypeMatch(delargs[i].ParameterType, args[i].ParameterType);
                        }
                    }
                }
            }

            return(argsMatch);
        }
Пример #12
0
		void InitializeDelegateData ()
		{
			DelegateData delegate_data = new DelegateData ();
			if (method_info.IsStatic) {
				if (m_target != null) {
					delegate_data.curried_first_arg = true;
				} else {
					MethodInfo invoke = GetType ().GetMethod ("Invoke");
					if (invoke.GetParametersCount () + 1 == method_info.GetParametersCount ())
						delegate_data.curried_first_arg = true;
				}
			}
			this.data = delegate_data;
		}
Пример #13
0
 public IAsyncResult BeginData(string data, AsyncCallback callback)
 {
     this._delegateData = this.Data;
     return this._delegateData.BeginInvoke(data, callback, null);
 }
        internal CallConversionParameters(CallConversionInfo conversionInfo, IntPtr callerTransitionBlockParam)
        {
            // Make sure the thred static variable has been initialized for this thread
            s_pinnedGCHandles = s_pinnedGCHandles ?? new GCHandleContainer();

            _conversionInfo = conversionInfo;
            _callerTransitionBlock = (byte*)callerTransitionBlockParam.ToPointer();
            _functionPointerToCall = conversionInfo.TargetFunctionPointer;
            _instantiatingStubArgument = conversionInfo.InstantiatingStubArgument;
            _delegateData = default(DelegateData);
            _calleeArgs = default(ArgIterator);
            _invokeReturnValue = IntPtr.Zero;
            _copyReturnValue = true;
            _dynamicInvokeParams = null;
            _dynamicInvokeByRefObjectArgs = null;

            // 
            // Setup input argument iterator for the caller
            //
            ArgIteratorData callerIteratorData;

            if (conversionInfo.IsDelegateDynamicInvokeThunk)
                callerIteratorData = s_delegateDynamicInvokeImplArgIteratorData;
            else if (conversionInfo.IsReflectionDynamicInvokerThunk)
                callerIteratorData = s_reflectionDynamicInvokeImplArgIteratorData;
            else
                callerIteratorData = conversionInfo.ArgIteratorData;

            _callerArgs = new ArgIterator(callerIteratorData,
                                              callerIteratorData.HasThis() ?
                                                CallingConvention.ManagedInstance :
                                                CallingConvention.ManagedStatic,
                                              conversionInfo.CallerHasParamType,
                                              conversionInfo.CallerHasExtraParameterWhichIsFunctionTarget,
                                              conversionInfo.CallerForcedByRefData,
                                              false, false); // Setup input

            bool forceCalleeHasParamType = false;

            // If the callee MAY have a param type, we need to know before we create the callee arg iterator
            // To do this we need to actually load the target address and see if it has the generic method pointer
            // bit set.
            if (conversionInfo.CalleeMayHaveParamType)
            {
                ArgIterator callerArgsLookupTargetFunctionPointer = new ArgIterator(conversionInfo.ArgIteratorData,
                                                                                        conversionInfo.ArgIteratorData.HasThis() ?
                                                                                            CallingConvention.ManagedInstance :
                                                                                            CallingConvention.ManagedStatic,
                                                                                        conversionInfo.CallerHasParamType,
                                                                                        conversionInfo.CallerHasExtraParameterWhichIsFunctionTarget,
                                                                                        conversionInfo.CallerForcedByRefData,
                                                                                        false, false);

                // Find the last valid caller offset. That's the offset of the target function pointer.
                int ofsCallerValid = TransitionBlock.InvalidOffset;
                while (true)
                {
                    // Setup argument offsets.
                    int ofsCallerTemp = callerArgsLookupTargetFunctionPointer.GetNextOffset();

                    // Check to see if we've handled all the arguments that we are to pass to the callee. 
                    if (TransitionBlock.InvalidOffset == ofsCallerTemp)
                        break;

                    ofsCallerValid = ofsCallerTemp;
                }

                if (ofsCallerValid == TransitionBlock.InvalidOffset)
                    throw new InvalidProgramException();

                int stackSizeCaller = callerArgsLookupTargetFunctionPointer.GetArgSize();
                Debug.Assert(stackSizeCaller == IntPtr.Size);
                void* pSrc = _callerTransitionBlock + ofsCallerValid;
                IntPtr tempFunctionPointer = *((IntPtr*)pSrc);

                forceCalleeHasParamType = UpdateCalleeFunctionPointer(tempFunctionPointer);
            }

            // Retrieve target function pointer and instantiation argument for delegate thunks
            if (conversionInfo.IsDelegateThunk)
            {
                Debug.Assert(_callerArgs.HasThis() && !_conversionInfo.IsUnboxingThunk);

                IntPtr locationOfThisPointer = (IntPtr)(_callerTransitionBlock + ArgIterator.GetThisOffset());
                _delegateData._delegateObject = (Delegate)Unsafe.As<IntPtr, Object>(ref *(IntPtr*)locationOfThisPointer);
                Debug.Assert(_delegateData._delegateObject != null);

                RuntimeAugments.GetDelegateData(
                    _delegateData._delegateObject,
                    out _delegateData._firstParameter,
                    out _delegateData._helperObject,
                    out _delegateData._extraFunctionPointerOrData,
                    out _delegateData._functionPointer);

                if (conversionInfo.TargetDelegateFunctionIsExtraFunctionPointerOrDataField)
                {
                    if (conversionInfo.IsOpenInstanceDelegateThunk)
                    {
                        _delegateData._boxedFirstParameter = BoxedCallerFirstArgument;
                        Debug.Assert(_delegateData._boxedFirstParameter != null);
                        _callerArgs.Reset();

                        IntPtr resolvedTargetFunctionPointer = OpenMethodResolver.ResolveMethod(_delegateData._extraFunctionPointerOrData, _delegateData._boxedFirstParameter);
                        forceCalleeHasParamType = UpdateCalleeFunctionPointer(resolvedTargetFunctionPointer);
                    }
                    else
                    {
                        forceCalleeHasParamType = UpdateCalleeFunctionPointer(_delegateData._extraFunctionPointerOrData);
                    }
                }
                else if (conversionInfo.IsMulticastDelegate)
                {
                    _delegateData._multicastTargetCount = (int)_delegateData._extraFunctionPointerOrData;
                }
            }

            // 
            // Setup output argument iterator for the callee
            //
            _calleeArgs = new ArgIterator(conversionInfo.ArgIteratorData,
                                                (conversionInfo.ArgIteratorData.HasThis() && !conversionInfo.IsStaticDelegateThunk) ?
                                                    CallingConvention.ManagedInstance :
                                                    CallingConvention.ManagedStatic,
                                                forceCalleeHasParamType || conversionInfo.CalleeHasParamType,
                                                false,
                                                conversionInfo.CalleeForcedByRefData,
                                                conversionInfo.IsOpenInstanceDelegateThunk,
                                                conversionInfo.IsClosedStaticDelegate);

            // The function pointer, 'hasParamType', and 'hasThis' flags for the callee arg iterator need to be computed/read from the caller's 
            // input arguments in the case of a reflection invoker thunk (the target method pointer and 'hasThis' flags are
            // passed in as parameters from the caller, not loaded from a static method signature in native layout)
            if (conversionInfo.IsReflectionDynamicInvokerThunk)
                ComputeCalleeFlagsAndFunctionPointerForReflectionInvokeThunk();

#if CALLINGCONVENTION_CALLEE_POPS
            // Ensure that the count of bytes in the stack is available
            _callerArgs.CbStackPop();
#endif
        }