}
}
+ 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;
// 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);
}
}
}
+
+// vim:sw=8 noet
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;
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"))));
}
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);
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