ExtUtils-ParseXS

 view release on metacpan or  search on metacpan

lib/ExtUtils/ParseXS/Constants.pm  view on Meta::CPAN


# These are all the line-based keywords which can appear in an XS file,
# except MODULE and TYPEMAP, which are handled specially by fetch_para()
# and are thus never seen by the parser.
# It also doesn't include non-line-based keywords such as
# IN_OUT, NO_INIT, NO_OUTPUT.
# This list is mainly used by the parser to delineate blocks (such as
# blocks of CODE or lines of INPUT).

our @XSKeywords      = qw( 
  REQUIRE BOOT CASE PREINIT INPUT INIT CODE PPCODE
  OUTPUT CLEANUP ALIAS ATTRS PROTOTYPES PROTOTYPE
  VERSIONCHECK INCLUDE INCLUDE_COMMAND SCOPE INTERFACE
  INTERFACE_MACRO C_ARGS POSTCALL OVERLOAD FALLBACK
  EXPORT_XSUB_SYMBOLS
);

our $XSKeywordsAlternation = join('|', @XSKeywords);


# keywords which can appear anywhere within an XSUB.

lib/ExtUtils/ParseXS/Node.pm  view on Meta::CPAN


The C<parse()> and C<as_code()> methods for some subclasses may have
parameters in addition to those.

Some subclasses may also have additional helper methods.

=head2 Class Hierachy

C<Node> and its sub-classes form the following inheritance hierarchy.
Various abstract classes are used by concrete subclasses where the
processing and/or fields are similar: for example, C<CODE>, C<PPCODE> etc
all consume a block of uninterpreted lines from the source file until the
next keyword, and emit that code, possibly wrapped in C<#line> directives.
This common behaviour is provided by the C<codeblock> class.

    Node
        XS_file
        preamble
        C_part
        C_part_POD
        C_part_code

lib/ExtUtils/ParseXS/Node.pm  view on Meta::CPAN

                INTERFACE
                INTERFACE_MACRO
                OVERLOAD
            ATTRS
            PROTOTYPE
            codeblock
                CODE
                CLEANUP
                INIT
                POSTCALL
                PPCODE
                PREINIT
        keylines
            ALIAS
            INPUT
            OUTPUT
        keyline
            ALIAS_line
            INPUT_line
            OUTPUT_line

lib/ExtUtils/ParseXS/Node.pm  view on Meta::CPAN

# Process an entire XSUB definition

BEGIN { $build_subclass->(
    'decl',       # Node::xsub_decl object holding this XSUB's declaration

    # Boolean flags: they indicate that at least one of each specified
    # keyword has been seen in this XSUB
    'seen_ALIAS',
    'seen_INTERFACE',
    'seen_INTERFACE_MACRO',
    'seen_PPCODE',
    'seen_PROTOTYPE',
    'seen_SCOPE',

    # These three fields indicate how many SVs are returned to the caller,
    # and so influence the emitting of 'EXTEND(n)', 'XSRETURN(n)', and
    # potentially, the value of n in 'ST(n) = ...'.
    #
    # XSRETURN_count_basic is 0 or 1 and indicates whether a basic return
    # value is pushed onto the stack. It is usually directly related to
    # whether the XSUB is declared void, but NO_RETURN and CODE_sets_ST0

lib/ExtUtils/ParseXS/Node.pm  view on Meta::CPAN

        }
        else {
            # cv and items likely to be unused
            print $self->Q(<<"EOF");
                |    PERL_UNUSED_VAR(cv); /* -W */
                |    PERL_UNUSED_VAR(items); /* -W */
EOF
        }
    }

    # gcc -Wall: if an XSUB has PPCODE, it is possible that none of ST,
    # XSRETURN or XSprePUSH macros are used.  Hence 'ax' (setup by
    # dXSARGS) is unused.
    # XXX: could breakup the dXSARGS; into dSP;dMARK;dITEMS
    # but such a move could break third-party extensions
    print $self->Q(<<"EOF") if $self->{seen_PPCODE};
        |    PERL_UNUSED_VAR(ax); /* -Wall */
