Re: How can I push an AV * onto the stack?
[email protected] (bulk88)
| Newsgroups | perl.xs |
|---|---|
| Message-ID | <[email protected]> |
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;").