Пример #1
0
        protected sealed override void SetFieldBypassCctor(Object obj, Object value, BinderBundle binderBundle)
        {
            value = RuntimeAugments.CheckArgument(value, FieldTypeHandle, binderBundle);
            IntPtr fieldAddress = RuntimeAugments.GetThreadStaticFieldAddress(_declaringTypeHandle, _cookie);

            RuntimeAugments.StoreValueTypeField(fieldAddress, value, FieldTypeHandle);
        }
Пример #2
0
        public static object CallDynamicInvokeMethod(
            object thisPtr,
            IntPtr methodToCall,
            object thisPtrDynamicInvokeMethod,
            IntPtr dynamicInvokeHelperMethod,
            IntPtr dynamicInvokeHelperGenericDictionary,
            object defaultParametersContext,
            object[] parameters,
            BinderBundle binderBundle,
            bool wrapInTargetInvocationException,
            bool invokeMethodHelperIsThisCall,
            bool methodToCallIsThisCall)
        {
            object result = InvokeUtils.CallDynamicInvokeMethod(
                thisPtr,
                methodToCall,
                thisPtrDynamicInvokeMethod,
                dynamicInvokeHelperMethod,
                dynamicInvokeHelperGenericDictionary,
                defaultParametersContext,
                parameters,
                binderBundle,
                wrapInTargetInvocationException,
                invokeMethodHelperIsThisCall,
                methodToCallIsThisCall);

            System.Diagnostics.DebugAnnotations.PreviousCallContainsDebuggerStepInCode();
            return(result);
        }
        public sealed override Object Invoke(Object thisObject, Object[] arguments, BinderBundle binderBundle)
        {
            switch (_id)
            {
            case StringConstructorId.CharArray:
            {
                CheckArgumentCount(arguments, 1);
                char[] value = (char[])(RuntimeAugments.CheckArgument(arguments[0], typeof(char[]).TypeHandle, binderBundle));
                return(new String(value));
            }

            case StringConstructorId.Char_Int:
            {
                CheckArgumentCount(arguments, 2);
                char c     = (char)(RuntimeAugments.CheckArgument(arguments[0], typeof(char).TypeHandle, binderBundle));
                int  count = (int)(RuntimeAugments.CheckArgument(arguments[1], typeof(int).TypeHandle, binderBundle));
                return(new String(c, count));
            }

            case StringConstructorId.CharArray_Int_Int:
            {
                CheckArgumentCount(arguments, 3);
                char[] value      = (char[])(RuntimeAugments.CheckArgument(arguments[0], typeof(char[]).TypeHandle, binderBundle));
                int    startIndex = (int)(RuntimeAugments.CheckArgument(arguments[1], typeof(int).TypeHandle, binderBundle));
                int    length     = (int)(RuntimeAugments.CheckArgument(arguments[2], typeof(int).TypeHandle, binderBundle));
                return(new String(value, startIndex, length));
            }

            default:
                throw new InvalidOperationException();
            }
        }
Пример #4
0
        public sealed override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture)
        {
            FieldAccessor fieldAccessor = this.FieldAccessor;
            BinderBundle  binderBundle  = binder.ToBinderBundle(invokeAttr, culture);

            fieldAccessor.SetField(obj, value, binderBundle);
        }
Пример #5
0
        protected sealed override void SetFieldBypassCctor(Object obj, Object value, BinderBundle binderBundle)
        {
            value = RuntimeAugments.CheckArgument(value, FieldTypeHandle, binderBundle);
            IntPtr tlsFieldsStartAddress = RuntimeAugments.GetThreadStaticFieldAddress(_declaringTypeHandle, IntPtr.Zero);
            IntPtr fieldAddress          = tlsFieldsStartAddress + _fieldOffset;

            RuntimeAugments.StoreReferenceTypeField(fieldAddress, value);
        }
Пример #6
0
        public Object Invoke(Object thisObject, Object[] arguments, Binder binder, BindingFlags invokeAttr, CultureInfo cultureInfo)
        {
            BinderBundle binderBundle = binder.ToBinderBundle(invokeAttr, cultureInfo);
            Object       result       = Invoke(thisObject, arguments, binderBundle);

            System.Diagnostics.DebugAnnotations.PreviousCallContainsDebuggerStepInCode();
            return(result);
        }
Пример #7
0
 public sealed override void SetField(Object obj, Object value, BinderBundle binderBundle)
 {
     if (_cctorContext != IntPtr.Zero)
     {
         RuntimeAugments.EnsureClassConstructorRun(_cctorContext);
     }
     SetFieldBypassCctor(obj, value, binderBundle);
 }
