From b0974e83178ff937b2b119a4ffaacc9d5693b20e Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Mon, 4 May 2020 11:08:44 +0200 Subject: [PATCH] Convert Runtime.ConvertNSStringToSmartEnum and Runtime.ConvertSmartEnumToNSString to use GCHandle. These methods were already partially using GCHandles, so convert the parameter using ObjectWrapper to GCHandle, and port the rest of the existing logic to use the new helper API. --- runtime/delegates.t4 | 6 +++--- runtime/trampolines.m | 11 ++--------- src/ObjCRuntime/Runtime.cs | 6 +++--- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/runtime/delegates.t4 b/runtime/delegates.t4 index 97ac7fa667..4b11d70e33 100644 --- a/runtime/delegates.t4 +++ b/runtime/delegates.t4 @@ -264,15 +264,15 @@ }, new XDelegate ("NSString *", "IntPtr", "xamarin_convert_smart_enum_to_nsstring", - "void *", "IntPtr", "value" + "GCHandle->MonoObject *", "IntPtr", "value" ) { WrappedManagedFunction = "ConvertSmartEnumToNSString", OnlyDynamicUsage = true, }, - new XDelegate ("void *", "IntPtr", "xamarin_convert_nsstring_to_smart_enum", + new XDelegate ("GCHandle->MonoObject *", "IntPtr", "xamarin_convert_nsstring_to_smart_enum", "NSString *", "IntPtr", "value", - "MonoReflectionType *", "IntPtr", "type" + "GCHandle->MonoReflectionType *", "IntPtr", "type" ) { WrappedManagedFunction = "ConvertNSStringToSmartEnum", OnlyDynamicUsage = true, diff --git a/runtime/trampolines.m b/runtime/trampolines.m index 1f00915bf2..b097edac85 100644 --- a/runtime/trampolines.m +++ b/runtime/trampolines.m @@ -1400,9 +1400,7 @@ xamarin_smart_enum_to_nsstring (MonoObject *value, void *context /* token ref */ guint32 context_ref = GPOINTER_TO_UINT (context); if (context_ref == INVALID_TOKEN_REF) { // This requires the dynamic registrar to invoke the correct conversion function - uint32_t handle = mono_gchandle_new (value, FALSE); - NSString *rv = xamarin_convert_smart_enum_to_nsstring (GINT_TO_POINTER (handle), exception_gchandle); - mono_gchandle_free (handle); + NSString *rv = xamarin_convert_smart_enum_to_nsstring (value, exception_gchandle); return rv; } else { // The static registrar found the correct conversion function, and provided a token ref we can use @@ -1435,16 +1433,13 @@ void * xamarin_nsstring_to_smart_enum (id value, void *ptr, MonoClass *managedType, void *context, guint32 *exception_gchandle) { guint32 context_ref = GPOINTER_TO_UINT (context); - uint32_t gc_handle = 0; MonoObject *obj; if (context_ref == INVALID_TOKEN_REF) { // This requires the dynamic registrar to invoke the correct conversion function - void *rv = xamarin_convert_nsstring_to_smart_enum (value, mono_type_get_object (mono_domain_get (), mono_class_get_type (managedType)), exception_gchandle); + obj = xamarin_convert_nsstring_to_smart_enum (value, mono_type_get_object (mono_domain_get (), mono_class_get_type (managedType)), exception_gchandle); if (*exception_gchandle != 0) return ptr; - gc_handle = GPOINTER_TO_UINT (rv); - obj = mono_gchandle_get_target (gc_handle); } else { // The static registrar found the correct conversion function, and provided a token ref we can use // to find it (and invoke it), without needing the dynamic registrar. @@ -1471,8 +1466,6 @@ xamarin_nsstring_to_smart_enum (id value, void *ptr, MonoClass *managedType, voi ptr = xamarin_calloc (size); void *value_ptr = mono_object_unbox (obj); memcpy (ptr, value_ptr, size); - if (context_ref == INVALID_TOKEN_REF) - mono_gchandle_free (gc_handle); return ptr; } diff --git a/src/ObjCRuntime/Runtime.cs b/src/ObjCRuntime/Runtime.cs index 701000ff9b..f90325da22 100644 --- a/src/ObjCRuntime/Runtime.cs +++ b/src/ObjCRuntime/Runtime.cs @@ -363,7 +363,7 @@ namespace ObjCRuntime { // returns: a handle to a native NSString * static IntPtr ConvertSmartEnumToNSString (IntPtr value_handle) { - var value = GCHandle.FromIntPtr (value_handle).Target; + var value = GetGCHandleTarget (value_handle); var smart_type = value.GetType (); MethodBase getConstantMethod, getValueMethod; if (!Registrar.IsSmartEnum (smart_type, out getConstantMethod, out getValueMethod)) @@ -380,13 +380,13 @@ namespace ObjCRuntime { // returns: GCHandle to a (smart) enum value. Caller must free the GCHandle. static IntPtr ConvertNSStringToSmartEnum (IntPtr value, IntPtr type) { - var smart_type = (Type) ObjectWrapper.Convert (type); + var smart_type = (Type) GetGCHandleTarget (type); var str = GetNSObject (value); MethodBase getConstantMethod, getValueMethod; if (!Registrar.IsSmartEnum (smart_type, out getConstantMethod, out getValueMethod)) throw ErrorHelper.CreateError (8024, $"Could not find a valid extension type for the smart enum '{smart_type.FullName}'. Please file a bug at https://github.com/xamarin/xamarin-macios/issues/new."); var rv = ((MethodInfo) getValueMethod).Invoke (null, new object [] { str }); - return GCHandle.ToIntPtr (GCHandle.Alloc (rv)); + return AllocGCHandle (rv); } #region Wrappers for delegate callbacks