From 54bc2f1dfe4089b65d716f36246e23bd7cc43d84 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Mon, 4 May 2020 11:08:26 +0200 Subject: [PATCH] [runtime] Add GCHandle pointer-sized API. --- runtime/mono-runtime.h.t4 | 10 ++++++++++ runtime/runtime.m | 42 +++++++++++++++++++++++++++++++++++++++ runtime/xamarin/runtime.h | 12 +++++++++++ 3 files changed, 64 insertions(+) diff --git a/runtime/mono-runtime.h.t4 b/runtime/mono-runtime.h.t4 index f1b7fd9bf7..b3a4ad8814 100644 --- a/runtime/mono-runtime.h.t4 +++ b/runtime/mono-runtime.h.t4 @@ -294,6 +294,16 @@ bool <#= export.EntryPoint #>_exists (); <# } #> + +/* + * Wrapper GCHandle functions that takes pointer sized handles instead of ints, + * so that we can adapt our code incrementally to use pointers instead of ints + * until Mono's pointer-sized API is available for us. + * Ref: https://github.com/dotnet/runtime/commit/3886a63841434af716292172737a42757a15c6a6 + */ +#define INVALID_GCHANDLE 0 +typedef void* GCHandle; + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/runtime/runtime.m b/runtime/runtime.m index 72d2e436f2..c68dc7d304 100644 --- a/runtime/runtime.m +++ b/runtime/runtime.m @@ -2666,6 +2666,48 @@ xamarin_get_managed_method_for_token (guint32 token_ref, guint32 *exception_gcha return xamarin_get_reflection_method_method (reflection_method); } +GCHandle +xamarin_gchandle_new (MonoObject *obj, bool track_resurrection) +{ + if (obj == NULL) + return INVALID_GCHANDLE; + return GINT_TO_POINTER (mono_gchandle_new (obj, track_resurrection)); +} + +GCHandle +xamarin_gchandle_new_weakref (MonoObject *obj, bool pinned) +{ + if (obj == NULL) + return INVALID_GCHANDLE; + return GINT_TO_POINTER (mono_gchandle_new_weakref (obj, pinned)); +} + +MonoObject * +xamarin_gchandle_get_target (GCHandle handle) +{ + if (handle == INVALID_GCHANDLE) + return NULL; + return mono_gchandle_get_target (GPOINTER_TO_UINT (handle)); +} + +void +xamarin_gchandle_free (GCHandle handle) +{ + if (handle == INVALID_GCHANDLE) + return; + mono_gchandle_free (GPOINTER_TO_UINT (handle)); +} + +MonoObject * +xamarin_gchandle_unwrap (GCHandle handle) +{ + if (handle == INVALID_GCHANDLE) + return NULL; + MonoObject *rv = mono_gchandle_get_target (GPOINTER_TO_UINT (handle)); + mono_gchandle_free (GPOINTER_TO_UINT (handle)); + return rv; +} + /* * Object unregistration: * diff --git a/runtime/xamarin/runtime.h b/runtime/xamarin/runtime.h index 71b24ba45e..9f1f6259ed 100644 --- a/runtime/xamarin/runtime.h +++ b/runtime/xamarin/runtime.h @@ -260,6 +260,18 @@ void xamarin_printf (const char *format, ...); void xamarin_vprintf (const char *format, va_list args); void xamarin_install_log_callbacks (); +/* + * Wrapper GCHandle functions that takes pointer sized handles instead of ints, + * so that we can adapt our code incrementally to use pointers instead of ints + * until Mono's pointer-sized API is available for us. + * Ref: https://github.com/dotnet/runtime/commit/3886a63841434af716292172737a42757a15c6a6 + */ +GCHandle xamarin_gchandle_new (MonoObject *obj, bool track_resurrection); +GCHandle xamarin_gchandle_new_weakref (MonoObject *obj, bool pinned); +MonoObject * xamarin_gchandle_get_target (GCHandle handle); +void xamarin_gchandle_free (GCHandle handle); +MonoObject * xamarin_gchandle_unwrap (GCHandle handle); // Will get the target and free the GCHandle + /* * Look for an assembly in the app and open it. *