[vala] GAsync: Fix async methods returning arrays or delegates



commit 5a2bfdf3fd3c96bc8d7ebffa3f658c91ff34738d
Author: Jürg Billeter <j bitron ch>
Date:   Wed Sep 16 18:12:18 2009 +0200

    GAsync: Fix async methods returning arrays or delegates

 codegen/valaccodearraymodule.vala      |    8 +++---
 codegen/valaccodebasemodule.vala       |   41 +++++++++++++++++++++++--------
 codegen/valaccodedelegatemodule.vala   |   10 ++++----
 codegen/valaccodemethodcallmodule.vala |    4 +-
 codegen/valagasyncmodule.vala          |   41 +++++++++++++++++--------------
 5 files changed, 63 insertions(+), 41 deletions(-)
---
diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala
index 0dc1572..2121dc7 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 ac7b3d6..e9ac207 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 2aab947..182cf5a 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 f11b279..b3c9ea5 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 a60eeb1..1c33906 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<int,CCodeFormalParameter> cparam_map, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, Map<int,CCodeExpression>? carg_map = null, CCodeFunctionCall? vcall = null, int direction = 3) {



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