vala r2264 - in trunk: . gobject vala



Author: juergbi
Date: Sun Jan  4 14:11:35 2009
New Revision: 2264
URL: http://svn.gnome.org/viewvc/vala?rev=2264&view=rev

Log:
2009-01-04  JÃrg Billeter  <j bitron ch>

	* vala/valabinaryexpression.vala:
	* gobject/valaccodearraymodule.vala:
	* gobject/valaccodeassignmentmodule.vala:
	* gobject/valaccodebasemodule.vala:
	* gobject/valaccodemodule.vala:

	Support += to efficiently append elements to arrays,
	fixes part of bug 566425


Modified:
   trunk/ChangeLog
   trunk/gobject/valaccodearraymodule.vala
   trunk/gobject/valaccodeassignmentmodule.vala
   trunk/gobject/valaccodebasemodule.vala
   trunk/gobject/valaccodemodule.vala
   trunk/vala/valabinaryexpression.vala

Modified: trunk/gobject/valaccodearraymodule.vala
==============================================================================
--- trunk/gobject/valaccodearraymodule.vala	(original)
+++ trunk/gobject/valaccodearraymodule.vala	Sun Jan  4 14:11:35 2009
@@ -1,6 +1,7 @@
 /* valaccodearraymodule.vala
  *
- * Copyright (C) 2006-2008  JÃrg Billeter, Raffaele Sandrini
+ * Copyright (C) 2006-2009  JÃrg Billeter
+ * Copyright (C) 2006-2008  Raffaele Sandrini
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -21,14 +22,11 @@
  *	Raffaele Sandrini <raffaele sandrini ch>
  */
 
-using GLib;
 using Gee;
 
-/**
- * The link between an assignment and generated code.
- */
 public class Vala.CCodeArrayModule : CCodeMethodCallModule {
-	private int next_array_dup_id = 0;
+	int next_array_dup_id = 0;
+	int next_array_add_id = 0;
 
 	public CCodeArrayModule (CCodeGenerator codegen, CCodeModule? next) {
 		base (codegen, next);
@@ -227,6 +225,48 @@
 		}
 	}
 
+	public override string get_array_size_cname (string array_cname) {
+		return "%s_size".printf (array_cname);
+	}
+
+	public override CCodeExpression get_array_size_cexpression (Expression array_expr) {
+		if (array_expr.symbol_reference is LocalVariable) {
+			var local = (LocalVariable) array_expr.symbol_reference;
+			return get_variable_cexpression (get_array_size_cname (get_variable_cname (local.name)));
+		} else if (array_expr.symbol_reference is Field) {
+			var field = (Field) array_expr.symbol_reference;
+			var ma = (MemberAccess) array_expr;
+
+			CCodeExpression size_expr = null;
+
+			if (field.binding == MemberBinding.INSTANCE) {
+				var cl = field.parent_symbol as Class;
+				bool is_gtypeinstance = (cl != null && !cl.is_compact);
+
+				string size_cname = get_array_size_cname (field.name);
+				CCodeExpression typed_inst = (CCodeExpression) get_ccodenode (ma.inner);
+
+				CCodeExpression inst;
+				if (is_gtypeinstance && field.access == SymbolAccessibility.PRIVATE) {
+					inst = new CCodeMemberAccess.pointer (typed_inst, "priv");
+				} else {
+					inst = typed_inst;
+				}
+				if (((TypeSymbol) field.parent_symbol).is_reference_type ()) {
+					size_expr = new CCodeMemberAccess.pointer (inst, size_cname);
+				} else {
+					size_expr = new CCodeMemberAccess (inst, size_cname);
+				}
+			} else {
+				size_expr = new CCodeIdentifier (get_array_size_cname (field.get_cname ()));
+			}
+
+			return size_expr;
+		}
+
+		assert_not_reached ();
+	}
+
 	public override void visit_element_access (ElementAccess expr) {
 		expr.accept_children (codegen);
 
@@ -480,6 +520,68 @@
 		return dup_func;
 	}
 