EOF

    print $self->Q(<<"EOF") if $self->{seen_PPCODE};
        |    SP -= items;
EOF

    # ----------------------------------------------------------------
    # Emit the main body of the XSUB (all the CASE statements + bodies
    # or a single body)
    # ----------------------------------------------------------------

    $_->as_code($pxs, $self) for @{$self->{kids}};

lib/ExtUtils/ParseXS/Node.pm  view on Meta::CPAN

    # CODE section rolled its own return, so this code may be
    # unreachable. So suppress any compiler warnings.
    # XXX Currently this is just for HP. Make more generic??

    # Suppress "statement is unreachable" warning on HPUX
    print "#if defined(__HP_cc) || defined(__HP_aCC)\n",
                "#pragma diag_suppress 2128\n",
                "#endif\n"
        if $^O eq "hpux";

    unless ($self->{seen_PPCODE}) {
        my $nret = $self->{XSRETURN_count_basic}
                 + $self->{XSRETURN_count_extra};

        print $nret ? "    XSRETURN($nret);\n"
                    : "    XSRETURN_EMPTY;\n";
    }

    # Suppress "statement is unreachable" warning on HPUX
    print "#if defined(__HP_cc) || defined(__HP_aCC)\n",
                "#pragma diag_default 2128\n",

lib/ExtUtils/ParseXS/Node.pm  view on Meta::CPAN

        $_->as_code($pxs, $xsub, $self) for @{$self->{kids}};
    }

    # ----------------------------------------------------------------
    # Emit trailers for the body of the XSUB
    # ----------------------------------------------------------------

    if ($xsub->{SCOPE_enabled}) {
        # the matching opens were emitted in input_part->as_code()
        print "      $close_brace\n";
        # PPCODE->as_code emits its own LEAVE and return, so this
        # line would never be reached.
        print "      LEAVE;\n" unless $xsub->{seen_PPCODE};
    }

    # matches the $open_brace at the start of this function
    print "    $close_brace\n";

    print $self->Q(<<"EOF") if $pxs->{config_allow_exceptions};
      |    BEGHANDLERS
      |    CATCHALL
      |    sprintf(errbuf, "%s: %s\\tpropagated", Xname, Xreason);
      |    ENDHANDLERS

lib/ExtUtils/ParseXS/Node.pm  view on Meta::CPAN



sub parse {
    my __PACKAGE__                    $self  = shift;
    my ExtUtils::ParseXS              $pxs   = shift;
    my ExtUtils::ParseXS::Node::xsub  $xsub  = shift;
    my ExtUtils::ParseXS::Node::xbody $xbody = shift;

    $self->SUPER::parse($pxs); # set file/line_no

    # Look for a CODE/PPCODE/NOT_IMPLEMENTED_YET keyword; if found, add
    # the kid to the current node.
    return 1 if $self->parse_keywords(
                        $pxs, $xsub, $xbody,
                        1, # match at most one keyword
                        "CODE|PPCODE",
                        $keywords_flag_NOT_IMPLEMENTED_YET,
                    );

    # Didn't find a CODE keyword or similar, so auto-generate a call
    # to the same-named C library function.

    my $autocall = ExtUtils::ParseXS::Node::autocall->new();
    # mainly a NOOP, but sets line number etc and flags that autocall seen
    $autocall->parse($pxs, $xsub, $xbody)
        or return;

lib/ExtUtils/ParseXS/Node.pm  view on Meta::CPAN

    $cond = " if ($cond)" if length $cond;
    print "   ", ($self->{num} > 1 ? " else" : ""), $cond, "\n";
    $_->as_code($pxs, $xsub) for @{$self->{kids}};
}


# ======================================================================

package ExtUtils::ParseXS::Node::autocall;

# Handle an empty XSUB body (i.e. no CODE or PPCODE)
# by auto-generating a call to a C library function of the same
# name

BEGIN { $build_subclass->(
    'args',  # Str: text to use for auto function call arguments
    'types', # Str: text to use for auto function type declaration
)};


