[vala] codegen: Use TargetValue methods in capture_parameter



commit ac608b1d17debd15ab7e20c15174d1601f00ddf2
Author: Luca Bruno <lucabru src gnome org>
Date:   Sun May 8 08:42:07 2011 +0200

    codegen: Use TargetValue methods in capture_parameter
    
    Fixes capturing arrays with no array length and delegates with no target.

 codegen/valaccodebasemodule.vala |   33 +++++++++------------------------
 tests/methods/closures.vala      |    7 +++++++
 2 files changed, 16 insertions(+), 24 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 8864e17..842a274 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -1636,45 +1636,30 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 		bool is_unowned_delegate = param.variable_type is DelegateType && !param.variable_type.value_owned;
 
 		// create copy if necessary as captured variables may need to be kept alive
-		CCodeExpression cparam = get_variable_cexpression (param.name);
-		if (param.variable_type.is_real_non_null_struct_type ()) {
-			cparam = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, cparam);
-		}
+		param.captured = false;
+		var value = load_parameter (param);
 		if (requires_copy (param_type) && !param.variable_type.value_owned && !is_unowned_delegate)  {
 			// directly access parameters in ref expressions
-			param.captured = false;
-			var value = load_parameter (param);
-			((GLibValue) value).cvalue = cparam;
-			cparam = get_cvalue_ (copy_value (value, param));
-			param.captured = true;
+			value = copy_value (value, param);
 		}
 
-		ccode.add_assignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_variable_cname (param.name)), cparam);
-
 		if (param.variable_type is ArrayType) {
 			var array_type = (ArrayType) param.variable_type;
 			for (int dim = 1; dim <= array_type.rank; dim++) {
 				data.add_field ("gint", get_parameter_array_length_cname (param, dim));
-				ccode.add_assignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_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.variable_type is DelegateType) {
-			CCodeExpression target_expr;
-			CCodeExpression delegate_target_destroy_notify;
-			if (is_in_coroutine ()) {
-				target_expr = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (get_variable_cname (param.name)));
-				delegate_target_destroy_notify = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)));
-			} else {
-				target_expr = new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (param.name)));
-				delegate_target_destroy_notify = new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)));
-			}
-
 			data.add_field ("gpointer", get_delegate_target_cname (get_variable_cname (param.name)));
-			ccode.add_assignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_delegate_target_cname (get_variable_cname (param.name))), target_expr);
 			if (param.variable_type.value_owned) {
 				data.add_field ("GDestroyNotify", get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)));
-				ccode.add_assignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_delegate_target_destroy_notify_cname (get_variable_cname (param.name))), delegate_target_destroy_notify);
+				// reference transfer for delegates
+				var lvalue = get_parameter_cvalue (param);
+				((GLibValue) value).delegate_target_destroy_notify_cvalue = get_delegate_target_destroy_notify_cvalue (lvalue);
 			}
 		}
+		param.captured = true;
+
+		store_parameter (param, value);
 	}
 
 	public override void visit_block (Block b) {
diff --git a/tests/methods/closures.vala b/tests/methods/closures.vala
index acee5de..d2be8e0 100644
--- a/tests/methods/closures.vala
+++ b/tests/methods/closures.vala
@@ -1,5 +1,8 @@
 delegate int Func ();
 
+[CCode (has_target = false)]
+delegate void NoTargetFunc ();
+
 int A (int k, Func x1, Func x2, Func x3, Func x4, Func x5) {
 	Func B = null;
 	B = () => {
@@ -9,6 +12,10 @@ int A (int k, Func x1, Func x2, Func x3, Func x4, Func x5) {
 	return k <= 0 ? x4 () + x5 () : B ();
 }
 
+void B ([CCode (array_length = false, array_null_terminated = true)] int[] array, NoTargetFunc func) {
+	Func C = () => { array = null; func (); return 0; };
+}
+
 void main () {
 	int result = A (10, () => 1, () => -1, () => -1, () => 1, () => 0);
 	assert (result == -67);



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