diff --git a/runtime/coreclr-bridge.m b/runtime/coreclr-bridge.m index 8c8e3df47e..f5a9b0a4cf 100644 --- a/runtime/coreclr-bridge.m +++ b/runtime/coreclr-bridge.m @@ -533,6 +533,14 @@ mono_class_get_element_class (MonoClass *klass) return rv; } +MonoClass * +mono_class_get_nullable_param (MonoClass * klass) +{ + MonoClass *rv = xamarin_bridge_get_nullable_element_type (klass); + LOG_CORECLR (stderr, "%s (%p) => %p\n", __func__, klass, rv); + return rv; +} + bool xamarin_is_class_nsobject (MonoClass *cls) { diff --git a/runtime/delegates.t4 b/runtime/delegates.t4 index 8f8b27573c..68fc651f11 100644 --- a/runtime/delegates.t4 +++ b/runtime/delegates.t4 @@ -519,6 +519,14 @@ OnlyCoreCLR = true, }, + new XDelegate ("MonoObject *", "MonoObject *", "xamarin_bridge_get_nullable_element_type", + "MonoObject *", "MonoObject *", "typeobj" + ) { + WrappedManagedFunction = "GetNullableElementType", + OnlyDynamicUsage = false, + OnlyCoreCLR = true, + }, + new XDelegate ("bool", "bool", "xamarin_bridge_is_delegate", "MonoObject *", "MonoObject *", "typeobj" ) { diff --git a/runtime/exports.t4 b/runtime/exports.t4 index 8b30198caf..b39eca2cf4 100644 --- a/runtime/exports.t4 +++ b/runtime/exports.t4 @@ -96,7 +96,9 @@ new Export (true, "MonoClass *", "mono_class_get_nullable_param", "MonoClass *", "klass" - ), + ) { + HasCoreCLRBridgeFunction = true, + }, #endregion #region metadata/debug-helpers.h diff --git a/runtime/trampolines.m b/runtime/trampolines.m index e6523b2ab4..ad88d61088 100644 --- a/runtime/trampolines.m +++ b/runtime/trampolines.m @@ -931,6 +931,7 @@ exception_handling: xamarin_mono_object_release (&nativeType); xamarin_mono_object_release (&nativeElementType); xamarin_mono_object_release (&managedElementType); + xamarin_mono_object_release (&nullableManagedType); return convertedValue; } @@ -1019,6 +1020,7 @@ exception_handling: xamarin_mono_object_release (&nativeType); xamarin_mono_object_release (&nativeElementType); xamarin_mono_object_release (&managedElementType); + xamarin_mono_object_release (&nullableManagedType); return convertedValue; } diff --git a/src/ObjCRuntime/Runtime.CoreCLR.cs b/src/ObjCRuntime/Runtime.CoreCLR.cs index 74683ce256..b0f3a3b8f0 100644 --- a/src/ObjCRuntime/Runtime.CoreCLR.cs +++ b/src/ObjCRuntime/Runtime.CoreCLR.cs @@ -151,6 +151,13 @@ namespace ObjCRuntime { return (MonoObject*) GetMonoObject (type.GetElementType ()); } + static unsafe MonoObject* GetNullableElementType (MonoObject* typeobj) + { + var type = (Type) GetMonoObjectTarget (typeobj); + var elementType = type.GetGenericArguments () [0]; + return (MonoObject*) GetMonoObject (elementType); + } + static IntPtr CreateGCHandle (IntPtr gchandle, GCHandleType type) { // It's valid to create a GCHandle to a null value. diff --git a/tools/common/StaticRegistrar.cs b/tools/common/StaticRegistrar.cs index 8a14a02d8c..03cd4f0137 100644 --- a/tools/common/StaticRegistrar.cs +++ b/tools/common/StaticRegistrar.cs @@ -4474,6 +4474,7 @@ namespace Registrar { underlyingManagedType = GetNullableType (managedType); sb.AppendLine ($"{classVariableName} = xamarin_get_nullable_type ({managedClassExpression}, &exception_gchandle);"); sb.AppendLine ($"if (exception_gchandle != INVALID_GCHANDLE) goto exception_handling;"); + cleanup.AppendLine ($"xamarin_mono_object_release (&{classVariableName});"); } else { sb.AppendLine ($"{classVariableName} = {managedClassExpression};"); } @@ -4565,6 +4566,7 @@ namespace Registrar { underlyingManagedType = GetNullableType (managedType); sb.AppendLine ($"{classVariableName} = xamarin_get_nullable_type ({managedClassExpression}, &exception_gchandle);"); sb.AppendLine ($"if (exception_gchandle != INVALID_GCHANDLE) goto exception_handling;"); + cleanup.AppendLine ($"xamarin_mono_object_release (&{classVariableName});"); } else { sb.AppendLine ($"{classVariableName} = {managedClassExpression};"); }