vala r1832 - in trunk: . gobject



Author: juergbi
Date: Sat Oct 11 11:18:49 2008
New Revision: 1832
URL: http://svn.gnome.org/viewvc/vala?rev=1832&view=rev

Log:
2008-10-11  JÃrg Billeter  <j bitron ch>

	* gobject/valaccodegenerator.vala:

	Add support for copying arrays, fixes bug 477107


Modified:
   trunk/ChangeLog
   trunk/gobject/valaccodegenerator.vala

Modified: trunk/gobject/valaccodegenerator.vala
==============================================================================
--- trunk/gobject/valaccodegenerator.vala	(original)
+++ trunk/gobject/valaccodegenerator.vala	Sat Oct 11 11:18:49 2008
@@ -81,6 +81,7 @@
 	public int next_temp_var_id = 0;
 	private int current_try_id = 0;
 	private int next_try_id = 0;
+	private int next_array_dup_id = 0;
 	public bool in_creation_method = false;
 	private bool in_constructor = false;
 	public bool in_static_or_class_ctor = false;
@@ -1392,7 +1393,7 @@
 					dup_function = "";
 				}
 			} else {
-				// duplicating non-reference counted structs may cause side-effects (and performance issues)
+				// duplicating non-reference counted objects may cause side-effects (and performance issues)
 				Report.error (source_reference, "duplicating %s instance, use weak variable or explicitly invoke copy method".printf (type.data_type.name));
 				return null;
 			}
@@ -1402,8 +1403,7 @@
 			string func_name = "%s_dup_func".printf (type.type_parameter.name.down ());
 			return new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), func_name);
 		} else if (type is ArrayType) {
-			Report.error (source_reference, "internal error: duplicating %s instances not yet supported".printf (type.to_string ()));
-			return null;
+			return new CCodeIdentifier (generate_array_dup_wrapper ((ArrayType) type));
 		} else if (type is PointerType) {
 			var pointer_type = (PointerType) type;
 			return get_dup_func_expression (pointer_type.base_type, source_reference);
@@ -1412,6 +1412,77 @@
 		}
 	}
 
+	string generate_array_dup_wrapper (ArrayType array_type) {
+		string dup_func = "_vala_array_dup%d".printf (++next_array_dup_id);
+
+		if (!add_wrapper (dup_func)) {
+			// wrapper already defined
+			return dup_func;
+		}
+
+		// declaration
+
+		var function = new CCodeFunction (dup_func, array_type.get_cname ());
+		function.modifiers = CCodeModifiers.STATIC;
+
+		function.add_parameter (new CCodeFormalParameter ("self", array_type.get_cname ()));
+		// total length over all dimensions
+		function.add_parameter (new CCodeFormalParameter ("length", "int"));
+
+		// definition
+
+		var block = new CCodeBlock ();
+
+		if (requires_copy (array_type.element_type)) {
+			var old_temp_vars = temp_vars;
+
+			var cdecl = new CCodeDeclaration (array_type.get_cname ());
+			var cvardecl = new CCodeVariableDeclarator ("result");
+			cdecl.add_declarator (cvardecl);
+			var gnew = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
+			gnew.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
+			gnew.add_argument (new CCodeIdentifier ("length"));
+			cvardecl.initializer = gnew;
+			block.add_statement (cdecl);
+
+			var idx_decl = new CCodeDeclaration ("int");
+			idx_decl.add_declarator (new CCodeVariableDeclarator ("i"));
+			block.add_statement (idx_decl);
+
+			var loop_body = new CCodeBlock ();
+			loop_body.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeElementAccess (new CCodeIdentifier ("result"), new CCodeIdentifier ("i")), get_ref_cexpression (array_type.element_type, new CCodeElementAccess (new CCodeIdentifier ("self"), new CCodeIdentifier ("i")), null, array_type))));
+
+			var cfor = new CCodeForStatement (new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier ("i"), new CCodeIdentifier ("length")), loop_body);
+			cfor.add_initializer (new CCodeAssignment (new CCodeIdentifier ("i"), new CCodeConstant ("0")));
+			cfor.add_iterator (new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier ("i")));
+			block.add_statement (cfor);
+
+			block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("result")));
+
+			var cfrag = new CCodeFragment ();
+			append_temp_decl (cfrag, temp_vars);
+			block.add_statement (cfrag);
+			temp_vars = old_temp_vars;
+		} else {
+			var dup_call = new CCodeFunctionCall (new CCodeIdentifier ("g_memdup"));
+			dup_call.add_argument (new CCodeIdentifier ("self"));
+
+			var sizeof_call = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
+			sizeof_call.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
+			dup_call.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeIdentifier ("length"), sizeof_call));
+
+			block.add_statement (new CCodeReturnStatement (dup_call));
+		}
+
+		// append to file
+
+		source_type_member_declaration.append (function.copy ());
+
+		function.block = block;
+		source_type_member_definition.append (function);
+
+		return dup_func;
+	}
 
 	private string generate_struct_dup_wrapper (ValueType value_type) {
 		string dup_func = "_%sdup".printf (value_type.type_symbol.get_lower_case_cprefix ());
@@ -3092,7 +3163,7 @@
 			var ctemp = new CCodeIdentifier (decl.name);
 			
 			var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ctemp, new CCodeConstant ("NULL"));
-			if (expression_type.data_type == null) {
+			if (expression_type.type_parameter != null) {
 				if (!(current_type_symbol is Class)) {
 					return cexpr;
 				}
@@ -3102,11 +3173,27 @@
 				cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.OR, cisnull, cdupisnull);
 			}
 
-			if (expression_type.data_type != null) {
-				ccall.add_argument (ctemp);
-			} else {
+			if (expression_type.type_parameter != null) {
 				// cast from gconstpointer to gpointer as GBoxedCopyFunc expects gpointer
 				ccall.add_argument (new CCodeCastExpression (ctemp, "gpointer"));
+			} else {
+				ccall.add_argument (ctemp);
+			}
+
+			if (expression_type is ArrayType) {
+				var array_type = (ArrayType) expression_type;
+				bool first = true;
+				CCodeExpression csizeexpr = null;
+				for (int dim = 1; dim <= array_type.rank; dim++) {
+					if (first) {
+						csizeexpr = get_array_length_cexpression (expr, dim);
+						first = false;
+					} else {
+						csizeexpr = new CCodeBinaryExpression (CCodeBinaryOperator.MUL, csizeexpr, get_array_length_cexpression (expr, dim));
+					}
+				}
+
+				ccall.add_argument (csizeexpr);
 			}
 
 			var ccomma = new CCodeCommaExpression ();



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