vala r1949 - in trunk: . ccode gobject vala



Author: juergbi
Date: Sat Nov  1 20:34:39 2008
New Revision: 1949
URL: http://svn.gnome.org/viewvc/vala?rev=1949&view=rev

Log:
2008-11-01  JÃrg Billeter  <j bitron ch>

	* vala/valamethod.vala:
	* ccode/valaccodeblock.vala:
	* gobject/valaccodebasemodule.vala:
	* gobject/valaccodegenerator.vala:
	* gobject/valaccodeinvocationexpressionmodule.vala:
	* gobject/valaccodemethodmodule.vala:
	* gobject/valaccodemodule.vala:

	Add experimental support for yield statements and coroutines


Modified:
   trunk/ChangeLog
   trunk/ccode/valaccodeblock.vala
   trunk/gobject/valaccodebasemodule.vala
   trunk/gobject/valaccodegenerator.vala
   trunk/gobject/valaccodeinvocationexpressionmodule.vala
   trunk/gobject/valaccodemethodmodule.vala
   trunk/gobject/valaccodemodule.vala
   trunk/vala/valamethod.vala

Modified: trunk/ccode/valaccodeblock.vala
==============================================================================
--- trunk/ccode/valaccodeblock.vala	(original)
+++ trunk/ccode/valaccodeblock.vala	Sat Nov  1 20:34:39 2008
@@ -59,7 +59,7 @@
 			statement.write_declaration (writer);
 
 			// determine last reachable statement
-			if (statement is CCodeLabel) {
+			if (statement is CCodeLabel || statement is CCodeCaseStatement) {
 				last_statement = null;
 			} else if (statement is CCodeReturnStatement || statement is CCodeGotoStatement
 			|| statement is CCodeContinueStatement || statement is CCodeBreakStatement) {

Modified: trunk/gobject/valaccodebasemodule.vala
==============================================================================
--- trunk/gobject/valaccodebasemodule.vala	(original)
+++ trunk/gobject/valaccodebasemodule.vala	Sat Nov  1 20:34:39 2008
@@ -241,6 +241,7 @@
 		
 		codegen.string_h_needed = false;
 		codegen.gvaluecollector_h_needed = false;
+		codegen.gio_h_needed = false;
 		codegen.dbus_glib_h_needed = false;
 		codegen.requires_free_checked = false;
 		codegen.requires_array_free = false;
@@ -344,6 +345,10 @@
 			codegen.source_include_directives.append (new CCodeIncludeDirective ("gobject/gvaluecollector.h"));
 		}
 
+		if (codegen.gio_h_needed) {
+			codegen.header_begin.append (new CCodeIncludeDirective ("gio/gio.h"));
+		}
+
 		if (codegen.dbus_glib_h_needed) {
 			codegen.source_include_directives.append (new CCodeIncludeDirective ("dbus/dbus-glib.h"));
 		}

Modified: trunk/gobject/valaccodegenerator.vala
==============================================================================
--- trunk/gobject/valaccodegenerator.vala	(original)
+++ trunk/gobject/valaccodegenerator.vala	Sat Nov  1 20:34:39 2008
@@ -88,6 +88,7 @@
 	private bool in_constructor = false;
 	public bool in_static_or_class_ctor = false;
 	public bool current_method_inner_error = false;
+	int next_coroutine_state = 1;
 
 	public DataType bool_type;
 	public DataType char_type;
@@ -132,6 +133,7 @@
 	
 	public bool string_h_needed;
 	public bool gvaluecollector_h_needed;
+	public bool gio_h_needed;
 	public bool requires_free_checked;
 	public bool requires_array_free;
 	public bool requires_array_move;
@@ -2680,7 +2682,22 @@
 
 	public override void visit_yield_statement (YieldStatement stmt) {
 		if (stmt.yield_expression == null) {
-			stmt.ccodenode = new CCodeFragment ();
+			var cfrag = new CCodeFragment ();
+			stmt.ccodenode = cfrag;
+
+			if (current_method.coroutine) {
+				var idle_call = new CCodeFunctionCall (new CCodeIdentifier ("g_idle_add"));
+				idle_call.add_argument (new CCodeCastExpression (new CCodeIdentifier (current_method.get_real_cname ()), "GSourceFunc"));
+				idle_call.add_argument (new CCodeIdentifier ("data"));
+
+				int state = next_coroutine_state++;
+
+				cfrag.append (new CCodeExpressionStatement (idle_call));
+				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 ())));
+			}
+
 			return;
 		}
 

