vala r1814 - in trunk: . gobject vala



Author: juergbi
Date: Mon Sep 29 21:35:39 2008
New Revision: 1814
URL: http://svn.gnome.org/viewvc/vala?rev=1814&view=rev

Log:
2008-09-29  JÃrg Billeter  <j bitron ch>

	* vala/valadatatype.vala:
	* vala/valastruct.vala:
	* vala/valavaluetype.vala:
	* gobject/valaccodegenerator.vala:
	* gobject/valaccodegeneratorstruct.vala:

	Add experimental memory management support for structs that use
	reference types in fields, fixes bug 526552


Modified:
   trunk/ChangeLog
   trunk/gobject/valaccodegenerator.vala
   trunk/gobject/valaccodegeneratorstruct.vala
   trunk/vala/valadatatype.vala
   trunk/vala/valastruct.vala
   trunk/vala/valavaluetype.vala

Modified: trunk/gobject/valaccodegenerator.vala
==============================================================================
--- trunk/gobject/valaccodegenerator.vala	(original)
+++ trunk/gobject/valaccodegenerator.vala	Mon Sep 29 21:35:39 2008
@@ -1486,6 +1486,9 @@
 					if (unref_function == null) {
 						unref_function = "g_free";
 					}
+				} else {
+					var st = (Struct) type.data_type;
+					unref_function = st.get_destroy_function ();
 				}
 			}
 			if (unref_function == null) {
@@ -1551,6 +1554,14 @@
 	}
 
 	public CCodeExpression get_unref_expression (CCodeExpression cvar, DataType type, Expression expr) {
+		var ccall = new CCodeFunctionCall (get_destroy_func_expression (type));
+
+		if (type is ValueType && !type.nullable) {
+			// normal value type, no null check
+			ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cvar));
+			return ccall;
+		}
+
 		/* (foo == NULL ? NULL : foo = (unref (foo), NULL)) */
 		
 		/* can be simplified to
@@ -1569,9 +1580,8 @@
 			cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.OR, cisnull, cunrefisnull);
 		}
 
-		var ccall = new CCodeFunctionCall (get_destroy_func_expression (type));
 		ccall.add_argument (cvar);
-		
+
 		/* set freed references to NULL to prevent further use */
 		var ccomma = new CCodeCommaExpression ();
 
@@ -3027,11 +3037,29 @@
 		return true;
 	}
 
