fe85e9268532bf95e9ba71c2ce1e29c74a1caf45
[platform/upstream/dotnet/runtime.git] /
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3
4 using System;
5 using System.Reflection;
6 using System.Diagnostics;
7 using System.Globalization;
8 using System.Reflection.Runtime.General;
9 using System.Runtime.CompilerServices;
10
11 using Internal.Runtime.Augments;
12
13 namespace Internal.Reflection.Core.Execution
14 {
15     //
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.
18     //
19     [ReflectionBlocked]
20     public abstract class MethodInvoker
21     {
22         protected MethodInvoker() { }
23
24         [DebuggerGuidedStepThrough]
25         public object? Invoke(object thisObject, object?[] arguments, Binder? binder, BindingFlags invokeAttr, CultureInfo? cultureInfo)
26         {
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();
31             return result;
32         }
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);
35
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; }
38
39         protected static void ValidateThis(object thisObject, RuntimeTypeHandle declaringTypeHandle)
40         {
41             if (thisObject == null)
42                 throw new TargetException(SR.RFLCT_Targ_StatMethReqTarg);
43
44             if (RuntimeAugments.IsAssignable(thisObject, declaringTypeHandle))
45                 return;
46
47             if (RuntimeAugments.IsInterface(declaringTypeHandle))
48             {
49                 if (RuntimeAugments.IsInstanceOfInterface(thisObject, declaringTypeHandle))
50                     return;
51             }
52
53             throw new TargetException(SR.RFLCT_Targ_ITargMismatch);
54         }
55     }
56 }