ExtUtils-ParseXS

 view release on metacpan or  search on metacpan

lib/perlxs.pod  view on Meta::CPAN

C<CODE> lines. But it is usually cleaner to use C<PPCODE> instead.

Any lines following C<CODE> until the next keyword (except POD and XS
comments) are copied out as-is to the C code file. Multiple C<CODE>
keywords are not allowed.

=head3 The PPCODE: Keyword

    # XS equivalent of: sub one_to_n { my $n = $_[0]; 1..$n }

    void
    one_to_n(int n)
      PPCODE:
        {
            int i;
            if (n < 1)
                Perl_croak_nocontext(
                    "one_to_n(): argument %d must be >= 1", n);
            EXTEND(SP, n);
            for (i = 1; i <= n; i++)
                mPUSHi(i);
        }

The C<PPCODE> keyword is similar to the C<CODE> keyword, except that on
entry it resets the stack pointer to the base of the current stack frame,
and it doesn't generate any code to return C<RETVAL> or similar: pushing
return values onto the stack is left to the programmer. In this way it can
be viewed as a lower-level alternative to C<CODE>, when you want to take
full control of manipulating the argument stack. The "PP" in its name
stands for "PUSH/PULL", reflecting the low-level stack manipulation.
C<PPCODE> is typically used when you want to return several values or even
an arbitrary list, compared with C<CODE>, which normally returns just the
value of C<RETVAL>.

The C<PPCODE> keyword must be the last keyword in the XSUB. Any lines
following C<PPCODE> until the end of the XSUB (except POD and XS comments)
are copied out as-is to the C code file. Multiple C<PPCODE> keywords are
not allowed.

Typically you declare a C<PPCODE> XSUB with a return type of C<void>; any
other return type will cause a C<RETVAL> auto variable of that type to be
declared, which will be otherwise unused.

On entry to the C<PPCODE> block of code, the values of any declared
parameters arguments will have already been assigned to auto variables,
but the original SVs will still be on the stack and initially accessible
via C<ST(i)> if necessary. But the default assumption for a C<PPCODE>
block is that you have already finished processing any supplied arguments,
and that you want to push a number of return values onto the stack. The
simple C<one_to_n()> example shown above is based on that assumption. But
more complex strategies are possible.

There are basically two ways to access and manipulate the stack in a
C<PPCODE> block. First, by using the C<ST(i)> macro, to get, modify, or
replace the I<i>th item in the current stack frame, and secondly to push
(usually temporary) return values onto the stack. The first uses the
hidden C<ax> variable, which is set on entry to the XSUB, and is the index
of the base of the current stack frame. This remains unchanged throughout
execution of the XSUB. The second approach uses the local stack pointer,
C<SP> (more on that below), which on entry to the C<PPCODE> block points
to the base of the stack frame. Macros like C<mPUSHi()> store a temporary
SV at that location, then increment C<SP>. On return from a C<PPCODE>
XSUB, the current value of C<SP> is used to indicate to the caller how
many values are being returned.

In general these two ways of accessing the stack should not be mixed, or
confusion is likely to arise. The PUSH strategy is most useful when you
have no further use for the passed arguments, and just want to generate
and return a list of values, as in the C<one_to_n()> example above. The
C<ST(i)> strategy is better when you still need to access the passed
arguments. In the example below,

    # XS equivalent of: sub triple { map { $_ * 3} @_ }

    void
    triple(...)
      PPCODE:
        SP += items;
        {
            int i;
            for (i = 0; i < items; i++) {
                int val  = (int)SvIV(ST(i));
                ST(i) = sv_2mortal(newSViv(val*3));
            }
        }

C<SP> is first incremented to reclaim the passed arguments which are still
on the stack; then one by one, each passed argument is retrieved, and then
each stack slot is replaced with a new mortal value. When the loop is
finished, the current stack frame contains a list of mortals, which is
then returned to the caller, with C<SP> indicating how many items are
returned. Note that in this example the C<SP += items> could have been
done at the end instead. However, if the code was doing a mixture of
updating the passed arguments I<and> pushing extra return values, then
setting it early (before the first push) would be important.

Before pushing return values onto the stack (or storing values at C<ST(i)>
locations higher than the number of passed arguments), it is necessary to
ensure there is sufficient space on the stack. This can be achieved either
through the C<EXTEND(SP, n)> macro as shown in the C<one_to_n()> example
above, or by using the 'X' variants of the push macros, such as
C<mXPUSHi()>, which can be used to check and extend the stack by one each
time. Doing a single C<EXTEND> in advance is more efficient. C<EXTEND>
will ensure that there is at least enough space on the stack for n further
items to be pushed.

If using the PUSH strategy, it is useful to understand in more detail how
pushing and the local stack pointer, C<SP> are implemented. The generated
C file will have access to (among others) the following macro definitions
or similar:

    #define dSP       SV **sp = PL_stack_sp
    #define SP        sp
    #define PUSHs(s)  *++sp = (s)
    #define mPUSHi(i) sv_setiv(PUSHs(sv_newmortal()), (IV)(i))
    #define PUTBACK   PL_stack_sp = sp
    #define SPAGAIN   sp = PL_stack_sp
    #define dXSARGS   dSP; ....

The global (or per-interpreter) variable C<PL_stack_sp> is a pointer to
the current top-most entry on the stack, equal initially to



( run in 0.897 second using v1.01-cache-2.11-cpan-bbe5e583499 )