[vala] GAsync: Support async callback from closure
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [vala] GAsync: Support async callback from closure
- Date: Thu, 4 Feb 2010 18:03:47 +0000 (UTC)
commit 2ae8cd1509f3489277f621440a8902b8eecf9e79
Author: Jürg Billeter <j bitron ch>
Date: Thu Feb 4 19:02:44 2010 +0100
GAsync: Support async callback from closure
Fixes bug 608184.
codegen/valaccodebasemodule.vala | 15 +++++++++++++--
codegen/valaccodedelegatemodule.vala | 9 +++++++--
codegen/valaccodemethodcallmodule.vala | 14 ++++++++++++--
vala/valamemberaccess.vala | 19 +++++++++++++++++--
vala/valasemanticanalyzer.vala | 17 ++++++++++++++++-
5 files changed, 65 insertions(+), 9 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index ca5af4a..7b29aed 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -1,6 +1,6 @@
/* 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
@@ -1802,8 +1802,10 @@ internal class Vala.CCodeBaseModule : CCodeModule {
}
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;
@@ -1859,6 +1861,15 @@ internal class Vala.CCodeBaseModule : CCodeModule {
}
}
+ 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 ();
diff --git a/codegen/valaccodedelegatemodule.vala b/codegen/valaccodedelegatemodule.vala
index 5e4dd46..7213707 100644
--- a/codegen/valaccodedelegatemodule.vala
+++ b/codegen/valaccodedelegatemodule.vala
@@ -1,6 +1,6 @@
/* 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
@@ -296,7 +296,12 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule {
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 ()) {
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index 5c9e3c6..f42117e 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -1,6 +1,6 @@
/* 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
@@ -153,7 +153,17 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
}
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) {
diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala
index 6f7f510..5e95a98 100644
--- a/vala/valamemberaccess.vala
+++ b/vala/valamemberaccess.vala
@@ -1,6 +1,6 @@
/* 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
@@ -471,7 +471,22 @@ public class Vala.MemberAccess : Expression {
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) {
diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala
index b18fe96..8d6c77f 100644
--- a/vala/valasemanticanalyzer.vala
+++ b/vala/valasemanticanalyzer.vala
@@ -1,6 +1,6 @@
/* 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
@@ -66,6 +66,21 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
}
}
+ 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;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]