[vala] Fix array and delegate variable handling in closures and coroutines



commit daef7c2b19f2a7ce527ba846c5d96dc5d98e5002
Author: Jürg Billeter <j bitron ch>
Date:   Wed Sep 16 15:04:08 2009 +0200

    Fix array and delegate variable handling in closures and coroutines

 codegen/valaccodearraymodule.vala    |   56 ++++++++++++++++++++++------------
 codegen/valaccodebasemodule.vala     |    8 ++++-
 codegen/valaccodedelegatemodule.vala |    4 ++
 codegen/valagasyncmodule.vala        |   16 ++++++++++
 4 files changed, 63 insertions(+), 21 deletions(-)
---
diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala
index 9dc70a4..e207168 100644
--- a/codegen/valaccodearraymodule.vala
+++ b/codegen/valaccodearraymodule.vala
@@ -169,33 +169,49 @@ internal class Vala.CCodeArrayModule : CCodeMethodCallModule {
 		} else if (array_expr.symbol_reference != null) {
 			if (array_expr.symbol_reference is FormalParameter) {
 				var param = (FormalParameter) array_expr.symbol_reference;
-				if (param.array_null_terminated) {
-					var carray_expr = get_variable_cexpression (param.name);
-					requires_array_length = true;
-					var len_call = new CCodeFunctionCall (new CCodeIdentifier ("_vala_array_length"));
-					len_call.add_argument (carray_expr);
-					return len_call;
-				} else if (!param.no_array_length) {
-					CCodeExpression length_expr = get_variable_cexpression (get_array_length_cname (get_variable_cname (param.name), dim));
-					if (param.direction != ParameterDirection.IN) {
-						// accessing argument of out/ref param
-						length_expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, length_expr);
+				if (param.captured) {
+					// captured variables are stored on the heap
+					var block = ((Method) param.parent_symbol).body;
+					return new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (get_block_id (block))), get_array_length_cname (param.name, dim));
+				} else if (current_method != null && current_method.coroutine) {
+					return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_array_length_cname (param.name, dim));
+				} else {
+					if (param.array_null_terminated) {
+						var carray_expr = get_variable_cexpression (param.name);
+						requires_array_length = true;
+						var len_call = new CCodeFunctionCall (new CCodeIdentifier ("_vala_array_length"));
+						len_call.add_argument (carray_expr);
+						return len_call;
+					} else if (!param.no_array_length) {
+						CCodeExpression length_expr = get_variable_cexpression (get_array_length_cname (get_variable_cname (param.name), dim));
+						if (param.direction != ParameterDirection.IN) {
+							// accessing argument of out/ref param
+							length_expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, length_expr);
+						}
+						if (is_out) {
+							// passing array as out/ref
+							return new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, length_expr);
+						} else {
+							return length_expr;
+						}
 					}
+				}
+			} else if (array_expr.symbol_reference is LocalVariable) {
+				var local = (LocalVariable) array_expr.symbol_reference;
+				if (local.captured) {
+					// captured variables are stored on the heap
+					var block = (Block) local.parent_symbol;
+					return new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (get_block_id (block))), get_array_length_cname (local.name, dim));
+				} else if (current_method != null && current_method.coroutine) {
+					return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_array_length_cname (local.name, dim));
+				} else {
+					var length_expr = get_variable_cexpression (get_array_length_cname (get_variable_cname (local.name), dim));
 					if (is_out) {
-						// passing array as out/ref
 						return new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, length_expr);
 					} else {
 						return length_expr;
 					}
 				}
