Re: AV API thoughts: AVs as proxies for other things

[email protected] (Tony Cook) Fri, 12 Jun 2026 10:40:54 +1000
Newsgroups perl.perl5.porters
Message-ID <[email protected]>
On Thu, Jun 11, 2026 at 11:31:21AM +0100, Paul "LeoNerd" Evans wrote:
>   https://github.com/Perl/perl5/pull/24451
> 
> The currently-last comment in that PR I liked above, is some thinking
> out loud on the complicated problem with the C-level API it proposes. 
> It observes that if at the C level you call `av_splice(...)` on a given
> AV that is tied, there's no guarantee that the Perl `SPLICE` method that
> gets invoked returns the right number of deleted items. In particular,
> it could return more, which would be too many items for the caller to
> account for in the C-level array it passed in for the purpose. Much
> trouble. My comment ends with the observation that perhaps a workable
> API would be to have three variants of the function, which differ in
> the way they pass in or out a list (sequence?) of SVs for the splice
> operation. The three variants could use C-level arrays of SV pointers,
> perl's AV structures, or the perl data stack.
> 
...
> As I said at the top, this isn't a fully-formed plan, or a set of
> questions. I just wanted to write it out while it was in my head, for
> future reference in case someone else came to similar ideas before, or
> in future looking back at this.

My initial thought thinking over this was that for inputs the (SV**,
size_t) pair is sufficient, if the caller has a (non-tied) AV they can
pass (AvARRAY(av), av_count(av)), if they have a local C array they
can populate that, if the SVs are on the stack they can pass (MARK,
(PL_stack_sp-MARK)).

But Michael's comment on exceptions vs warnings reminded me that we
need to deal with exceptions - if we support tied targets how do we
deal with cleanup of these objects on an exception?

For the stack it's no big deal, the objects can be mortal
(non-RC_STACK) or owned by the stack (RC_STACK) and are cleaned up on
rewind, but the others are more messy.  So perhaps your proxies are
the right way to do it.

Returning stuff is harder as we found.

One option might be the caller supplies an AV and an offset, the API
extends the AV as needed and adds the elements to the AV, which should
cover returning on the stack too. (though we'd need to check something
like (av == PL_curstack && rpp_stack_is_rc()) to decide on reference
counting handling).

Tony