[vala/staging] codegen: Allow passing/retrieving any delegate to/from varargs parameter



commit bab871f3a10c124465db5c47f1815bacd99e728f
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Thu Oct 3 10:43:22 2019 +0200

    codegen: Allow passing/retrieving any delegate to/from varargs parameter
    
    Initialize target/notify cvalues of delegate-typed arguments/result of
    inferred varargs parameters and va_list.arg() calls.
    
    Only the actual function pointer will be passed or retrieved. The target
    and destroy values will be null.

 codegen/valaccodemethodcallmodule.vala | 24 ++++++++++++++++++++++++
 tests/Makefile.am                      |  1 +
 tests/methods/varargs-delegate.vala    | 30 ++++++++++++++++++++++++++++++
 3 files changed, 55 insertions(+)
---
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index d41e2904d..3c3290092 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -475,6 +475,17 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
                                        set_cvalue (arg, get_variable_cexpression (temp_var.name));
                                        arg.target_value.value_type = arg.value_type;
 
+                                       if (arg.value_type is DelegateType && ((DelegateType) 
arg.value_type).delegate_symbol.has_target) {
+                                               // Initialize target/destroy cvalues to allow assignment of 
delegates from varargs
+                                               unowned GLibValue arg_value = (GLibValue) arg.target_value;
+                                               if (arg_value.delegate_target_cvalue == null) {
+                                                       arg_value.delegate_target_cvalue = new CCodeConstant 
("NULL");
+                                               }
+                                               if (arg_value.delegate_target_destroy_notify_cvalue == null) {
+                                                       arg_value.delegate_target_destroy_notify_cvalue = new 
CCodeConstant ("NULL");
+                                               }
+                                       }
+
                                        cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, 
get_cvalue (arg));
                                } else {
                                        cexpr = handle_struct_argument (null, arg, cexpr);
@@ -831,6 +842,19 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
                                        // TODO avoid code duplication
                                        result_type = expr.value_type;
                                }
+                               if (st != null && get_ccode_name (st) == "va_list" && ma.member_name == 
"arg") {
+                                       if (result_type is DelegateType && ((DelegateType) 
result_type).delegate_symbol.has_target) {
+                                               set_cvalue (expr, null);
+                                               // Initialize target/destroy cvalues to allow assignment of 
delegates from varargs
+                                               unowned GLibValue arg_value = (GLibValue) expr.target_value;
+                                               if (arg_value.delegate_target_cvalue == null) {
+                                                       arg_value.delegate_target_cvalue = new CCodeConstant 
("NULL");
+                                               }
+                                               if (arg_value.delegate_target_destroy_notify_cvalue == null) {
+                                                       arg_value.delegate_target_destroy_notify_cvalue = new 
CCodeConstant ("NULL");
+                                               }
+                                       }
+                               }
                        }
 
                        if (m != null && m.get_format_arg_index () >= 0) {
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 068914630..f6b4c42a4 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -149,6 +149,7 @@ TESTS = \
        methods/printf-invalid.test \
        methods/printf-constructor.vala \
        methods/printf-constructor-invalid.test \
+       methods/varargs-delegate.vala \
        methods/varargs-delegate-without-target.vala \
        methods/varargs-gvalue.vala \
        methods/varargs-out.vala \
diff --git a/tests/methods/varargs-delegate.vala b/tests/methods/varargs-delegate.vala
new file mode 100644
index 000000000..a797d4c5d
--- /dev/null
+++ b/tests/methods/varargs-delegate.vala
@@ -0,0 +1,30 @@
+delegate string Foo ();
+
+string foo (void* data) {
+       return "foo";
+}
+
+void bar (int first, ...) {
+       assert (first == 23);
+       var args = va_list ();
+       Foo** out_func = args.arg ();
+       *out_func = (Foo*) foo;
+}
+
+void baz (int first, ...) {
+       assert (first == 42);
+       var args = va_list ();
+       Foo func = args.arg ();
+       assert (func () == "foo");
+}
+
+void main () {
+       {
+               Foo func;
+               bar (23, out func);
+               assert (func () == "foo");
+       }
+       {
+               baz (42, foo);
+       }
+}


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