vala r2225 - in trunk: . gobject



Author: juergbi
Date: Fri Dec 19 17:17:32 2008
New Revision: 2225
URL: http://svn.gnome.org/viewvc/vala?rev=2225&view=rev

Log:
2008-12-19  JÃrg Billeter  <j bitron ch>

	* gobject/valaccodebasemodule.vala:
	* gobject/valaccodemethodcallmodule.vala:

	Generate async and finish calls when calling async methods from
	coroutines


Modified:
   trunk/ChangeLog
   trunk/gobject/valaccodebasemodule.vala
   trunk/gobject/valaccodemethodcallmodule.vala

Modified: trunk/gobject/valaccodebasemodule.vala
==============================================================================
--- trunk/gobject/valaccodebasemodule.vala	(original)
+++ trunk/gobject/valaccodebasemodule.vala	Fri Dec 19 17:17:32 2008
@@ -69,7 +69,11 @@
 	public CCodeEnum cenum;
 	public CCodeFunction function;
 	public CCodeBlock block;
-	
+
+	// code nodes to be inserted before the current statement
+	// used by async method calls in coroutines
+	public CCodeFragment pre_statement_fragment;
+
 	/* all temporary variables */
 	public ArrayList<LocalVariable> temp_vars = new ArrayList<LocalVariable> ();
 	/* temporary variables that own their content */
@@ -1479,6 +1483,11 @@
 
 		var cfrag = new CCodeFragment ();
 
+		if (pre_statement_fragment != null) {
+			cfrag.append (pre_statement_fragment);
+			pre_statement_fragment = null;
+		}
+
 		if (current_method != null && current_method.coroutine) {
 			closure_struct.add_field (local.variable_type.get_cname (), get_variable_cname (local.name));
 
@@ -1937,25 +1946,6 @@
 
 		stmt.ccodenode = new CCodeExpressionStatement ((CCodeExpression) stmt.expression.ccodenode);
 
-		var invoc = stmt.expression as MethodCall;
-		if (invoc != null) {
-			var m = invoc.call.symbol_reference as Method;
-			var ma = invoc.call as MemberAccess;
-			if (m != null && m.coroutine && current_method != null && current_method.coroutine &&
-			    (ma == null || ma.member_name != "begin" || ma.inner.symbol_reference != ma.symbol_reference)) {
-				var cfrag = new CCodeFragment ();
-
-				int state = next_coroutine_state++;
-
-				cfrag.append (stmt.ccodenode);
-				cfrag.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "state"), new CCodeConstant (state.to_string ()))));
-				cfrag.append (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
-				cfrag.append (new CCodeCaseStatement (new CCodeConstant (state.to_string ())));
-
-				stmt.ccodenode = cfrag;
-			}
-		}
-
 		if (stmt.tree_can_fail && stmt.expression.tree_can_fail) {
 			// simple case, no node breakdown necessary
 
@@ -1977,7 +1967,12 @@
 		
 		var cfrag = new CCodeFragment ();
 		append_temp_decl (cfrag, temp_vars);
-		
+
+		if (pre_statement_fragment != null) {
+			cfrag.append (pre_statement_fragment);
+			pre_statement_fragment = null;
+		}
+
 		cfrag.append (stmt.ccodenode);
 		
 		foreach (LocalVariable local in temp_ref_vars) {

Modified: trunk/gobject/valaccodemethodcallmodule.vala
==============================================================================
--- trunk/gobject/valaccodemethodcallmodule.vala	(original)
+++ trunk/gobject/valaccodemethodcallmodule.vala	Fri Dec 19 17:17:32 2008
@@ -35,6 +35,8 @@
 		// the bare function call
 		var ccall = new CCodeFunctionCall ((CCodeExpression) expr.call.ccodenode);
 
+		CCodeFunctionCall async_call = null;
+
 		Method m = null;
 		Gee.List<FormalParameter> params;
 		
@@ -60,6 +62,32 @@
 			ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_real_cname ()));
 		}
 
+		HashMap<int,CCodeExpression> in_arg_map, out_arg_map;
+
+		if (m != null && m.coroutine
+		    && ((current_method != null && current_method.coroutine)
+		        || (ma.member_name == "begin" && ma.inner.symbol_reference == ma.symbol_reference))) {
+			// async call
+
+			in_arg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
+			out_arg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
+
+			async_call = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname () + "_async"));
+
+			if (ma.member_name == "begin" && ma.inner.symbol_reference == ma.symbol_reference) {
+				// no finish call
+				ccall = async_call;
+			} else {
+				ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname () + "_finish"));
+
+				// pass GAsyncResult stored in closure to finish function
+				out_arg_map.set (get_param_pos (0.1), new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "res"));
+			}
+		} else {
+			in_arg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
+			out_arg_map = in_arg_map;
+		}
+
 		if (m is CreationMethod) {
 			ccall.add_argument (new CCodeIdentifier ("object_type"));
 		}
