]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Add partial support for calling coroutines from other coroutines
authorJürg Billeter <j@bitron.ch>
Sun, 2 Nov 2008 15:15:42 +0000 (15:15 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Sun, 2 Nov 2008 15:15:42 +0000 (15:15 +0000)
2008-11-02  Jürg Billeter  <j@bitron.ch>

* gobject/valaccodegenerator.vala:
* gobject/valaccodeinvocationexpressionmodule.vala:
* gobject/valaccodemethodmodule.vala:

Add partial support for calling coroutines from other coroutines

svn path=/trunk/; revision=1952

ChangeLog
gobject/valaccodegenerator.vala
gobject/valaccodeinvocationexpressionmodule.vala
gobject/valaccodemethodmodule.vala

index 0fd58f2153ae974e2ef7866278f7891ea2c07171..ad37e4e1a237c830492cfcc1c40006440c76cbe5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2008-11-02  Jürg Billeter  <j@bitron.ch>
+
+       * gobject/valaccodegenerator.vala:
+       * gobject/valaccodeinvocationexpressionmodule.vala:
+       * gobject/valaccodemethodmodule.vala:
+
+       Add partial support for calling coroutines from other coroutines
+
 2008-11-02  Jürg Billeter  <j@bitron.ch>
 
        * vala/valamethodtype.vala:
index 04ce826b1d50b1175a604c306793781f855c9dbf..f0e2e1827ed73967c2794e67a1af501454ea6bda 100644 (file)
@@ -1900,6 +1900,25 @@ public class Vala.CCodeGenerator : CodeGenerator {
 
                stmt.ccodenode = new CCodeExpressionStatement ((CCodeExpression) stmt.expression.ccodenode);
 
+               var invoc = stmt.expression as InvocationExpression;
+               if (invoc != null) {
+                       var m = invoc.call.symbol_reference as Method;
+                       var ma = invoc.call as MemberAccess;
+                       if (m != null && m.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
 
index 42fd0cdd7387a7ffe0ac282076205980e1582e4f..d571e67e35a0e24bc55d936270263b56c8244e76 100644 (file)
@@ -349,8 +349,14 @@ public class Vala.CCodeInvocationExpressionModule : CCodeModule {
                }
 
                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 (ma.member_name == "begin" && ma.inner.symbol_reference == ma.symbol_reference) {
+                               // asynchronous begin call
+                               carg_map.set (codegen.get_param_pos (-1), new CCodeConstant ("NULL"));
+                               carg_map.set (codegen.get_param_pos (-0.9), new CCodeConstant ("NULL"));
+                       } else {
+                               carg_map.set (codegen.get_param_pos (-1), new CCodeIdentifier (codegen.current_method.get_cname () + "_ready"));
+                               carg_map.set (codegen.get_param_pos (-0.9), new CCodeIdentifier ("data"));
+                       }
                }
 
                if (expr.tree_can_fail) {
index b87fb020c6e7334dcd679e0bbf0e526d56fe2a09..1b0dd34b367d9dbfd98b4abe835b4619060b5dff 100644 (file)
@@ -257,8 +257,29 @@ public class Vala.CCodeMethodModule : CCodeModule {
 
                                if (m.coroutine) {
                                        var cswitch = new CCodeSwitchStatement (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "state"));
+
+                                       // initial coroutine state
                                        cswitch.add_statement (new CCodeCaseStatement (new CCodeConstant ("0")));
+
+                                       // coroutine body
                                        cswitch.add_statement (codegen.function.block);
+
+                                       // complete async call by invoking callback
+                                       var object_creation = new CCodeFunctionCall (new CCodeIdentifier ("g_object_newv"));
+                                       object_creation.add_argument (new CCodeConstant ("G_TYPE_OBJECT"));
+                                       object_creation.add_argument (new CCodeConstant ("0"));
+                                       object_creation.add_argument (new CCodeConstant ("NULL"));
+
+                                       var async_result_creation = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_new"));
+                                       async_result_creation.add_argument (object_creation);
+                                       async_result_creation.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "callback"));
+                                       async_result_creation.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "user_data"));
+                                       async_result_creation.add_argument (new CCodeIdentifier ("data"));
+
+                                       var completecall = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_complete"));
+                                       completecall.add_argument (async_result_creation);
+                                       cswitch.add_statement (new CCodeExpressionStatement (completecall));
+
                                        cswitch.add_statement (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
 
                                        codegen.function.block = new CCodeBlock ();
@@ -546,6 +567,7 @@ public class Vala.CCodeMethodModule : CCodeModule {
                        datastruct.add_field ("int", "state");
                        datastruct.add_field ("GAsyncReadyCallback", "callback");
                        datastruct.add_field ("gpointer", "user_data");
+                       datastruct.add_field ("GAsyncResult*", "res");
 
                        foreach (FormalParameter param in m.get_parameters ()) {
                                datastruct.add_field (param.parameter_type.get_cname (), param.name);
@@ -623,6 +645,33 @@ public class Vala.CCodeMethodModule : CCodeModule {
                        finishfunc.block = finishblock;
 
                        codegen.source_type_member_definition.append (finishfunc);
+
+                       // generate ready callback handler
+                       var readyfunc = new CCodeFunction (m.get_cname () + "_ready", "void");
+                       readyfunc.line = codegen.function.line;
+
+                       readyfunc.add_parameter (new CCodeFormalParameter ("source_object", "GObject*"));
+                       readyfunc.add_parameter (new CCodeFormalParameter ("res", "GAsyncResult*"));
+                       readyfunc.add_parameter (new CCodeFormalParameter ("user_data", "gpointer"));
+
+                       var readyblock = new CCodeBlock ();
+
+                       datadecl = new CCodeDeclaration (dataname + "*");
+                       datadecl.add_declarator (new CCodeVariableDeclarator ("data"));
+                       readyblock.add_statement (datadecl);
+                       readyblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("data"), new CCodeIdentifier ("user_data"))));
+                       readyblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "res"), new CCodeIdentifier ("res"))));
+
+                       ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_real_cname ()));
+                       ccall.add_argument (new CCodeIdentifier ("data"));
+                       readyblock.add_statement (new CCodeExpressionStatement (ccall));
+
+                       readyfunc.modifiers |= CCodeModifiers.STATIC;
+                       codegen.source_type_member_declaration.append (readyfunc.copy ());
+
+                       readyfunc.block = readyblock;
+
+                       codegen.source_type_member_definition.append (readyfunc);
                }
 
                if (m is CreationMethod) {