summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Lortie <desrt@desrt.ca>2009-02-11 16:03:53 +0000
committerRyan Lortie <ryanl@src.gnome.org>2009-02-11 16:03:53 +0000
commit95883d2d9d67577282dfc53878656b50dfe38d7c (patch)
treeaac17476904b062d2fdb64edb2b319cb1e966b0c
parent12f57c93e4d8a328490faca70fe2f40f17652082 (diff)
downloadvala-95883d2d9d67577282dfc53878656b50dfe38d7c.tar.gz
Bug 571263 – make yielding functions dispatch results to mainloop
2009-02-11 Ryan Lortie <desrt@desrt.ca> Bug 571263 – make yielding functions dispatch results to mainloop * gobject/valaccodemethodmodule.vala: * valagasyncmodule.vala: Create simple async result from _async entry function and use it when doing return; throw; or at the end of the function. Fix return statements for the async case. Dispatch via idle handler in the case that we are returning without having yielded. svn path=/trunk/; revision=2430
-rw-r--r--ChangeLog12
-rw-r--r--gobject/valaccodemethodmodule.vala50
-rw-r--r--gobject/valagasyncmodule.vala73
3 files changed, 95 insertions, 40 deletions
diff --git a/ChangeLog b/ChangeLog
index 9be6b85ef..94b3d3967 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2009-02-11 Ryan Lortie <desrt@desrt.ca>
+ Bug 571263 – make yielding functions dispatch results to mainloop
+
+ * gobject/valaccodemethodmodule.vala:
+ * valagasyncmodule.vala:
+
+ Create simple async result from _async entry function and use it when
+ doing return; throw; or at the end of the function. Fix return
+ statements for the async case. Dispatch via idle handler in the case
+ that we are returning without having yielded.
+
+2009-02-11 Ryan Lortie <desrt@desrt.ca>
+
Bug 566363 – yielding functions that throw don't work
* gobject/valagerrormodule.vala:
diff --git a/gobject/valaccodemethodmodule.vala b/gobject/valaccodemethodmodule.vala
index ee5abed11..ad71357d3 100644
--- a/gobject/valaccodemethodmodule.vala
+++ b/gobject/valaccodemethodmodule.vala
@@ -111,6 +111,35 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
}
}
+ public CCodeStatement complete_async () {
+ var complete_block = new CCodeBlock ();
+
+ var direct_block = new CCodeBlock ();
+ var direct_call = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_complete"));
+ var async_result_expr = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_async_result");
+ direct_call.add_argument (async_result_expr);
+ direct_block.add_statement (new CCodeExpressionStatement (direct_call));
+
+ var idle_block = new CCodeBlock ();
+ var idle_call = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_complete_in_idle"));
+ idle_call.add_argument (async_result_expr);
+ idle_block.add_statement (new CCodeExpressionStatement (idle_call));
+
+ var state = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "state");
+ var zero = new CCodeConstant ("0");
+ var state_is_zero = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, state, zero);
+ var dispatch = new CCodeIfStatement (state_is_zero, idle_block, direct_block);
+ complete_block.add_statement (dispatch);
+
+ var unref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
+ unref.add_argument (async_result_expr);
+ complete_block.add_statement (new CCodeExpressionStatement (unref));
+
+ complete_block.add_statement (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
+
+ return complete_block;
+ }
+
public override void visit_method (Method m) {
var old_type_symbol = current_type_symbol;
var old_symbol = current_symbol;
@@ -281,23 +310,8 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
// coroutine body
cswitch.add_statement (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")));
+ // epilogue
+ cswitch.add_statement (complete_async ());
co_function.block = new CCodeBlock ();
co_function.block.add_statement (cswitch);
@@ -924,3 +938,5 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
}
}
}
+
+// vim:sw=8 noet
diff --git a/gobject/valagasyncmodule.vala b/gobject/valagasyncmodule.vala
index b75699ac3..01177e501 100644
--- a/gobject/valagasyncmodule.vala
+++ b/gobject/valagasyncmodule.vala
@@ -44,9 +44,8 @@ internal class Vala.GAsyncModule : GSignalModule {
closure_struct = new CCodeStruct ("_" + dataname);
closure_struct.add_field ("int", "state");
- closure_struct.add_field ("GAsyncReadyCallback", "callback");
- closure_struct.add_field ("gpointer", "user_data");
closure_struct.add_field ("GAsyncResult*", "res");
+ closure_struct.add_field ("GSimpleAsyncResult*", "_async_result");
if (m.binding == MemberBinding.INSTANCE) {
var type_sym = (TypeSymbol) m.parent_symbol;
@@ -82,8 +81,25 @@ internal class Vala.GAsyncModule : GSignalModule {
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"))));
+ var create_result = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_new"));
+
+ var cl = m.parent_symbol as Class;
+ if (m.binding == MemberBinding.INSTANCE &&
+ cl != null && cl.is_subtype_of (gobject_type)) {
+ create_result.add_argument (new CCodeIdentifier ("self"));
+ } else {
+ 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"));
+ create_result.add_argument (object_creation);
+ }
+
+ create_result.add_argument (new CCodeIdentifier ("callback"));
+ create_result.add_argument (new CCodeIdentifier ("user_data"));
+ create_result.add_argument (new CCodeIdentifier (m.get_real_cname () + "_async"));
+
+ asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_async_result"), create_result)));
if (m.binding == MemberBinding.INSTANCE) {
asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "self"), new CCodeIdentifier ("self"))));
@@ -283,25 +299,11 @@ internal class Vala.GAsyncModule : GSignalModule {
}
var block = new CCodeBlock ();
- var cl = current_method.parent_symbol as Class;
-
- var report_idle = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_report_gerror_in_idle"));
-
- if (current_method.binding == MemberBinding.INSTANCE &&
- cl != null && cl.is_subtype_of (gobject_type)) {
- report_idle.add_argument (new CCodeIdentifier ("self"));
- } else {
- 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"));
- report_idle.add_argument (object_creation);
- }
- report_idle.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "callback"));
- report_idle.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "user_data"));
- report_idle.add_argument (error_expr);
- block.add_statement (new CCodeExpressionStatement (report_idle));
+ var set_error = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_set_from_error"));
+ set_error.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_async_result"));
+ set_error.add_argument (error_expr);
+ block.add_statement (new CCodeExpressionStatement (set_error));
var free_error = new CCodeFunctionCall (new CCodeIdentifier ("g_error_free"));
free_error.add_argument (error_expr);
@@ -311,10 +313,35 @@ internal class Vala.GAsyncModule : GSignalModule {
append_local_free (current_symbol, free_locals, false);
block.add_statement (free_locals);
- block.add_statement (new CCodeReturnStatement ());
+ block.add_statement (complete_async ());
return block;
}
+
+ public override void visit_return_statement (ReturnStatement stmt) {
+ if (current_method == null || !current_method.coroutine) {
+ base.visit_return_statement (stmt);
+ return;
+ }
+
+ stmt.accept_children (codegen);
+
+ var result_block = new CCodeBlock ();
+ stmt.ccodenode = result_block;
+
+ if (stmt.return_expression != null) {
+ var result_var = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "result");
+ var assign_result = new CCodeAssignment (result_var, (CCodeExpression) stmt.return_expression.ccodenode);
+ result_block.add_statement (new CCodeExpressionStatement (assign_result));
+ create_temp_decl (stmt, stmt.return_expression.temp_vars);
+ }
+
+ var free_locals = new CCodeFragment ();
+ append_local_free (current_symbol, free_locals, false);
+ result_block.add_statement (free_locals);
+
+ result_block.add_statement (complete_async ());
+ }
}
// vim:sw=8 noet