-			} else if (array_expr.symbol_reference is LocalVariable) {
-				var local = (LocalVariable) array_expr.symbol_reference;
-				var length_expr = get_variable_cexpression (get_array_length_cname (get_variable_cname (local.name), dim));
-				if (is_out) {
-					return new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, length_expr);
-				} else {
-					return length_expr;
-				}
 			} else if (array_expr.symbol_reference is Field) {
 				var field = (Field) array_expr.symbol_reference;
 				if (field.array_null_terminated) {
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 5063d38..aeade77 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -1688,7 +1688,13 @@ internal class Vala.CCodeBaseModule : CCodeModule {
 						data.add_field (param.parameter_type.get_cname (), get_variable_cname (param.name));
 						cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), get_variable_cname (param.name)), new CCodeIdentifier (get_variable_cname (param.name)))));
 
-						if (param.parameter_type is DelegateType) {
+						if (param.parameter_type is ArrayType) {
+							var array_type = (ArrayType) param.parameter_type;
+							for (int dim = 1; dim <= array_type.rank; dim++) {
+								data.add_field ("gint", get_array_length_cname (get_variable_cname (param.name), dim));
+								cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), get_array_length_cname (get_variable_cname (param.name), dim)), new CCodeIdentifier (get_array_length_cname (get_variable_cname (param.name), dim)))));
+							}
+						} else if (param.parameter_type is DelegateType) {
 							data.add_field ("gpointer", get_delegate_target_cname (get_variable_cname (param.name)));
 							cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (block_id)), get_delegate_target_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (param.name))))));
 						}
diff --git a/codegen/valaccodedelegatemodule.vala b/codegen/valaccodedelegatemodule.vala
index c148d8a..2d1f2bf 100644
--- a/codegen/valaccodedelegatemodule.vala
+++ b/codegen/valaccodedelegatemodule.vala
@@ -156,6 +156,8 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule {
 					// captured variables are stored on the heap
 					var block = ((Method) param.parent_symbol).body;
 					return new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (param.name));
+				} else if (current_method != null && current_method.coroutine) {
+					return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (param.name));
 				} else {
 					CCodeExpression target_expr = new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (param.name)));
 					if (param.direction != ParameterDirection.IN) {
@@ -175,6 +177,8 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule {
 					// captured variables are stored on the heap
 					var block = (Block) local.parent_symbol;
 					return new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (local.name));
+				} else if (current_method != null && current_method.coroutine) {
+					return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (local.name));
 				} else {
 					var target_expr = new CCodeIdentifier (get_delegate_target_cname (local.name));
 					if (is_out) {
diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala
index 5a3af2d..a60eeb1 100644
--- a/codegen/valagasyncmodule.vala
+++ b/codegen/valagasyncmodule.vala
@@ -43,6 +43,14 @@ internal class Vala.GAsyncModule : GSignalModule {
 
 		foreach (FormalParameter param in m.get_parameters ()) {
 			data.add_field (param.parameter_type.get_cname (), get_variable_cname (param.name));
+			if (param.parameter_type is ArrayType) {
+				var array_type = (ArrayType) param.parameter_type;
+				for (int dim = 1; dim <= array_type.rank; dim++) {
+					data.add_field ("gint", get_array_length_cname (get_variable_cname (param.name), dim));
+				}
+			} else if (param.parameter_type is DelegateType) {
+				data.add_field ("gpointer", get_delegate_target_cname (get_variable_cname (param.name)));
+			}
 		}
 
 		if (!(m.return_type is VoidType)) {
@@ -153,6 +161,14 @@ internal class Vala.GAsyncModule : GSignalModule {
 		foreach (FormalParameter param in m.get_parameters ()) {
 			if (param.direction != ParameterDirection.OUT) {
 				asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_variable_cname (param.name)), new CCodeIdentifier (get_variable_cname (param.name)))));
+				if (param.parameter_type is ArrayType) {
+					var array_type = (ArrayType) param.parameter_type;
+					for (int dim = 1; dim <= array_type.rank; dim++) {
+						asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_array_length_cname (get_variable_cname (param.name), dim)), new CCodeIdentifier (get_array_length_cname (get_variable_cname (param.name), dim)))));
+					}
+				} else if (param.parameter_type is DelegateType) {
+					asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (param.name))))));
+				}
 			}
 		}
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]