From: Jürg Billeter Date: Wed, 16 Sep 2009 13:04:08 +0000 (+0200) Subject: Fix array and delegate variable handling in closures and coroutines X-Git-Tag: 0.7.6~44 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=daef7c2b19f2a7ce527ba846c5d96dc5d98e5002;p=thirdparty%2Fvala.git Fix array and delegate variable handling in closures and coroutines --- diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala index 9dc70a4bb..e2071688e 100644 --- a/codegen/valaccodearraymodule.vala +++ b/codegen/valaccodearraymodule.vala @@ -169,33 +169,49 @@ internal class Vala.CCodeArrayModule : CCodeMethodCallModule { } else if (array_expr.symbol_reference != null) { if (array_expr.symbol_reference is FormalParameter) { var param = (FormalParameter) array_expr.symbol_reference; - if (param.array_null_terminated) { - var carray_expr = get_variable_cexpression (param.name); - requires_array_length = true; - var len_call = new CCodeFunctionCall (new CCodeIdentifier ("_vala_array_length")); - len_call.add_argument (carray_expr); - return len_call; - } else if (!param.no_array_length) { - CCodeExpression length_expr = get_variable_cexpression (get_array_length_cname (get_variable_cname (param.name), dim)); - if (param.direction != ParameterDirection.IN) { - // accessing argument of out/ref param - length_expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, length_expr); + if (param.captured) { + // captured variables are stored on the heap + var block = ((Method) param.parent_symbol).body; + return new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (get_block_id (block))), get_array_length_cname (param.name, dim)); + } else if (current_method != null && current_method.coroutine) { + return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_array_length_cname (param.name, dim)); + } else { + if (param.array_null_terminated) { + var carray_expr = get_variable_cexpression (param.name); + requires_array_length = true; + var len_call = new CCodeFunctionCall (new CCodeIdentifier ("_vala_array_length")); + len_call.add_argument (carray_expr); + return len_call; + } else if (!param.no_array_length) { + CCodeExpression length_expr = get_variable_cexpression (get_array_length_cname (get_variable_cname (param.name), dim)); + if (param.direction != ParameterDirection.IN) { + // accessing argument of out/ref param + length_expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, length_expr); + } + if (is_out) { + // passing array as out/ref + return new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, length_expr); + } else { + return length_expr; + } } + } + } else if (array_expr.symbol_reference is LocalVariable) { + var local = (LocalVariable) array_expr.symbol_reference; + if (local.captured) { + // captured variables are stored on the heap + var block = (Block) local.parent_symbol; + return new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (get_block_id (block))), get_array_length_cname (local.name, dim)); + } else if (current_method != null && current_method.coroutine) { + return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_array_length_cname (local.name, dim)); + } else { + var length_expr = get_variable_cexpression (get_array_length_cname (get_variable_cname (local.name), dim)); if (is_out) { - // passing array as out/ref return new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, length_expr); } else { return length_expr; } } - } else if (array_expr.symbol_reference is LocalVariable) { - var local = (LocalVariable) array_expr.symbol_reference; - var length_expr = get_variable_cexpression (get_array_length_cname (get_variable_cname (local.name), dim)); - if (is_out) { - return new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, length_expr); - } else { - return length_expr; - } } else if (array_expr.symbol_reference is Field) { var field = (Field) array_expr.symbol_reference; if (field.array_null_terminated) { diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 5063d38c1..aeade773b 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -1688,7 +1688,13 @@ internal class Vala.CCodeBaseModule : CCodeModule { data.add_field (param.parameter_type.get_cname (), get_variable_cname (param.name)); cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), get_variable_cname (param.name)), new CCodeIdentifier (get_variable_cname (param.name))))); - if (param.parameter_type is DelegateType) { + if (param.parameter_type is ArrayType) { + var array_type = (ArrayType) param.parameter_type; + for (int dim = 1; dim <= array_type.rank; dim++) { + data.add_field ("gint", get_array_length_cname (get_variable_cname (param.name), dim)); + cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_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.parameter_type is DelegateType) { data.add_field ("gpointer", get_delegate_target_cname (get_variable_cname (param.name))); cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), get_delegate_target_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (param.name)))))); } diff --git a/codegen/valaccodedelegatemodule.vala b/codegen/valaccodedelegatemodule.vala index c148d8ae5..2d1f2bf34 100644 --- a/codegen/valaccodedelegatemodule.vala +++ b/codegen/valaccodedelegatemodule.vala @@ -156,6 +156,8 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule { // captured variables are stored on the heap var block = ((Method) param.parent_symbol).body; return new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (param.name)); + } else if (current_method != null && current_method.coroutine) { + return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (param.name)); } else { CCodeExpression target_expr = new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (param.name))); if (param.direction != ParameterDirection.IN) { @@ -175,6 +177,8 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule { // captured variables are stored on the heap var block = (Block) local.parent_symbol; return new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (local.name)); + } else if (current_method != null && current_method.coroutine) { + return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (local.name)); } else { var target_expr = new CCodeIdentifier (get_delegate_target_cname (local.name)); if (is_out) { diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala index 5a3af2dcb..a60eeb188 100644 --- a/codegen/valagasyncmodule.vala +++ b/codegen/valagasyncmodule.vala @@ -43,6 +43,14 @@ internal class Vala.GAsyncModule : GSignalModule { foreach (FormalParameter param in m.get_parameters ()) { data.add_field (param.parameter_type.get_cname (), get_variable_cname (param.name)); + if (param.parameter_type is ArrayType) { + var array_type = (ArrayType) param.parameter_type; + for (int dim = 1; dim <= array_type.rank; dim++) { + data.add_field ("gint", get_array_length_cname (get_variable_cname (param.name), dim)); + } + } else if (param.parameter_type is DelegateType) { + data.add_field ("gpointer", get_delegate_target_cname (get_variable_cname (param.name))); + } } if (!(m.return_type is VoidType)) { @@ -153,6 +161,14 @@ internal class Vala.GAsyncModule : GSignalModule { foreach (FormalParameter param in m.get_parameters ()) { if (param.direction != ParameterDirection.OUT) { asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_variable_cname (param.name)), new CCodeIdentifier (get_variable_cname (param.name))))); + if (param.parameter_type is ArrayType) { + var array_type = (ArrayType) param.parameter_type; + for (int dim = 1; dim <= array_type.rank; dim++) { + asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), 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.parameter_type is DelegateType) { + asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (param.name)))))); + } } }