Ben Bullock wrote:
Is there a way to push an AV * onto the stack as an array?
Right now I have the following:
if (wantarray) {
EXTEND (SP, av_len (wantarray));
for (i = 0; i <= av_len (wantarray); i++) {
PUSHs (sv_2mortal (*(av_fetch (wantarray, i, 0))));
}
}
See:
https://github.com/benkasminbullock/Text-Fuzzy/blob/master/Fuzzy.xs#L163
Is there a better way to do it?
"PUSHs (sv_2mortal (*(av_fetch (wantarray, i, 0))));" will cause a double free. av_fetch doesn't give you a refcount
notch to own. Call *SvREFCNT_inc_simple_void_NN* on the returned SV * then call sv_2mortal. Also realize you are passing an alias
back to the caller. "@arr = xsub();" will make a copy, but "$scalar = \xsub()" will let them control what is
in your array. You can also return an array reference but then then the xsub won't be list context, just scalar context. GIMME_V
will tell you want the caller wants. In the github code, you also leaked AV * wantarray. You didn't mortal it, or *SvREFCNT_dec*
it or put it in a RV that itself is mortaled or *SvREFCNT_dec*'d. You could also, this is high end stuff, do a memcpy from
AvARRAY to Perl stack, then do "SP += count;" (or is that "SP += count;").