vala r1949 - in trunk: . ccode gobject vala
- From: juergbi svn gnome org
- To: svn-commits-list gnome org
- Subject: vala r1949 - in trunk: . ccode gobject vala
- Date: Sat, 1 Nov 2008 20:34:39 +0000 (UTC)
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]