I was playing around a bit with the set_keyed and get_keyed ops and found that this:
new P0, PerlArray set I0, 0 LOOP: set_keyed P0, I0, I0 inc I0 lt I0, 10000, LOOP end causes Parrot to segfault. The culprit appears to be this bit of code in trace_active_PMCs in resources.c: ---- else { /* The only thing left is "buffer of PMCs" */ Buffer *trace_buf = current->data; PMC **cur_pmc = trace_buf->bufstart; /* Mark the damn buffer as used! */ trace_buf->flags |= BUFFER_live_FLAG; for (i = 0; i < trace_buf->buflen; i++) { if (cur_pmc[i]) { last = mark_used(cur_pmc[i], last); } } } ---- The problem is that trace_buf->buflen is the size of the buffer, and not the number of PMCs contained in it, so the loop reads out of the end of cur_pmc and into garbage data. The patch below fixes this, and also adds a test-case to perlarray.t to stop it from coming back. Simon --- resources.c.old Sat Apr 20 17:55:28 2002 +++ resources.c Sat Apr 20 17:58:45 2002 @@ -462,9 +462,10 @@ /* The only thing left is "buffer of PMCs" */ Buffer *trace_buf = current->data; PMC **cur_pmc = trace_buf->bufstart; + UINTVAL no_of_pmcs = trace_buf->buflen / sizeof(PMC*); /* Mark the damn buffer as used! */ trace_buf->flags |= BUFFER_live_FLAG; - for (i = 0; i < trace_buf->buflen; i++) { + for (i = 0; i < no_of_pmcs; i++) { if (cur_pmc[i]) { last = mark_used(cur_pmc[i], last); } --- t/pmc/perlarray.t.old Sat Apr 20 18:09:16 2002 +++ t/pmc/perlarray.t Sat Apr 20 18:13:48 2002 @@ -1,6 +1,6 @@ #! perl -w -use Parrot::Test tests => 6; +use Parrot::Test tests => 7; use Test::More; output_is(<<'CODE', <<'OUTPUT', "size of the array"); @@ -275,4 +275,18 @@ ok 19 OUTPUT +output_is(<<'CODE', <<'OUTPUT', "Array resizing stress-test"); + new P0, PerlArray + set I0, 0 +LOOP: set_keyed P0, I0, I0 # set P0[I0], I0 + inc I0 + lt I0, 10000, LOOP + get_keyed I1, P0, 9999 # set I1, P0[9999] + print I1 + print "\n" + end +CODE +9999 +OUTPUT + 1;