Release 0.7.8
[vala-lang.git] / codegen / valagasyncmodule.vala
blob3d6f9feddc7ebf7a15ea270e4088c5505f375991
1 /* valagasyncmodule.vala
3 * Copyright (C) 2008-2009 Jürg Billeter
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 * Author:
20 * Jürg Billeter <j@bitron.ch>
23 using GLib;
25 internal class Vala.GAsyncModule : GSignalModule {
26 public GAsyncModule (CCodeGenerator codegen, CCodeModule? next) {
27 base (codegen, next);
30 CCodeStruct generate_data_struct (Method m) {
31 string dataname = Symbol.lower_case_to_camel_case (m.get_cname ()) + "Data";
32 var data = new CCodeStruct ("_" + dataname);
34 data.add_field ("int", "_state_");
35 data.add_field ("GAsyncResult*", "_res_");
36 data.add_field ("GSimpleAsyncResult*", "_async_result");
38 if (m.binding == MemberBinding.INSTANCE) {
39 var type_sym = (TypeSymbol) m.parent_symbol;
40 data.add_field (type_sym.get_cname () + "*", "self");
43 foreach (FormalParameter param in m.get_parameters ()) {
44 var param_type = param.parameter_type.copy ();
45 param_type.value_owned = true;
46 data.add_field (param_type.get_cname (), get_variable_cname (param.name));
48 if (param.parameter_type is ArrayType) {
49 var array_type = (ArrayType) param.parameter_type;
50 for (int dim = 1; dim <= array_type.rank; dim++) {
51 data.add_field ("gint", get_array_length_cname (get_variable_cname (param.name), dim));
53 } else if (param.parameter_type is DelegateType) {
54 data.add_field ("gpointer", get_delegate_target_cname (get_variable_cname (param.name)));
55 data.add_field ("GDestroyNotify", get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)));
59 if (!(m.return_type is VoidType)) {
60 data.add_field (m.return_type.get_cname (), "result");
61 if (m.return_type is ArrayType) {
62 var array_type = (ArrayType) m.return_type;
63 for (int dim = 1; dim <= array_type.rank; dim++) {
64 data.add_field ("gint", get_array_length_cname ("result", dim));
66 } else if (m.return_type is DelegateType) {
67 data.add_field ("gpointer", get_delegate_target_cname ("result"));
68 data.add_field ("GDestroyNotify", get_delegate_target_destroy_notify_cname ("result"));
72 return data;
75 CCodeFunction generate_free_function (Method m) {
76 var dataname = Symbol.lower_case_to_camel_case (m.get_cname ()) + "Data";
78 var freefunc = new CCodeFunction (m.get_real_cname () + "_data_free", "void");
79 freefunc.modifiers = CCodeModifiers.STATIC;
80 freefunc.add_parameter (new CCodeFormalParameter ("_data", "gpointer"));
82 var freeblock = new CCodeBlock ();
83 freefunc.block = freeblock;
85 var datadecl = new CCodeDeclaration (dataname + "*");
86 datadecl.add_declarator (new CCodeVariableDeclarator ("data", new CCodeIdentifier ("_data")));
87 freeblock.add_statement (datadecl);
89 var old_symbol = current_symbol;
90 current_symbol = m;
92 foreach (FormalParameter param in m.get_parameters ()) {
93 if (param.direction != ParameterDirection.OUT) {
94 var param_type = param.parameter_type.copy ();
95 param_type.value_owned = true;
97 if (requires_destroy (param_type)) {
98 var ma = new MemberAccess.simple (param.name);
99 ma.symbol_reference = param;
100 ma.value_type = param.parameter_type.copy ();
101 freeblock.add_statement (new CCodeExpressionStatement (get_unref_expression (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_variable_cname (param.name)), param.parameter_type, ma)));
106 if (requires_destroy (m.return_type)) {
107 /* this is very evil. */
108 var v = new LocalVariable (m.return_type, ".result");
109 var ma = new MemberAccess.simple (".result");
110 ma.symbol_reference = v;
111 var unref_expr = get_unref_expression (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "result"), m.return_type, ma);
112 freeblock.add_statement (new CCodeExpressionStatement (unref_expr));
115 current_symbol = old_symbol;
117 var freecall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free"));
118 freecall.add_argument (new CCodeIdentifier (dataname));
119 freecall.add_argument (new CCodeIdentifier ("data"));
120 freeblock.add_statement (new CCodeExpressionStatement (freecall));
122 return freefunc;
125 CCodeFunction generate_async_function (Method m) {
126 var asyncblock = new CCodeBlock ();
128 // logic copied from valaccodemethodmodule
129 if (m.overrides || (m.base_interface_method != null && !m.is_abstract && !m.is_virtual)) {
130 Method base_method;
132 if (m.overrides) {
133 base_method = m.base_method;
134 } else {
135 base_method = m.base_interface_method;
138 var base_expression_type = new ObjectType ((ObjectTypeSymbol) base_method.parent_symbol);
139 var type_symbol = m.parent_symbol as ObjectTypeSymbol;
141 var self_target_type = new ObjectType (type_symbol);
142 var cself = transform_expression (new CCodeIdentifier ("base"), base_expression_type, self_target_type);
143 var cdecl = new CCodeDeclaration ("%s *".printf (type_symbol.get_cname ()));
144 cdecl.add_declarator (new CCodeVariableDeclarator ("self", cself));
145 asyncblock.add_statement (cdecl);
148 var dataname = Symbol.lower_case_to_camel_case (m.get_cname ()) + "Data";
149 var asyncfunc = new CCodeFunction (m.get_real_cname (), "void");
150 var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
152 var dataalloc = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_new0"));
153 dataalloc.add_argument (new CCodeIdentifier (dataname));
155 var data_var = new CCodeIdentifier ("_data_");
157 var datadecl = new CCodeDeclaration (dataname + "*");
158 datadecl.add_declarator (new CCodeVariableDeclarator ("_data_"));
159 asyncblock.add_statement (datadecl);
160 asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (data_var, dataalloc)));
162 var create_result = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_new"));
164 var cl = m.parent_symbol as Class;
165 if (m.binding == MemberBinding.INSTANCE &&
166 cl != null && cl.is_subtype_of (gobject_type)) {
167 var gobject_cast = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT"));
168 gobject_cast.add_argument (new CCodeIdentifier ("self"));
170 create_result.add_argument (gobject_cast);
171 } else {
172 create_result.add_argument (new CCodeConstant ("NULL"));
175 create_result.add_argument (new CCodeIdentifier ("_callback_"));
176 create_result.add_argument (new CCodeIdentifier ("_user_data_"));
177 create_result.add_argument (new CCodeIdentifier (m.get_real_cname ()));
179 asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, "_async_result"), create_result)));
181 var set_op_res_call = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_set_op_res_gpointer"));
182 set_op_res_call.add_argument (new CCodeMemberAccess.pointer (data_var, "_async_result"));
183 set_op_res_call.add_argument (data_var);
184 set_op_res_call.add_argument (new CCodeIdentifier (m.get_real_cname () + "_data_free"));
185 asyncblock.add_statement (new CCodeExpressionStatement (set_op_res_call));
187 if (m.binding == MemberBinding.INSTANCE) {
188 asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, "self"), new CCodeIdentifier ("self"))));
191 foreach (FormalParameter param in m.get_parameters ()) {
192 if (param.direction != ParameterDirection.OUT) {
193 var param_type = param.parameter_type.copy ();
194 param_type.value_owned = true;
196 // create copy if necessary as variables in async methods may need to be kept alive
197 CCodeExpression cparam = get_variable_cexpression (param.name);
198 if (requires_copy (param_type) && !param.parameter_type.value_owned) {
199 var ma = new MemberAccess.simple (param.name);
200 ma.symbol_reference = param;
201 cparam = get_ref_cexpression (param.parameter_type, cparam, ma, param);
204 asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_variable_cname (param.name)), cparam)));
205 if (param.parameter_type is ArrayType) {
206 var array_type = (ArrayType) param.parameter_type;
207 for (int dim = 1; dim <= array_type.rank; dim++) {
208 asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_array_length_cname (get_variable_cname (param.name), dim)), new CCodeIdentifier (get_array_length_cname (get_variable_cname (param.name), dim)))));
210 } else if (param.parameter_type is DelegateType) {
211 var deleg_type = (DelegateType) param.parameter_type;
212 asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_delegate_target_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (param.name))))));
213 if (deleg_type.value_owned) {
214 asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_delegate_target_destroy_notify_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_variable_cname (param.name))))));
220 var cfrag = new CCodeFragment ();
221 append_temp_decl (cfrag, temp_vars);
222 temp_vars.clear ();
223 asyncblock.add_statement (cfrag);
225 var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_real_cname () + "_co"));
226 ccall.add_argument (data_var);
227 asyncblock.add_statement (new CCodeExpressionStatement (ccall));
229 cparam_map.set (get_param_pos (-1), new CCodeFormalParameter ("_callback_", "GAsyncReadyCallback"));
230 cparam_map.set (get_param_pos (-0.9), new CCodeFormalParameter ("_user_data_", "gpointer"));
232 generate_cparameters (m, source_declarations, cparam_map, asyncfunc, null, null, null, 1);
234 if (m.base_method != null || m.base_interface_method != null) {
235 // declare *_real_* function
236 asyncfunc.modifiers |= CCodeModifiers.STATIC;
237 source_declarations.add_type_member_declaration (asyncfunc.copy ());
238 } else if (m.is_private_symbol ()) {
239 asyncfunc.modifiers |= CCodeModifiers.STATIC;
242 asyncfunc.block = asyncblock;
244 return asyncfunc;
247 void append_struct (CCodeStruct structure) {
248 var typename = new CCodeVariableDeclarator (structure.name.substring (1));
249 var typedef = new CCodeTypeDefinition ("struct " + structure.name, typename);
250 source_declarations.add_type_declaration (typedef);
251 source_declarations.add_type_definition (structure);
254 void append_function (CCodeFunction function) {
255 var block = function.block;
256 function.block = null;
258 source_declarations.add_type_member_declaration (function.copy ());
260 function.block = block;
261 source_type_member_definition.append (function);
264 public override void generate_method_declaration (Method m, CCodeDeclarationSpace decl_space) {
265 if (m.coroutine) {
266 if (decl_space.add_symbol_declaration (m, m.get_cname ())) {
267 return;
270 var asyncfunc = new CCodeFunction (m.get_cname (), "void");
271 var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
272 cparam_map.set (get_param_pos (-1), new CCodeFormalParameter ("_callback_", "GAsyncReadyCallback"));
273 cparam_map.set (get_param_pos (-0.9), new CCodeFormalParameter ("_user_data_", "gpointer"));
275 generate_cparameters (m, decl_space, cparam_map, asyncfunc, null, null, null, 1);
277 if (m.is_private_symbol ()) {
278 asyncfunc.modifiers |= CCodeModifiers.STATIC;
281 decl_space.add_type_member_declaration (asyncfunc);
283 var finishfunc = new CCodeFunction (m.get_finish_cname ());
284 cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
285 cparam_map.set (get_param_pos (0.1), new CCodeFormalParameter ("_res_", "GAsyncResult*"));
287 generate_cparameters (m, decl_space, cparam_map, finishfunc, null, null, null, 2);
289 if (m.is_private_symbol ()) {
290 finishfunc.modifiers |= CCodeModifiers.STATIC;
293 decl_space.add_type_member_declaration (finishfunc);
294 } else {
295 base.generate_method_declaration (m, decl_space);
299 public override void visit_method (Method m) {
300 if (m.coroutine) {
301 source_declarations.add_include ("gio/gio.h");
302 if (!m.is_internal_symbol ()) {
303 header_declarations.add_include ("gio/gio.h");
306 if (!m.is_abstract) {
307 var data = generate_data_struct (m);
309 append_function (generate_free_function (m));
310 source_type_member_definition.append (generate_async_function (m));
311 source_type_member_definition.append (generate_finish_function (m));
312 append_function (generate_ready_function (m));
314 // append the _co function
315 closure_struct = data;
316 base.visit_method (m);
317 closure_struct = null;
319 // only append data struct here to make sure all struct member
320 // types are declared before the struct definition
321 append_struct (data);
324 if (m.is_abstract || m.is_virtual) {
325 // generate virtual function wrappers
326 var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
327 var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
328 generate_vfunc (m, new VoidType (), cparam_map, carg_map, "", 1);
330 cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
331 carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
332 generate_vfunc (m, m.return_type, cparam_map, carg_map, "_finish", 2);
334 } else {
335 base.visit_method (m);
340 CCodeFunction generate_finish_function (Method m) {
341 string dataname = Symbol.lower_case_to_camel_case (m.get_cname ()) + "Data";
343 var finishfunc = new CCodeFunction (m.get_finish_real_cname ());
345 var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
347 var finishblock = new CCodeBlock ();
349 var return_type = m.return_type;
350 if (!(return_type is VoidType)) {
351 var cdecl = new CCodeDeclaration (m.return_type.get_cname ());
352 cdecl.add_declarator (new CCodeVariableDeclarator ("result"));
353 finishblock.add_statement (cdecl);
356 var data_var = new CCodeIdentifier ("_data_");
358 var datadecl = new CCodeDeclaration (dataname + "*");
359 datadecl.add_declarator (new CCodeVariableDeclarator ("_data_"));
360 finishblock.add_statement (datadecl);
362 var simple_async_result_cast = new CCodeFunctionCall (new CCodeIdentifier ("G_SIMPLE_ASYNC_RESULT"));
363 simple_async_result_cast.add_argument (new CCodeIdentifier ("_res_"));
365 if (m.get_error_types ().size > 0) {
366 // propagate error from async method
367 var propagate_error = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_propagate_error"));
368 propagate_error.add_argument (simple_async_result_cast);
369 propagate_error.add_argument (new CCodeIdentifier ("error"));
370 var errorblock = new CCodeBlock ();
371 if (return_type is VoidType) {
372 errorblock.add_statement (new CCodeReturnStatement ());
373 } else {
374 errorblock.add_statement (new CCodeReturnStatement (default_value_for_type (return_type, false)));
376 finishblock.add_statement (new CCodeIfStatement (propagate_error, errorblock));
379 var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_get_op_res_gpointer"));
380 ccall.add_argument (simple_async_result_cast);
381 finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (data_var, ccall)));
383 foreach (FormalParameter param in m.get_parameters ()) {
384 if (param.direction != ParameterDirection.IN) {
385 finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (param.name)), new CCodeMemberAccess.pointer (data_var, get_variable_cname (param.name)))));
386 finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, get_variable_cname (param.name)), new CCodeConstant ("NULL"))));
390 if (!(return_type is VoidType)) {
391 finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("result"), new CCodeMemberAccess.pointer (data_var, "result"))));
392 if (return_type is ArrayType) {
393 var array_type = (ArrayType) return_type;
394 for (int dim = 1; dim <= array_type.rank; dim++) {
395 finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (get_array_length_cname ("result", dim))), new CCodeMemberAccess.pointer (data_var, get_array_length_cname ("result", dim)))));
397 } else if (return_type is DelegateType) {
398 finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (get_delegate_target_cname ("result"))), new CCodeMemberAccess.pointer (data_var, get_delegate_target_cname ("result")))));
400 if (!(return_type is ValueType) || return_type.nullable) {
401 finishblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (data_var, "result"), new CCodeConstant ("NULL"))));
403 finishblock.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
406 cparam_map.set (get_param_pos (0.1), new CCodeFormalParameter ("_res_", "GAsyncResult*"));
408 generate_cparameters (m, source_declarations, cparam_map, finishfunc, null, null, null, 2);
410 if (m.is_private_symbol () || m.base_method != null || m.base_interface_method != null) {
411 finishfunc.modifiers |= CCodeModifiers.STATIC;
414 finishfunc.block = finishblock;
416 return finishfunc;
419 CCodeFunction generate_ready_function (Method m) {
420 // generate ready callback handler
421 var dataname = Symbol.lower_case_to_camel_case (m.get_cname ()) + "Data";
423 var readyfunc = new CCodeFunction (m.get_cname () + "_ready", "void");
425 readyfunc.add_parameter (new CCodeFormalParameter ("source_object", "GObject*"));
426 readyfunc.add_parameter (new CCodeFormalParameter ("_res_", "GAsyncResult*"));
427 readyfunc.add_parameter (new CCodeFormalParameter ("_user_data_", "gpointer"));
429 var readyblock = new CCodeBlock ();
431 var datadecl = new CCodeDeclaration (dataname + "*");
432 datadecl.add_declarator (new CCodeVariableDeclarator ("data"));
433 readyblock.add_statement (datadecl);
434 readyblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("data"), new CCodeIdentifier ("_user_data_"))));
435 readyblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_res_"), new CCodeIdentifier ("_res_"))));
437 var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_real_cname () + "_co"));
438 ccall.add_argument (new CCodeIdentifier ("data"));
439 readyblock.add_statement (new CCodeExpressionStatement (ccall));
441 readyfunc.modifiers |= CCodeModifiers.STATIC;
443 readyfunc.block = readyblock;
445 return readyfunc;
448 public override void generate_virtual_method_declaration (Method m, CCodeDeclarationSpace decl_space, CCodeStruct type_struct) {
449 if (!m.coroutine) {
450 base.generate_virtual_method_declaration (m, decl_space, type_struct);
451 return;
454 if (!m.is_abstract && !m.is_virtual) {
455 return;
458 // add vfunc field to the type struct
459 var vdeclarator = new CCodeFunctionDeclarator (m.vfunc_name);
460 var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
462 generate_cparameters (m, decl_space, cparam_map, new CCodeFunction ("fake"), vdeclarator, null, null, 1);
464 var vdecl = new CCodeDeclaration ("void");
465 vdecl.add_declarator (vdeclarator);
466 type_struct.add_declaration (vdecl);
468 // add vfunc field to the type struct
469 vdeclarator = new CCodeFunctionDeclarator (m.get_finish_vfunc_name ());
470 cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
472 generate_cparameters (m, decl_space, cparam_map, new CCodeFunction ("fake"), vdeclarator, null, null, 2);
474 vdecl = new CCodeDeclaration (m.return_type.get_cname ());
475 vdecl.add_declarator (vdeclarator);
476 type_struct.add_declaration (vdecl);
479 public override void visit_yield_statement (YieldStatement stmt) {
480 if (current_method == null || !current_method.coroutine) {
481 stmt.ccodenode = new CCodeEmptyStatement ();
482 return;
485 if (stmt.yield_expression == null) {
486 var cfrag = new CCodeFragment ();
487 stmt.ccodenode = cfrag;
489 int state = next_coroutine_state++;
491 cfrag.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_state_"), new CCodeConstant (state.to_string ()))));
492 cfrag.append (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
493 cfrag.append (new CCodeCaseStatement (new CCodeConstant (state.to_string ())));
494 cfrag.append (new CCodeEmptyStatement ());
496 return;
499 stmt.accept_children (codegen);
501 if (stmt.yield_expression.error) {
502 stmt.error = true;
503 return;
506 stmt.ccodenode = new CCodeExpressionStatement ((CCodeExpression) stmt.yield_expression.ccodenode);
508 if (stmt.tree_can_fail && stmt.yield_expression.tree_can_fail) {
509 // simple case, no node breakdown necessary
511 var cfrag = new CCodeFragment ();
513 cfrag.append (stmt.ccodenode);
515 head.add_simple_check (stmt.yield_expression, cfrag);
517 stmt.ccodenode = cfrag;
520 /* free temporary objects */
522 if (((List<LocalVariable>) temp_vars).size == 0) {
523 /* nothing to do without temporary variables */
524 return;
527 var cfrag = new CCodeFragment ();
528 append_temp_decl (cfrag, temp_vars);
530 cfrag.append (stmt.ccodenode);
532 foreach (LocalVariable local in temp_ref_vars) {
533 var ma = new MemberAccess.simple (local.name);
534 ma.symbol_reference = local;
535 cfrag.append (new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier (local.name), local.variable_type, ma)));
538 stmt.ccodenode = cfrag;
540 temp_vars.clear ();
541 temp_ref_vars.clear ();
544 public override CCodeStatement return_with_exception (CCodeExpression error_expr)
546 if (!current_method.coroutine) {
547 return base.return_with_exception (error_expr);
550 var block = new CCodeBlock ();
552 var set_error = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_set_from_error"));
553 set_error.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_async_result"));
554 set_error.add_argument (error_expr);
555 block.add_statement (new CCodeExpressionStatement (set_error));
557 var free_error = new CCodeFunctionCall (new CCodeIdentifier ("g_error_free"));
558 free_error.add_argument (error_expr);
559 block.add_statement (new CCodeExpressionStatement (free_error));
561 var free_locals = new CCodeFragment ();
562 append_local_free (current_symbol, free_locals, false);
563 block.add_statement (free_locals);
565 block.add_statement (complete_async ());
567 return block;
570 public override void visit_return_statement (ReturnStatement stmt) {
571 base.visit_return_statement (stmt);
573 if (current_method == null || !current_method.coroutine) {
574 return;
577 var cfrag = (CCodeFragment) stmt.ccodenode;
579 cfrag.append (complete_async ());
582 public override void generate_cparameters (Method m, CCodeDeclarationSpace decl_space, Map<int,CCodeFormalParameter> cparam_map, CCodeFunction func, CCodeFunctionDeclarator? vdeclarator = null, Map<int,CCodeExpression>? carg_map = null, CCodeFunctionCall? vcall = null, int direction = 3) {
583 if (m.coroutine) {
584 decl_space.add_include ("gio/gio.h");
586 if (direction == 1) {
587 cparam_map.set (get_param_pos (-1), new CCodeFormalParameter ("_callback_", "GAsyncReadyCallback"));
588 cparam_map.set (get_param_pos (-0.9), new CCodeFormalParameter ("_user_data_", "gpointer"));
589 if (carg_map != null) {
590 carg_map.set (get_param_pos (-1), new CCodeIdentifier ("_callback_"));
591 carg_map.set (get_param_pos (-0.9), new CCodeIdentifier ("_user_data_"));
593 } else if (direction == 2) {
594 cparam_map.set (get_param_pos (0.1), new CCodeFormalParameter ("_res_", "GAsyncResult*"));
595 if (carg_map != null) {
596 carg_map.set (get_param_pos (0.1), new CCodeIdentifier ("_res_"));
600 base.generate_cparameters (m, decl_space, cparam_map, func, vdeclarator, carg_map, vcall, direction);
604 // vim:sw=8 noet