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); }
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(); } }
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); }
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); }
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); }
public sealed override void SetField(Object obj, Object value, BinderBundle binderBundle) { if (_cctorContext != IntPtr.Zero) { RuntimeAugments.EnsureClassConstructorRun(_cctorContext); } SetFieldBypassCctor(obj, value, binderBundle); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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; } }
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); }
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); }
public sealed override void SetField(Object obj, Object value, BinderBundle binderBundle) { throw new FieldAccessException(SR.Acc_ReadOnly); }
protected abstract void SetFieldBypassCctor(Object obj, Object value, BinderBundle binderBundle);
public abstract void SetField(Object obj, Object value, BinderBundle binderBundle);
protected sealed override void SetFieldBypassCctor(object value, BinderBundle binderBundle) { throw new FieldAccessException(SR.Acc_ReadOnly); }
protected sealed override void SetFieldBypassCctor(Object obj, Object value, BinderBundle binderBundle) { value = RuntimeAugments.CheckArgument(value, FieldTypeHandle, binderBundle); RuntimeAugments.StoreReferenceTypeField(_fieldAddress, value); }
public static object CheckArgument(object srcObject, RuntimeTypeHandle dstType, BinderBundle binderBundle) { return(InvokeUtils.CheckArgument(srcObject, dstType, binderBundle)); }
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); }
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); }
// // 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)); }
protected abstract object Invoke(object thisObject, object[] arguments, BinderBundle binderBundle, bool wrapInTargetInvocationException);
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); } }
protected sealed override Object Invoke(Object thisObject, Object[] arguments, BinderBundle binderBundle, bool wrapInTargetInvocationException) { throw new InvalidOperationException(SR.Arg_UnboundGenParam); }