From: Luca Bruno Date: Sun, 8 May 2011 06:42:07 +0000 (+0200) Subject: codegen: Use TargetValue methods in capture_parameter X-Git-Tag: 0.13.0~138 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ac608b1d17debd15ab7e20c15174d1601f00ddf2;p=thirdparty%2Fvala.git codegen: Use TargetValue methods in capture_parameter Fixes capturing arrays with no array length and delegates with no target. --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 8864e17a3..842a274b3 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -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) { diff --git a/tests/methods/closures.vala b/tests/methods/closures.vala index acee5de28..d2be8e0d9 100644 --- a/tests/methods/closures.vala +++ b/tests/methods/closures.vala @@ -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);