From bda872709d797a0149349a8d4531774921e7a99b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksey=20Kliger=20=28=CE=BBgeek=29?= Date: Mon, 11 Oct 2021 13:25:38 -0400 Subject: [PATCH] [reflection] Return n2m wrapper from RuntimeMethodHandle.GetFunctionPointer (#60200) for functions marked with UnmanagedCallersOnlyAttribute, return a pointer to the n2m wrapper for calls to GetFunctionPointer Contributes to https://github.com/dotnet/runtime/issues/59815 --- src/mono/mono/metadata/icall.c | 5 +++++ src/mono/mono/mini/interp/interp.c | 13 ++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index c48f2b1199a0df..04479684a61258 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -6293,6 +6293,11 @@ ves_icall_System_Environment_get_TickCount64 (void) gpointer ves_icall_RuntimeMethodHandle_GetFunctionPointer (MonoMethod *method, MonoError *error) { + /* WISH: we should do this in managed */ + if (G_UNLIKELY (mono_method_has_unmanaged_callers_only_attribute (method))) { + method = mono_marshal_get_managed_wrapper (method, NULL, (MonoGCHandle)0, error); + return_val_if_nok (error, NULL); + } return mono_get_runtime_callbacks ()->get_ftnptr (method, error); } diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 6a0039ca872d7c..be586a546ed864 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -6542,9 +6542,16 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK; MonoMethod *cmethod = LOCAL_VAR (ip [2], MonoMethod*); - InterpMethod *m = mono_interp_get_imethod (cmethod, error); - mono_error_assert_ok (error); - LOCAL_VAR (ip [1], gpointer) = imethod_to_ftnptr (m, FALSE); + if (G_UNLIKELY (mono_method_has_unmanaged_callers_only_attribute (cmethod))) { + cmethod = mono_marshal_get_managed_wrapper (cmethod, NULL, (MonoGCHandle)0, error); + mono_error_assert_ok (error); + gpointer addr = mini_get_interp_callbacks ()->create_method_pointer (cmethod, TRUE, error); + LOCAL_VAR (ip [1], gpointer) = addr; + } else { + InterpMethod *m = mono_interp_get_imethod (cmethod, error); + mono_error_assert_ok (error); + LOCAL_VAR (ip [1], gpointer) = imethod_to_ftnptr (m, FALSE); + } ip += 3; MINT_IN_BREAK; }