vala r826 - in trunk: . compiler gobject vapi vapigen



Author: juergbi
Date: Thu Jan 10 14:01:30 2008
New Revision: 826
URL: http://svn.gnome.org/viewvc/vala?rev=826&view=rev

Log:
2008-01-10  Juerg Billeter  <j bitron ch>

	* gobject/valaccodegeneratorinvocationexpression.vala,
	  gobject/valaccodegeneratormethod.vala, compiler/valacompiler.vala,
	  vapi/glib-2.0.vapi, vapigen/valavapigen.vala: fix memory management
	  of out parameters, fixes bug 501838


Modified:
   trunk/ChangeLog
   trunk/compiler/valacompiler.vala
   trunk/gobject/valaccodegeneratorinvocationexpression.vala
   trunk/gobject/valaccodegeneratormethod.vala
   trunk/vapi/glib-2.0.vapi
   trunk/vapigen/valavapigen.vala

Modified: trunk/compiler/valacompiler.vala
==============================================================================
--- trunk/compiler/valacompiler.vala	(original)
+++ trunk/compiler/valacompiler.vala	Thu Jan 10 14:01:30 2008
@@ -340,7 +340,7 @@
 			var opt_context = new OptionContext ("- Vala Compiler");
 			opt_context.set_help_enabled (true);
 			opt_context.add_main_entries (options, null);
-			opt_context.parse (out args);
+			opt_context.parse (ref args);
 		} catch (OptionError e) {
 			stdout.printf ("%s\n", e.message);
 			stdout.printf ("Run '%s --help' to see a full list of available command line options.\n", args[0]);

Modified: trunk/gobject/valaccodegeneratorinvocationexpression.vala
==============================================================================
--- trunk/gobject/valaccodegeneratorinvocationexpression.vala	(original)
+++ trunk/gobject/valaccodegeneratorinvocationexpression.vala	Thu Jan 10 14:01:30 2008
@@ -28,8 +28,9 @@
 	public override void visit_invocation_expression (InvocationExpression! expr) {
 		expr.accept_children (this);
 
+		// the bare function call
 		var ccall = new CCodeFunctionCall ((CCodeExpression) expr.call.ccodenode);
-		
+
 		Method m = null;
 		Collection<FormalParameter> params;
 		
@@ -49,6 +50,9 @@
 		} else if (itype is SignalType) {
 			ccall = (CCodeFunctionCall) expr.call.ccodenode;
 		}
+
+		// the complete call expression, might include casts, comma expressions, and/or assignments
+		CCodeExpression ccall_expr = ccall;
 		
 		if (m is ArrayResizeMethod) {
 			var array = (Array) m.parent_symbol;
@@ -239,6 +243,41 @@
 								cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cexpr);
 							}
 						}