@@ -67,11 +95,9 @@
 		// the complete call expression, might include casts, comma expressions, and/or assignments
 		CCodeExpression ccall_expr = ccall;
 
-		var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
-
 		if (m is ArrayResizeMethod) {
 			var array_type = (ArrayType) ma.inner.value_type;
-			carg_map.set (get_param_pos (0), new CCodeIdentifier (array_type.element_type.get_cname ()));
+			in_arg_map.set (get_param_pos (0), new CCodeIdentifier (array_type.element_type.get_cname ()));
 		} else if (m is ArrayMoveMethod) {
 			requires_array_move = true;
 		}
@@ -103,7 +129,8 @@
 				}
 			}
 
-			carg_map.set (get_param_pos (m.cinstance_parameter_position), instance);
+			in_arg_map.set (get_param_pos (m.cinstance_parameter_position), instance);
+			out_arg_map.set (get_param_pos (m.cinstance_parameter_position), instance);
 		} else if (m != null && m.binding == MemberBinding.CLASS) {
 			var cl = (Class) m.parent_symbol;
 			var cast = new CCodeFunctionCall (new CCodeIdentifier (cl.get_upper_case_cname (null) + "_CLASS"));
@@ -127,14 +154,15 @@
 			}
 
 			cast.add_argument (klass);