sub parse {

lib/ExtUtils/ParseXS/Node.pm  view on Meta::CPAN

    $pxs->{VERSIONCHECK_value} = $self->{enable};
    1;
}


# ======================================================================

package ExtUtils::ParseXS::Node::multiline;

# Generic base class for keyword Nodes which can contain multiple lines,
# e.g. C code or other data: so anything from ALIAS to PPCODE.
# On entry, $self->lines[0] will be any text (on the same line) which
# follows the keyword.

BEGIN { $build_subclass->(
    'lines', # Array ref of all lines until the next keyword
)};


# Consume all the lines up until the next directive and store in @$lines.

lib/ExtUtils/ParseXS/Node.pm  view on Meta::CPAN

# Store the code lines associated with the POSTCALL: keyword

BEGIN { $build_subclass->(-parent => 'codeblock',
)};

# Currently all methods are just inherited.


# ======================================================================

package ExtUtils::ParseXS::Node::PPCODE;

# Store the code lines associated with the PPCODE keyword

BEGIN { $build_subclass->(-parent => 'codeblock',
)};

sub parse {
    my __PACKAGE__                    $self  = shift;
    my ExtUtils::ParseXS              $pxs   = shift;
    my ExtUtils::ParseXS::Node::xsub  $xsub  = shift;
    my ExtUtils::ParseXS::Node::xbody $xbody = shift;

    $self->SUPER::parse($pxs); # set file/line_no/lines
    $xsub->{seen_PPCODE} = 1;
    $pxs->death("Error: PPCODE must be the last thing") if @{$pxs->{line}};
    1;
}


sub as_code {
    my __PACKAGE__                    $self  = shift;
    my ExtUtils::ParseXS              $pxs   = shift;
    my ExtUtils::ParseXS::Node::xsub  $xsub  = shift;
    my ExtUtils::ParseXS::Node::xbody $xbody = shift;

    # Just emit the code block and then code to do PUTBACK and return.
    # The # user of PPCODE is supposed to have done all the return stack
    # manipulation themselves.
    # Note that PPCODE blocks often include a XSRETURN(1) or
    # similar, so any final code we emit after that is in danger of
    # triggering a "statement is unreachable" warning.

    $self->SUPER::as_code($pxs, $xsub, $xbody); # emit code block

    print "\tLEAVE;\n" if $xsub->{SCOPE_enabled};

    # Suppress "statement is unreachable" warning on HPUX
    print "#if defined(__HP_cc) || defined(__HP_aCC)\n",
          "#pragma diag_suppress 2111\n",

lib/ExtUtils/xsubpp  view on Meta::CPAN

Currently doesn't do anything at all.  This flag has been a no-op for
many versions of perl, at least as far back as perl5.003_07.  It's
allowed here for backwards compatibility.

=item B<-s=...> or B<-strip=...>

I<This option is obscure and discouraged.>

If specified, the given string will be stripped off from the beginning
of the C function name in the generated XS functions (if it starts with that prefix).
This only applies to XSUBs without C<CODE> or C<PPCODE> blocks.
For example, the XS:

  void foo_bar(int i);

when C<xsubpp> is invoked with C<-s foo_> will install a C<foo_bar>
function in Perl, but really call C<bar(i)> in C. Most of the time,
this is the opposite of what you want and failure modes are somewhat
obscure, so please avoid this option where possible.

=back

lib/perlxs.pod  view on Meta::CPAN


 cases             = (
                        "CASE:" ( C_expression | empty )
                        xbody
                     )+

 xbody             = implicit_input     ?
                     xbody_input_part   *
                     xbody_init_part    *
                     xbody_code_part
                     xbody_output_part  * // Not after PPCODE.
                     xbody_cleanup_part * // Not after PPCODE.

 implicit_input    = ( blank_line | input_line )+

 xbody_input_part  =
                       "INPUT:" ( blank_line | input_line )*
                     | "PREINIT:"
                           code_block
                     | xbody_generic_key
                     | c_args
                     | interface_macro

lib/perlxs.pod  view on Meta::CPAN

                           code_block
                     | xbody_generic_key
                     | c_args
                     | interface
                     | interface_macro

 xbody_code_part   =
                       autocall
                     | "CODE:"
                           code_block
                     | "PPCODE:"
                           code_block
                     | // Only recognised if immediately following
                       // an INPUT section:
                       "NOT_IMPLEMENTED_YET:"

                     // Implicit call to wrapped library function.
 autocall          = empty

 xbody_output_part =
                      xbody_postcall *

lib/perlxs.pod  view on Meta::CPAN

3.54-3.61, more things are likely to warn or raise errors during XS
parsing, rather than silently generating a non-compilable C code file.

As mentioned earlier, an XSUB definition typically starts with C</\n\n\S/>
and continues until the next C</\n\n\S/>. The XSUB definition consists of
a declaration, followed by an optional body. The declaration gives the
function's name, parameters and return type, and is intended to mimic a C
function declaration. It is usually two lines long.

The XSUB's body consists of a series of keywords. The main C code of an
XSUB is specified by a C<CODE> or C<PPCODE> section. In the absence of
this, a short body is generated automatically, which consists of a call to
a C function with the same name and arguments as the XSUB. In this way,
the XSUB becomes a short wrapper function between Perl and the C library
function, with the wrapper handling the conversion been Perl and C
arguments. This is referred to in this document as I<autocall>.

Other keywords can be used to modify the code generated for the XSUB, or
to alter how it is registered with the interpreter (e.g. adding
attributes).

lib/perlxs.pod  view on Meta::CPAN

to specify their type).

