[vala] GAsync: Fix base access in async methods
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [vala] GAsync: Fix base access in async methods
- Date: Mon, 16 Nov 2009 21:09:36 +0000 (UTC)
commit 07e2c63dbfdb8a2c6bc802540f1ad4691952a774
Author: Jürg Billeter <j bitron ch>
Date: Mon Nov 16 22:07:48 2009 +0100
GAsync: Fix base access in async methods
Fixes bug 601558.
codegen/valaccodebasemodule.vala | 10 +++++++++-
codegen/valaccodemethodcallmodule.vala | 22 ++++++++++++++++++++--
tests/Makefile.am | 1 +
tests/asynchronous/bug601558.vala | 13 +++++++++++++
vala/valaparser.vala | 11 ++++++++---
5 files changed, 51 insertions(+), 6 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 9b240a4..0a7779f 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -3220,7 +3220,15 @@ internal class Vala.CCodeBaseModule : CCodeModule {
}
public override void visit_base_access (BaseAccess expr) {
- expr.ccodenode = generate_instance_cast (new CCodeIdentifier ("self"), expr.value_type.data_type);
+ CCodeExpression this_access;
+ if (current_method != null && current_method.coroutine) {
+ // use closure
+ this_access = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "self");
+ } else {
+ this_access = new CCodeIdentifier ("self");
+ }
+
+ expr.ccodenode = generate_instance_cast (this_access, expr.value_type.data_type);
}
public override void visit_postfix_expression (PostfixExpression expr) {
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index c5a188d..4589cbf 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -73,6 +73,24 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
// async call
async_call = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname ()));
+ var finish_call = new CCodeFunctionCall (new CCodeIdentifier (m.get_finish_cname ()));
+
+ if (ma.inner is BaseAccess) {
+ if (m.base_method != null) {
+ var base_class = (Class) m.base_method.parent_symbol;
+ var vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (base_class.get_upper_case_cname (null))));
+ vcast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (current_class.get_lower_case_cname (null))));
+
+ async_call.call = new CCodeMemberAccess.pointer (vcast, m.vfunc_name);
+ finish_call.call = new CCodeMemberAccess.pointer (vcast, m.get_finish_vfunc_name ());
+ } else if (m.base_interface_method != null) {
+ var base_iface = (Interface) m.base_interface_method.parent_symbol;
+ string parent_iface_var = "%s_%s_parent_iface".printf (current_class.get_lower_case_cname (null), base_iface.get_lower_case_cname (null));
+
+ async_call.call = new CCodeMemberAccess.pointer (new CCodeIdentifier (parent_iface_var), m.vfunc_name);
+ finish_call.call = new CCodeMemberAccess.pointer (new CCodeIdentifier (parent_iface_var), m.get_finish_vfunc_name ());
+ }
+ }
if (ma.member_name == "begin" && ma.inner.symbol_reference == ma.symbol_reference) {
// no finish call
@@ -80,14 +98,14 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
params = m.get_async_begin_parameters ();
} else if (ma.member_name == "end" && ma.inner.symbol_reference == ma.symbol_reference) {
// no async call
- ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_finish_cname ()));
+ ccall = finish_call;
params = m.get_async_end_parameters ();
} else if (!expr.is_yield_expression) {
// same as .begin, backwards compatible to bindings without async methods
ccall = async_call;
params = m.get_async_begin_parameters ();
} else {
- ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_finish_cname ()));
+ ccall = finish_call;
// output arguments used separately
out_arg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 7e6f222..87d3b72 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -71,6 +71,7 @@ TESTS = \
asynchronous/bug598698.vala \
asynchronous/bug599568.vala \
asynchronous/bug600827.vala \
+ asynchronous/bug601558.vala \
dbus/basic-types.test \
dbus/arrays.test \
dbus/async.test \
diff --git a/tests/asynchronous/bug601558.vala b/tests/asynchronous/bug601558.vala
new file mode 100644
index 0000000..cd98c0f
--- /dev/null
+++ b/tests/asynchronous/bug601558.vala
@@ -0,0 +1,13 @@
+public class Foo {
+ public virtual async void do_foo () {
+ }
+}
+
+public class Bar : Foo {
+ public override async void do_foo () {
+ yield base.do_foo ();
+ }
+}
+
+void main () {
+}
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index 6828341..ff97edf 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -854,7 +854,12 @@ public class Vala.Parser : CodeVisitor {
Expression parse_yield_expression () throws ParseError {
var begin = get_location ();
expect (TokenType.YIELD);
- var member = parse_member_name ();
+ Expression base_expr = null;
+ if (current () == TokenType.BASE) {
+ base_expr = parse_base_access ();
+ expect (TokenType.DOT);
+ }
+ var member = parse_member_name (base_expr);
var call = (MethodCall) parse_method_call (begin, member);
call.is_yield_expression = true;
return call;
@@ -3103,7 +3108,7 @@ public class Vala.Parser : CodeVisitor {
return null;
}
- MemberAccess parse_member_name () throws ParseError {
+ MemberAccess parse_member_name (Expression? base_expr = null) throws ParseError {
var begin = get_location ();
MemberAccess expr = null;
bool first = true;
@@ -3118,7 +3123,7 @@ public class Vala.Parser : CodeVisitor {
}
List<DataType> type_arg_list = parse_type_argument_list (false);
- expr = new MemberAccess (expr, id, get_src (begin));
+ expr = new MemberAccess (expr != null ? expr : base_expr, id, get_src (begin));
expr.qualified = qualified;
if (type_arg_list != null) {
foreach (DataType type_arg in type_arg_list) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]