[vala] Use result variable in C for method results



commit 84923b2355a95ff1105c1f4219bbc261abec455f
Author: Jürg Billeter <j bitron ch>
Date:   Thu Jun 4 13:24:07 2009 +0200

    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.
---
 codegen/valaccodebasemodule.vala   |   50 ++++++++++++++---------------------
 codegen/valaccodemethodmodule.vala |    6 ++++
 2 files changed, 26 insertions(+), 30 deletions(-)

diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 36e2b2c..9ce9d08 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 e1e3de1..ecf1519 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



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]