+	string generate_array_add_wrapper (ArrayType array_type) {
+		string add_func = "_vala_array_add%d".printf (++next_array_add_id);
+
+		if (!add_wrapper (add_func)) {
+			// wrapper already defined
+			return add_func;
+		}
+
+		// declaration
+
+		var function = new CCodeFunction (add_func, "void");
+		function.modifiers = CCodeModifiers.STATIC;
+
+		function.add_parameter (new CCodeFormalParameter ("array", array_type.get_cname () + "*"));
+		function.add_parameter (new CCodeFormalParameter ("length", "int*"));
+		function.add_parameter (new CCodeFormalParameter ("size", "int*"));
+
+		string typename = array_type.element_type.get_cname ();
+		CCodeExpression value = new CCodeIdentifier ("value");
+		if (array_type.element_type.is_real_struct_type ()) {
+			if (!array_type.element_type.nullable || !array_type.element_type.value_owned) {
+				typename = "const " + typename;
+			}
+			if (!array_type.element_type.nullable) {
+				typename += "*";
+				value = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, value);
+			}
+		}
+		function.add_parameter (new CCodeFormalParameter ("value", typename));
+
+		var array = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("array"));
+		var length = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("length"));
+		var size = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("size"));
+
+		// definition
+
+		var block = new CCodeBlock ();
+
+		var renew_call = new CCodeFunctionCall (new CCodeIdentifier ("g_renew"));
+		renew_call.add_argument (new CCodeIdentifier (array_type.element_type.get_cname ()));
+		renew_call.add_argument (array);
+		renew_call.add_argument (size);
+
+		var resize_block = new CCodeBlock ();
+		resize_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (size, new CCodeConditionalExpression (size, new CCodeBinaryExpression (CCodeBinaryOperator.MUL, new CCodeConstant ("2"), size), new CCodeConstant ("4")))));
+		resize_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (array, renew_call)));
+
+		var csizecheck = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, length, size);
+		block.add_statement (new CCodeIfStatement (csizecheck, resize_block));
+
+		block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeElementAccess (array, new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, length)), value)));
+
+		// append to file
+
+		source_type_member_declaration.append (function.copy ());
+
+		function.block = block;
+		source_type_member_definition.append (function);
+
+		return add_func;
+	}
+
 	public override void visit_method_call (MethodCall expr) {
 		base.visit_method_call (expr);
 
@@ -500,4 +602,44 @@
 
 		ccall.insert_argument (1, new CCodeIdentifier (element_type.get_cname ()));
 	}
+
+	bool is_array_add (Assignment assignment) {
+		var binary = assignment.right as BinaryExpression;
+		if (binary != null && binary.left.value_type is ArrayType) {
+			if (binary.operator == BinaryOperator.PLUS) {
+				if (assignment.left.symbol_reference == binary.left.symbol_reference) {
+					return true;
+				}
+			}
+		}
+
+		return false;
+	}
+
+	public override void visit_assignment (Assignment assignment) {
+		if (!is_array_add (assignment)) {
+			base.visit_assignment (assignment);
+			return;
+		}
+
+		var binary = assignment.right as BinaryExpression;
+
+		var array = binary.left;
+		var array_type = (ArrayType) array.value_type;
+		var element = binary.right;
+
+		array.accept (codegen);
+		element.target_type = array_type.element_type.copy ();
+		element.accept (codegen);
+
+		var value_param = new FormalParameter ("value", element.target_type);
+
+		var ccall = new CCodeFunctionCall (new CCodeIdentifier (generate_array_add_wrapper (array_type)));
+		ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, (CCodeExpression) array.ccodenode));
+		ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_array_length_cexpression (array)));
+		ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_array_size_cexpression (array)));
+		ccall.add_argument (handle_struct_argument (value_param, element, (CCodeExpression) element.ccodenode));
+
+		assignment.ccodenode = ccall;
+	}
 }