Пример #8
0
        public object Invoke(object thisObject, object[] arguments, Binder binder, BindingFlags invokeAttr, CultureInfo cultureInfo)
        {
            BinderBundle binderBundle = binder.ToBinderBundle(invokeAttr, cultureInfo);
            bool         wrapInTargetInvocationException = (invokeAttr & BindingFlags.DoNotWrapExceptions) == 0;
            object       result = Invoke(thisObject, arguments, binderBundle, wrapInTargetInvocationException);

            System.Diagnostics.DebugAnnotations.PreviousCallContainsDebuggerStepInCode();
            return(result);
        }
Пример #9
0
        protected sealed override void SetFieldBypassCctor(object value, BinderBundle binderBundle)
        {
            value = RuntimeAugments.CheckArgument(value, FieldTypeHandle, binderBundle);

            if (IsFieldInitOnly)
            {
                throw new FieldAccessException(SR.Acc_InitOnlyStatic);
            }

            UncheckedSetFieldBypassCctor(value);
        }
Пример #10
0
 public sealed override void SetField(Object obj, Object value, BinderBundle binderBundle)
 {
     if (obj == null)
     {
         throw new TargetException(SR.RFLCT_Targ_StatFldReqTarg);
     }
     if (!RuntimeAugments.IsAssignable(obj, this.DeclaringTypeHandle))
     {
         throw new ArgumentException();
     }
     value = RuntimeAugments.CheckArgument(value, this.FieldTypeHandle, binderBundle);
     UncheckedSetField(obj, value);
 }
Пример #11
0
        public sealed override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture)
        {
#if ENABLE_REFLECTION_TRACE
            if (ReflectionTrace.Enabled)
            {
                ReflectionTrace.FieldInfo_SetValue(this, obj, value);
            }
#endif

            FieldAccessor fieldAccessor = this.FieldAccessor;
            BinderBundle  binderBundle  = binder.ToBinderBundle(invokeAttr, culture);
            fieldAccessor.SetField(obj, value, binderBundle);
        }
Пример #12
0
        public sealed override Object Invoke(Object thisObject, Object[] arguments, BinderBundle binderBundle)
        {
            object result = RuntimeAugments.CallDynamicInvokeMethod(
                thisObject,
                MethodInvokeInfo.LdFtnResult,
                null /*thisPtrDynamicInvokeMethod*/,
                MethodInvokeInfo.DynamicInvokeMethod,
                MethodInvokeInfo.DynamicInvokeGenericDictionary,
                MethodInvokeInfo.MethodInfo,
                arguments,
                binderBundle,
                invokeMethodHelperIsThisCall: false,
                methodToCallIsThisCall: false);

            System.Diagnostics.DebugAnnotations.PreviousCallContainsDebuggerStepInCode();
            return(result);
        }
Пример #13
0
        public sealed override Object Invoke(Object thisObject, Object[] arguments, BinderBundle binderBundle)
        {
            MethodInvokerUtils.ValidateThis(thisObject, _declaringTypeHandle);

            IntPtr resolvedVirtual = OpenMethodResolver.ResolveMethod(MethodInvokeInfo.VirtualResolveData, thisObject);

            Object result = RuntimeAugments.CallDynamicInvokeMethod(
                thisObject,
                resolvedVirtual,
                null /*thisPtrDynamicInvokeMethod*/,
                MethodInvokeInfo.DynamicInvokeMethod,
                MethodInvokeInfo.DynamicInvokeGenericDictionary,
                MethodInvokeInfo.MethodInfo,
                arguments,
                binderBundle,
                invokeMethodHelperIsThisCall: false,
                methodToCallIsThisCall: true);

            System.Diagnostics.DebugAnnotations.PreviousCallContainsDebuggerStepInCode();
            return(result);
        }
Пример #14
0
        public override Object Invoke(Object thisObject, Object[] arguments, BinderBundle binderBundle)
        {
            //@todo: This does not handle optional parameters (nor does it need to as today we're only using it for three synthetic array methods.)
            if (!(thisObject == null && 0 != (_options & InvokerOptions.AllowNullThis)))
            {
                MethodInvokerUtils.ValidateThis(thisObject, _thisType);
            }
            if (arguments == null)
            {
                arguments = Array.Empty <Object>();
            }
            if (arguments.Length != _parameterTypes.Length)
            {
                throw new TargetParameterCountException();
            }
            Object[] convertedArguments = new Object[arguments.Length];
            for (int i = 0; i < arguments.Length; i++)
            {
                convertedArguments[i] = RuntimeAugments.CheckArgument(arguments[i], _parameterTypes[i], binderBundle);
            }
            Object result;

            try
            {
                result = _invoker(thisObject, convertedArguments);
            }
            catch (Exception e)
            {
                if (0 != (_options & InvokerOptions.DontWrapException))
                {
                    throw;
                }
                else
                {
                    throw new TargetInvocationException(e);
                }
            }
            return(result);
        }
