From: Jürg Billeter Date: Wed, 16 Sep 2009 16:12:18 +0000 (+0200) Subject: GAsync: Fix async methods returning arrays or delegates X-Git-Tag: 0.7.6~35 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5a2bfdf3fd3c96bc8d7ebffa3f658c91ff34738d;p=thirdparty%2Fvala.git GAsync: Fix async methods returning arrays or delegates --- diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala index 0dc15721e..2121dc7b6 100644 --- a/codegen/valaccodearraymodule.vala +++ b/codegen/valaccodearraymodule.vala @@ -172,9 +172,9 @@ internal class Vala.CCodeArrayModule : CCodeMethodCallModule { if (param.captured) { // captured variables are stored on the heap var block = ((Method) param.parent_symbol).body; - return new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_array_length_cname (param.name, dim)); + return new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_array_length_cname (get_variable_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)); + return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_array_length_cname (get_variable_cname (param.name), dim)); } else { if (param.array_null_terminated) { var carray_expr = get_variable_cexpression (param.name); @@ -201,9 +201,9 @@ internal class Vala.CCodeArrayModule : CCodeMethodCallModule { if (local.captured) { // captured variables are stored on the heap var block = (Block) local.parent_symbol; - return new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_array_length_cname (local.name, dim)); + return new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_array_length_cname (get_variable_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)); + return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_array_length_cname (get_variable_cname (local.name), dim)); } else { var length_expr = get_variable_cexpression (get_array_length_cname (get_variable_cname (local.name), dim)); if (is_out) { diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index ac7b3d63a..e9ac20786 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -1806,6 +1806,9 @@ internal class Vala.CCodeBaseModule : CCodeModule { public string get_variable_cname (string name) { if (name[0] == '.') { + if (name == ".result") { + return "result"; + } // compiler-internal variable if (!variable_name_map.contains (name)) { variable_name_map.set (name, "_tmp%d_".printf (next_temp_var_id)); @@ -1819,6 +1822,14 @@ internal class Vala.CCodeBaseModule : CCodeModule { } } + public CCodeExpression get_result_cexpression (string cname = "result") { + if (current_method != null && current_method.coroutine) { + return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), cname); + } else { + return new CCodeIdentifier (cname); + } + } + public override void visit_local_variable (LocalVariable local) { check_type (local.variable_type); @@ -2747,7 +2758,10 @@ internal class Vala.CCodeBaseModule : CCodeModule { var array_type = (ArrayType) current_return_type; for (int dim = 1; dim <= array_type.rank; dim++) { - var len_l = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (head.get_array_length_cname ("result", dim))); + var len_l = get_result_cexpression (head.get_array_length_cname ("result", dim)); + if (current_method == null || !current_method.coroutine) { + len_l = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, len_l); + } var len_r = head.get_array_length_cexpression (stmt.return_expression, dim); ccomma.append_expression (new CCodeAssignment (len_l, len_r)); } @@ -2764,9 +2778,12 @@ internal class Vala.CCodeBaseModule : CCodeModule { var ccomma = new CCodeCommaExpression (); ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (return_expr_decl.name), (CCodeExpression) stmt.return_expression.ccodenode)); - var len_l = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (get_delegate_target_cname ("result"))); - var len_r = get_delegate_target_cexpression (stmt.return_expression); - ccomma.append_expression (new CCodeAssignment (len_l, len_r)); + var target_l = get_result_cexpression (get_delegate_target_cname ("result")); + if (current_method == null || !current_method.coroutine) { + target_l = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, target_l); + } + var target_r = get_delegate_target_cexpression (stmt.return_expression); + ccomma.append_expression (new CCodeAssignment (target_l, target_r)); ccomma.append_expression (get_variable_cexpression (return_expr_decl.name)); @@ -2778,8 +2795,8 @@ internal class Vala.CCodeBaseModule : CCodeModule { var cfrag = new CCodeFragment (); // assign method result to `result' - CCodeExpression result_lhs = new CCodeIdentifier ("result"); - if (current_return_type.is_real_struct_type ()) { + CCodeExpression result_lhs = get_result_cexpression (); + if (current_return_type.is_real_struct_type () && (current_method == null || !current_method.coroutine)) { result_lhs = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, result_lhs); } cfrag.append (new CCodeExpressionStatement (new CCodeAssignment (result_lhs, (CCodeExpression) stmt.return_expression.ccodenode))); @@ -2794,11 +2811,13 @@ internal class Vala.CCodeBaseModule : CCodeModule { } } - // structs are returned via out parameter - if (current_return_type.is_real_struct_type()) { - cfrag.append (new CCodeReturnStatement ()); - } else { - cfrag.append (new CCodeReturnStatement (new CCodeIdentifier ("result"))); + if (current_method == null || !current_method.coroutine) { + // structs are returned via out parameter + if (current_return_type.is_real_struct_type()) { + cfrag.append (new CCodeReturnStatement ()); + } else { + cfrag.append (new CCodeReturnStatement (new CCodeIdentifier ("result"))); + } } stmt.ccodenode = cfrag; diff --git a/codegen/valaccodedelegatemodule.vala b/codegen/valaccodedelegatemodule.vala index 2aab947be..182cf5a01 100644 --- a/codegen/valaccodedelegatemodule.vala +++ b/codegen/valaccodedelegatemodule.vala @@ -155,9 +155,9 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule { if (param.captured) { // captured variables are stored on the heap var block = ((Method) param.parent_symbol).body; - return new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (param.name)); + return new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (get_variable_cname (param.name))); } else if (current_method != null && current_method.coroutine) { - return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (param.name)); + return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (get_variable_cname (param.name))); } else { CCodeExpression target_expr = new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (param.name))); if (param.direction != ParameterDirection.IN) { @@ -176,11 +176,11 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule { if (local.captured) { // captured variables are stored on the heap var block = (Block) local.parent_symbol; - return new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (local.name)); + return new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (get_variable_cname (local.name))); } else if (current_method != null && current_method.coroutine) { - return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (local.name)); + return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (get_variable_cname (local.name))); } else { - var target_expr = new CCodeIdentifier (get_delegate_target_cname (local.name)); + var target_expr = new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (local.name))); if (is_out) { return new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, target_expr); } else { diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala index f11b279be..b3c9ea5b8 100644 --- a/codegen/valaccodemethodcallmodule.vala +++ b/codegen/valaccodemethodcallmodule.vala @@ -437,7 +437,7 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule { } /* add length argument for methods returning arrays */ - if (m != null && m.return_type is ArrayType) { + if (m != null && m.return_type is ArrayType && async_call != ccall) { var array_type = (ArrayType) m.return_type; for (int dim = 1; dim <= array_type.rank; dim++) { if (m.array_null_terminated) { @@ -473,7 +473,7 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule { expr.append_array_size (new CCodeConstant ("-1")); } } - } else if (m != null && m.return_type is DelegateType) { + } else if (m != null && m.return_type is DelegateType && async_call != ccall) { var deleg_type = (DelegateType) m.return_type; var d = deleg_type.delegate_symbol; if (d.has_target) { diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala index a60eeb188..1c3390626 100644 --- a/codegen/valagasyncmodule.vala +++ b/codegen/valagasyncmodule.vala @@ -55,6 +55,14 @@ internal class Vala.GAsyncModule : GSignalModule { if (!(m.return_type is VoidType)) { data.add_field (m.return_type.get_cname (), "result"); + if (m.return_type is ArrayType) { + var array_type = (ArrayType) m.return_type; + for (int dim = 1; dim <= array_type.rank; dim++) { + data.add_field ("gint", get_array_length_cname ("result", dim)); + } + } else if (m.return_type is DelegateType) { + data.add_field ("gpointer", get_delegate_target_cname ("result")); + } } return data; @@ -76,8 +84,8 @@ internal class Vala.GAsyncModule : GSignalModule { if (requires_destroy (m.return_type)) { /* this is very evil. */ - var v = new LocalVariable (m.return_type, "result"); - var ma = new MemberAccess.simple ("result"); + var v = new LocalVariable (m.return_type, ".result"); + var ma = new MemberAccess.simple (".result"); ma.symbol_reference = v; var old_symbol = current_symbol; current_symbol = m; @@ -320,6 +328,14 @@ internal class Vala.GAsyncModule : GSignalModule { if (!(return_type is VoidType)) { finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "result")))); + if (return_type is ArrayType) { + var array_type = (ArrayType) return_type; + for (int dim = 1; dim <= array_type.rank; dim++) { + finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (get_array_length_cname ("result", dim))), new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_array_length_cname ("result", dim))))); + } + } else if (return_type is DelegateType) { + finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (get_delegate_target_cname ("result"))), new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname ("result"))))); + } if (!(return_type is ValueType) || return_type.nullable) { finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "result"), new CCodeConstant ("NULL")))); } @@ -491,28 +507,15 @@ internal class Vala.GAsyncModule : GSignalModule { } public override void visit_return_statement (ReturnStatement stmt) { + base.visit_return_statement (stmt); + if (current_method == null || !current_method.coroutine) { - base.visit_return_statement (stmt); return; } - stmt.accept_children (codegen); - - var result_block = new CCodeBlock (); - stmt.ccodenode = result_block; - - if (stmt.return_expression != null) { - var result_var = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "result"); - var assign_result = new CCodeAssignment (result_var, (CCodeExpression) stmt.return_expression.ccodenode); - result_block.add_statement (new CCodeExpressionStatement (assign_result)); - create_temp_decl (stmt, stmt.return_expression.temp_vars); - } - - var free_locals = new CCodeFragment (); - append_local_free (current_symbol, free_locals, false); - result_block.add_statement (free_locals); + var cfrag = (CCodeFragment) stmt.ccodenode; - result_block.add_statement (complete_async ()); + cfrag.append (complete_async ()); } public override void generate_cparameters (Method m, CCodeDeclarationSpace decl_space, Map cparam_map, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, Map? carg_map = null, CCodeFunctionCall? vcall = null, int direction = 3) {