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

Re: segv on stack extending



Kevin Ryde wrote:

>> But maybe there's a better way?
> 
> What about leaving the names on the stack and replacing progressively
> with the results.  (Note the change from PPCODE: to CODE:, the latter
> not using a local "SP" at all and not popping anything until you
> XSRETURN ... umm, if I'm right about that.)

Good idea.  I committed the attached patch.  Thanks!

-Torsten
Index: GObject.xs
===================================================================
RCS file: /cvsroot/gtk2-perl/gtk2-perl-xs/Glib/GObject.xs,v
retrieving revision 1.76
diff -u -d -p -r1.76 GObject.xs
--- GObject.xs	3 Aug 2008 16:01:12 -0000	1.76
+++ GObject.xs	6 Sep 2008 12:58:53 -0000
@@ -1190,16 +1190,21 @@ g_object_get (object, ...)
     PREINIT:
 	GValue value = {0,};
 	int i;
-    PPCODE:
+    CODE:
+	/* Use CODE: instead of PPCODE: so we can handle the stack ourselves in
+	 * order to avoid that xsubs called by g_object_get_property overwrite
+	 * what we put on the stack. */
 	PERL_UNUSED_VAR (ix);
-	EXTEND (SP, items-1);
 	for (i = 1; i < items; i++) {
 		char *name = SvPV_nolen (ST (i));
 		init_property_value (object, name, &value);
 		g_object_get_property (object, name, &value);
-		PUSHs(sv_2mortal(_gperl_sv_from_value_internal(&value, TRUE)));
+		ST (i - 1) =
+			sv_2mortal (
+				_gperl_sv_from_value_internal (&value, TRUE));
 		g_value_unset (&value);
 	}
+	XSRETURN (items - 1);
 
 
 =for apidoc Glib::Object::set
Index: t/5.t
===================================================================
RCS file: /cvsroot/gtk2-perl/gtk2-perl-xs/Glib/t/5.t,v
retrieving revision 1.7
diff -u -d -p -r1.7 5.t
--- t/5.t	9 Sep 2006 15:04:08 -0000	1.7
+++ t/5.t	6 Sep 2008 12:58:53 -0000
@@ -8,8 +8,9 @@
 
 use strict;
 use warnings;
+use Test::More; # for eq_array
 
-print "1..9\n";
+print "1..10\n";
 
 use Glib;
 
@@ -42,10 +43,17 @@ sub INIT_INSTANCE {
 }
 
 sub FINALIZE_INSTANCE {
-   print "ok 8\n";
+   print "ok 9\n";
+}
+
+sub grow_the_stack {
+  1 .. 500;
 }
 
 sub GET_PROPERTY {
+   # grow the stack to trigger reallocation and movement of it in order to test
+   # that Glib::Object->get handles the stack correctly
+   my @list = grow_the_stack();
    77;
 }
 
@@ -79,9 +87,13 @@ package main;
    # set should have bailed out before setting some_string to bar.
    # cannot use get() here, because GET_PROPERTY always returns 77.
    print $my->{some_string} ne 'foo' ? "not " : "", "ok 7\n";
+
+   # verify that fetching multiple properties doesn't corrupt the stack.
+   print eq_array([$my->get("some_string", "some_string")], [77, 77])
+      ? "" : "not ", "ok 8\n";
 }
 
-print "ok 9\n";
+print "ok 10\n";
 
 
 


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