1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
5 using System.Reflection;
6 using System.Diagnostics;
7 using System.Globalization;
8 using System.Reflection.Runtime.General;
9 using System.Runtime.CompilerServices;
11 using Internal.Runtime.Augments;
13 namespace Internal.Reflection.Core.Execution
16 // This class polymorphically implements the MethodBase.Invoke() api and its close cousins. MethodInvokers are designed to be built once and cached
17 // for maximum Invoke() throughput.
20 public abstract class MethodInvoker
22 protected MethodInvoker() { }
24 [DebuggerGuidedStepThrough]
25 public object? Invoke(object thisObject, object?[] arguments, Binder? binder, BindingFlags invokeAttr, CultureInfo? cultureInfo)
27 BinderBundle binderBundle = binder.ToBinderBundle(invokeAttr, cultureInfo);
28 bool wrapInTargetInvocationException = (invokeAttr & BindingFlags.DoNotWrapExceptions) == 0;
29 object? result = Invoke(thisObject, arguments, binderBundle, wrapInTargetInvocationException);
30 System.Diagnostics.DebugAnnotations.PreviousCallContainsDebuggerStepInCode();
33 protected abstract object? Invoke(object? thisObject, object?[]? arguments, BinderBundle binderBundle, bool wrapInTargetInvocationException);
34 public abstract Delegate CreateDelegate(RuntimeTypeHandle delegateType, object target, bool isStatic, bool isVirtual, bool isOpen);
36 // This property is used to retrieve the target method pointer. It is used by the RuntimeMethodHandle.GetFunctionPointer API
37 public abstract IntPtr LdFtnResult { get; }
39 protected static void ValidateThis(object thisObject, RuntimeTypeHandle declaringTypeHandle)
41 if (thisObject == null)
42 throw new TargetException(SR.RFLCT_Targ_StatMethReqTarg);
44 if (RuntimeAugments.IsAssignable(thisObject, declaringTypeHandle))
47 if (RuntimeAugments.IsInterface(declaringTypeHandle))
49 if (RuntimeAugments.IsInstanceOfInterface(thisObject, declaringTypeHandle))
53 throw new TargetException(SR.RFLCT_Targ_ITargMismatch);