On Monday 20 November 2006 14:20, Patrick R.Michaud wrote:

> I don't seem to be able to use iterators on subclasses of
> ResizablePMCArray.  Here's an example:
>
>     $ cat t.pir
>     .sub main :main
>         .local pmc ar, iter
>         $P0 = subclass 'ResizablePMCArray', 'MyArray'
>
>         ar = new 'MyArray'
>         push ar, 1
>         push ar, 3
>         push ar, 5
>
>         $I0 = elements ar
>         print $I0
>         print "\n"
>
>         iter = new .Iterator, ar
>       iter_loop:
>         unless iter goto iter_end
>         $P0 = shift iter
>         say $P0
>         goto iter_loop
>       iter_end:
>     .end
>
>     $ ./parrot t.pir
>     3
>     Segmentation fault
>     $
>
> Test being added to t/pmc/resizablepmcarray.t .

Here's a naive patch which demonstrates exactly what the problem is.  The 
iteration code within the PMC checks that it has an object without checking 
to see if that object extends an iterable type.  I hard-coded this test 
because it was easier than the correct fix -- making an iterable role and 
making sure that VTABLE_does() works all the way back to "array".

-- c
=== src/pmc/iterator.pmc
==================================================================
--- src/pmc/iterator.pmc	(revision 539)
+++ src/pmc/iterator.pmc	(local)
@@ -502,7 +502,9 @@
         PMC * const key = PMC_struct_val(SELF);
         PMC * const agg = PMC_pmc_val(SELF);
         PMC *ret;
-        if (PObj_is_object_TEST(agg)) {
+        STRING *array_role = const_string(INTERP, "ResizablePMCArray");
+
+        if (PObj_is_object_TEST(agg) && ! VTABLE_isa(INTERP, agg, array_role)) {
             REG_PMC(2) = agg;
             return VTABLE_shift_pmc(INTERP, key);
         }

Reply via email to