From: Jürg Billeter Date: Thu, 4 Jun 2009 11:24:07 +0000 (+0200) Subject: Use result variable in C for method results X-Git-Tag: 0.7.4~54 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=84923b2355a95ff1105c1f4219bbc261abec455f;p=thirdparty%2Fvala.git Use result variable in C for method results This eliminates the long C return statements and will help when adding support for postconditions in normal methods. --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 36e2b2cd9..9ce9d0840 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -1335,6 +1335,12 @@ internal class Vala.CCodeBaseModule : CCodeModule { function.block.prepend_statement (cdecl); } + if (acc.readable) { + var cdecl = new CCodeDeclaration (acc.value_type.get_cname ()); + cdecl.add_declarator (new CCodeVariableDeclarator ("result")); + function.block.prepend_statement (cdecl); + } + if (current_method_inner_error) { var cdecl = new CCodeDeclaration ("GError *"); cdecl.add_declarator (new CCodeVariableDeclarator ("_inner_error_", new CCodeConstant ("NULL"))); @@ -2212,7 +2218,7 @@ internal class Vala.CCodeBaseModule : CCodeModule { stmt.ccodenode = cfrag; } - public void append_local_free (Symbol sym, CCodeFragment cfrag, bool stop_at_loop) { + public void append_local_free (Symbol sym, CCodeFragment cfrag, bool stop_at_loop = false) { var b = (Block) sym; var local_vars = b.get_local_variables (); @@ -2281,7 +2287,7 @@ internal class Vala.CCodeBaseModule : CCodeModule { stmt.ccodenode = cfrag; } - private bool append_local_free_expr (Symbol sym, CCodeCommaExpression ccomma, bool stop_at_loop) { + private bool append_local_free_expr (Symbol sym, CCodeCommaExpression ccomma, bool stop_at_loop = false) { bool found = false; var b = (Block) sym; @@ -2320,28 +2326,6 @@ internal class Vala.CCodeBaseModule : CCodeModule { return found; } - private void create_local_free_expr (Expression expr) { - var expr_type = expr.value_type; - if (expr.target_type != null) { - expr_type = expr.target_type; - } - - var return_expr_decl = get_temp_variable (expr_type, true, expr); - - var ccomma = new CCodeCommaExpression (); - ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (return_expr_decl.name), (CCodeExpression) expr.ccodenode)); - - if (!append_local_free_expr (current_symbol, ccomma, false)) { - /* no local variables need to be freed */ - return; - } - - ccomma.append_expression (get_variable_cexpression (return_expr_decl.name)); - - expr.ccodenode = ccomma; - expr.temp_vars.add (return_expr_decl); - } - public override void visit_return_statement (ReturnStatement stmt) { // avoid unnecessary ref/unref pair if (stmt.return_expression != null) { @@ -2398,7 +2382,13 @@ internal class Vala.CCodeBaseModule : CCodeModule { stmt.return_expression.temp_vars.add (return_expr_decl); } - create_local_free_expr (stmt.return_expression); + var cfrag = new CCodeFragment (); + + // assign method result to `result' + cfrag.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), (CCodeExpression) stmt.return_expression.ccodenode))); + + // free local variables + append_local_free (current_symbol, cfrag); // Property getters of non simple structs shall return the struct value as out parameter, // therefore replace any return statement with an assignment statement to the out formal @@ -2406,14 +2396,14 @@ internal class Vala.CCodeBaseModule : CCodeModule { if (current_property_accessor != null && current_property_accessor.readable && current_property_accessor.prop.property_type.is_real_struct_type()) { - var cfragment = new CCodeFragment (); - cfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("*value"), (CCodeExpression) stmt.return_expression.ccodenode))); - cfragment.append (new CCodeReturnStatement ()); - stmt.ccodenode = cfragment; + cfrag.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("*value"), new CCodeIdentifier ("result")))); + cfrag.append (new CCodeReturnStatement ()); } else { - stmt.ccodenode = new CCodeReturnStatement ((CCodeExpression) stmt.return_expression.ccodenode); + cfrag.append (new CCodeReturnStatement (new CCodeIdentifier ("result"))); } + stmt.ccodenode = cfrag; + create_temp_decl (stmt, stmt.return_expression.temp_vars); if (return_expression_symbol != null) { diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala index e1e3de1af..ecf151967 100644 --- a/codegen/valaccodemethodmodule.vala +++ b/codegen/valaccodemethodmodule.vala @@ -431,6 +431,12 @@ internal class Vala.CCodeMethodModule : CCodeStructModule { } } + if (!(m.return_type is VoidType)) { + var cdecl = new CCodeDeclaration (m.return_type.get_cname ()); + cdecl.add_declarator (new CCodeVariableDeclarator ("result")); + cinit.append (cdecl); + } + if (inner_error) { /* always separate error parameter and inner_error local variable * as error may be set to NULL but we're always interested in inner errors