[perl-Glib] Glib::ParamSpec->value_validate(): copy boxed objects if necessary



commit 7b3d380d9b98e45a8a32fab3098ec7e64f60ad2f
Author: Kevin Ryde <user42 zip com au>
Date:   Sun Nov 28 11:18:10 2010 +1100

    Glib::ParamSpec->value_validate(): copy boxed objects if necessary
    
    Firstly return the incoming SV directly if value already valid (which is usual
    for GParamSpecBoxed), or if the GValue is modified then make a copy of its
    content before destroying it as it's probably new memory not still a pointer to
    the original.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=635809

 GParamSpec.xs |   25 +++++++++++++++++++++++--
 1 files changed, 23 insertions(+), 2 deletions(-)
---
diff --git a/GParamSpec.xs b/GParamSpec.xs
index 49341d4..6c2e046 100644
--- a/GParamSpec.xs
+++ b/GParamSpec.xs
@@ -20,6 +20,7 @@
  */
 
 #include "gperl.h"
+#include "gperl-private.h" /* for _gperl_sv_from_value_internal() */
 
 /*
  * this isn't already done for us.  :-(
@@ -787,8 +788,28 @@ g_param_value_validate (GParamSpec * pspec, SV *value)
 	modify = g_param_value_validate (pspec, &v);
 	ST(0) = sv_2mortal (boolSV (modify));
 	if (GIMME_V == G_ARRAY) {
-		ST(1) = sv_2mortal (gperl_sv_from_value (&v));
-		retcount = 2;
+	    /* If unmodified then can leave ST(1) "value" alone.
+
+	       If modified then expect that g_param_value_validate() will
+	       have made a new block of memory owned by the GValue and which
+	       will be freed at the g_value_unset().  For that reason ask
+	       _gperl_sv_from_value_internal() to "copy_boxed" to grab
+	       before it's freed.
+
+	       If g_param_value_validate() says modified but doesn't
+	       in fact modify but just leaves the GValue pointing into
+	       the input ST(1) "value" then we might prefer not to
+	       copy (but instead leave ST(1) as the return).  Believe
+	       that shouldn't happen, ie. a value_validate vfunc
+	       shouldn't modify the input but rather if modifying
+	       something then it will put in new memory.  Or
+	       alternately if it doesn't modify anything then it
+	       shouldn't say modified.  (The Glib ref manual circa
+	       2.27 doesn't have much guidance on this.)  */
+
+	    retcount = 2;
+	    if (modify)
+		ST(1) = sv_2mortal (_gperl_sv_from_value_internal(&v,TRUE));
 	}
 	g_value_unset (&v);
 	XSRETURN(retcount);



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