Пример #15
0
        internal static object CallDynamicInvokeMethod(
            object thisPtr,
            IntPtr methodToCall,
            object thisPtrDynamicInvokeMethod,
            IntPtr dynamicInvokeHelperMethod,
            IntPtr dynamicInvokeHelperGenericDictionary,
            object targetMethodOrDelegate,
            object[] parameters,
            BinderBundle binderBundle,
            bool wrapInTargetInvocationException,
            bool invokeMethodHelperIsThisCall = true,
            bool methodToCallIsThisCall       = true)
        {
            // This assert is needed because we've double-purposed "targetMethodOrDelegate" (which is actually a MethodBase anytime a custom binder is used)
            // as a way of obtaining the true parameter type which we need to pass to Binder.ChangeType(). (The type normally passed to DynamicInvokeParamHelperCore
            // isn't always the exact type (byref stripped off, enums converted to int, etc.)
            Debug.Assert(!(binderBundle != null && !(targetMethodOrDelegate is MethodBase)), "The only callers that can pass a custom binder are those servicing MethodBase.Invoke() apis.");

            bool          parametersNeedCopyBack = false;
            ArgSetupState argSetupState          = default(ArgSetupState);

            // Capture state of thread static invoke helper statics
            object[]     parametersOld = s_parameters;
            object[]     nullableCopyBackObjectsOld = s_nullableCopyBackObjects;
            int          curIndexOld = s_curIndex;
            object       targetMethodOrDelegateOld = s_targetMethodOrDelegate;
            BinderBundle binderBundleOld           = s_binderBundle;

            s_binderBundle = binderBundle;
            object[] customBinderProvidedParametersOld = s_customBinderProvidedParameters;
            s_customBinderProvidedParameters = null;

            try
            {
                // If the passed in array is not an actual object[] instance, we need to copy it over to an actual object[]
                // instance so that the rest of the code can safely create managed object references to individual elements.
                if (parameters != null && EETypePtr.EETypePtrOf <object[]>() != parameters.EETypePtr)
                {
                    s_parameters = new object[parameters.Length];
                    Array.Copy(parameters, s_parameters, parameters.Length);
                    parametersNeedCopyBack = true;
                }
                else
                {
                    s_parameters = parameters;
                }

                s_nullableCopyBackObjects = null;
                s_curIndex = 0;
                s_targetMethodOrDelegate = targetMethodOrDelegate;

                try
                {
                    object result = null;
                    if (invokeMethodHelperIsThisCall)
                    {
                        Debug.Assert(methodToCallIsThisCall == true);
                        result = CalliIntrinsics.Call(dynamicInvokeHelperMethod, thisPtrDynamicInvokeMethod, thisPtr, methodToCall, ref argSetupState);
                        System.Diagnostics.DebugAnnotations.PreviousCallContainsDebuggerStepInCode();
                    }
                    else
                    {
                        if (dynamicInvokeHelperGenericDictionary != IntPtr.Zero)
                        {
                            result = CalliIntrinsics.Call(dynamicInvokeHelperMethod, dynamicInvokeHelperGenericDictionary, thisPtr, methodToCall, ref argSetupState, methodToCallIsThisCall);
                            DebugAnnotations.PreviousCallContainsDebuggerStepInCode();
                        }
                        else
                        {
                            result = CalliIntrinsics.Call(dynamicInvokeHelperMethod, thisPtr, methodToCall, ref argSetupState, methodToCallIsThisCall);
                            DebugAnnotations.PreviousCallContainsDebuggerStepInCode();
                        }
                    }

                    return(result);
                }
                catch (Exception e) when(wrapInTargetInvocationException && argSetupState.fComplete)
                {
                    throw new TargetInvocationException(e);
                }
                finally
                {
                    if (parametersNeedCopyBack)
                    {
                        Array.Copy(s_parameters, parameters, parameters.Length);
                    }

                    if (argSetupState.fComplete)
                    {
                        // Nullable objects can't take advantage of the ability to update the boxed value on the heap directly, so perform
                        // an update of the parameters array now.
                        if (argSetupState.nullableCopyBackObjects != null)
                        {
                            for (int i = 0; i < argSetupState.nullableCopyBackObjects.Length; i++)
                            {
                                if (argSetupState.nullableCopyBackObjects[i] != null)
                                {
                                    parameters[i] = DynamicInvokeBoxIntoNonNullable(argSetupState.nullableCopyBackObjects[i]);
                                }
                            }
                        }
                    }
                }
            }
            finally
            {
                // Restore state of thread static helper statics
                s_parameters = parametersOld;
                s_nullableCopyBackObjects = nullableCopyBackObjectsOld;
                s_curIndex = curIndexOld;
                s_targetMethodOrDelegate         = targetMethodOrDelegateOld;
                s_binderBundle                   = binderBundleOld;
                s_customBinderProvidedParameters = customBinderProvidedParametersOld;
            }
        }
