]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Use TargetValue methods in capture_parameter
authorLuca Bruno <lucabru@src.gnome.org>
Sun, 8 May 2011 06:42:07 +0000 (08:42 +0200)
committerLuca Bruno <lucabru@src.gnome.org>
Sun, 8 May 2011 07:13:18 +0000 (09:13 +0200)
Fixes capturing arrays with no array length and delegates with no target.

codegen/valaccodebasemodule.vala
tests/methods/closures.vala

index 8864e17a33d796d7c07875d44cf5ac504e935f63..842a274b3c9ad65ab3e8064a83031316034151ef 100644 (file)
@@ -1636,45 +1636,30 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                bool is_unowned_delegate = param.variable_type is DelegateType && !param.variable_type.value_owned;
 
                // create copy if necessary as captured variables may need to be kept alive
-               CCodeExpression cparam = get_variable_cexpression (param.name);
-               if (param.variable_type.is_real_non_null_struct_type ()) {
-                       cparam = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, cparam);
-               }
+               param.captured = false;
+               var value = load_parameter (param);
                if (requires_copy (param_type) && !param.variable_type.value_owned && !is_unowned_delegate)  {
                        // directly access parameters in ref expressions
-                       param.captured = false;
-                       var value = load_parameter (param);
-                       ((GLibValue) value).cvalue = cparam;
-                       cparam = get_cvalue_ (copy_value (value, param));
-                       param.captured = true;
+                       value = copy_value (value, param);
                }
 
-               ccode.add_assignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_variable_cname (param.name)), cparam);
-
                if (param.variable_type is ArrayType) {
                        var array_type = (ArrayType) param.variable_type;
                        for (int dim = 1; dim <= array_type.rank; dim++) {
                                data.add_field ("gint", get_parameter_array_length_cname (param, dim));
-                               ccode.add_assignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_array_length_cname (get_variable_cname (param.name), dim)), new CCodeIdentifier (get_array_length_cname (get_variable_cname (param.name), dim)));
                        }
                } else if (param.variable_type is DelegateType) {
-                       CCodeExpression target_expr;
-                       CCodeExpression delegate_target_destroy_notify;
-                       if (is_in_coroutine ()) {
-                               target_expr = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (get_variable_cname (param.name)));
-                               delegate_target_destroy_notify = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)));
-                       } else {
-                               target_expr = new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (param.name)));
-                               delegate_target_destroy_notify = new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)));
-                       }
-
                        data.add_field ("gpointer", get_delegate_target_cname (get_variable_cname (param.name)));
-                       ccode.add_assignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_delegate_target_cname (get_variable_cname (param.name))), target_expr);
                        if (param.variable_type.value_owned) {
                                data.add_field ("GDestroyNotify", get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)));
-                               ccode.add_assignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_delegate_target_destroy_notify_cname (get_variable_cname (param.name))), delegate_target_destroy_notify);
+                               // reference transfer for delegates
+                               var lvalue = get_parameter_cvalue (param);
+                               ((GLibValue) value).delegate_target_destroy_notify_cvalue = get_delegate_target_destroy_notify_cvalue (lvalue);
                        }
                }
+               param.captured = true;
+
+               store_parameter (param, value);
        }
 
        public override void visit_block (Block b) {
index acee5de289e015adceb9effcfeeb4aab48ae4221..d2be8e0d9af5b7bea0c478785f0dcbef95a7457a 100644 (file)
@@ -1,5 +1,8 @@
 delegate int Func ();
 
+[CCode (has_target = false)]
+delegate void NoTargetFunc ();
+
 int A (int k, Func x1, Func x2, Func x3, Func x4, Func x5) {
        Func B = null;
        B = () => {
@@ -9,6 +12,10 @@ int A (int k, Func x1, Func x2, Func x3, Func x4, Func x5) {
        return k <= 0 ? x4 () + x5 () : B ();
 }
 
+void B ([CCode (array_length = false, array_null_terminated = true)] int[] array, NoTargetFunc func) {
+       Func C = () => { array = null; func (); return 0; };
+}
+
 void main () {
        int result = A (10, () => 1, () => -1, () => -1, () => 1, () => 0);
        assert (result == -67);