Note that C<INPUT> sections are generally obsolete these days, and
C<PREINIT> is rarely needed. Perls before 5.36 used C89 compiler
semantics, which didn't allow variable declarations after statements. CPAN
modules, depending on if/how they set compiler flags, may still default
to C89. To work around this, the C<PREINIT> keyword allows you to inject
additional variable declaration code early in the function.

Following on from the input part, the main body of the function is output;
this is copied exactly as-is from the C<CODE> or C<PPCODE> section, if
present. If neither is present, the parser will assume that this XSUB is
just wrapping a C library function of the same name as the XSUB, and will
automatically generate some code like the following:

    RETVAL = baz(a, b);

The C<INIT> and C<POSTCALL> keywords may be used to add code just before
and after the main code; typically only useful for autocall.

C<PPCODE> is the same as C<CODE> except that after argument processing,
the stack pointer is reset to the base of the frame, and the coder becomes
responsible for pushing any return values onto the stack. No further
keywords can follow C<PPCODE>.  This is typically used for XSUBs which
need to return a list or have other complex requirements beyond just
returning a single value.

For C<CODE> and autocall, unless the return type is void, the parser will
generate code to return the value of C<RETVAL>. This is automatic in the
case of autocall, but for C<CODE> you have to ask the parser to do so
with C<OUTPUT: RETVAL>. The code generated in either case may look
something like

    {

lib/perlxs.pod  view on Meta::CPAN

using a typemap template), then placed on the stack. In practice, various
optimisations may be used; in particular, the C<PADTMP> target SV which is
attached to the calling C<OP_ENTERSUB> may be used instead of allocating
and freeing an SV for each call, as explained earlier.

XSUB parameters declared as C<OUT> or C<OUTLIST> will cause additional
output code to be generated which respectively: updates the value of one
of the passed arguments; or pushes the value of that parameter onto the
stack (in addition to C<RETVAL>).

Finally, (apart from C<PPCODE>), a macro like this is added to the end of
the C function:

    XSRETURN(1);

This resets the stack pointer to one above the base of the frame (so the
top item on the stack is C<ST(0)>), then does C<return>.

For a C<void> XSUB, C<XSRETURN_EMPTY> is used instead.

=head2 Returning Values from an XSUB

lib/perlxs.pod  view on Meta::CPAN


    SV *
    create_array_ref()
      CODE:
        RETVAL =  newRV_noinc((SV*)newAV());
      OUTPUT:
        RETVAL

If instead you want to return a flattened array (the equivalent of Perl's
C<return @a>) then you would have to push the elements of the array
individually onto the stack in a C<PPCODE> block. See L</Returning a
list> below.

