[vala/staging] codegen: Don't override valid target/destroy of previous lambda argument



commit ba1231cd6770e668d6758567b3719d40808af806
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Tue Apr 6 13:00:16 2021 +0200

    codegen: Don't override valid target/destroy of previous lambda argument
    
    This does not enable proper support for delegates sharing a data argument,
    but allows this special case.
    
    See https://gitlab.gnome.org/GNOME/vala/issues/59

 codegen/valaccodemethodcallmodule.vala     | 13 +++--
 tests/delegates/lambda-shared-closure.vala | 79 ++++++++++++++++++++++++++++++
 2 files changed, 88 insertions(+), 4 deletions(-)
---
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index d60fcf0a3..c1ef29677 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -445,10 +445,15 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
                                                                        closure_new.add_argument (new 
CCodeCastExpression (delegate_target_destroy_notify, "GClosureNotify"));
                                                                        cexpr = new 
CCodeConditionalExpression (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, cexpr, new CCodeConstant 
("NULL")), new CCodeConstant ("NULL"), closure_new);
                                                                } else {
-                                                                       carg_map.set (get_param_pos 
(get_ccode_delegate_target_pos (param)), delegate_target);
-                                                                       if (deleg_type.is_disposable ()) {
-                                                                               assert 
(delegate_target_destroy_notify != null);
-                                                                               carg_map.set (get_param_pos 
(get_ccode_destroy_notify_pos (param)), delegate_target_destroy_notify);
+                                                                       // Override previously given 
target/destroy only if it was NULL
+                                                                       // TODO 
https://gitlab.gnome.org/GNOME/vala/issues/59
+                                                                       var node = carg_map.get 
(get_param_pos (get_ccode_delegate_target_pos (param)));
+                                                                       if (node == null || (node is 
CCodeConstant && ((CCodeConstant) node).name == "NULL")) {
+                                                                               carg_map.set (get_param_pos 
(get_ccode_delegate_target_pos (param)), delegate_target);
+                                                                               if (deleg_type.is_disposable 
()) {
+                                                                                       assert 
(delegate_target_destroy_notify != null);
+                                                                                       carg_map.set 
(get_param_pos (get_ccode_destroy_notify_pos (param)), delegate_target_destroy_notify);
+                                                                               }
                                                                        }
                                                                }
                                                        }
diff --git a/tests/delegates/lambda-shared-closure.vala b/tests/delegates/lambda-shared-closure.vala
index 028eca31a..08f694e6d 100644
--- a/tests/delegates/lambda-shared-closure.vala
+++ b/tests/delegates/lambda-shared-closure.vala
@@ -94,6 +94,80 @@ public class Foo : Object {
        }
 }
 
+void call_shared ([CCode (delegate_target_cname = "user_data", delegate_target_pos = 2.9)] FooFunc a, [CCode 
(delegate_target_cname = "user_data", delegate_target_pos = 2.9)] FooFunc b) {
+       a ();
+       b ();
+}
+
+void call_shared_owned ([CCode (delegate_target_cname = "user_data", delegate_target_pos = 2.9)] owned 
FooFunc a, [CCode (delegate_target_cname = "user_data", delegate_target_pos = 2.9)] owned FooFunc b) {
+       a ();
+       b ();
+}
+
+void run_static_1 () {
+       var foo = new Foo ();
+
+       assert (foo.ref_count == 1);
+
+       call_shared (
+               () => {
+                       assert (foo != null);
+               },
+               () => {
+               }
+       );
+
+       assert (foo.ref_count == 1);
+}
+
+void run_static_2 () {
+       var foo = new Foo ();
+
+       assert (foo.ref_count == 1);
+
+       call_shared (
+               () => {
+               },
+               () => {
+                       assert (foo != null);
+               }
+       );
+
+       assert (foo.ref_count == 1);
+}
+
+void run_static_3 () {
+       var foo = new Foo ();
+
+       assert (foo.ref_count == 1);
+
+       call_shared_owned (
+               () => {
+                       assert (foo != null);
+               },
+               () => {
+               }
+       );
+
+       assert (foo.ref_count == 1);
+}
+
+void run_static_4 () {
+       var foo = new Foo ();
+
+       assert (foo.ref_count == 1);
+
+       call_shared_owned (
+               () => {
+               },
+               () => {
+                       assert (foo != null);
+               }
+       );
+
+       assert (foo.ref_count == 1);
+}
+
 void main () {
        var foo = new Foo ();
        assert (foo.ref_count == 1);
@@ -105,4 +179,9 @@ void main () {
        assert (foo.ref_count == 1);
        foo.run_4 ();
        assert (foo.ref_count == 1);
+
+       run_static_1 ();
+       run_static_2 ();
+       run_static_3 ();
+       run_static_4 ();
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]