From b22c976b7a20ddaf8f0d36b9e0a6344bf7036924 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Wed, 28 Apr 2021 17:38:27 +0200 Subject: [PATCH] [runtime] Implement mono_object_get_class for CoreCLR. --- runtime/coreclr-bridge.m | 8 ++++++ runtime/delegates.t4 | 8 ++++++ runtime/exports.t4 | 4 ++- runtime/runtime.m | 4 +++ runtime/trampolines.m | 41 ++++++++++++++++++------------ src/ObjCRuntime/Runtime.CoreCLR.cs | 10 ++++++++ 6 files changed, 58 insertions(+), 17 deletions(-) diff --git a/runtime/coreclr-bridge.m b/runtime/coreclr-bridge.m index ab38a051ec85..ee563b077d2b 100644 --- a/runtime/coreclr-bridge.m +++ b/runtime/coreclr-bridge.m @@ -239,4 +239,12 @@ return rv; } +MonoClass * +mono_object_get_class (MonoObject * obj) +{ + MonoClass *rv = xamarin_bridge_object_get_type (obj); + LOG_CORECLR (stderr, "%s (%p) => %p\n", __func__, obj, rv); + return rv; +} + #endif // CORECLR_RUNTIME diff --git a/runtime/delegates.t4 b/runtime/delegates.t4 index 840ed12a3b34..3ad7ceecc365 100644 --- a/runtime/delegates.t4 +++ b/runtime/delegates.t4 @@ -365,6 +365,14 @@ OnlyDynamicUsage = false, OnlyCoreCLR = true, }, + + new XDelegate ("MonoObject *", "IntPtr", "xamarin_bridge_object_get_type", + "MonoObject *", "IntPtr", "gchandle" + ) { + WrappedManagedFunction = "ObjectGetType", + OnlyDynamicUsage = false, + OnlyCoreCLR = true, + }, }; delegates.CalculateLengths (); #><#+ diff --git a/runtime/exports.t4 b/runtime/exports.t4 index f96c144ce844..4c22a48102aa 100644 --- a/runtime/exports.t4 +++ b/runtime/exports.t4 @@ -161,7 +161,9 @@ new Export ("MonoClass *", "mono_object_get_class", "MonoObject *", "obj" - ), + ) { + HasCoreCLRBridgeFunction = true, + }, new Export ("MonoObject *", "mono_value_box", "MonoDomain *", "domain", diff --git a/runtime/runtime.m b/runtime/runtime.m index da45d48972e1..0276dfe4d397 100644 --- a/runtime/runtime.m +++ b/runtime/runtime.m @@ -675,6 +675,8 @@ -(void) xamarinSetFlags: (enum XamarinGCHandleFlags) flags; xamarin_free (msg); *exception_gchandle = xamarin_gchandle_new ((MonoObject *) exc, FALSE); } + + xamarin_mono_object_release (&klass); return rv; } @@ -703,6 +705,7 @@ -(void) xamarinSetFlags: (enum XamarinGCHandleFlags) flags; mono_free (to_name); xamarin_free (msg); mono_free (method_full_name); + xamarin_mono_object_release (&from); *exception_gchandle = xamarin_gchandle_new ((MonoObject *) mono_ex, FALSE); } } @@ -2299,6 +2302,7 @@ -(void) xamarinSetFlags: (enum XamarinGCHandleFlags) flags; MONO_THREAD_ATTACH; // COOP: will switch to GC_UNSAFE fullname = xamarin_get_object_type_fullname (handle, &exception_gchandle); + if (exception_gchandle != INVALID_GCHANDLE) { PRINT (PRODUCT ": Got an exception when trying to get the typename for an exception (this exception will be ignored):"); PRINT ("%@", xamarin_print_all_exceptions (exception_gchandle)); diff --git a/runtime/trampolines.m b/runtime/trampolines.m index cf8d529fec3a..49b5cda4f308 100644 --- a/runtime/trampolines.m +++ b/runtime/trampolines.m @@ -94,36 +94,42 @@ case _C_ID: { MonoClass *r_klass = mono_object_get_class ((MonoObject *) retval); + void *returnValue; if (desc && desc->bindas [0].original_type_handle != INVALID_GCHANDLE) { MonoReflectionType *original_type = (MonoReflectionType *) xamarin_gchandle_get_target (desc->bindas [0].original_type_handle); MonoType *original_tp = mono_reflection_type_get_type (original_type); xamarin_mono_object_release (&original_type); - return xamarin_generate_conversion_to_native (retval, mono_class_get_type (r_klass), original_tp, method, (void *) INVALID_TOKEN_REF, exception_gchandle); + returnValue = xamarin_generate_conversion_to_native (retval, mono_class_get_type (r_klass), original_tp, method, (void *) INVALID_TOKEN_REF, exception_gchandle); } else if (r_klass == mono_get_string_class ()) { - return xamarin_string_to_nsstring ((MonoString *) retval, retain); + returnValue = xamarin_string_to_nsstring ((MonoString *) retval, retain); } else if (xamarin_is_class_array (r_klass)) { NSArray *rv = xamarin_managed_array_to_nsarray ((MonoArray *) retval, NULL, r_klass, exception_gchandle); if (retain && rv) [rv retain]; - return rv; + returnValue = rv; } else if (xamarin_is_class_nsobject (r_klass)) { id i = xamarin_get_handle (retval, exception_gchandle); - if (*exception_gchandle != INVALID_GCHANDLE) - return NULL; - - xamarin_framework_peer_lock (); - [i retain]; - xamarin_framework_peer_unlock (); - if (!retain) - [i autorelease]; - - mt_dummy_use (retval); - return i; + if (*exception_gchandle != INVALID_GCHANDLE) { + returnValue = NULL; + } else { + xamarin_framework_peer_lock (); + [i retain]; + xamarin_framework_peer_unlock (); + if (!retain) + [i autorelease]; + + mt_dummy_use (retval); + returnValue = i; + } } else if (xamarin_is_class_inativeobject (r_klass)) { - return xamarin_get_handle_for_inativeobject (retval, exception_gchandle); + returnValue = xamarin_get_handle_for_inativeobject (retval, exception_gchandle); } else { xamarin_assertion_message ("Don't know how to marshal a return value of type '%s.%s'. Please file a bug with a test case at https://github.com/xamarin/xamarin-macios/issues/new\n", mono_class_get_namespace (r_klass), mono_class_get_name (r_klass)); } + + xamarin_mono_object_release (&r_klass); + + return returnValue; } case _C_CHARPTR: return (void *) mono_string_to_utf8 ((MonoString *) retval); @@ -1589,7 +1595,10 @@ return [NSArray array]; buf = (id *) malloc (sizeof (id) * length); - MonoClass *element_class = mono_class_get_element_class (mono_object_get_class ((MonoObject *) array)); + MonoClass *object_class = mono_object_get_class ((MonoObject *) array); + MonoClass *element_class = mono_class_get_element_class (object_class); + xamarin_mono_object_release (&object_class); + bool is_value_type = mono_class_is_valuetype (element_class); if (is_value_type) { element_size = (size_t) mono_class_value_size (element_class, NULL); diff --git a/src/ObjCRuntime/Runtime.CoreCLR.cs b/src/ObjCRuntime/Runtime.CoreCLR.cs index 031b2b564c09..0819685c6c08 100644 --- a/src/ObjCRuntime/Runtime.CoreCLR.cs +++ b/src/ObjCRuntime/Runtime.CoreCLR.cs @@ -159,6 +159,16 @@ static IntPtr GetMethodDeclaringType (MonoObjectPtr mobj) return GetMonoObject (method.DeclaringType); } + static IntPtr ObjectGetType (MonoObjectPtr mobj) + { + var obj = GetMonoObjectTarget (mobj); + if (obj == null) { + log_coreclr ($"ObjectGetType (0x{mobj.ToString ("x")}) => null object"); + return IntPtr.Zero; + } + return GetMonoObject (obj.GetType ()); + } + } }