Finally, the C C<SVREF> type in the standard typemap is a way of creating
and returning a I<reference> to a scalar. This is in contrast to the
C<SV*> type, which just returns a scalar.

Note that unlike C<SV> etc, C<SVREF> isn't a standard built-in Perl type:
it exists purely as an entry in a typemap. So In this case you have to
tell the C compiler that C<SVREF> is just another name for C<SV*>:

lib/perlxs.pod  view on Meta::CPAN


See L</"Updating and returning parameter values: the IN_OUT etc keywords">
for the full details,

=head3 Returning a list

If you want to return a list, i.e. an arbitrary number of items on the
stack, you generally have to forgo the convenience of some of the
boilerplate code generated by XS, which is biased towards returning a
single value. Instead you will have to create and push the SVs yourself.
The L<PPCODE|/The PPCODE: Keyword> keyword is specifically intended for
this purpose. Here is a simple example which does the same as the
Perl-level C<return 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 causes the argument stack pointer to be initially
reset to the base of the frame (discarding any passed arguments), and
suppresses any automatic return code generation. The return type of the
XSUB is ignored, except that declaring it C<void> suppresses the
declaration of a C<RETVAL> variable.

The C<EXTEND()> macro makes sure that there are at least that many free
slots on the stack (its first argument should always be C<SP>). The
C<mPUSHi()> macro creates a new SV, mortalises it, sets its value to the
integer C<i>, and pushes it on the stack.

Here's another example, which flattens the array passed as an argument:
the equivalent of this Perl:

    sub flatten { my $aref = $_[0]; @$aref: }

In this example, the SVs being pushed aren't freshly created with a
reference count one too high, so don't need mortalising.

    void
    flatten(AV *av)
      PPCODE:
        {
            int i;
            int max_ix = AvFILL(av);
            SV **svp;
            EXTEND(SP, max_ix + 1);
            for (i = 0; i <= max_ix; i++)  {
                svp = av_fetch(av, i, 0);
                PUSHs(svp ? *svp : &PL_sv_undef);
            }
        }

lib/perlxs.pod  view on Meta::CPAN

something starting on column one which isn't otherwise recognised as an
XSUB keyword or file-scoped directive.

An XSUB definition consists of a declaration (typically two lines),
followed by an optional body. The declaration specifies the XSUB's name,
parameters and return type. The body consists of sections started by
keywords, which may specify how its parameters and any return value
should be processed, and what the main C code body of the XSUB consists
of. Other keywords can change the behaviour of the XSUB, or affect how it
is registered with Perl, e.g. with extra named aliases. In the absence of
an explicit main C code body specified by the C<CODE> or C<PPCODE>
keywords, the parser will generate a body automatically; this is referred
to as L<autocall|/"Auto-calling a C function"> in this document.

Nothing can appear between keyword sections apart from POD, XS comments,
and trailing blank lines, all of which are stripped out before the main
parsing takes place. Anything else will either raise an error, or be
interpreted as the start of a new XSUB.

An XSUB's body can be thought of as having up to five parts. These are, in
order of appearance, the L<Input|/"The XSUB Input Part">, L<Init|/"The

lib/perlxs.pod  view on Meta::CPAN


    # Complex parameters; plus variable argument count:

    int
    foo3(OUT int i, IN_OUTLIST char *s, STRLEN length(s), ...)

    # No automatic argument processing:

    void
    foo4(...)
        PPCODE:

    # C++ method; plus various return type qualifiers:

    NO_OUTPUT extern "C" static int
    X::Y::foo5(int i, char *s) const


An XSUB declaration consists of a return type, name, parameters, and
optional C<NO_OUTPUT>, C<extern "C">, C<static> and C<const> keywords.

lib/perlxs.pod  view on Meta::CPAN

            }
        }
      OUTPUT:
        RETVAL

It is possible to write an XSUB which both accepts and returns a list. For
example, this XSUB does the equivalent of the Perl C<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));
            }
        }