Modified: trunk/gobject/valaccodeassignmentmodule.vala
==============================================================================
--- trunk/gobject/valaccodeassignmentmodule.vala	(original)
+++ trunk/gobject/valaccodeassignmentmodule.vala	Sun Jan  4 14:11:35 2009
@@ -1,6 +1,7 @@
 /* valaccodeassignmentmodule.vala
  *
- * Copyright (C) 2006-2008  JÃrg Billeter, Raffaele Sandrini
+ * Copyright (C) 2006-2009  JÃrg Billeter
+ * Copyright (C) 2006-2008  Raffaele Sandrini
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -168,6 +169,16 @@
 					var rhs_array_len = head.get_array_length_cexpression (assignment.right, dim);
 					ccomma.append_expression (new CCodeAssignment (lhs_array_len, rhs_array_len));
 				}
+				if (array_type.rank == 1) {
+					var array_var = assignment.left.symbol_reference;
+					if (array_var != null && array_var.is_internal_symbol ()
+					    && (assignment.left.symbol_reference is LocalVariable
+					        || assignment.left.symbol_reference is Field)) {
+						var lhs_array_size = head.get_array_size_cexpression (assignment.left);
+						var rhs_array_len = head.get_array_length_cexpression (assignment.left, 1);
+						ccomma.append_expression (new CCodeAssignment (lhs_array_size, rhs_array_len));
+					}
+				}
 			} else if (instance_delegate) {
 				var lhs_delegate_target = get_delegate_target_cexpression (assignment.left);
 				var rhs_delegate_target = get_delegate_target_cexpression (assignment.right);

Modified: trunk/gobject/valaccodebasemodule.vala
==============================================================================
--- trunk/gobject/valaccodebasemodule.vala	(original)
+++ trunk/gobject/valaccodebasemodule.vala	Sun Jan  4 14:11:35 2009
@@ -1,6 +1,7 @@
 /* valaccodebasemodule.vala
  *
- * Copyright (C) 2006-2009  JÃrg Billeter, Raffaele Sandrini
+ * Copyright (C) 2006-2009  JÃrg Billeter
+ * Copyright (C) 2006-2008  Raffaele Sandrini
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -819,12 +820,15 @@
 			if (f.field_type is ArrayType && !f.no_array_length) {
 				// create fields to store array dimensions
 				var array_type = (ArrayType) f.field_type;
+				var len_type = int_type.copy ();
 				
 				for (int dim = 1; dim <= array_type.rank; dim++) {
-					var len_type = int_type.copy ();
-
 					st.add_field (len_type.get_cname (), head.get_array_length_cname (f.name, dim));
 				}
+
+				if (array_type.rank == 1 && f.is_internal_symbol ()) {
+					st.add_field (len_type.get_cname (), head.get_array_size_cname (f.name));
+				}
 			} else if (f.field_type is DelegateType) {
 				var delegate_type = (DelegateType) f.field_type;
 				if (delegate_type.delegate_symbol.has_target) {
@@ -940,6 +944,15 @@
 					}
 					source_type_member_declaration.append (len_def);
 				}
+
+				if (array_type.rank == 1 && f.is_internal_symbol ()) {
+					var len_type = int_type.copy ();
+
+					var cdecl = new CCodeDeclaration (len_type.get_cname ());
+					cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer (head.get_array_size_cname (f.get_cname ()), new CCodeConstant ("0")));
+					cdecl.modifiers = CCodeModifiers.STATIC;
+					source_type_member_declaration.append (cdecl);
+				}
 			} else if (f.field_type is DelegateType) {
 				var delegate_type = (DelegateType) f.field_type;
 				if (delegate_type.delegate_symbol.has_target) {
@@ -1400,6 +1413,11 @@
 				var len_var = new LocalVariable (int_type.copy (), head.get_array_length_cname (get_variable_cname (local.name), dim));
 				temp_vars.insert (0, len_var);
 			}
+
+			if (array_type.rank == 1) {
+				var size_var = new LocalVariable (int_type.copy (), head.get_array_size_cname (get_variable_cname (local.name)));
+				temp_vars.insert (0, size_var);
+			}
 		} else if (local.variable_type is DelegateType) {
 			var deleg_type = (DelegateType) local.variable_type;
 			var d = deleg_type.delegate_symbol;
@@ -1428,6 +1446,11 @@
 					var rhs_array_len = head.get_array_length_cexpression (local.initializer, dim);
 					ccomma.append_expression (new CCodeAssignment (lhs_array_len, rhs_array_len));
 				}
+				if (array_type.rank == 1) {
+					var lhs_array_size = get_variable_cexpression (head.get_array_size_cname (get_variable_cname (local.name)));
+					var rhs_array_len = get_variable_cexpression (head.get_array_length_cname (get_variable_cname (local.name), 1));
+					ccomma.append_expression (new CCodeAssignment (lhs_array_size, rhs_array_len));
+				}
 				
 				ccomma.append_expression (get_variable_cexpression (temp_var.name));
 				

Modified: trunk/gobject/valaccodemodule.vala
==============================================================================
--- trunk/gobject/valaccodemodule.vala	(original)
+++ trunk/gobject/valaccodemodule.vala	Sun Jan  4 14:11:35 2009
@@ -1,6 +1,6 @@
 /* valaccodemodule.vala
  *
- * Copyright (C) 2008  JÃrg Billeter
+ * Copyright (C) 2008-2009  JÃrg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -404,6 +404,14 @@
 		return next.get_array_length_cexpression (array_expr, dim);
 	}
 
+	public virtual string get_array_size_cname (string array_cname) {
+		return next.get_array_size_cname (array_cname);
+	}
+
+	public virtual CCodeExpression get_array_size_cexpression (Expression array_expr) {
+		return next.get_array_size_cexpression (array_expr);
+	}
+
 	public virtual void add_simple_check (CodeNode node, CCodeFragment cfrag) {
 		next.add_simple_check (node, cfrag);
 	}

Modified: trunk/vala/valabinaryexpression.vala
==============================================================================
--- trunk/vala/valabinaryexpression.vala	(original)
+++ trunk/vala/valabinaryexpression.vala	Sun Jan  4 14:11:35 2009
@@ -229,6 +229,19 @@
 			} else {
 				value_type.value_owned = true;
 			}
+		} else if (left.value_type is ArrayType && operator == BinaryOperator.PLUS) {
+			// array concatenation
+
+			var array_type = (ArrayType) left.value_type;
+
+			if (right.value_type == null || !right.value_type.compatible (array_type.element_type)) {
+				error = true;
+				Report.error (source_reference, "Incompatible operand");
+				return false;
+			}
+
+			value_type = array_type.copy ();
+			value_type.value_owned = true;
 		} else if (operator == BinaryOperator.PLUS
 			   || operator == BinaryOperator.MINUS
 			   || operator == BinaryOperator.MUL



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