[vala] codegen: Use separate C statements for out arguments



commit 72f2c382c4976d8510bb5369295be12e70f3101a
Author: Jürg Billeter <j bitron ch>
Date:   Thu Oct 14 12:24:59 2010 +0200

    codegen: Use separate C statements for out arguments

 codegen/valaccodemethodcallmodule.vala |  212 +++++++++++++++-----------------
 1 files changed, 100 insertions(+), 112 deletions(-)
---
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index 3d64c57..bfb707f 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -339,131 +339,92 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 						carg_map = out_arg_map;
 					}
 
-					if (!param.no_array_length && param.variable_type is ArrayType) {
-						var array_type = (ArrayType) param.variable_type;
-						for (int dim = 1; dim <= array_type.rank; dim++) {
-							CCodeExpression? array_length_expr = null;
-							if (param.array_length_type != null) {
-								if (param.direction == ParameterDirection.OUT) {
-									var temp_array_length = get_temp_variable (new CType (param.array_length_type));
-									emit_temp_var (temp_array_length);
-									array_length_expr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_array_length.name));
-
-									var comma = new CCodeCommaExpression ();
-									LocalVariable? temp_result = null;
-									if (!(m.return_type is VoidType)) {
-										temp_result = get_temp_variable (m.return_type);
-										emit_temp_var (temp_result);
-										ccall_expr = new CCodeAssignment (get_variable_cexpression (temp_result.name), ccall_expr);
-									}
-
-									comma.append_expression (ccall_expr);
-									comma.append_expression (new CCodeAssignment (get_variable_cexpression (get_array_length_cname (((UnaryExpression) arg).inner.to_string (), dim)), new CCodeCastExpression (get_variable_cexpression (temp_array_length.name), int_type.get_cname ())));
-
-									if (temp_result != null) {
-										comma.append_expression (get_variable_cexpression (temp_result.name));
-									}
-									ccall_expr = comma;
-								} else {
+					var unary = arg as UnaryExpression;
+					if (unary == null || unary.operator != UnaryOperator.OUT) {
+						if (!param.no_array_length && param.variable_type is ArrayType) {
+							var array_type = (ArrayType) param.variable_type;
+							for (int dim = 1; dim <= array_type.rank; dim++) {
+								CCodeExpression? array_length_expr = null;
+								if (param.array_length_type != null) {
 									array_length_expr = new CCodeCastExpression (get_array_length_cexpression (arg, dim), param.array_length_type);
+								} else {
+									array_length_expr = get_array_length_cexpression (arg, dim);
 								}
-							} else {
-								array_length_expr = get_array_length_cexpression (arg, dim);
+								carg_map.set (get_param_pos (param.carray_length_parameter_position + 0.01 * dim), array_length_expr);
 							}
-							carg_map.set (get_param_pos (param.carray_length_parameter_position + 0.01 * dim), array_length_expr);
-						}
-					} else if (param.variable_type is DelegateType) {
-						var deleg_type = (DelegateType) param.variable_type;
-						var d = deleg_type.delegate_symbol;
-						if (d.has_target) {
-							CCodeExpression delegate_target_destroy_notify;
-							var delegate_target = get_delegate_target_cexpression (arg, out delegate_target_destroy_notify);
-							if (param.ctype == "GClosure*") {
-								// one single GClosure parameter
-								var closure_new = new CCodeFunctionCall (new CCodeIdentifier ("g_cclosure_new"));
-								closure_new.add_argument (new CCodeCastExpression (cexpr, "GCallback"));
-								closure_new.add_argument (delegate_target);
-								closure_new.add_argument (delegate_target_destroy_notify);
-								cexpr = closure_new;
-							} else {
-								carg_map.set (get_param_pos (param.cdelegate_target_parameter_position), delegate_target);
-								if (deleg_type.value_owned) {
-									carg_map.set (get_param_pos (param.cdelegate_target_parameter_position + 0.01), delegate_target_destroy_notify);
+						} else if (param.variable_type is DelegateType) {
+							var deleg_type = (DelegateType) param.variable_type;
+							var d = deleg_type.delegate_symbol;
+							if (d.has_target) {
+								CCodeExpression delegate_target_destroy_notify;
+								var delegate_target = get_delegate_target_cexpression (arg, out delegate_target_destroy_notify);
+								if (param.ctype == "GClosure*") {
+									// one single GClosure parameter
+									var closure_new = new CCodeFunctionCall (new CCodeIdentifier ("g_cclosure_new"));
+									closure_new.add_argument (new CCodeCastExpression (cexpr, "GCallback"));
+									closure_new.add_argument (delegate_target);
+									closure_new.add_argument (delegate_target_destroy_notify);
+									cexpr = closure_new;
+								} else {
+									carg_map.set (get_param_pos (param.cdelegate_target_parameter_position), delegate_target);
+									if (deleg_type.value_owned) {
+										carg_map.set (get_param_pos (param.cdelegate_target_parameter_position + 0.01), delegate_target_destroy_notify);
+									}
 								}
 							}
-						}
-					} else if (param.variable_type is MethodType) {
-						// callbacks in dynamic method calls
-						CCodeExpression delegate_target_destroy_notify;
-						carg_map.set (get_param_pos (param.cdelegate_target_parameter_position), get_delegate_target_cexpression (arg, out delegate_target_destroy_notify));
-					} else if (param.variable_type is GenericType) {
-						if (m != null && m.simple_generics) {
-							var generic_type = (GenericType) param.variable_type;
-							int type_param_index = m.get_type_parameter_index (generic_type.type_parameter.name);
-							var type_arg = ma.get_type_arguments ().get (type_param_index);
-							if (requires_copy (type_arg)) {
-								carg_map.set (get_param_pos (param.cdestroy_notify_parameter_position), get_destroy_func_expression (type_arg));
-							} else {
-								carg_map.set (get_param_pos (param.cdestroy_notify_parameter_position), new CCodeConstant ("NULL"));
+						} else if (param.variable_type is MethodType) {
+							// callbacks in dynamic method calls
+							CCodeExpression delegate_target_destroy_notify;
+							carg_map.set (get_param_pos (param.cdelegate_target_parameter_position), get_delegate_target_cexpression (arg, out delegate_target_destroy_notify));
+						} else if (param.variable_type is GenericType) {
+							if (m != null && m.simple_generics) {
+								var generic_type = (GenericType) param.variable_type;
+								int type_param_index = m.get_type_parameter_index (generic_type.type_parameter.name);
+								var type_arg = ma.get_type_arguments ().get (type_param_index);
+								if (requires_copy (type_arg)) {
+									carg_map.set (get_param_pos (param.cdestroy_notify_parameter_position), get_destroy_func_expression (type_arg));
+								} else {
+									carg_map.set (get_param_pos (param.cdestroy_notify_parameter_position), new CCodeConstant ("NULL"));
+								}
 							}
 						}
-					}
-
-					cexpr = handle_struct_argument (param, arg, cexpr);
-
-					// unref old value for non-null non-weak ref/out arguments
-					// disabled for arrays for now as that requires special handling
-					// (ret_tmp = call (&tmp), var1 = (assign_tmp = dup (tmp), free (var1), assign_tmp), ret_tmp)
-					if (param.direction != ParameterDirection.IN && requires_destroy (arg.value_type)
-					    && (param.direction == ParameterDirection.OUT || !param.variable_type.value_owned)
-					    && !(param.variable_type is ArrayType) && !(param.variable_type is DelegateType)) {
-						var unary = (UnaryExpression) arg;
-
-						var ccomma = new CCodeCommaExpression ();
 
+						cexpr = handle_struct_argument (param, arg, cexpr);
+					} else {
 						var temp_var = get_temp_variable (param.variable_type, param.variable_type.value_owned);
 						emit_temp_var (temp_var);
-						cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression (temp_var.name));
-
-						if (param.direction == ParameterDirection.REF) {
-							var crefcomma = new CCodeCommaExpression ();
-							crefcomma.append_expression (new CCodeAssignment (get_variable_cexpression (temp_var.name), get_cvalue (unary.inner)));
-							crefcomma.append_expression (cexpr);
-							cexpr = crefcomma;
-						}
-
-						// call function
-						LocalVariable ret_temp_var = null;
-						if (itype.get_return_type () is VoidType || itype.get_return_type ().is_real_struct_type () ||
-						    (expr.parent_node is ExpressionStatement && !requires_destroy (itype.get_return_type ()))) {
-							ccomma.append_expression (ccall_expr);
-						} else {
-							ret_temp_var = get_temp_variable (itype.get_return_type (), true, null, false);
-							emit_temp_var (ret_temp_var);
-							ccomma.append_expression (new CCodeAssignment (get_variable_cexpression (ret_temp_var.name), ccall_expr));
-						}
+						set_cvalue (arg, get_variable_cexpression (temp_var.name));
 
-						var cassign_comma = new CCodeCommaExpression ();
+						cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_cvalue (arg));
 
-						var assign_temp_var = get_temp_variable (unary.inner.value_type, unary.inner.value_type.value_owned, null, false);
-						emit_temp_var (assign_temp_var);
-
-						cassign_comma.append_expression (new CCodeAssignment (get_variable_cexpression (assign_temp_var.name), transform_expression (get_variable_cexpression (temp_var.name), param.variable_type, unary.inner.value_type, arg)));
-
-						// unref old value
-						cassign_comma.append_expression (get_unref_expression (get_cvalue (unary.inner), arg.value_type, arg));
-
-						cassign_comma.append_expression (get_variable_cexpression (assign_temp_var.name));
-
-						// assign new value
-						ccomma.append_expression (new CCodeAssignment (get_cvalue (unary.inner), cassign_comma));
-
-						// return value
-						if (ret_temp_var != null) {
-							ccomma.append_expression (get_variable_cexpression (ret_temp_var.name));
+						if (!param.no_array_length && param.variable_type is ArrayType) {
+							var array_type = (ArrayType) param.variable_type;
+							var array_length_type = int_type;
+							if (param.array_length_type != null) {
+								array_length_type = new CType (param.array_length_type);
+							}
+							for (int dim = 1; dim <= array_type.rank; dim++) {
+								var temp_array_length = get_temp_variable (array_length_type);
+								emit_temp_var (temp_array_length);
+								append_array_size (arg, new CCodeIdentifier (temp_array_length.name));
+								carg_map.set (get_param_pos (param.carray_length_parameter_position + 0.01 * dim), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_array_sizes (arg).get (dim - 1)));
+							}
+						} else if (param.variable_type is DelegateType) {
+							var deleg_type = (DelegateType) param.variable_type;
+							var d = deleg_type.delegate_symbol;
+							if (d.has_target) {
+								temp_var = get_temp_variable (new PointerType (new VoidType ()));
+								emit_temp_var (temp_var);
+								set_delegate_target (arg, get_variable_cexpression (temp_var.name));
+								carg_map.set (get_param_pos (param.cdelegate_target_parameter_position), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_delegate_target (arg)));
+								if (deleg_type.value_owned) {
+									temp_var = get_temp_variable (new DelegateType ((Delegate) context.root.scope.lookup ("GLib").scope.lookup ("DestroyNotify")));
+									emit_temp_var (temp_var);
+									set_delegate_target_destroy_notify (arg, get_variable_cexpression (temp_var.name));
+									carg_map.set (get_param_pos (param.cdelegate_target_parameter_position + 0.01), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_delegate_target_destroy_notify (arg)));
+								}
+							}
 						}
-
-						ccall_expr = ccomma;
 					}
 
 					if (param.ctype != null) {
@@ -785,6 +746,33 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 			ccode.add_expression (new CCodeAssignment (temp_ref, ccall_expr));
 			set_cvalue (expr, temp_ref);
 		}
+
+		foreach (Expression arg in expr.get_argument_list ()) {
+			var unary = arg as UnaryExpression;
+			if (unary == null || unary.operator != UnaryOperator.OUT) {
+				continue;
+			}
+
+			if (requires_destroy (arg.value_type)) {
+				// unref old value
+				ccode.add_expression (get_unref_expression (get_cvalue (unary.inner), unary.inner.value_type, unary.inner));
+			}
+
+			// assign new value
+			ccode.add_expression (new CCodeAssignment (get_cvalue (unary.inner), transform_expression (get_cvalue (unary), unary.target_type, unary.inner.value_type, arg)));
+
+			var array_type = arg.value_type as ArrayType;
+			if (array_type != null) {
+				for (int dim = 1; dim <= array_type.rank; dim++) {
+					ccode.add_expression (new CCodeAssignment (get_array_sizes (unary.inner).get (dim - 1), get_array_sizes (unary).get (dim - 1)));
+				}
+			}
+
+			var delegate_type = arg.value_type as DelegateType;
+			if (delegate_type != null) {
+				ccode.add_expression (new CCodeAssignment (get_delegate_target (unary.inner), get_delegate_target (unary)));
+			}
+		}
 	}
 
 	private string generate_enum_tostring_function (Enum en) {



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