Note that the L<PPCODE|/The PPCODE: Keyword> keyword, in comparison to
C<CODE>, resets the local copy of the argument stack pointer, and relies
on the coder to place any return values on the stack. The example above
reclaims the passed arguments by setting C<SP> back to the top of the
stack, then replaces the items on the stack one by one.

=head2 The XSUB Input Part

Following an XSUB's declaration part, the body of the XSUB follows. The
first part of the body is the I<input> part, and is mainly concerned with
declaring auto variables and assigning to them values extracted from the

lib/perlxs.pod  view on Meta::CPAN

      OUTPUT:
        RETVAL

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

=head2 The XSUB Code Part

Following an XSUB's optional init part, an optional code part follows. This
consists mainly of the C<CODE> or C<PPCODE> keywords, which provide the
code block for the main body of the XSUB. These two keywords are similar,
except that C<PPCODE> can be thought of as acting at a lower level; it
resets the stack pointer to the base of the stack frame and then relies on
the programmer to push any return values; whereas C<CODE> will (with
prompting) automatically generate code to return the value of C<RETVAL>.

There is also a rarely-used C<NOT_IMPLEMENTED_YET> keyword which generates
a body which croaks.

Only one of these keywords may appear in this part, and at most once; and
no other keywords are recognised in this part (although such keywords
could instead be processed in the tail or head of the preceding and
following init and output parts).

In the absence of any of those three keywords, the XS compiler will
generate an autocall: a call to the C function of the same name as the
XSUB.

=head3 Auto-calling a C function

In the absence of any explicit main body code via C<CODE>, C<PPCODE> or
C<NOT_IMPLEMENTED_YET>, the XS parser will generate a body for you
automatically (this is referred to as C<autocall> in this document). In
its most basic form, the parser assumes that the XSUB will be a simple
wrapper for a C function of the same name, with the same parameters and
return type as the XSUB. So for example, these two XSUB definitions are
equivalent, but the first is an autocall with less boilerplate needed:

    int
    foo(char *s, short flags)

lib/perlxs.pod  view on Meta::CPAN

    void foo2(int a, int b)
      C_ARGS: a < 0 ? 0 : a,
              b,
              0

Normally the arguments for an autocall are generated automatically, based
on the XSUB's parameter declarations. The C<C_ARGS> keyword allows you to
override this and manually specify the text that will be placed between
the parentheses in the autocall. This is useful when the ordering and
nature of parameters varies between Perl and C, without a need to write a
C<CODE> or C<PPCODE> section.

The C<C_ARGS> section consists of all lines of text until the next keyword
or to the end of the XSUB, and is used without modification (except that
any POD or XS comments will be stripped).

=head3 The CODE: Keyword

    int
    abs_double(int i)
      CODE:

lib/perlxs.pod  view on Meta::CPAN

Similarly to autocall XSUBs, a C<RETVAL> variable is declared if the
return value of the XSUB is not C<void>. Unlike autocall, you have to
explicitly tell the XS compiler to generate code to return the value of
C<RETVAL>, by using the The L<OUTPUT|/"The OUTPUT: Keyword"> keyword.
(Requiring this was probably a bad design decision, but we're stuck with
it now.) Newer XS parsers will warn if C<RETVAL> is seen in the C<CODE>
section without a corresponding C<OUTPUT> section.

A C<CODE> XSUB will typically return just the C<RETVAL> value (or possibly
more items with the C<OUTLIST> parameter modifiers). To take complete
control over returning values, you can use the C<PPCODE> keyword instead.
Note that it is possible for a C<CODE> section to do this too, by doing its
own stack manipulation and then doing an C<XSRETURN(n)> to return directly
while indicating that there are C<n> items on the stack. This bypasses the
normal C<XSRETURN(1)> etc that the XS parser will have planted after the
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

lib/perlxs.pod  view on Meta::CPAN

    mPUSHp(str, len)   create+push mortal and set to the string+length
    mPUSHpvs("string") create+push mortal and set to the literal string
                         (perl 5.38.0 onwards)

=head3 The NOT_IMPLEMENTED_YET: Keyword

    void
    foo(int a)
        NOT_IMPLEMENTED_YET:

