From ff86152eccb6e956a67912e1e8b63eb36d120828 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Mon, 27 May 2019 23:08:45 -0700 Subject: [PATCH] [generator] Fix generation of ReturnRelease code for third-party bindings. (#6135) Don't use internal platform API (the Selector.Release field), and make sure the void_objc_msgSend function exists in the binding. --- src/generator.cs | 13 +++++++++++-- tests/generator/BGenTests.cs | 6 ++++++ tests/generator/generator-tests.csproj | 3 ++- tests/generator/tests/return-release.cs | 18 ++++++++++++++++++ 4 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 tests/generator/tests/return-release.cs diff --git a/src/generator.cs b/src/generator.cs index b820d38e9c..c900dc4536 100644 --- a/src/generator.cs +++ b/src/generator.cs @@ -4449,14 +4449,23 @@ public partial class Generator : IMemberGatherer { } if (minfo.is_return_release) { + + // Make sure we generate the required signature in Messaging only if needed + // bool_objc_msgSendSuper_IntPtr: for respondsToSelector: + if (!send_methods.ContainsKey ("void_objc_msgSend")) { + print (m, "[DllImport (LIBOBJC_DYLIB, EntryPoint=\"objc_msgSendSuper\")]"); + print (m, "public extern static void void_objc_msgSend (IntPtr receiever, IntPtr selector);"); + RegisterMethodName ("void_objc_msgSend"); + } + if (!needsPtrZeroCheck) - print ("{0}.void_objc_msgSend (ret.Handle, Selector.GetHandle (Selector.Release));", ns.Messaging); + print ("global::{0}.void_objc_msgSend (ret.Handle, Selector.GetHandle (\"release\"));", ns.Messaging); else { // We must create the managed wrapper before calling Release on it // FIXME: https://trello.com/c/1ukS9TbL/43-introduce-common-object-type-for-all-unmanaged-types-which-will-correctly-implement-idisposable-and-inativeobject // We should consider using return INativeObject (ptr, bool); here at some point print ("global::{0} relObj = ret == IntPtr.Zero ? null : new global::{0} (ret);", mi.ReturnType.FullName); - print ("if (relObj != null) global::{0}.void_objc_msgSend (relObj.Handle, Selector.GetHandle (Selector.Release));", ns.Messaging); + print ("if (relObj != null) global::{0}.void_objc_msgSend (relObj.Handle, Selector.GetHandle (\"release\"));", ns.Messaging); } } diff --git a/tests/generator/BGenTests.cs b/tests/generator/BGenTests.cs index cbe60c9992..e0bc475844 100644 --- a/tests/generator/BGenTests.cs +++ b/tests/generator/BGenTests.cs @@ -588,10 +588,16 @@ namespace GeneratorTests [Test] public void GHIssue5692 () => BuildFile (Profile.iOS, "ghissue5692.cs"); + [Test] public void RefOutParameters () { BuildFile (Profile.macOSMobile, true, "tests/ref-out-parameters.cs"); + } + [Test] + public void ReturnRelease () + { + BuildFile (Profile.iOS, "tests/return-release.cs"); } BGenTool BuildFile (Profile profile, params string [] filenames) diff --git a/tests/generator/generator-tests.csproj b/tests/generator/generator-tests.csproj index c5ed1af7bb..f45a2b3e87 100644 --- a/tests/generator/generator-tests.csproj +++ b/tests/generator/generator-tests.csproj @@ -70,7 +70,8 @@ - + + diff --git a/tests/generator/tests/return-release.cs b/tests/generator/tests/return-release.cs new file mode 100644 index 0000000000..01cb438631 --- /dev/null +++ b/tests/generator/tests/return-release.cs @@ -0,0 +1,18 @@ +using System; +using Foundation; + +namespace NS +{ + [Protocol] + interface ProtocolWithReturnRelease + { + [Abstract, Export ("newRequiredObject")] + [return: Release] + NSObject CreateRequiredObject (); + + [Export ("newOptionalObject")] + [return: Release] + NSObject CreateOptionalObject (); + } +} +