]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Don't override valid target/destroy of previous lambda argument
authorRico Tzschichholz <ricotz@ubuntu.com>
Tue, 6 Apr 2021 11:00:16 +0000 (13:00 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Thu, 8 Apr 2021 06:34:20 +0000 (08:34 +0200)
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
tests/delegates/lambda-shared-closure.vala

index 2d47f3ee416a1cc28fc9690dd8cc51d7fc5f5b03..42a7fcaa0635bd35968865e690713fd15fa2cdc7 100644 (file)
@@ -434,10 +434,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);
+                                                                               }
                                                                        }
                                                                }
                                                        }
index 028eca31a96c8fb6e0de1925e5bc94efd7b6f995..08f694e6decc898a427b3d39885de30638d437a3 100644 (file)
@@ -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 ();
 }