This keyword, as a fourth alternative to C<CODE>, C<PPCODE> and autocall,
generates a main body for the XSUB consisting solely of the C code:

    Perl_croak(aTHX_ "Foo::Bar::foo: not implemented yet");

The current implementation is quite buggy in terms of parsing and where
the keyword can appear within an XSUB, so it's generally better to avoid
it. It is documented here for completeness.

=head2 The XSUB Output Part

lib/perlxs.pod  view on Meta::CPAN

    my $i7  = 7;
    my $i13 = 13;

=head3 The ATTRS: Keyword

    MODULE = Foo::Bar PACKAGE = Foo::Bar

    SV*
    debug()
      ATTRS: lvalue
      PPCODE:
        # return $Foo::Bar::DEBUG, creating it if not already present
        # (NB: XPUSHs() not needed here as the stack always has one
        # allocated slot available when an XSUB is called):
        PUSHs(GvSV(gv_fetchpvs("Foo::Bar::DEBUG", GV_ADD, SVt_IV)));

The C<ATTRS> keyword allows you to apply subroutine attributes to an XSUB
in a similar fashion to Perl subroutines. The XSUB in the example above is
equivalent to this Perl:

    sub debug :lvalue { return $Foo::Bar::DEBUG }

lib/perlxstut.pod  view on Meta::CPAN

		const char *    c
	    CODE:
		RETVAL = foo(a,b,c);
	    OUTPUT:
		RETVAL

However, these two XSUBs provide almost identical generated C code: B<xsubpp>
compiler is smart enough to figure out the C<CODE:> section from the first
two lines of the description of XSUB.  What about C<OUTPUT:> section?  In
fact, that is absolutely the same!  The C<OUTPUT:> section can be removed
as well, I<as far as C<CODE:> section or C<PPCODE:> section> is not
specified: B<xsubpp> can see that it needs to generate a function call
section, and will autogenerate the OUTPUT section too.  Thus one can
shortcut the XSUB to become:

	double
	foo(a,b,c)
		int             a
		long            b
		const char *    c

lib/perlxstut.pod  view on Meta::CPAN

