diff options
Diffstat (limited to 'codegen')
-rw-r--r-- | codegen/valaccodeattribute.vala | 6 | ||||
-rw-r--r-- | codegen/valaccodemethodmodule.vala | 76 | ||||
-rw-r--r-- | codegen/valagasyncmodule.vala | 4 |
3 files changed, 78 insertions, 8 deletions
diff --git a/codegen/valaccodeattribute.vala b/codegen/valaccodeattribute.vala index 8cf459107..bd4c6b29d 100644 --- a/codegen/valaccodeattribute.vala +++ b/codegen/valaccodeattribute.vala @@ -762,7 +762,11 @@ public class Vala.CCodeAttribute : AttributeCache { } if (sym.name == "main" && sym.parent_symbol.name == null) { // avoid conflict with generated main function - return "_vala_main"; + if (m.coroutine) { + return "_vala_main_async"; + } else { + return "_vala_main"; + } } else if (sym.name.has_prefix ("_")) { return "_%s%s".printf (get_ccode_lower_case_prefix (sym.parent_symbol), sym.name.substring (1)); } else { diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala index ff6d679ac..9b9fd3690 100644 --- a/codegen/valaccodemethodmodule.vala +++ b/codegen/valaccodemethodmodule.vala @@ -840,6 +840,42 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule { if (m.entry_point) { // m is possible entry point, add appropriate startup code + + if (m.coroutine) { + // add callback for async main + var asyncmain_callback = new CCodeFunction (real_name + "_callback"); + asyncmain_callback.add_parameter (new CCodeParameter ("source_object", "GObject*")); + asyncmain_callback.add_parameter (new CCodeParameter ("res", "GAsyncResult*")); + asyncmain_callback.add_parameter (new CCodeParameter ("user_data", "gpointer")); + asyncmain_callback.modifiers |= CCodeModifiers.STATIC; + + push_function (asyncmain_callback); + ccode.add_declaration ("GMainLoop*", new CCodeVariableDeclarator.zero ("loop", new CCodeIdentifier ("user_data"))); + + // get the return value + var finish_call = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_finish_real_name (m))); + finish_call.add_argument (new CCodeIdentifier ("res")); + if (m.return_type is VoidType) { + ccode.add_expression (finish_call); + } else { + // save the return value + var asyncmain_result = new CCodeIdentifier (real_name + "_result"); + var asyncmain_result_decl = new CCodeDeclaration (get_ccode_name (int_type)); + asyncmain_result_decl.add_declarator (new CCodeVariableDeclarator (asyncmain_result.name)); + asyncmain_result_decl.modifiers = CCodeModifiers.STATIC; + cfile.add_type_member_declaration (asyncmain_result_decl); + ccode.add_assignment (asyncmain_result, finish_call); + } + + // quit the main loop + var loop_quit_call = new CCodeFunctionCall (new CCodeIdentifier ("g_main_loop_quit")); + loop_quit_call.add_argument (new CCodeIdentifier ("loop")); + ccode.add_expression (loop_quit_call); + + pop_function (); + cfile.add_function (asyncmain_callback); + } + var cmain = new CCodeFunction ("main", "int"); cmain.line = function.line; cmain.add_parameter (new CCodeParameter ("argc", "int")); @@ -855,17 +891,47 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule { } } - var main_call = new CCodeFunctionCall (new CCodeIdentifier (function.name)); + var main_call = new CCodeFunctionCall (new CCodeIdentifier (m.coroutine ? real_name : function.name)); if (m.get_parameters ().size == 1) { main_call.add_argument (new CCodeIdentifier ("argv")); main_call.add_argument (new CCodeIdentifier ("argc")); } - if (m.return_type is VoidType) { - // method returns void, always use 0 as exit code + + if (m.coroutine) { + // main method is asynchronous, so we have to setup GMainLoop and run it + var main_loop_new_call = new CCodeFunctionCall (new CCodeIdentifier ("g_main_loop_new")); + main_loop_new_call.add_argument (new CCodeConstantIdentifier ("NULL")); + main_loop_new_call.add_argument (new CCodeConstantIdentifier ("FALSE")); + ccode.add_declaration ("GMainLoop*", new CCodeVariableDeclarator.zero ("loop", main_loop_new_call)); + + // add some more arguments to main_call + main_call.add_argument (new CCodeIdentifier (real_name + "_callback")); + main_call.add_argument (new CCodeIdentifier ("loop")); ccode.add_expression (main_call); - ccode.add_return (new CCodeConstant ("0")); + + var main_loop_run_call = new CCodeFunctionCall (new CCodeIdentifier ("g_main_loop_run")); + main_loop_run_call.add_argument (new CCodeIdentifier ("loop")); + ccode.add_expression (main_loop_run_call); + + var main_loop_unref_call = new CCodeFunctionCall (new CCodeIdentifier ("g_main_loop_unref")); + main_loop_unref_call.add_argument (new CCodeIdentifier ("loop")); + ccode.add_expression (main_loop_unref_call); + + if (m.return_type is VoidType) { + // method returns void, always use 0 as exit code + ccode.add_return (new CCodeConstant ("0")); + } else { + // get the saved return value + ccode.add_return (new CCodeIdentifier (real_name + "_result")); + } } else { - ccode.add_return (main_call); + if (m.return_type is VoidType) { + // method returns void, always use 0 as exit code + ccode.add_expression (main_call); + ccode.add_return (new CCodeConstant ("0")); + } else { + ccode.add_return (main_call); + } } pop_function (); cfile.add_function (cmain); diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala index 4f130946e..bbe810496 100644 --- a/codegen/valagasyncmodule.vala +++ b/codegen/valagasyncmodule.vala @@ -354,7 +354,7 @@ public class Vala.GAsyncModule : GtkModule { var cparam_map = new HashMap<int,CCodeParameter> (direct_hash, direct_equal); var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal); - if (m.is_private_symbol ()) { + if (m.is_private_symbol () || m.entry_point) { asyncfunc.modifiers |= CCodeModifiers.STATIC; } else if (context.hide_internal && m.is_internal_symbol ()) { asyncfunc.modifiers |= CCodeModifiers.INTERNAL; @@ -374,7 +374,7 @@ public class Vala.GAsyncModule : GtkModule { cparam_map = new HashMap<int,CCodeParameter> (direct_hash, direct_equal); carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal); - if (m.is_private_symbol ()) { + if (m.is_private_symbol () || m.entry_point) { finishfunc.modifiers |= CCodeModifiers.STATIC; } else if (context.hide_internal && m.is_internal_symbol ()) { finishfunc.modifiers |= CCodeModifiers.INTERNAL; |