[vala] GAsync: Fix base access in async methods



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]