-			carg_map.set (get_param_pos (m.cinstance_parameter_position), cast);
+			in_arg_map.set (get_param_pos (m.cinstance_parameter_position), cast);
+			out_arg_map.set (get_param_pos (m.cinstance_parameter_position), cast);
 		}
 
 		if (m is ArrayMoveMethod) {
 			var array_type = (ArrayType) ma.inner.value_type;
 			var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
 			csizeof.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
-			carg_map.set (get_param_pos (0.1), csizeof);
+			in_arg_map.set (get_param_pos (0.1), csizeof);
 		} else if (m is DynamicMethod) {
 			m.clear_parameters ();
 			int param_nr = 1;
@@ -171,6 +199,9 @@
 		Iterator<FormalParameter> params_it = params.iterator ();
 		foreach (Expression arg in expr.get_argument_list ()) {
 			CCodeExpression cexpr = (CCodeExpression) arg.ccodenode;
+
+			var carg_map = in_arg_map;
+
 			if (params_it.next ()) {
 				var param = params_it.get ();
 				ellipsis = param.params_array || param.ellipsis;
@@ -182,6 +213,10 @@
 					// http://bugzilla.gnome.org/show_bug.cgi?id=519597
 					bool multiple_cargs = false;
 
+					if (param.direction == ParameterDirection.OUT) {
+						carg_map = out_arg_map;
+					}
+
 					if (!param.no_array_length && param.parameter_type is ArrayType) {
 						var array_type = (ArrayType) param.parameter_type;
 						for (int dim = 1; dim <= array_type.rank; dim++) {
@@ -327,7 +362,7 @@
 
 					temp_vars.insert (0, temp_var);
 
-					carg_map.set (get_param_pos (m.carray_length_parameter_position + 0.01 * dim), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
+					out_arg_map.set (get_param_pos (m.carray_length_parameter_position + 0.01 * dim), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
 
 					expr.append_array_size (temp_ref);
 				} else {
@@ -343,7 +378,7 @@
 
 				temp_vars.insert (0, temp_var);
 
-				carg_map.set (get_param_pos (m.cdelegate_target_parameter_position), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
+				out_arg_map.set (get_param_pos (m.cdelegate_target_parameter_position), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
 
 				expr.delegate_target = temp_ref;
 			}
@@ -353,38 +388,37 @@
 			if ((current_method != null && current_method.coroutine)
 			    || (ma.member_name == "begin" && ma.inner.symbol_reference == ma.symbol_reference)) {
 				// asynchronous call
-				var cid = (CCodeIdentifier) ccall.call;
-				cid.name += "_async";
 				if (ma.member_name == "begin" && ma.inner.symbol_reference == ma.symbol_reference) {
-					carg_map.set (get_param_pos (-1), new CCodeConstant ("NULL"));
-					carg_map.set (get_param_pos (-0.9), new CCodeConstant ("NULL"));
+					in_arg_map.set (get_param_pos (-1), new CCodeConstant ("NULL"));
+					in_arg_map.set (get_param_pos (-0.9), new CCodeConstant ("NULL"));
 				} else {
-					carg_map.set (get_param_pos (-1), new CCodeIdentifier (current_method.get_cname () + "_ready"));
-					carg_map.set (get_param_pos (-0.9), new CCodeIdentifier ("data"));
+					in_arg_map.set (get_param_pos (-1), new CCodeIdentifier (current_method.get_cname () + "_ready"));
+					in_arg_map.set (get_param_pos (-0.9), new CCodeIdentifier ("data"));
 				}
 			}
 		}
 
 		if (m is CreationMethod && m.get_error_types ().size > 0) {
-			carg_map.set (get_param_pos (-1), new CCodeIdentifier ("error"));
+			out_arg_map.set (get_param_pos (-1), new CCodeIdentifier ("error"));
 		} else if (expr.tree_can_fail) {
 			// method can fail
 			current_method_inner_error = true;
 			// add &inner_error before the ellipsis arguments
-			carg_map.set (get_param_pos (-1), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("inner_error")));
+			out_arg_map.set (get_param_pos (-1), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("inner_error")));
 		}
 
 		if (ellipsis) {
 			/* ensure variable argument list ends with NULL
 			 * except when using printf-style arguments */
 			if (!m.printf_format && m.sentinel != "") {
-				carg_map.set (get_param_pos (-1, true), new CCodeConstant (m.sentinel));
+				in_arg_map.set (get_param_pos (-1, true), new CCodeConstant (m.sentinel));
 			}
 		} else if (itype is DelegateType) {
 			var deleg_type = (DelegateType) itype;
 			var d = deleg_type.delegate_symbol;
 			if (d.has_target) {
-				carg_map.set (get_param_pos (d.cinstance_parameter_position), get_delegate_target_cexpression (expr.call));
+				in_arg_map.set (get_param_pos (d.cinstance_parameter_position), get_delegate_target_cexpression (expr.call));
+				out_arg_map.set (get_param_pos (d.cinstance_parameter_position), get_delegate_target_cexpression (expr.call));
 			}
 		}
 
@@ -400,7 +434,7 @@
 
 				temp_vars.insert (0, temp_var);
 
-				carg_map.set (get_param_pos (-1, true), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
+				out_arg_map.set (get_param_pos (-1, true), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
 			
 				var ccomma = new CCodeCommaExpression ();
 				ccomma.append_expression ((CCodeExpression) ccall_expr);
@@ -415,7 +449,7 @@
 		int min_pos;
 		while (true) {
 			min_pos = -1;
-			foreach (int pos in carg_map.get_keys ()) {
+			foreach (int pos in out_arg_map.get_keys ()) {
 				if (pos > last_pos && (min_pos == -1 || pos < min_pos)) {
 					min_pos = pos;
 				}
@@ -423,16 +457,47 @@
 			if (min_pos == -1) {
 				break;
 			}
-			ccall.add_argument (carg_map.get (min_pos));
+			ccall.add_argument (out_arg_map.get (min_pos));
 			last_pos = min_pos;
 		}
 
+		if (async_call != null) {
+			last_pos = -1;
+			while (true) {
+				min_pos = -1;
+				foreach (int pos in in_arg_map.get_keys ()) {
+					if (pos > last_pos && (min_pos == -1 || pos < min_pos)) {
+						min_pos = pos;
+					}
+				}
+				if (min_pos == -1) {
+					break;
+				}
+				async_call.add_argument (in_arg_map.get (min_pos));
+				last_pos = min_pos;
+			}
+		}
+
 		if (m != null && m.binding == MemberBinding.INSTANCE && m.returns_modified_pointer) {
 			expr.ccodenode = new CCodeAssignment (instance, ccall_expr);
 		} else {
 			expr.ccodenode = ccall_expr;
 		}
-		
+
+		if (m != null && m.coroutine && current_method != null && current_method.coroutine) {
+			if (ma.member_name != "begin" || ma.inner.symbol_reference != ma.symbol_reference) {
+				if (pre_statement_fragment == null) {
+					pre_statement_fragment = new CCodeFragment ();
+				}
+				pre_statement_fragment.append (new CCodeExpressionStatement (async_call));
+
+				int state = next_coroutine_state++;
+				pre_statement_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "state"), new CCodeConstant (state.to_string ()))));
+				pre_statement_fragment.append (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
+				pre_statement_fragment.append (new CCodeCaseStatement (new CCodeConstant (state.to_string ())));
+			}
+		}
+
 		if (m is ArrayResizeMethod) {
 			// FIXME: size expression must not be evaluated twice at runtime (potential side effects)
 			Iterator<Expression> arg_it = expr.get_argument_list ().iterator ();



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