Re: treeiter stamp sign extension

muppet wrote:
In a custom TreeModel I was foolish enough to let my iter "stamp"
generation come up with a 32-bit value.  A cpan testers report on an
int=32bit long=64bit system had me making 0x807012D8, but after storing
that to a TreeIter then getting it back in an arrayref to a method call
the array had instead 0xFFFFFFFF807012D8.

You've fallen prey to perl's IV being defined as an integer large enough to hold a pointer. So, even though the platform is sizeof(int)=4, sizeof(IV) will be 8 because sizeof(void*)=64.

To be honest, this isn't something we considered when wrapping that stuff.

Why are we using the newSVuv/SvUV converters for the iter stamp? I can't find any documentation or code that confines GtkTreeIter stamps to positive numbers.

The attached patch changes the GtkTreeIter converters to use gint and newSViv/SvIV. With it applied, Kevin's test program outputs:

intended stamp 2147483648
aref got stamp -2147483648

I think that's fair (2147483648 is out of range for 32 bit gints) -- but it can be considered a backwards incompatibility.
Index: xs/GtkTreeModel.xs
--- xs/GtkTreeModel.xs  (revision 2134)
+++ xs/GtkTreeModel.xs  (working copy)
@@ -183,7 +183,7 @@ sv_from_iter (GtkTreeIter * iter)
        AV * av = newAV ();
        if (!iter)
                return &PL_sv_undef;
-       av_push (av, newSVuv (iter->stamp));
+       av_push (av, newSViv (iter->stamp));
        av_push (av, newSViv (PTR2IV (iter->user_data)));
        av_push (av, iter->user_data2 ? newRV (iter->user_data2) : &PL_sv_undef);
        av_push (av, iter->user_data3 ? newRV (iter->user_data3) : &PL_sv_undef);
@@ -207,7 +207,7 @@ iter_from_sv (GtkTreeIter * iter,
                               sv_reftype (SvRV (sv), 0));
                av = (AV*) SvRV (sv);
                if ((svp = av_fetch (av, 0, FALSE)))
-                       iter->stamp = SvUV (*svp);
+                       iter->stamp = SvIV (*svp);
                if ((svp = av_fetch (av, 1, FALSE)) && SvIOK (*svp))
                        iter->user_data = INT2PTR (gpointer, SvIV (*svp));
@@ -921,7 +921,7 @@ model.  See L<Gtk2::TreeModel/CREATING A
 more information.
-to_arrayref (GtkTreeIter * iter, IV stamp)
+to_arrayref (GtkTreeIter * iter, gint stamp)
        if (iter->stamp != stamp)
                croak ("invalid iter -- stamp %d does not match requested %d",

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