Fixes bug 608184.
/* valaccodebasemodule.vala
*
- * Copyright (C) 2006-2009 Jürg Billeter
+ * Copyright (C) 2006-2010 Jürg Billeter
* Copyright (C) 2006-2008 Raffaele Sandrini
*
* This library is free software; you can redistribute it and/or
}
if (b.parent_symbol is Method) {
+ var m = (Method) b.parent_symbol;
+
// parameters are captured with the top-level block of the method
- foreach (var param in ((Method) b.parent_symbol).get_parameters ()) {
+ foreach (var param in m.get_parameters ()) {
if (param.captured) {
var param_type = param.parameter_type.copy ();
param_type.value_owned = true;
}
}
+ if (m.coroutine) {
+ // capture async data to allow invoking callback from inside closure
+ data.add_field ("gpointer", "_async_data_");
+
+ // async method is suspended while waiting for callback,
+ // so we never need to care about memory management of async data
+ cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), "_async_data_"), new CCodeIdentifier ("data"))));
+ }
+
var cfrag = new CCodeFragment ();
append_temp_decl (cfrag, temp_vars);
temp_vars.clear ();
/* valaccodedelegatemodule.vala
*
- * Copyright (C) 2006-2009 Jürg Billeter
+ * Copyright (C) 2006-2010 Jürg Billeter
* Copyright (C) 2006-2008 Raffaele Sandrini
*
* This library is free software; you can redistribute it and/or
if (m.binding == MemberBinding.STATIC) {
return new CCodeConstant ("NULL");
} else if (m.is_async_callback) {
- return new CCodeIdentifier ("data");
+ if (current_method.closure) {
+ var block = ((Method) m.parent_symbol).body;
+ return new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), "_async_data_");
+ } else {
+ return new CCodeIdentifier ("data");
+ }
} else {
var delegate_target = (CCodeExpression) get_ccodenode (ma.inner);
if (expr_owned && ma.inner.value_type.data_type != null && ma.inner.value_type.data_type.is_reference_counting ()) {
/* valaccodemethodcallmodule.vala
*
- * Copyright (C) 2006-2009 Jürg Billeter
+ * Copyright (C) 2006-2010 Jürg Billeter
* Copyright (C) 2006-2008 Raffaele Sandrini
*
* This library is free software; you can redistribute it and/or
}
CCodeExpression instance = null;
- if (m != null && m.binding == MemberBinding.INSTANCE && !(m is CreationMethod)) {
+ if (m != null && m.is_async_callback) {
+ if (current_method.closure) {
+ var block = ((Method) m.parent_symbol).body;
+ instance = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), "_async_data_");
+ } else {
+ instance = new CCodeIdentifier ("data");
+ }
+
+ in_arg_map.set (get_param_pos (m.cinstance_parameter_position), instance);
+ out_arg_map.set (get_param_pos (m.cinstance_parameter_position), instance);
+ } else if (m != null && m.binding == MemberBinding.INSTANCE && !(m is CreationMethod)) {
instance = (CCodeExpression) ma.inner.ccodenode;
if ((ma.member_name == "begin" || ma.member_name == "end") && ma.inner.symbol_reference == ma.symbol_reference) {
/* valamemberaccess.vala
*
- * Copyright (C) 2006-2009 Jürg Billeter
+ * Copyright (C) 2006-2010 Jürg Billeter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
var m = (Method) member;
if (m.is_async_callback) {
// ensure to use right callback method for virtual/abstract async methods
- m = analyzer.current_method.get_callback_method ();
+ // and also for lambda expressions within async methods
+ var async_method = analyzer.current_async_method;
+
+ if (async_method != analyzer.current_method) {
+ Symbol sym = analyzer.current_method;
+ while (sym != async_method) {
+ var method = sym as Method;
+ if (method != null) {
+ method.closure = true;
+ }
+ sym = sym.parent_symbol;
+ }
+ async_method.body.captured = true;
+ }
+
+ m = async_method.get_callback_method ();
symbol_reference = m;
member = symbol_reference;
} else if (m.base_method != null) {
/* valasemanticanalyzer.vala
*
- * Copyright (C) 2006-2009 Jürg Billeter
+ * Copyright (C) 2006-2010 Jürg Billeter
* Copyright (C) 2006-2008 Raffaele Sandrini
*
* This library is free software; you can redistribute it and/or
}
}
+ public Method? current_async_method {
+ get {
+ var sym = current_symbol;
+ while (sym is Block || sym is Method) {
+ var m = sym as Method;
+ if (m != null && m.coroutine) {
+ break;
+ }
+
+ sym = sym.parent_symbol;
+ }
+ return sym as Method;
+ }
+ }
+
public PropertyAccessor? current_property_accessor {
get {
var sym = current_symbol;