Return to the Mytest directory and add the following code to the end of
Mytest.xs:

	void
	statfs(path)
		char *  path
	    INIT:
		int i;
		struct statfs buf;

	    PPCODE:
		i = statfs(path, &buf);
		if (i == 0) {
			XPUSHs(sv_2mortal(newSVnv(buf.f_bavail)));
			XPUSHs(sv_2mortal(newSVnv(buf.f_bfree)));
			XPUSHs(sv_2mortal(newSVnv(buf.f_blocks)));
			XPUSHs(sv_2mortal(newSVnv(buf.f_bsize)));
			XPUSHs(sv_2mortal(newSVnv(buf.f_ffree)));
			XPUSHs(sv_2mortal(newSVnv(buf.f_files)));
			XPUSHs(sv_2mortal(newSVnv(buf.f_type)));
		} else {

lib/perlxstut.pod  view on Meta::CPAN

This example added quite a few new concepts.  We'll take them one at a time.

=over 4

=item *

The INIT: directive contains code that will be placed immediately after
the argument stack is decoded.  C does not allow variable declarations at
arbitrary locations inside a function,
so this is usually the best way to declare local variables needed by the XSUB.
(Alternatively, one could put the whole C<PPCODE:> section into braces, and
put these declarations on top.)

=item *

This routine also returns a different number of arguments depending on the
success or failure of the call to statfs.  If there is an error, the error
number is returned as a single-element array.  If the call is successful,
then a 7-element array is returned.  Since only one argument is passed into
this function, we need room on the stack to hold the 7 values which may be
returned.

We do this by using the PPCODE: directive, rather than the CODE: directive.
This tells B<xsubpp> that we will be managing the return values that will be
put on the argument stack by ourselves.

=item *

When we want to place values to be returned to the caller onto the stack,
we use the series of macros that begin with "XPUSH".  There are five
different versions, for placing integers, unsigned integers, doubles,
strings, and Perl scalars on the stack.  In our example, we placed a
Perl scalar onto the stack.  (In fact this is the only macro which

lib/perlxstut.pod  view on Meta::CPAN


There are a number of new concepts introduced here, described below:

=over 4

=item *

This function does not use a typemap.  Instead, we declare it as accepting
one SV* (scalar) parameter, and returning an SV* value, and we take care of
populating these scalars within the code.  Because we are only returning
one value, we don't need a C<PPCODE:> directive - instead, we use C<CODE:>
and C<OUTPUT:> directives.

=item *

When dealing with references, it is important to handle them with caution.
The C<INIT:> block first calls SvGETMAGIC(paths), in case
paths is a tied variable.  Then it checks that C<SvROK> returns
true, which indicates that paths is a valid reference.  (Simply
checking C<SvROK> won't trigger FETCH on a tied variable.)  It
then verifies that the object referenced by paths is an array, using C<SvRV>

t/008-parse-xsub-keywords.t  view on Meta::CPAN

            [  0, qr{^\s+\Qfoo(aaa);}m,             "has code body"     ],
            [  0, qr{\Qfoo(aaa);\E\n\#line 8 },     "correct #line"     ],
         ],
    );

    test_many($preamble, 'XS_Foo_', \@test_fns);
}


{
    # Test PPCODE keyword

    my $preamble = Q(<<'EOF');
        |MODULE = Foo PACKAGE = Foo
        |
        |PROTOTYPES:  DISABLE
        |
EOF

    my @test_fns = (
        [
            "PPCODE basic",
            Q(<<'EOF'),
                |void
                |foo(int aaa)
                |  PPCODE:
                |     YYY
EOF
            [  0, qr{\bint\s+aaa},           "has aaa decl"   ],
            [  0, qr{YYY},                   "has code body"  ],
            [  0, qr{aaa.*YYY}s,             "in sequence"    ],
            [  0, qr{\#line 8 .*\n\s+YYY},   "correct #line"  ],
        ],
        [
            "PPCODE empty",
            Q(<<'EOF'),
                |void
                |foo(int aaa)
                |  PPCODE:
EOF
            [  0, qr{\bint\s+aaa},               "has aaa decl"   ],
            [  0, qr{aaa.*\n\s*;\s*\n\#line 8 }, "correct #line"  ],
        ],
        [
            "PPCODE trailing keyword",
            Q(<<'EOF'),
                |void
                |foo(int aaa)
                |  PPCODE:
                |     YYY
                |  OUTPUT:
                |     blah
EOF
            [ERR, qr{Error: PPCODE must be the last thing}, "got expected err"  ],
        ],
        [
            "PPCODE code tweaks",
            Q(<<'EOF'),
                |void
                |foo(int aaa)
                |  PPCODE:
                |     YYY
EOF
            [  0, qr{\QPERL_UNUSED_VAR(ax);},   "got PERL_UNUSED_VAR"    ],
            [  0, qr{\QSP -= items;},           "got SP -= items"        ],
            [NOT, qr{\QXSRETURN},               "no XSRETURN"            ],
            [  0, qr{\bPUTBACK\b.*\breturn\b}s, "got PUTBACK and return" ],
        ],

    );

t/008-parse-xsub-keywords.t  view on Meta::CPAN

        |
EOF

    my @test_fns;

    for my $kw (qw(
                    CLEANUP
                    CODE
                    INIT
                    POSTCALL
                    PPCODE
                    PREINIT
                ))
    {
        push @test_fns,
            [
                "Warn if junk after $kw'",
                Q(<<"EOF"),
                    |int foo()
                    |$kw: blah
                    |  codeline

t/XSTest.xs  view on Meta::CPAN

void
xstest_something2 (some_thing)
	char * some_thing

void
xstest_something3 (myclass, some_thing)
	SV   * myclass
	char * some_thing
    PREINIT:
    	int i = 0;
    PPCODE:
    	/* it's up to us clear these warnings */
	myclass = myclass;
	some_thing = some_thing;
	i = i;
	XSRETURN_UNDEF;
	
int
consts (myclass)
	SV * myclass
    ALIAS:



( run in 1.103 second using v1.01-cache-2.11-cpan-5511b514fd6 )