develooper Front page | perl.perl5.porters | Postings from November 2022

bikeshedding refcounted stack inline functions

Thread Next
Dave Mitchell
November 24, 2022 17:08
bikeshedding refcounted stack inline functions
Message ID:
I'm about to ask a bikeshedding question. I regret this already....

As many of you will be aware, I'm currently working on making perl's
argument stack contribute to the reference count of the SVs it points to
(a.k.a. "make the stack ref-counted").

Part of this involves introducing a new set of inline functions to replace
all the old stack manipulation macros like EXTEND(), TOPs. POPi() etc.

So I thought I'd run my provisional design choices past you all. Note that
I'm going with what I've already chosen (names and action) unless a good
reason is pointed out for doing otherwise.

Currently these functions will only be used in the core, mainly in pp
functions. I don't yet know what new API (if any) will be provided to XS
authors, and whether it needs to differ from the core ones discussed here.
I want to avoid an XS discussion for now if possible.

Here are a few examples:


They all have a common prefix, rpp_. This stands for 'Reference-counted
stack Push/Pull'. I'm open to other suggestions, but I want something
short. It doesn't have to be particularly meaningful - these will be
littered all over the pp*.c files and any coder will very soon learn what
they are (in the same way that we know what PUSHs, POPi etc are currently).

The second part of the name is what the function does, while the third
part describes a particular variant. The 3 parts being separated by '_'
for easy reading.

rpp_push_1(sv) pushes one sv onto the stack and updates its reference count.

rpp_popfree_2() pops two items off the stack and frees them (i.e.
decrements their reference count). There's also an rpp_popfree_1() and a
more general rpp_popfree_to(svp).

rpp_replace_21(sv) pops two args and pushes 1, so its a more efficient
combo of { rpp_popfree_2(); rpp_push_1(sv); } while ensuring that nothing
leaks or is prematurely freed if something croaks.

In general, pp functions used to pop args off the stack, then process
them, then push the result. To avoid leaking if the code dies during
processing, the new paradigm is to leave the values on the stack while
processing their values, and only update the stack at the end. There is no
dSP macro - we access PL_stack_sp directly, so no need to mess with

So for example, (but hugely oversimplified), pp_concat() used to look

        SV *right = POPs;
        SV *left  = POPs;

        sv_setsv(TARG, left);
        sv_catsv(TARG, right);
        return NORMAL;

and in future would look like

        SV *right = PL_stack_sp[0];
        SV *left  = PL_stack_sp[-1];

        sv_setsv(TARG, left);
        sv_catsv(TARG, right);
        return NORMAL;

I don't see any point in providing macros or static functions to directly
access SVs on the stack (like TOPs, TOPm1s etc). These always struck me as
just a further level of obfuscation rather than useful abstraction.

I'm also not adding the equivalent of TOPi etc. I expect that to be
written directly as SvIV(*PL_stack_sp).

"But Sidley Park is already a picture, and a most amiable picture too.
The slopes are green and gentle. The trees are companionably grouped at
intervals that show them to advantage. The rill is a serpentine ribbon
unwound from the lake peaceably contained by meadows on which the right
amount of sheep are tastefully arranged." -- Lady Croom, "Arcadia"

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About