[vala] Fix memory management with g_object_get and struct properties



commit 3172ab1437dd01449dea4b99fb7a94fb6c16abac
Author: Sergey Nizovtsev <snizovtsev gmail com>
Date:   Wed Mar 31 21:13:40 2010 +0200

    Fix memory management with g_object_get and struct properties
    
    Fixes bug 613918.

 codegen/valaccodearraymodule.vala |    2 +-
 codegen/valaccodebasemodule.vala  |    2 +-
 codegen/valagobjectmodule.vala    |   32 +++++++++++++++++---------------
 3 files changed, 19 insertions(+), 17 deletions(-)
---
diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala
index 093605d..01bf85f 100644
--- a/codegen/valaccodearraymodule.vala
+++ b/codegen/valaccodearraymodule.vala
@@ -736,7 +736,7 @@ internal class Vala.CCodeArrayModule : CCodeMethodCallModule {
 		}
 	}
 
-	public override CCodeExpression get_unref_expression (CCodeExpression cvar, DataType type, Expression expr, bool is_macro_definition) {
+	public override CCodeExpression get_unref_expression (CCodeExpression cvar, DataType type, Expression? expr, bool is_macro_definition) {
 		if (type is ArrayType) {
 			var array_type = (ArrayType) type;
 
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 6bbd100..634fb66 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -2843,7 +2843,7 @@ internal class Vala.CCodeBaseModule : CCodeModule {
 		return null;
 	}
 
-	public virtual CCodeExpression get_unref_expression (CCodeExpression cvar, DataType type, Expression expr, bool is_macro_definition = false) {
+	public virtual CCodeExpression get_unref_expression (CCodeExpression cvar, DataType type, Expression? expr, bool is_macro_definition = false) {
 		if (type is DelegateType) {
 			CCodeExpression delegate_target_destroy_notify;
 			var delegate_target = get_delegate_target_cexpression (expr, out delegate_target_destroy_notify);
diff --git a/codegen/valagobjectmodule.vala b/codegen/valagobjectmodule.vala
index feadc07..0894b03 100644
--- a/codegen/valagobjectmodule.vala
+++ b/codegen/valagobjectmodule.vala
@@ -188,7 +188,7 @@ internal class Vala.GObjectModule : GTypeModule {
 		cdecl.add_declarator (new CCodeVariableDeclarator ("self", ccall));
 		block.add_statement (cdecl);
 
-		bool boxed_declared = false;
+		int boxed_name_id = 0;
 		bool length_declared = false;
 
 		var cswitch = new CCodeSwitchStatement (new CCodeIdentifier ("property_id"));
@@ -220,26 +220,28 @@ internal class Vala.GObjectModule : GTypeModule {
 
 			cswitch.add_statement (new CCodeCaseStatement (new CCodeIdentifier (prop.get_upper_case_cname ())));
 			if (prop.property_type.is_real_struct_type ()) {
-				if (!boxed_declared) {
-					cdecl = new CCodeDeclaration ("gpointer");
-					cdecl.add_declarator (new CCodeVariableDeclarator ("boxed"));
-					block.add_statement (cdecl);
-					boxed_declared = true;
-				}
-
 				var st = prop.property_type.data_type as Struct;
-				var struct_creation = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
-				struct_creation.add_argument (new CCodeIdentifier (st.get_cname ()));
-				struct_creation.add_argument (new CCodeConstant ("1"));
-				cswitch.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("boxed"), struct_creation)));
+				var boxed = "boxed%d".printf (boxed_name_id++);
+
+				cdecl = new CCodeDeclaration (st.get_cname ());
+				cdecl.add_declarator (new CCodeVariableDeclarator (boxed));
+				block.add_statement (cdecl);
+
 				ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_get_%s".printf (prefix, prop.name)));
 				ccall.add_argument (cself);
-				ccall.add_argument (new CCodeIdentifier ("boxed"));
+				var boxed_addr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (boxed));
+				ccall.add_argument (boxed_addr);
 				cswitch.add_statement (new CCodeExpressionStatement (ccall));
-				var csetcall = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_boxed"));
+
+				var csetcall = new CCodeFunctionCall ();
+				csetcall.call = head.get_value_setter_function (prop.property_type);
 				csetcall.add_argument (new CCodeIdentifier ("value"));
-				csetcall.add_argument (new CCodeIdentifier ("boxed"));
+				csetcall.add_argument (boxed_addr);
 				cswitch.add_statement (new CCodeExpressionStatement (csetcall));
+
+				if (requires_destroy (prop.get_accessor.value_type)) {
+					cswitch.add_statement (new CCodeExpressionStatement (get_unref_expression (new CCodeIdentifier (boxed), prop.get_accessor.value_type, null)));
+				}
 			} else {
 				ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_get_%s".printf (prefix, prop.name)));
 				ccall.add_argument (cself);



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