+
+						// unref old value for non-null non-weak out arguments
+						if (param.type_reference.is_out && param.type_reference.takes_ownership && !(arg.static_type is NullType)) {
+							var unary = (UnaryExpression) arg;
+
+							// (ret_tmp = call (&tmp), free (var1), var1 = tmp, ret_tmp)
+							var ccomma = new CCodeCommaExpression ();
+
+							var temp_decl = get_temp_variable_declarator (unary.inner.static_type);
+							temp_vars.insert (0, temp_decl);
+							cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_decl.name));
+
+							// call function
+							VariableDeclarator ret_temp_decl;
+							if (m.return_type is VoidType) {
+								ccomma.append_expression (ccall_expr);
+							} else {
+								ret_temp_decl = get_temp_variable_declarator (m.return_type);
+								temp_vars.insert (0, ret_temp_decl);
+								ccomma.append_expression (new CCodeAssignment (new CCodeIdentifier (ret_temp_decl.name), ccall_expr));
+							}
+
+							// unref old value
+							ccomma.append_expression (get_unref_expression ((CCodeExpression) unary.inner.ccodenode, arg.static_type, arg));
+
+							// assign new value
+							ccomma.append_expression (new CCodeAssignment ((CCodeExpression) unary.inner.ccodenode, new CCodeIdentifier (temp_decl.name)));
+
+							// return value
+							if (!(m.return_type is VoidType)) {
+								ccomma.append_expression (new CCodeIdentifier (ret_temp_decl.name));
+							}
+
+							ccall_expr = ccomma;
+						}
 					}
 				} else if (expr.can_fail && !(m is DBusMethod)) {
 					// method can fail
@@ -329,13 +368,13 @@
 		}
 		
 		if (m != null && m.instance && m.returns_modified_pointer) {
-			expr.ccodenode = new CCodeAssignment (instance, ccall);
+			expr.ccodenode = new CCodeAssignment (instance, ccall_expr);
 		} else {
 			/* cast pointer to actual type if this is a generic method return value */
 			if (m != null && m.return_type.type_parameter != null && expr.static_type.data_type != null) {
-				expr.ccodenode = convert_from_generic_pointer (ccall, expr.static_type);
+				expr.ccodenode = convert_from_generic_pointer (ccall_expr, expr.static_type);
 			} else {
-				expr.ccodenode = ccall;
+				expr.ccodenode = ccall_expr;
 			}
 		
 			visit_expression (expr);

Modified: trunk/gobject/valaccodegeneratormethod.vala
==============================================================================
--- trunk/gobject/valaccodegeneratormethod.vala	(original)
+++ trunk/gobject/valaccodegeneratormethod.vala	Thu Jan 10 14:01:30 2008
@@ -280,11 +280,17 @@
 					}
 
 					var t = param.type_reference.data_type;
-					if (t != null && t.is_reference_type () && !param.type_reference.is_out) {
-						var type_check = create_method_type_check_statement (m, creturn_type, t, (context.non_null && !param.type_reference.nullable), param.name);
-						if (type_check != null) {
-							type_check.line = function.line;
-							cinit.append (type_check);
+					if (t != null && t.is_reference_type ()) {
+						if (!param.type_reference.is_out) {
+							var type_check = create_method_type_check_statement (m, creturn_type, t, (context.non_null && !param.type_reference.nullable), param.name);
+							if (type_check != null) {
+								type_check.line = function.line;
+								cinit.append (type_check);
+							}
+						} else {
+							// ensure that the passed reference for output parameter is cleared
+							var a = new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (param.name)), new CCodeConstant ("NULL"));
+							cinit.append (new CCodeExpressionStatement (a));
 						}
 					} else if (t is Struct) {
 						var st = (Struct) t;

Modified: trunk/vapi/glib-2.0.vapi
==============================================================================
--- trunk/vapi/glib-2.0.vapi	(original)
+++ trunk/vapi/glib-2.0.vapi	Thu Jan 10 14:01:30 2008
@@ -1970,7 +1970,7 @@
 	[CCode (free_function = "g_option_context_free")]
 	public class OptionContext {
 		public OptionContext (string parameter_string);
-		public bool parse (out string[] argv) throws OptionError;
+		public bool parse (ref string[] argv) throws OptionError;
 		public void set_help_enabled (bool help_enabled);
 		[NoArrayLength ()]
 		public void add_main_entries (OptionEntry[] entries, string translation_domain);

Modified: trunk/vapigen/valavapigen.vala
==============================================================================
--- trunk/vapigen/valavapigen.vala	(original)
+++ trunk/vapigen/valavapigen.vala	Thu Jan 10 14:01:30 2008
@@ -1,6 +1,6 @@
 /* valavapigen.vala
  *
- * Copyright (C) 2006-2007  JÃrg Billeter
+ * Copyright (C) 2006-2008  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
@@ -200,7 +200,7 @@
 			var opt_context = new OptionContext ("- Vala API Generator");
 			opt_context.set_help_enabled (true);
 			opt_context.add_main_entries (options, null);
-			opt_context.parse (out args);
+			opt_context.parse (ref args);
 		} catch (OptionError e) {
 			stdout.printf ("%s\n", e.message);
 			stdout.printf ("Run '%s --help' to see a full list of available command line options.\n", args[0]);



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