On Dec 23, 2008, at 12:08 PM, Shlomi Fish wrote:
Hi all!
In:
http://opensvn.csie.org/shlomif/documents/perl/trunk/perl5/ext-embed-internals/docbook/examples/incremental-examples-1/XSTest/
I have written the following XS function:
[snip big function attempting to make a new array containing direct
references to items in the originals]
Are you sure that's what you want to do? You compare to the syntax
$combined = [ @array1, @array2 ];
but that's not what that syntax does. The square brackets give you a
reference to a new array containing copies of the stuff inside.
If you dump the contents of an array like that with
Devel::Peek::Dump(), you'll see that each element has a refcount of 1
and even the scalars are different actual SVs.
So i think what you want to do in the middle of the loop is a simple
loop that does a copy. Just tested this, which should be a drop-in
replacement for you:
AV *
concatenate_two_array_refs (AV * a1, AV * a2)
PREINIT:
AV * av;
int a1len, a2len, i, n;
CODE:
a1len = av_len (a1) + 1;
a2len = av_len (a2) + 1;
n = 0;
av = newAV ();
/* Pre-extend the array so we don't waste time allocating each time
* through the loop. */
av_extend (av, a1len + a2len);
for (i = 0 ; i < a1len ; i++) {
SV ** svp = av_fetch (a1, i, FALSE);
/* Since we already checked the array length,
* fetch should not fail */
assert (svp);
/* Let the new array take ownership of a new copy of the sv. */
av_store (av, n, newSVsv (*svp));
n++;
}
/* Same as above for the other array */
for (i = 0 ; i < a2len ; i++) {
SV ** svp = av_fetch (a2, i, FALSE);
assert (svp);
av_store (av, n, newSVsv (*svp));
n++;
}
assert (n == (a1len + a2len));
RETVAL = av;
OUTPUT:
RETVAL
--
elysse: You dance better than some.
me: "Some" what?
elysse: Some asparagus.