]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Separate async state switch from the code using goto and labels
authorLuca Bruno <lethalman88@gmail.com>
Wed, 10 Mar 2010 10:26:56 +0000 (11:26 +0100)
committerJürg Billeter <j@bitron.ch>
Sun, 21 Mar 2010 22:58:00 +0000 (23:58 +0100)
Fixes bug 602200.

codegen/valaccodebasemodule.vala
codegen/valaccodemethodcallmodule.vala
codegen/valaccodemethodmodule.vala
codegen/valagasyncmodule.vala

index ea136b213862113d097b628b3df27de2ff23add5..2633f8d0342908fc98a4647be2ae5fffba5011d8 100644 (file)
@@ -135,6 +135,8 @@ internal class Vala.CCodeBaseModule : CCodeModule {
        // code nodes to be inserted before the current statement
        // used by async method calls in coroutines
        public CCodeFragment pre_statement_fragment;
+       // case statements to be inserted for the couroutine state
+       public CCodeSwitchStatement state_switch_statement;
 
        /* all temporary variables */
        public ArrayList<LocalVariable> temp_vars = new ArrayList<LocalVariable> ();
index 8439beca3a206be632606bf01eba964f3feba6a5..9545c4e84f8ddf0fe03d2dee88341c362f505c8b 100644 (file)
@@ -715,12 +715,14 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 
                        // set state before calling async function to support immediate callbacks
                        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 CCodeExpressionStatement (async_call));
+                       state_switch_statement.add_statement (new CCodeCaseStatement (new CCodeConstant (state.to_string ())));
+                       state_switch_statement.add_statement (new CCodeGotoStatement ("_state_%d".printf (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 CCodeExpressionStatement (async_call));
                        pre_statement_fragment.append (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
-                       pre_statement_fragment.append (new CCodeCaseStatement (new CCodeConstant (state.to_string ())));
+                       pre_statement_fragment.append (new CCodeLabel ("_state_%d".printf (state)));
                }
 
                if (m is ArrayResizeMethod) {
index 39f264ac2c8498eda6fde91995b60f33f0e6cbfe..35257f1e18510420512e436d8129f03cbdde3fa8 100644 (file)
@@ -268,6 +268,7 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
                var old_temp_ref_vars = temp_ref_vars;
                var old_variable_name_map = variable_name_map;
                var old_try = current_try;
+               var old_state_switch_statement = state_switch_statement;
                current_symbol = m;
                current_method_inner_error = false;
                next_temp_var_id = 0;
@@ -275,6 +276,7 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
                temp_ref_vars = new ArrayList<LocalVariable> ();
                variable_name_map = new HashMap<string,string> (str_hash, str_equal);
                current_try = null;
+               state_switch_statement = null;
 
                bool in_gobject_creation_method = false;
                bool in_fundamental_creation_method = false;
@@ -292,6 +294,15 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
                        }
                }
 
+               if (m.coroutine) {
+                       state_switch_statement = new CCodeSwitchStatement (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_state_"));
+
+                       // initial coroutine state
+                       state_switch_statement.add_statement (new CCodeCaseStatement (new CCodeConstant ("0")));
+                       state_switch_statement.add_statement (new CCodeGotoStatement ("_state_0"));
+               }
+               var current_state_switch = state_switch_statement;
+
                var creturn_type = m.return_type;
                if (m.return_type.is_real_non_null_struct_type ()) {
                        // structs are returned via out parameter
@@ -390,6 +401,7 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
                temp_ref_vars = old_temp_ref_vars;
                variable_name_map = old_variable_name_map;
                current_try = old_try;
+               state_switch_statement = old_state_switch_statement;
 
                // do not declare overriding methods and interface implementations
                if (m.is_abstract || m.is_virtual
@@ -446,23 +458,19 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
                                        co_function.modifiers |= CCodeModifiers.STATIC;
                                        source_declarations.add_type_member_declaration (co_function.copy ());
 
-                                       var cswitch = new CCodeSwitchStatement (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_state_"));
-
                                        // let gcc know that this can't happen
-                                       cswitch.add_statement (new CCodeLabel ("default"));
-                                       cswitch.add_statement (new CCodeExpressionStatement (new CCodeFunctionCall (new CCodeIdentifier ("g_assert_not_reached"))));
+                                       current_state_switch.add_statement (new CCodeLabel ("default"));
+                                       current_state_switch.add_statement (new CCodeExpressionStatement (new CCodeFunctionCall (new CCodeIdentifier ("g_assert_not_reached"))));
 
-                                       // initial coroutine state
-                                       cswitch.add_statement (new CCodeCaseStatement (new CCodeConstant ("0")));
+                                       co_function.block = new CCodeBlock ();
+                                       co_function.block.add_statement (current_state_switch);
 
                                        // coroutine body
-                                       cswitch.add_statement (function.block);
+                                       co_function.block.add_statement (new CCodeLabel ("_state_0"));
+                                       co_function.block.add_statement (function.block);
 
                                        // epilogue
-                                       cswitch.add_statement (complete_async ());
-
-                                       co_function.block = new CCodeBlock ();
-                                       co_function.block.add_statement (cswitch);
+                                       co_function.block.add_statement (complete_async ());
 
                                        source_type_member_definition.append (co_function);
                                }
index e6ffb0d6c99bc4066590eeabf776a554e705e6ee..c9d9d769fdab6fa8d6384179b2faf5ca2b3a2b20 100644 (file)
@@ -519,9 +519,12 @@ internal class Vala.GAsyncModule : GSignalModule {
 
                        int state = next_coroutine_state++;
 
+                       state_switch_statement.add_statement (new CCodeCaseStatement (new CCodeConstant (state.to_string ())));
+                       state_switch_statement.add_statement (new CCodeGotoStatement ("_state_%d".printf (state)));
+
                        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 ())));
+                       cfrag.append (new CCodeLabel ("_state_%d".printf (state)));
                        cfrag.append (new CCodeEmptyStatement ());
 
                        return;