Modified: trunk/gobject/valaccodeinvocationexpressionmodule.vala
==============================================================================
--- trunk/gobject/valaccodeinvocationexpressionmodule.vala	(original)
+++ trunk/gobject/valaccodeinvocationexpressionmodule.vala	Sat Nov  1 20:34:39 2008
@@ -348,6 +348,11 @@
 			}
 		}
 
+		if (m != null && m.coroutine) {
+			carg_map.set (codegen.get_param_pos (-1), new CCodeConstant ("NULL"));
+			carg_map.set (codegen.get_param_pos (-0.9), new CCodeConstant ("NULL"));
+		}
+
 		if (expr.tree_can_fail) {
 			// method can fail
 			codegen.current_method_inner_error = true;

Modified: trunk/gobject/valaccodemethodmodule.vala
==============================================================================
--- trunk/gobject/valaccodemethodmodule.vala	(original)
+++ trunk/gobject/valaccodemethodmodule.vala	Sat Nov  1 20:34:39 2008
@@ -36,7 +36,11 @@
 		return (method.get_attribute ("NoWrapper") == null);
 	}
 
-	public override string? get_custom_creturn_type (Method m) {
+	public override string? get_custom_creturn_type (Method m) {
+		if (m.coroutine) {
+			return "gboolean";
+		}
+
 		var attr = m.get_attribute ("CCode");
 		if (attr != null) {
 			string type = attr.get_string ("type");
@@ -217,7 +221,14 @@
 			cparam_map.set (codegen.get_param_pos (m.cinstance_parameter_position), class_param);
 		}
 
-		generate_cparameters (m, creturn_type, in_gtypeinstance_creation_method, cparam_map, codegen.function, vdeclarator);
+		if (!m.coroutine) {
+			generate_cparameters (m, creturn_type, in_gtypeinstance_creation_method, cparam_map, codegen.function, vdeclarator);
+		} else {
+			// data struct to hold parameters, local variables, and the return value
+			cparam_map.set (codegen.get_param_pos (0), new CCodeFormalParameter ("data", Symbol.lower_case_to_camel_case (m.get_cname ()) + "Data*"));
+
+			generate_cparameters (m, creturn_type, in_gtypeinstance_creation_method, cparam_map, codegen.function, vdeclarator, null, null, 0);
+		}
 
 		bool visible = !m.is_internal_symbol ();
 
@@ -244,6 +255,16 @@
 				var cinit = new CCodeFragment ();
 				codegen.function.block.prepend_statement (cinit);
 
+				if (m.coroutine) {
+					var cswitch = new CCodeSwitchStatement (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "state"));
+					cswitch.add_statement (new CCodeCaseStatement (new CCodeConstant ("0")));
+					cswitch.add_statement (codegen.function.block);
+					cswitch.add_statement (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
+
+					codegen.function.block = new CCodeBlock ();
+					codegen.function.block.add_statement (cswitch);
+				}
+
 				if (m.parent_symbol is Class) {
 					var cl = (Class) m.parent_symbol;
 					if (m.overrides || (m.base_interface_method != null && !m.is_abstract && !m.is_virtual)) {
@@ -514,7 +535,96 @@
 			}
 			codegen.source_type_member_definition.append (vfunc);
 		}
-		
+
+		if (m.coroutine) {
+			codegen.gio_h_needed = true;
+
+			// generate struct to hold parameters, local variables, and the return value
+			string dataname = Symbol.lower_case_to_camel_case (m.get_cname ()) + "Data";
+			var datastruct = new CCodeStruct ("_" + dataname);
+
+			datastruct.add_field ("int", "state");
+			datastruct.add_field ("GAsyncReadyCallback", "callback");
+			datastruct.add_field ("gpointer", "user_data");
+
+			foreach (FormalParameter param in m.get_parameters ()) {
+				datastruct.add_field (param.parameter_type.get_cname (), param.name);
+			}
+
+			if (!(m.return_type is VoidType)) {
+				datastruct.add_field (m.return_type.get_cname (), "result");
+			}
+
+			codegen.source_type_definition.append (datastruct);
+			codegen.source_type_declaration.append (new CCodeTypeDefinition ("struct _" + dataname, new CCodeVariableDeclarator (dataname)));
+
+			// generate async function
+			var asyncfunc = new CCodeFunction (m.get_cname (), "void");
+			asyncfunc.line = codegen.function.line;
+
+			cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
+
+			var asyncblock = new CCodeBlock ();
+
+			var dataalloc = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_new0"));
+			dataalloc.add_argument (new CCodeIdentifier (dataname));
+
+			var datadecl = new CCodeDeclaration (dataname + "*");
+			datadecl.add_declarator (new CCodeVariableDeclarator ("data"));
+			asyncblock.add_statement (datadecl);
+			asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("data"), dataalloc)));
+
+			asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "callback"), new CCodeIdentifier ("callback"))));
+			asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "user_data"), new CCodeIdentifier ("user_data"))));
+
+			foreach (FormalParameter param in m.get_parameters ()) {
+				asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), param.name), new CCodeIdentifier (param.name))));
+			}
+
+			var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_real_cname ()));
+			ccall.add_argument (new CCodeIdentifier ("data"));
+			asyncblock.add_statement (new CCodeExpressionStatement (ccall));
+
+			cparam_map.set (codegen.get_param_pos (-1), new CCodeFormalParameter ("callback", "GAsyncReadyCallback"));
+			cparam_map.set (codegen.get_param_pos (-0.9), new CCodeFormalParameter ("user_data", "gpointer"));
+
+			generate_cparameters (m, creturn_type, in_gtypeinstance_creation_method, cparam_map, asyncfunc, null, null, null, 1);
+
+			if (visible) {
+				codegen.header_type_member_declaration.append (asyncfunc.copy ());
+			} else {
+				asyncfunc.modifiers |= CCodeModifiers.STATIC;
+				codegen.source_type_member_declaration.append (asyncfunc.copy ());
+			}
+			
+			asyncfunc.block = asyncblock;
+
+			codegen.source_type_member_definition.append (asyncfunc);
+
+			// generate finish function
+			var finishfunc = new CCodeFunction (m.get_cname () + "_finish", creturn_type.get_cname ());
+			finishfunc.line = codegen.function.line;
+
+			cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
+
+			var finishblock = new CCodeBlock ();
+
+			cparam_map.set (codegen.get_param_pos (0.1), new CCodeFormalParameter ("res", "GAsyncResult*"));
+
+			generate_cparameters (m, creturn_type, in_gtypeinstance_creation_method, cparam_map, finishfunc, null, null, null, 2);
+
+			if (visible) {
+				codegen.header_type_member_declaration.append (finishfunc.copy ());
+			} else {
+				finishfunc.modifiers |= CCodeModifiers.STATIC;
+				codegen.source_type_member_declaration.append (finishfunc.copy ());
+			}
+			
+			finishfunc.block = finishblock;
+
+			codegen.source_type_member_definition.append (finishfunc);
+		}
+
 		if (m is CreationMethod) {
 			if (codegen.current_class != null && !codegen.current_class.is_compact) {
 				var vfunc = new CCodeFunction (m.get_cname (), creturn_type.get_cname ());
@@ -618,7 +728,7 @@
 		}
 	}
 
