| File: Internal\Reflection\Execution\MethodInvokers\VirtualMethodInvoker.cs | Web Access |
| Project: src\runtime\src\coreclr\nativeaot\System.Private.Reflection.Execution\src\System.Private.Reflection.Execution.csproj (System.Private.Reflection.Execution) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using global::Internal.Runtime.Augments; using global::Internal.Runtime.CompilerServices; using global::System; using global::System.Diagnostics; using global::System.Reflection; namespace Internal.Reflection.Execution.MethodInvokers { // // Implements Invoke() for virtual methods on interfaces. // internal sealed class VirtualMethodInvoker : MethodInvokerWithMethodInvokeInfo { public VirtualMethodInvoker(MethodInvokeInfo methodInvokeInfo, RuntimeTypeHandle declaringTypeHandle) : base(methodInvokeInfo) { _declaringTypeHandle = declaringTypeHandle; } public sealed override Delegate CreateDelegate(RuntimeTypeHandle delegateType, object target, bool isStatic, bool isVirtual, bool isOpen) { if (!isOpen) { // We're creating a delegate to a virtual override of this method, so resolve the virtual now. IntPtr resolvedVirtual = OpenMethodResolver.ResolveMethod(MethodInvokeInfo.VirtualResolveData, target); return RuntimeAugments.CreateDelegate( delegateType, resolvedVirtual, target, isStatic: false, isOpen: isOpen); } else { // Create an open virtual method by providing the virtual resolver to the delegate type. return RuntimeAugments.CreateDelegate( delegateType, MethodInvokeInfo.VirtualResolveData, target, isStatic: false, isOpen: isOpen); } } [DebuggerGuidedStepThrough] protected sealed override object? Invoke(object? thisObject, object?[]? arguments, BinderBundle binderBundle, bool wrapInTargetInvocationException) { IntPtr resolvedVirtual = IntPtr.Zero; if (MethodInvokeInfo.IsSupportedSignature) // Workaround to match expected argument validation order { ValidateThis(thisObject, _declaringTypeHandle); try { resolvedVirtual = OpenMethodResolver.ResolveMethod(MethodInvokeInfo.VirtualResolveData, thisObject); } catch (Exception ex) when (wrapInTargetInvocationException) { throw new TargetInvocationException(ex); } } object? result = MethodInvokeInfo.Invoke( thisObject, resolvedVirtual, arguments, binderBundle, wrapInTargetInvocationException); DebugAnnotations.PreviousCallContainsDebuggerStepInCode(); return result; } [DebuggerGuidedStepThrough] protected sealed override object? Invoke(object? thisObject, Span<object?> arguments) { IntPtr resolvedVirtual = IntPtr.Zero; if (MethodInvokeInfo.IsSupportedSignature) // Workaround to match expected argument validation order { ValidateThis(thisObject, _declaringTypeHandle); resolvedVirtual = OpenMethodResolver.ResolveMethod(MethodInvokeInfo.VirtualResolveData, thisObject); } object? result = MethodInvokeInfo.Invoke( thisObject, resolvedVirtual, arguments); DebugAnnotations.PreviousCallContainsDebuggerStepInCode(); return result; } [DebuggerGuidedStepThrough] protected sealed override object? InvokeDirectWithFewArgs(object? thisObject, Span<object?> arguments) { IntPtr resolvedVirtual = IntPtr.Zero; if (MethodInvokeInfo.IsSupportedSignature) // Workaround to match expected argument validation order { ValidateThis(thisObject, _declaringTypeHandle); resolvedVirtual = OpenMethodResolver.ResolveMethod(MethodInvokeInfo.VirtualResolveData, thisObject); } object? result = MethodInvokeInfo.InvokeDirectWithFewArgs( thisObject, resolvedVirtual, arguments); DebugAnnotations.PreviousCallContainsDebuggerStepInCode(); return result; } protected sealed override object CreateInstance(object[] arguments, BinderBundle binderBundle, bool wrapInTargetInvocationException) { throw NotImplemented.ByDesign; } protected sealed override object CreateInstance(Span<object?> arguments) { throw NotImplemented.ByDesign; } protected sealed override object CreateInstanceWithFewArgs(Span<object?> arguments) { throw NotImplemented.ByDesign; } internal IntPtr ResolveTarget(RuntimeTypeHandle type) { return OpenMethodResolver.ResolveMethod(MethodInvokeInfo.VirtualResolveData, type); } // On CoreCLR/Desktop, we do not attempt to resolve the target virtual method based on the type of the 'this' pointer. // For compatibility reasons, we'll do the same here. public sealed override IntPtr LdFtnResult { get { if (RuntimeAugments.IsInterface(_declaringTypeHandle)) throw new PlatformNotSupportedException(); // Must be an abstract method if (MethodInvokeInfo.LdFtnResult == IntPtr.Zero && MethodInvokeInfo.VirtualResolveData != IntPtr.Zero) throw new PlatformNotSupportedException(); return MethodInvokeInfo.LdFtnResult; } } private RuntimeTypeHandle _declaringTypeHandle; } }