Пример #16
0
        protected sealed override object?Invoke(object?thisObject, object?[] arguments, BinderBundle binderBundle, bool wrapInTargetInvocationException)
        {
            Debug.Assert(arguments != null);

            // This does not handle optional parameters. None of the methods we use custom invocation for have them.
            if (!(thisObject == null && 0 != (_options & InvokerOptions.AllowNullThis)))
            {
                ValidateThis(thisObject, _thisType.TypeHandle);
            }

            if (arguments.Length != _parameterTypes.Length)
            {
                throw new TargetParameterCountException();
            }

            object[] convertedArguments = new object[arguments.Length];
            for (int i = 0; i < arguments.Length; i++)
            {
                convertedArguments[i] = RuntimeAugments.CheckArgument(arguments[i], _parameterTypes[i].TypeHandle, binderBundle);
            }
            object result;

            try
            {
                result = _action(thisObject, convertedArguments, _thisType);
            }
            catch (Exception e) when(wrapInTargetInvocationException)
            {
                throw new TargetInvocationException(e);
            }
            return(result);
        }
Пример #17
0
        protected sealed override object?Invoke(object?thisObject, object?[]?arguments, BinderBundle binderBundle, bool wrapInTargetInvocationException)
        {
            if (MethodInvokeInfo.IsSupportedSignature) // Workaround to match expected argument validation order
            {
                ValidateThis(thisObject, _declaringTypeHandle);
            }

            object?result = MethodInvokeInfo.Invoke(
                thisObject,
                MethodInvokeInfo.LdFtnResult,
                arguments,
                binderBundle,
                wrapInTargetInvocationException);

            System.Diagnostics.DebugAnnotations.PreviousCallContainsDebuggerStepInCode();
            return(result);
        }
Пример #18
0
 public sealed override void SetField(Object obj, Object value, BinderBundle binderBundle)
 {
     throw new FieldAccessException(SR.Acc_ReadOnly);
 }
Пример #19
0
 protected abstract void SetFieldBypassCctor(Object obj, Object value, BinderBundle binderBundle);
Пример #20
0
 public abstract void SetField(Object obj, Object value, BinderBundle binderBundle);
Пример #21
0
 protected sealed override void SetFieldBypassCctor(object value, BinderBundle binderBundle)
 {
     throw new FieldAccessException(SR.Acc_ReadOnly);
 }
Пример #22
0
 protected sealed override void SetFieldBypassCctor(Object obj, Object value, BinderBundle binderBundle)
 {
     value = RuntimeAugments.CheckArgument(value, FieldTypeHandle, binderBundle);
     RuntimeAugments.StoreReferenceTypeField(_fieldAddress, value);
 }
Пример #23
0
 public static object CheckArgument(object srcObject, RuntimeTypeHandle dstType, BinderBundle binderBundle)
 {
     return(InvokeUtils.CheckArgument(srcObject, dstType, binderBundle));
 }
Пример #24
0
 public abstract Object Invoke(Object thisObject, Object[] arguments, BinderBundle binderBundle);
 protected sealed override void SetFieldBypassCctor(object value, BinderBundle binderBundle)
 {
     value = RuntimeAugments.CheckArgument(value, FieldTypeHandle, binderBundle);
     UncheckedSetFieldBypassCctor(value);
 }
Пример #26
0
        protected sealed override object Invoke(object thisObject, object[] arguments, BinderBundle binderBundle, bool wrapInTargetInvocationException)
        {
            object result = RuntimeAugments.CallDynamicInvokeMethod(
                thisObject,
                MethodInvokeInfo.LdFtnResult,
                MethodInvokeInfo.DynamicInvokeMethod,
                MethodInvokeInfo.DynamicInvokeGenericDictionary,
                MethodInvokeInfo.MethodInfo,
                arguments,
                binderBundle,
                wrapInTargetInvocationException: wrapInTargetInvocationException,
                methodToCallIsThisCall: false);

            System.Diagnostics.DebugAnnotations.PreviousCallContainsDebuggerStepInCode();
            return(result);
        }