-	public override void generate_cparameters (Method m, DataType creturn_type, bool in_gtypeinstance_creation_method, Map<int,CCodeFormalParameter> cparam_map, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, Map<int,CCodeExpression>? carg_map = null, CCodeFunctionCall? vcall = null) {
+	public override void generate_cparameters (Method m, DataType creturn_type, bool in_gtypeinstance_creation_method, Map<int,CCodeFormalParameter> cparam_map, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, Map<int,CCodeExpression>? carg_map = null, CCodeFunctionCall? vcall = null, int direction = 3) {
 		if (in_gtypeinstance_creation_method) {
 			// memory management for generic types
 			int type_param_index = 0;
@@ -636,6 +746,18 @@
 		}
 
 		foreach (FormalParameter param in m.get_parameters ()) {
+			if (param.direction != ParameterDirection.OUT) {
+				if ((direction & 1) == 0) {
+					// no in paramters
+					continue;
+				}
+			} else {
+				if ((direction & 2) == 0) {
+					// no out paramters
+					continue;
+				}
+			}
+
 			if (!param.no_array_length && param.parameter_type is ArrayType) {
 				var array_type = (ArrayType) param.parameter_type;
 				
@@ -684,35 +806,37 @@
 			}
 		}
 
-		if (!m.no_array_length && creturn_type is ArrayType) {
-			// return array length if appropriate
-			var array_type = (ArrayType) creturn_type;
-
-			for (int dim = 1; dim <= array_type.rank; dim++) {
-				var cparam = new CCodeFormalParameter (head.get_array_length_cname ("result", dim), "int*");
-				cparam_map.set (codegen.get_param_pos (m.carray_length_parameter_position + 0.01 * dim), cparam);
-				if (carg_map != null) {
-					carg_map.set (codegen.get_param_pos (m.carray_length_parameter_position + 0.01 * dim), new CCodeIdentifier (cparam.name));
+		if ((direction & 2) != 0) {
+			if (!m.no_array_length && creturn_type is ArrayType) {
+				// return array length if appropriate
+				var array_type = (ArrayType) creturn_type;
+
+				for (int dim = 1; dim <= array_type.rank; dim++) {
+					var cparam = new CCodeFormalParameter (head.get_array_length_cname ("result", dim), "int*");
+					cparam_map.set (codegen.get_param_pos (m.carray_length_parameter_position + 0.01 * dim), cparam);
+					if (carg_map != null) {
+						carg_map.set (codegen.get_param_pos (m.carray_length_parameter_position + 0.01 * dim), new CCodeIdentifier (cparam.name));
+					}
 				}
-			}
-		} else if (creturn_type is DelegateType) {
-			// return delegate target if appropriate
-			var deleg_type = (DelegateType) creturn_type;
-			var d = deleg_type.delegate_symbol;
-			if (d.has_target) {
-				var cparam = new CCodeFormalParameter (codegen.get_delegate_target_cname ("result"), "void*");
-				cparam_map.set (codegen.get_param_pos (m.cdelegate_target_parameter_position), cparam);
-				if (carg_map != null) {
-					carg_map.set (codegen.get_param_pos (m.cdelegate_target_parameter_position), new CCodeIdentifier (cparam.name));
+			} else if (creturn_type is DelegateType) {
+				// return delegate target if appropriate
+				var deleg_type = (DelegateType) creturn_type;
+				var d = deleg_type.delegate_symbol;
+				if (d.has_target) {
+					var cparam = new CCodeFormalParameter (codegen.get_delegate_target_cname ("result"), "void*");
+					cparam_map.set (codegen.get_param_pos (m.cdelegate_target_parameter_position), cparam);
+					if (carg_map != null) {
+						carg_map.set (codegen.get_param_pos (m.cdelegate_target_parameter_position), new CCodeIdentifier (cparam.name));
+					}
 				}
 			}
-		}
 
-		if (m.get_error_types ().size > 0) {
-			var cparam = new CCodeFormalParameter ("error", "GError**");
-			cparam_map.set (codegen.get_param_pos (-1), cparam);
-			if (carg_map != null) {
-				carg_map.set (codegen.get_param_pos (-1), new CCodeIdentifier (cparam.name));
+			if (m.get_error_types ().size > 0) {
+				var cparam = new CCodeFormalParameter ("error", "GError**");
+				cparam_map.set (codegen.get_param_pos (-1), cparam);
+				if (carg_map != null) {
+					carg_map.set (codegen.get_param_pos (-1), new CCodeIdentifier (cparam.name));
+				}
 			}
 		}
 

Modified: trunk/gobject/valaccodemodule.vala
==============================================================================
--- trunk/gobject/valaccodemodule.vala	(original)
+++ trunk/gobject/valaccodemodule.vala	Sat Nov  1 20:34:39 2008
@@ -100,8 +100,8 @@
 		next.visit_array_creation_expression (expr);
 	}
 
-	public virtual void generate_cparameters (Method m, DataType creturn_type, bool in_gtypeinstance_creation_method, Map<int,CCodeFormalParameter> cparam_map, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, Map<int,CCodeExpression>? carg_map = null, CCodeFunctionCall? vcall = null) {
-		next.generate_cparameters (m, creturn_type, in_gtypeinstance_creation_method, cparam_map, func, vdeclarator, carg_map, vcall);
+	public virtual void generate_cparameters (Method m, DataType creturn_type, bool in_gtypeinstance_creation_method, Map<int,CCodeFormalParameter> cparam_map, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, Map<int,CCodeExpression>? carg_map = null, CCodeFunctionCall? vcall = null, int direction = 3) {
+		next.generate_cparameters (m, creturn_type, in_gtypeinstance_creation_method, cparam_map, func, vdeclarator, carg_map, vcall, direction);
 	}
 
 	public virtual string? get_custom_creturn_type (Method m) {

Modified: trunk/vala/valamethod.vala
==============================================================================
--- trunk/vala/valamethod.vala	(original)
+++ trunk/vala/valamethod.vala	Sat Nov  1 20:34:39 2008
@@ -338,8 +338,8 @@
 	 * @return the name to be used in C code
 	 */
 	public virtual string get_real_cname () {
-		if (base_method != null || base_interface_method != null) {
-			return "%s_real_%s".printf (parent_symbol.get_lower_case_cname (null), name);
+		if (base_method != null || base_interface_method != null || coroutine) {
+			return "%sreal_%s".printf (parent_symbol.get_lower_case_cprefix (), name);
 		} else {
 			return get_cname ();
 		}



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