-	private CCodeExpression? get_ref_expression (Expression expr) {
-		return get_ref_cexpression (expr.value_type, (CCodeExpression) expr.ccodenode, expr, expr);
-	}
-
 	private CCodeExpression? get_ref_cexpression (DataType expression_type, CCodeExpression cexpr, Expression? expr, CodeNode node) {
+		if (expression_type is ValueType && !expression_type.nullable) {
+			// normal value type, no null check
+			// (copy (&expr, &temp), temp)
+
+			var decl = get_temp_variable (expression_type, false, node);
+			temp_vars.insert (0, decl);
+
+			var ctemp = new CCodeIdentifier (decl.name);
+			
+			var vt = (ValueType) expression_type;
+			var st = (Struct) vt.type_symbol;
+			var copy_call = new CCodeFunctionCall (new CCodeIdentifier (st.get_copy_function ()));
+			copy_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cexpr));
+			copy_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp));
+
+			var ccomma = new CCodeCommaExpression ();
+			ccomma.append_expression (copy_call);
+			ccomma.append_expression (ctemp);
+
+			return ccomma;
+		}
+
 		/* (temp = expr, temp == NULL ? NULL : ref (temp))
 		 *
 		 * can be simplified to

Modified: trunk/gobject/valaccodegeneratorstruct.vala
==============================================================================
--- trunk/gobject/valaccodegeneratorstruct.vala	(original)
+++ trunk/gobject/valaccodegeneratorstruct.vala	Mon Sep 29 21:35:39 2008
@@ -53,8 +53,59 @@
 
 		st.accept_children (this);
 
+		if (st.is_disposable ()) {
+			add_struct_copy_function (st);
+			add_struct_destroy_function (st);
+		}
+
 		current_type_symbol = old_type_symbol;
 		instance_struct = old_instance_struct;
 		instance_finalize_fragment = old_instance_finalize_fragment;
 	}
+
+	void add_struct_copy_function (Struct st) {
+		var function = new CCodeFunction (st.get_copy_function (), "void");
+		if (st.access == SymbolAccessibility.PRIVATE) {
+			function.modifiers = CCodeModifiers.STATIC;
+		}
+
+		function.add_parameter (new CCodeFormalParameter ("self", "const " + st.get_cname () + "*"));
+		function.add_parameter (new CCodeFormalParameter ("dest", st.get_cname () + "*"));
+
+		if (st.access != SymbolAccessibility.PRIVATE) {
+			header_type_member_declaration.append (function.copy ());
+		} else {
+			source_type_member_declaration.append (function.copy ());
+		}
+
+		var cblock = new CCodeBlock ();
+
+		function.block = cblock;
+
+		source_type_member_definition.append (function);
+	}
+
+	void add_struct_destroy_function (Struct st) {
+		var function = new CCodeFunction (st.get_destroy_function (), "void");
+		if (st.access == SymbolAccessibility.PRIVATE) {
+			function.modifiers = CCodeModifiers.STATIC;
+		}
+
+		function.add_parameter (new CCodeFormalParameter ("self", st.get_cname () + "*"));
+
+		if (st.access != SymbolAccessibility.PRIVATE) {
+			header_type_member_declaration.append (function.copy ());
+		} else {
+			source_type_member_declaration.append (function.copy ());
+		}
+
+		var cblock = new CCodeBlock ();
+
+		cblock.add_statement (instance_finalize_fragment);
+
+		function.block = cblock;
+
+		source_type_member_definition.append (function);
+	}
 }
+

Modified: trunk/vala/valadatatype.vala
==============================================================================
--- trunk/vala/valadatatype.vala	(original)
+++ trunk/vala/valadatatype.vala	Mon Sep 29 21:35:39 2008
@@ -461,9 +461,6 @@
 
 		if (is_reference_type_or_type_parameter ()) {
 			return true;
-		} else if (this is ValueType) {
-			// nullable structs are heap allocated
-			return nullable;
 		}
 		return false;
 	}

Modified: trunk/vala/valastruct.vala
==============================================================================
--- trunk/vala/valastruct.vala	(original)
+++ trunk/vala/valastruct.vala	Mon Sep 29 21:35:39 2008
@@ -50,6 +50,8 @@
 	private string default_value = null;
 	private bool simple_type;
 	private string? type_signature;
+	private string copy_function;
+	private string destroy_function;
 
 	/**
 	 * Specifies the default construction method.
@@ -340,6 +342,12 @@
 		if (a.has_argument ("type_signature")) {
 			type_signature = a.get_string ("type_signature");
 		}
+		if (a.has_argument ("copy_function")) {
+			set_copy_function (a.get_string ("copy_function"));
+		}
+		if (a.has_argument ("destroy_function")) {
+			set_destroy_function (a.get_string ("destroy_function"));
+		}
 	}
 
 	private void process_integer_type_attribute (Attribute a) {
@@ -556,4 +564,49 @@
 		
 		return false;
 	}
+
+	public string get_default_copy_function () {
+		return get_lower_case_cprefix () + "copy";
+	}
+
+	public override string? get_copy_function () {
+		if (copy_function == null) {
+			copy_function = get_default_copy_function ();
+		}
+		return copy_function;
+	}
+
+	public void set_copy_function (string name) {
+		this.copy_function = name;
+	}
+
+	public string get_default_destroy_function () {
+		return get_lower_case_cprefix () + "destroy";
+	}
+
+	public override string? get_destroy_function () {
+		if (destroy_function == null) {
+			destroy_function = get_default_destroy_function ();
+		}
+		return destroy_function;
+	}
+
+	public void set_destroy_function (string name) {
+		this.destroy_function = name;
+	}
+
+	public bool is_disposable () {
+		if (destroy_function != null) {
+			return true;
+		}
+
+		foreach (Field f in fields) {
+			if (f.binding == MemberBinding.INSTANCE
+			    && f.field_type.is_disposable ()) {
+				return true;
+			}
+		}
+
+		return false;
+	}
 }

Modified: trunk/vala/valavaluetype.vala
==============================================================================
--- trunk/vala/valavaluetype.vala	(original)
+++ trunk/vala/valavaluetype.vala	Mon Sep 29 21:35:39 2008
@@ -59,4 +59,22 @@
 		}
 		return type_symbol.get_cname () + ptr;
 	}
+
+	public override bool is_disposable () {
+		if (!value_owned) {
+			return false;
+		}
+
+		// nullable structs are heap allocated
+		if (nullable) {
+			return true;
+		}
+
+		var st = type_symbol as Struct;
+		if (st != null) {
+			return st.is_disposable ();
+		}
+
+		return false;
+	}
 }



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