Пример #27
0
        //
        // Various reflection scenarios (Array.SetValue(), reflection Invoke, delegate DynamicInvoke and FieldInfo.Set()) perform
        // automatic conveniences such as automatically widening primitive types to fit the destination type.
        //
        // This method attempts to collect as much of that logic as possible in place. (This may not be completely possible
        // as the desktop CLR is not particularly consistent across all these scenarios either.)
        //
        // The transforms supported are:
        //
        //    Value-preserving widenings of primitive integrals and floats.
        //    Enums can be converted to the same or wider underlying primitive.
        //    Primitives can be converted to an enum with the same or wider underlying primitive.
        //
        //    null converted to default(T) (this is important when T is a valuetype.)
        //
        // There is also another transform of T -> Nullable<T>. This method acknowleges that rule but does not actually transform the T.
        // Rather, the transformation happens naturally when the caller unboxes the value to its final destination.
        //
        // This method is targeted by the Delegate ILTransformer.
        //
        //
        public static Object CheckArgument(Object srcObject, RuntimeTypeHandle dstType, BinderBundle binderBundle)
        {
            EETypePtr dstEEType = dstType.ToEETypePtr();

            return(CheckArgument(srcObject, dstEEType, CheckArgumentSemantics.DynamicInvoke, binderBundle, getExactTypeForCustomBinder: null));
        }
Пример #28
0
 protected abstract object Invoke(object thisObject, object[] arguments, BinderBundle binderBundle, bool wrapInTargetInvocationException);
Пример #29
0
        internal static Object CheckArgument(Object srcObject, EETypePtr dstEEType, CheckArgumentSemantics semantics, BinderBundle binderBundle, Func <Type> getExactTypeForCustomBinder = null)
        {
            if (srcObject == null)
            {
                // null -> default(T)
                if (dstEEType.IsValueType && !dstEEType.IsNullable)
                {
                    if (semantics == CheckArgumentSemantics.SetFieldDirect)
                    {
                        throw CreateChangeTypeException(CommonRuntimeTypes.Object.TypeHandle.ToEETypePtr(), dstEEType, semantics);
                    }
                    return(Runtime.RuntimeImports.RhNewObject(dstEEType));
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                EETypePtr srcEEType = srcObject.EETypePtr;

                if (RuntimeImports.AreTypesAssignable(srcEEType, dstEEType))
                {
                    return(srcObject);
                }


                if (dstEEType.IsInterface)
                {
                    ICastable castable = srcObject as ICastable;
                    Exception castError;

                    if (castable != null && castable.IsInstanceOfInterface(new RuntimeTypeHandle(dstEEType), out castError))
                    {
                        return(srcObject);
                    }
                }

                object    dstObject;
                Exception exception = ConvertOrWidenPrimitivesEnumsAndPointersIfPossible(srcObject, srcEEType, dstEEType, semantics, out dstObject);
                if (exception == null)
                {
                    return(dstObject);
                }

                if (binderBundle == null)
                {
                    throw exception;
                }

                // Our normal coercion rules could not convert the passed in argument but we were supplied a custom binder. See if it can do it.
                Type exactDstType;
                if (getExactTypeForCustomBinder == null)
                {
                    // We were called by someone other than DynamicInvokeParamHelperCore(). Those callers pass the correct dstEEType.
                    exactDstType = Type.GetTypeFromHandle(new RuntimeTypeHandle(dstEEType));
                }
                else
                {
                    // We were called by DynamicInvokeParamHelperCore(). He passes a dstEEType that enums folded to int and possibly other adjustments. A custom binder
                    // is app code however and needs the exact type.
                    exactDstType = getExactTypeForCustomBinder();
                }

                srcObject = binderBundle.ChangeType(srcObject, exactDstType);

                // For compat with desktop, the result of the binder call gets processed through the default rules again.
                dstObject = CheckArgument(srcObject, dstEEType, semantics, binderBundle: null, getExactTypeForCustomBinder: null);
                return(dstObject);
            }
        }
Пример #30
0
 protected sealed override Object Invoke(Object thisObject, Object[] arguments, BinderBundle binderBundle, bool wrapInTargetInvocationException)
 {
     throw new InvalidOperationException(SR.Arg_UnboundGenParam);
 }