Branch: refs/heads/davem/xs_refactor9
  Home:   https://github.com/Perl/perl5
  Commit: 95f7971b6c1f97efb22eb8c203f60a24871d3da9
      
https://github.com/Perl/perl5/commit/95f7971b6c1f97efb22eb8c203f60a24871d3da9
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS/Constants.pm
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS/CountLines.pm
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS/Eval.pm
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS/Node.pm
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS/Utilities.pm
    M dist/ExtUtils-ParseXS/lib/ExtUtils/Typemaps.pm
    M dist/ExtUtils-ParseXS/lib/ExtUtils/Typemaps/Cmd.pm
    M dist/ExtUtils-ParseXS/lib/ExtUtils/Typemaps/InputMap.pm
    M dist/ExtUtils-ParseXS/lib/ExtUtils/Typemaps/OutputMap.pm
    M dist/ExtUtils-ParseXS/lib/ExtUtils/Typemaps/Type.pm
    M dist/ExtUtils-ParseXS/lib/perlxs.pod

  Log Message:
  -----------
  ParseXS: bump version 3.56 => 3.57


  Commit: 644e4630ff2ab010ac1149d2b1d0e26aea03fbf7
      
https://github.com/Perl/perl5/commit/644e4630ff2ab010ac1149d2b1d0e26aea03fbf7
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: add tests for special array(type,n) type

There is currently only a single test for the special-cased return
type "array(type,nitems)" - which returns a packed string containing
nitems of type, on the assumption that RETVAL has been assigned a
pointer to an array of type[nitems].

So this commit adds more comprehensive tests.


  Commit: 97b0d4a170bc45bb8f7f46dac6ccb95b9aacd39e
      
https://github.com/Perl/perl5/commit/97b0d4a170bc45bb8f7f46dac6ccb95b9aacd39e
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: add tests for T_ARRAY/DO_ARRAY_ELEM

The T_ARRAY typemap input and output code relies on a special token,
DO_ARRAY_ELEM, which is converted by ParseXS into code to get/set
each element of an array.

This commit adds several tests for this under-tested misfeature.

A few of the tests are marked with 'XXX' comments where I explain that
they test the *current* behaviour, not necessarily the correct or best
behaviour.


  Commit: d26e16c026740a9938d70f6426ce662394337a85
      
https://github.com/Perl/perl5/commit/d26e16c026740a9938d70f6426ce662394337a85
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS/Node.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: fix DO_ARRAY_ELEM boundaries

Both INPUT and OUTPUT typemap template processing expand the text
token 'DO_ARRAY_ELEM'.

In particular, input processing has code like:

    if ($expr =~ /DO_ARRAY_ELEM/) {
        ...
        $expr =~ s/DO_ARRAY_ELEM/$subexpr/;
    }

and output processing has code like:

    if ($expr =~ /DO_ARRAY_ELEM/) {
        ...
        $expr =~ s/DO_ARRAY_ELEM\n/$subexpr/;
    }

Note that there is a \n in the pattern only in the second substitution.

This commit does two things. First it removes the extraneous \n, which
one assumes was a mistake; and secondly it wraps all four patterns with
\b so the token only matches as a whole word. This is very unlikely to
make any difference in the real world, as DO_ARRAY_ELEM is an
undocumented hack used only in the T_ARRAY typemap entry supplied with
perl, and not anywhere on CPAN AFAICT.

In a slight quirk, perl's INPUT and OUTPUT lines for T_ARRAY which
contain DO_ARRAY_ELEM are, respectively:

        DO_ARRAY_ELEM;

        DO_ARRAY_ELEM

The latter of which would now match (but wouldn't before) even if it had
a trailing ';'.

This commit also does a minor fixup to a test I added in the previous
commit, which had to temporarily not have any characters after the
DO_ARRAY_ELEM in the typemap due to the \n.


  Commit: 5f64df7e4f328fba10fc375169ab8724a7faf543
      
https://github.com/Perl/perl5/commit/5f64df7e4f328fba10fc375169ab8724a7faf543
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: forbid DO_ARRAY_ELEM on OUT,OUTLIST param

DO_ARRAY_ELEM is a text token which can appear in typemap INPUT and
OUTPUT code templates. It expands into code which sets the value of one
SV. It is intended for use within the T_ARRAY typemap, which for OUTPUT
includes DO_ARRAY_ELEM within a loop which stores new mortal SVs at
stack locations ST(0)..ST(n-1) and sets each SV to the value of each
element of RETVAL.

This makes no sense when applied to an OUT or OUTLIST parameter (as
opposed to RETVAL). The code gets emitted, but just interferes with the
code to return RETVAL. For example, in something like

    int
    foo(OUTLIST intARRAY* x)

code will be emitted to store temp SVs at ST(0), ST(1), ... containing
the values of x[0], x[1], ...; then code will also be emitted to store
the value of RETVAL at ST(0).

For OUT params it makes even less sense: an OUT param should update one
of the SVs passed as an argument, and shouldn't be pushing *anything*
onto the stack.

This commit makes it a compile error for the token 'DO_ARRAY_ELEM' to
appear in an OUTPUT typemap for a use other than returning RETVAL.


  Commit: 629201c928c35b10f05646d7efd435c56fa4b6da
      
https://github.com/Perl/perl5/commit/629201c928c35b10f05646d7efd435c56fa4b6da
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: forbid array(t,n) on OUT,OUTLIST param

The special type 'array(some_type.nitems) is intended for use only
as the return type of an XSUB. Make using it to return other variables
an error.

Previously it was allowed, but generated broken C code.


  Commit: 90d168d40fe3a1660554a07d9e328b439e3cab81
      
https://github.com/Perl/perl5/commit/90d168d40fe3a1660554a07d9e328b439e3cab81
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm

  Log Message:
  -----------
  ParseXS: handle undefined arg number in output

Add an "internal error" croak if generate_output() tries to update the
value of a passed argument whose arg num is undefined. This should
never happen. Previously there was an oblique check for this, with
the function silently returning if detected. This commit makes it more
obvious what's (not) going on.

There are no tests added because - ahem - this should ever happen.


  Commit: 9d512f536b84ebdd202708a24f7888b92c388e67
      
https://github.com/Perl/perl5/commit/9d512f536b84ebdd202708a24f7888b92c388e67
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm

  Log Message:
  -----------
  ParseXS: refactor: make DO_ARRAY_ELEM separate

The last statement in generate_output() is a big four-limb if/else to
handle the main types of variable value return. This commit splits the
first branch, if ($expr =~ /\bDO_ARRAY_ELEM\b/), into a separate if(),
with an added 'return' but no else; leaving the main if/else as only
three limb.

This is a step towards making the DO_ARRAY_ELEM processing just part of
typemap processing.

Should be no change in functionality.


  Commit: 28de88de06df7eb5021146c4c5e7fc7dfc47113d
      
https://github.com/Perl/perl5/commit/28de88de06df7eb5021146c4c5e7fc7dfc47113d
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: ignore DO_ARRAY_ELEM on custom OUTPUT

When there's custom return code specified on an OUTPUT line,
use that rather than the code from the typemap OUTPUT entry: even if
that template code includes the DO_ARRAY_ELEM special token.


  Commit: 4abaa5e3d072483c4e3354cc10184ced2c181174
      
https://github.com/Perl/perl5/commit/4abaa5e3d072483c4e3354cc10184ced2c181174
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm

  Log Message:
  -----------
  ParseXS: refactor: calc ST(n) once in output

In generate_output(), rather than setting $arg to "ST(n)" and later
amending it for OUTLIST parameters, just set it to the right value
initially. Should make no functional change, but just simplifies things
slightly.


  Commit: e010d1cba95ec842d5a584da581e5ab487a93561
      
https://github.com/Perl/perl5/commit/e010d1cba95ec842d5a584da581e5ab487a93561
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: honour OUTPUT override in array(type,n)

This restores the original behaviour broken during recent refactoring,
and adds tests.

In something like

    array(int,5)
    foo()
        OUTPUT:
            RETVAL my_setintptr(ST(0), RETVAL);

the special processing of the array(...) return type should be ignored
and instead the override code specified on the OUTPUT line should be
used.

This commit includes some duplicate cut and pasted perl code to return
the override; this will be refactored away shortly.


  Commit: 350bc8fa56fedee3c4c58fb12ee512e2bc6a876f
      
https://github.com/Perl/perl5/commit/350bc8fa56fedee3c4c58fb12ee512e2bc6a876f
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: add test for OUTPUT with code + bad type

Currently when an OUTPUT line includes a code override, the type
is still looked in the typemap (even though the result won't be used).
If the type of RETVAL is unknown, this causes an error.

This commit adds a test for this error, mainly so that the next commit,
which fixes this issue, can be seen to fix the test.


  Commit: a3b256e5a0b47d055e328248442842c685d92a1c
      
https://github.com/Perl/perl5/commit/a3b256e5a0b47d055e328248442842c685d92a1c
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: skip typemap lookup on OUTPUT override

Reorganise the typemap lookup code so that it's only called when
there isn't a return typemap override. For example:

    blah
    foo()
        OUTPUT:
            RETVAL  some_override_code(...)

Formerly it looked up 'blah' to get an OUTPUT typemap even though it's
value wouldn't be used and the text 'some_override_code(...)' would be
used instead. This would cause an error if 'blah' couldn't be found in
the typemap.

The diff looks quite complex mainly because the ordering of some lexical
variables has been changed: all the $type-derived vars are now grouped
together, and the 'my' declarations of some vars have been moved earlier
so they aren't wrapped in the new else block that's been put around the
typemap-lookup code.

The structure now looks like:

    my $type = ...;
    my $ntype = derived from $type;
    etc

    my $expr;
    if (defined $output_code) {
        $expr = $output_code;
    }
    elsif ($type =~ /^array\(([^,]*),(.*)\)/) {
        $expr = "sv_setpvn($arg, (char *)$var, $nitems * sizeof($atype));";
    }
    else {
      $expr = ... lookup typemap ...
    }


  Commit: 07c1fc206156184a1294588dc95f72d6a8c26e64
      
https://github.com/Perl/perl5/commit/07c1fc206156184a1294588dc95f72d6a8c26e64
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm

  Log Message:
  -----------
  ParseXS: reindent block

The previous commit wrapped some code lines in an 'else' block. Reindent
to match. Whitespace-only.


  Commit: 912d5f810978a73082464a901c390357cc3a651b
      
https://github.com/Perl/perl5/commit/912d5f810978a73082464a901c390357cc3a651b
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: make array(type,n) handling more regular

The array pseudo-type used for return values, e.g.

    array(int,5)
    foo(...)
        ...

Is currently completely special-cased. This commit makes so it so that
instead, it just pretends that a typemap lookup was done, and that the
output template returned was (for example):

    sv_setpvn($arg, (char *)$var, 5 * sizeof(int));

Then rather than emitting code like that directly, it now continues to
the general RETVAL-processing section. This means that any current or
future optimisations will be applied to it.

The test added by this commit shows that the generated code now uses the
minor RETVALSV optimisation. (It still doesn't use TARG yet).


  Commit: ab5a4a518e2d33e0a2302a0e0ce60fffc9a9728d
      
https://github.com/Perl/perl5/commit/ab5a4a518e2d33e0a2302a0e0ce60fffc9a9728d
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm

  Log Message:
  -----------
  ParseXS: refactor: generate_output: set $arg later

Move the $arg declaration and setting closer to its first use.
The previous commit removed an earlier need for it.

No functional changes.


  Commit: 11b3aef7cdec2880ef8bba7c40ce5e22da7b0592
      
https://github.com/Perl/perl5/commit/11b3aef7cdec2880ef8bba7c40ce5e22da7b0592
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: minor fixes for OUTPUT override code

Some of the refactoring earlier in this branch broke some edge cases.
This commit fixes those cases and adds tests.

In particular:

1) Optional typemap override code on OUTPUT lines is *not* eval-expanded
(unlike those on INPUT lines). So add a test for this, and don't bother
setting $expr in that case, since $expr is a meant to be a pre-eval
value. (This wasn't broken, but it wasn't tested, and setting $expr
didn't make any sense, and might cause new bugs further down the line).

2) In something like

    int
    foo(IN_OUTLIST int abc)
        OUTPUT:
            abc    my_set(ST[0], RETVAL);

generate_output() is called *twice* for abc, once to update the first
arg with the current value of abc, and once to push a new mortal onto
the stack holding the current value of abc. The typemap override,
my_set(...), should only be used for the updating, not the pushing.


  Commit: 2ce8484a8e5cd499d2014a89beb71d08365b2210
      
https://github.com/Perl/perl5/commit/2ce8484a8e5cd499d2014a89beb71d08365b2210
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm

  Log Message:
  -----------
  ParseXS: refactor: add xsub_stack_was_reset field

Add a boolean field,  xsub_stack_was_reset, to the ParseXS class.
This field indicates that "XSprePUSH" has been emitted.

In more detail: XS has two main ways of adding return SVs to the stack.
For simple single-value-return XSUBs, SP is kept pointing at the top of
the current stack frame (i.e. pointing at the highest passed arg), then
the return value SV is stored at the base of stack frame (ST(0) = ...),
and then just before returning, the stack pointer is reset to base+1
(XSRETURN(1)).

However in the presence of OUTLIST params, or where where RETVAL can be
returned via the TARG optimisation, SP is instead reset to point to the
base of the stack frame via "XSprePUSH", then RETVAL and any OUTLIST
params are PUSH()ed onto the stack.

ParseXS used to keep track of this by checking in various places whether
there were any OUTLIST params. Instead this commit sets a boolean flag
if XSprePUSH has been emitted, then checks that flag for any further
code-emitting decisions.

Currently there is no difference between the two approaches (flag or
check OUTLIST count), but this commit will allow in future for things
to potentially become more fluid without breaking.


  Commit: 592203f828b6007c2d6d1a1b2f27699f734f5d7e
      
https://github.com/Perl/perl5/commit/592203f828b6007c2d6d1a1b2f27699f734f5d7e
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm

  Log Message:
  -----------
  ParseXS: refactor: add xsub_targ_declared/usable

Add two new boolean fields to the ParseXS class:

    xsub_targ_declared  indicates that a dXSTARG was emitted;
    xsub_targ_usable    indicates that the TARG hasn't been used yet.

Currently ParseXS emits a dXSTARG early on if the typemap for RETVAL
indicates that it is TARG-optimisable. Later, when emitting code to
return RETVAL, the same check is made, and if so, a PUSHi() or whatever
is used to return an int/whatever more cheaply using TARG.

These two flags abstract out that a bit. It makes no difference yet,
but in future it would allow:

- a dXSTARG to be emitted later even if we couldn't have known
  earlier that we could use it. (We can't just always move the declaration
  to later, since various XS modules assume that TARG is available.)

- if/where there are more cases where using TARG might be useful, then
  we avoid any risk of accidentally using the same targ to return two
  different values.


  Commit: 381a207e3259b93f72136f3ed9294735a7da3432
      
https://github.com/Perl/perl5/commit/381a207e3259b93f72136f3ed9294735a7da3432
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm

  Log Message:
  -----------
  ParseXS: fix bool return code: RETVAL with magic

When generate_output() is asked to emit code which returns the value of
RETVAL when that value is boolean, then in the specific case of
$do_setmagic being true, it emits invalid code.

Now it so happens that for RETVAL, generate_output() is *never* called
with $do_setmagic set to true, so this is all a bit academic. But I'm
fixing it in case later refactoring tries to use this code path for
variables other than RETVAL. The fact that it can never happen is why
this commit doesn't include any tests.

The actual issue is that: while normally a bool return is simplified to
this single line of code:

    ST(0) = boolSV(RETVAL);

when magic needs to be set then the value needs to be saved to a temporary
value, such as:

    SV * RETVALSV;
    RETVALSV = boolSV(RETVAL);
    SvSETMAGIC(RETVALSV);
    ST(0) = RETVALSV;

but the code had incorrectly concluded that it could use RETVAL instead:

    RETVAL = boolSV(RETVAL);
    SvSETMAGIC(RETVAL);
    ST(0) = RETVAL;

Even though RETVAL is of type bool rather than SV*. With this fix,
RETVALSV is used.


  Commit: 2149e374f9f87248b367567649a2b0b3602fada5
      
https://github.com/Perl/perl5/commit/2149e374f9f87248b367567649a2b0b3602fada5
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS/Utilities.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: expand PUSHi/u/n to { TARGi/u/n; PUSHs }

When ParseXS emits code which uses the TARG optimisation to push
an IV/UV/NV SV onto the stack as the return value, it currently
uses one of the PUSHx macros, e.g.

    PUSHi((IV)RETVAL);

This commit makes it instead emit what that macro expands to, i.e.

    TARGi((IV)RETVAL, 1); PUSHs(TARG);

This separates out the logically separate steps of:

1) setting the TARG SV to the return value;
2) pushing that SV onto the stack for return.

Splitting it out like this is functionally equivalent, but will assist
in future code refactoring, where the setting and pushing need to be
done separately, such as for PERL_RC_STACK builds.

For perls before 5.24.0 which don't have the TARGx macros, simple
backwards-compatible definitions are now added to the standard C
preamble in the generated .c file.

Note that TARGi etc include an optimisation for simple SVs. Their
definition is something along the lines of:

    if (TARG is simple and no tainting) {
        SvFLAGS(TARG) |= (SVf_IOK|SVp_IOK);
        TARG->sv_u.svu_iv = TARGi_iv;
    }
    else
        sv_setiv_mg(targ, i);

I have not attempted to reproduce this logic for the pre-5.24.0 back-compat
macros: instead these are just:

    #define TARGi(iv, do_taint) sv_setiv_mg(TARG, iv)

etc, which mimic the pre-5.24 definitions of PUSHi etc:

    #define PUSHi(i)    sv_setiv(TARG, (IV)(i)); PUSHTARG;

One subtlety is that in the old macros, the sv_setiv didn't do set magic,
while the PUSHTARG did. In the new scheme it's the other way round; TARGi
or sv_setiv_mg() do set magic, while the PUSHs(TARG) doesn't.


  Commit: bd604dbe231471d8d74241ada1e0982d5f0e4858
      
https://github.com/Perl/perl5/commit/bd604dbe231471d8d74241ada1e0982d5f0e4858
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: expand PUSHp to { sv_setpvn_mg; PUSHs }

When ParseXS emits code which uses the TARG optimisation to push
a PV onto the stack as the return value, it currently uses one of two
approaches, depending on whether there is a length argument:

    1) PUSHp(val, len);
    2) sv_setpv(TARG, val); PUSHTARG;

This commit expands and simplifies the output for those macros. In
particular, separating out the TARG-setting and TARG-pushing operations
to make future refactoring easier.

For the first, this commit expands the PUSHp() macro so that the emitted
code becomes:

    sv_setpvn(TARG, val, len); SvSETMAGIC(TARG); PUSHs(TARG);

and then moves the magic setting into the function call:

    sv_setpvn_mg(TARG, val, len); PUSHs(TARG);

For the second, it expands the PUSHTARG:

    sv_setpv(TARG, val); SvSETMAGIC(TARG); PUSHs(TARG);

and again, then moves the magic setting into the function call:

    sv_setpv_mg(TARG, val); PUSHs(TARG);


  Commit: 46dbccd17965c71c9e2634065989fee7a5846b36
      
https://github.com/Perl/perl5/commit/46dbccd17965c71c9e2634065989fee7a5846b36
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm

  Log Message:
  -----------
  ParseXS: refactor: pull out common TARG PUSHs()

The last couple of commits have made it so that all branches of the TARG
optimisation end with

    print "\tPUSHs(TARG);\n";

so pull all these out into a single print at the end.


  Commit: 467b9312e8ed1b1f689d89298b887c05a04bdaba
      
https://github.com/Perl/perl5/commit/467b9312e8ed1b1f689d89298b887c05a04bdaba
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm

  Log Message:
  -----------
  ParseXS: refactor: TARG opt: do eval only once

For the TARG optimisation, the typemap parser has detected typemaps
of the form sv_setiv(), sv_setpvn() etc and split them out into their
components. These components will then be variable-expanded using eval,
then put back in a modified version of the original call.
So for example, for a typemap of

    sv_setiv($arg, (IV)$var);

we would do the equivalent of:

    $what = '(IV)$var';   # extracted out by typemap parser
    $what = $self->eval_output_typemap_code($what, {var => $var, ...});
    print "TARGi($what, 1);\n";

However for the sv_setpvn() case, there is an extra length arg.
Formerly this was variable-expanded using a *second* eval. This commit
combines both into a single eval, making the code simpler. So for this
typemap:

    sv_setpvn($arg, (char *)&$var, sizeof($var));

it now does the equivalent of:

    $what  = '(char *)&$var';  # extracted out by typemap parser
    $tsize = ', sizeof($var)'; # extracted out by typemap parser
    $what = $self->eval_output_typemap_code("$what$tsize", {var => $var, ...});
    print "sv_setpvn_mg(TARG, $what);\n";


  Commit: cab6ecd0f290c88ccd57c49e5f0f9585f7272865
      
https://github.com/Perl/perl5/commit/cab6ecd0f290c88ccd57c49e5f0f9585f7272865
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm

  Log Message:
  -----------
  ParseXS: refactor: pull out common XSprePUSH emit

The two branches of the TARG optimisation both emit a 'XSprePUSH;' line.
This commit hoists those two identical blocks of code to outside the
if/else.

For the TARGi/u/n case, as a side effect it changes the ordering of the
lines of C code from:

    XSprePUSH;           /* reset stack pointer to base of frame */
    TARGu((IV)RETVAL, 1);
    PUSHs(TARG);

to

    TARGu((IV)RETVAL, 1);
    XSprePUSH;           /* reset stack pointer to base of frame */
    PUSHs(TARG);

Which is functionally the same.

For the sv_setpv/sv_setpvn cases, there is no change in output (so this
commit actually makes things more consistent).


  Commit: a0e565886847121be99aaee47edb3d3128cda3ba
      
https://github.com/Perl/perl5/commit/a0e565886847121be99aaee47edb3d3128cda3ba
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm

  Log Message:
  -----------
  ParseXS: refactor: TARG opt: eval whole expression

Given a typemap like

    sv_setiv($arg, (IV)$var);

the TARG optimisation currently extracts out the '(IV)$var' part of it,
evals that as a double-quoted string in order to variable-expand '$var'
etc, then constructs a new expression using that result, e.g.
'TARGi((IV)RETVAL)'.

This commit changes it so that the eval expansion comes *after* the
reconstruction. So before:

    $what = '(IV)$var';
    $what = eval qq("$what");
    $result = "TARGi($what)";

and after:

    $what = '(IV)$var';
    $what = "TARGi($what)";
    $result = eval qq("$what");

The result should be the same, but it makes the code closer to how
RETVAL is handled in the rest of generate_output().


  Commit: fbb69e22e55268eeab1e2d1cb031b15842a42adc
      
https://github.com/Perl/perl5/commit/fbb69e22e55268eeab1e2d1cb031b15842a42adc
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: don't XSprePUSH for TARG returns

ParseXS currently generates two kinds of C code to return RETVAL.

For the general case, the code looks like (give or take some extra
messing around with sv_newmortal(), SvSETMAGIC() etc):

    sv_setfoo(RETVALSV, (foo)RETVAL);  /* from the typemap template */
    ST(0) = RETVALSV;
    XSRETURN(1);

While for the "use TARG instead of a new mortal" optimisation, it
looks like:

    TARGi((foo)RETVAL); /* modified typemap template to set TARG efficiently */
    XSprePUSH;
    PUSHs(TARG);
    XSRETURN(1);

This commit makes the TARG optimisation use the first form too. As well
as being marginally more efficient, it will help with refactoring
ParseXS: soon the TARG optimisation branch and the general branch should
be able to be mostly combined. It's also more friendly to implementing
PERL_RC_STACK eventually.

In more detail:

On entry to an XSUB, ax is set to the offset to the first arg (i.e.
ST(0)), and SP/sp is set to point to the last (topmost) arg.

During execution of the body of the XSUB, the args are left on the
stack. Then when putting return values on the stack (typically just one
- RETVAL - although rarely others may be pushed too via OUTLIST), then
  the general code expands to something like:

    *(PL_stack_base + ax) = RETVALSV;    /* ST(0) = RETVALSV; */
    PL_stack_sp = PL_stack_base + ax;    /* XSRETURN(1); */

Which effectively replaces the first arg with RETVAL and then blows the
rest of the args away.

While the TARG code does:

    sp = PL_stack_base + ax - 1;         /* XSprePUSH;  */
    *++sp = TARG;                        /* PUSHs(TARG); */
    PL_stack_sp = PL_stack_base + ax;    /* XSRETURN(1); */

i.e. blow all the args away, then push RETVAL.

The resetting and incrementing of sp is unnecessary: it is just a
hangover from when the TARG optimisation used PUSHi() etc.

Note that in the presence of at least one OUTLIST param, an XSprePUSH
is still emitted. The stack is reset before any value(s) are output;
the 'ST(0) = ...' actually modifies the stack slot *above* sp, but then
'SP++' is immediately emitted after that.


  Commit: 54cfd7986fae2facd32d483713832c848a272540
      
https://github.com/Perl/perl5/commit/54cfd7986fae2facd32d483713832c848a272540
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm

  Log Message:
  -----------
  ParseXS: remove dead SvSETMAGIC()-emitting code

In the big chunk of code in generate_output() which is responsible for
emitting the C code which creates a mortal SV and then sets its value to
RETVAL and pushes it on the stack, there is a bunch of code to emit
"SvSETMAGIC(RETVALSV);" or similar if $do_setmagic is true.

However, for RETVAL:
a) $do_setmagic should never be true; and
b) even if it was, it would be pointless to call set magic on a fresh
temporary SV.

So this commit removes all the code which handles $do_setmagic in the
RETVAL branch, and instead adds a death("Internal error: ...") for if
$do_setmagic does happen to be true.

This commit should produce no changes to the generated C code.

The next commit will handle a similar situation for setting magic when
the TARG optimisation is being used.


  Commit: 2b5f07f58d12dd260cf4c6f53eecef52753f6f1b
      
https://github.com/Perl/perl5/commit/2b5f07f58d12dd260cf4c6f53eecef52753f6f1b
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: don't set magic on TARG return value.

There is a chunk of code in generate_output() which is responsible for
emitting the C code which grabs the targ from the pad, sets its value to
RETVAL, and pushes it on the stack.

The value setting can be one of two forms:

    TARGi((IV)RETVAL) /* and TARGu, TARGn */

    sv_setpvn_mg(TARG, RETVAL, length(retval))

The TARGi/u/n expand to:

    if (TARG is simple)
        update it directly
    else
        sv_setiv_mg(targ, i)

and similar.

However, for RETVAL:
a) $do_setmagic should never be true; and
b) even if it was, it would be pointless to call set magic on a TARG.

So this commit changes the sv_setpv_mg() to sv_setpv() and similarly
for sv_setpvn().

Note that TARGi/u/n still calls set magic in the non-shortcut case,
but I'm not worried about the slight inefficiency, as it shouldn't happen
very often.

Note that the previous commit did the same for RETVAL in the
non-TARG-optimisation case. Unlike the previous commit, this one *does*
affect what C code is generated.


  Commit: ac08a4ff41717501153066ce5f69f06a3942600f
      
https://github.com/Perl/perl5/commit/ac08a4ff41717501153066ce5f69f06a3942600f
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm

  Log Message:
  -----------
  ParseXS: refactor: simplify RETVAL logic

Simplify the code in generate_output() which emits C code to return the
value of RETVAL. This also prepares it for some changes which will
follow in the next commit.

Mainly it adds the $retvar lexical, which keeps track of what C var (or
expression) should be used when setting values or calling sv_2mortal()
etc: i.e. one of 'RETVALSV', 'RETVAL', or 'ST(0)'. (And might be 'TARG'
too in the next commit).

This replaces a couple of bool flags.

Should be no functional changes.


  Commit: 36c1a0ba5308b03968bc8394560150fcca5f9e05
      
https://github.com/Perl/perl5/commit/36c1a0ba5308b03968bc8394560150fcca5f9e05
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: make TARG code less exceptional

There is a block of code in generate_output() which for some typemaps of
the general form sv_set[ivnp]vn?($arg, $val), uses TARG rather than a
new mortal to return the value; and which in addition, for the [iuv]
cases uses TARGi() etc to set the value more efficiently sometimes.

Currently this is handled in an entirely separate 'if' block in
generate_output(), including doing its own: evalling the typemap,
emitting C code, and returning.

This commit changes it so that the TARG optimisation is instead handled
within the general RETVAL-handling code.

This makes the code simpler and easier to maintain.

The main differences in the old and new ways are that rather than:

- constructing and evalling a whole new typemap: e.g. ditching
  'sv_setiv($arg, $val)', replacing it with 'TARGi($val, 1)' and then
  evalling it to get e.g. 'TARGi((IV)RETVAL, 1)',

- we instead use the post-eval version of the standard typemap,
  'sv_setiv(RETVALSV, (IV)RETVAL)', and then for the specific cases of
  [iuv], apply a regex to convert it to 'TARGi((IV)RETVAL, 1)'. This
  should be functionally the same, but may have minor white space
  changes.

By using the standard eval code path, the typemap is evalled with the
full complement of vars such as $ntype, $num etc, rather than just $var
and $type. Whether this better or worse is debatable. Arguably the
standard eval sets too many vars (as a historical accident), while the
(just removed) TARG-specific eval arguably sets too few vars.

For the sv_setpv() and sv_setpvn() cases, we don't modify the result,
except to change 'RETVALSV' to 'TARG'. This now causes typecasts which
were in the original typemap to be kept, whereas before they were
striped. So

    sv_setpv(TARG, ....)

becomes

    sv_setpv((SV*)TARG, ....)

Which shouldn't make any difference since TARG is already SV*.

Apart from the white space and restoration of any cast, and the changes
in vars available to the eval, there should be no other functional
changes.

I've also added code which emits a late 'dXSTARG' if one hasn't already
been emitted earlier in the XSUB body, but for now, it should already
have been emitted earlier always. But this allows for potential future
expansions to what can use the TARG.


  Commit: b7fef9c793ee31bbe38ce2283b6a4231ca22b37c
      
https://github.com/Perl/perl5/commit/b7fef9c793ee31bbe38ce2283b6a4231ca22b37c
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm

  Log Message:
  -----------
  ParseXS: refactor: clean up output code comments

Recent commits have extensively messed with generate_output().
This commit updates and clean ups all the code comments in that area,`
and moves a couple of lexical var declarations closer to where they're
first used.


  Commit: c46d49ad08c540dd6757235ffce1104d65d44e5e
      
https://github.com/Perl/perl5/commit/c46d49ad08c540dd6757235ffce1104d65d44e5e
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: add more OUTLIST tests

Add several tests where an OUTLIST param is the first or second value
to be returned on the stack.

The next commit will make OUTLIST params use the same code path as the
RETVAL return code generation, so add lots of tests now to see what (if
anything) changes. In theory, merging the code paths opens up the
possibility of TARG being used to return an OUTLIST value for example.


  Commit: ac1b25c2b91f3482e6505aac91867628e80b3b16
      
https://github.com/Perl/perl5/commit/ac1b25c2b91f3482e6505aac91867628e80b3b16
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: regularise/optimise OUTLIST code gen

In an XSUB like

    int
    foo(OUTLIST int A, OUTLIST int B)
        ...

C code is emitted to push SVs onto the stack containing the values of
RETVAL, A and B. So in principle, something like:

    XSprePUSH;
    EXTEND(SP,3);

    PUSHs(sv_newmortal());
    sv_setiv(ST(0), (IV)RETVAL);

    PUSHs(sv_newmortal());
    sv_setiv(ST(1), (IV)A);

    PUSHs(sv_newmortal());
    sv_setiv(ST(2), (IV)B);

However, RETVAL and OUTLIST params are currently handled by two separate
branches within generate_output().

The OUTLIST branch always just emits a PUSHs() / sv_setX() pair.

The RETVAL branch on the other hand includes a number of optimisations,
such as using TARG instead of sv_newmortal(), using TARGi() rather than
sv_setiv() to set the value of the SV, using SV* RETVALSV as an
intermediate variable, not copying the SV when the typemap returns an
SV, and skipping a mortalise when the typemap returns an immortal SV.

This commit deletes the OUTLIST branch, and instead makes OUTLIST params
use the RETVAL branch. This immediately makes most of the RETVAL
optimisations available to OUTLIST params. In particular, if the XSUB is
void return type, then the TARG is still available to be used for the
first OUTLIST param.

This isn't as exciting as it may first seem, as very little real XS code
actually uses OUTLIST params. But it simplifies and regularises the code
in generate_output(), and means that any future added RETVAL
optimisations will automatically apply to OUTLIST values too.

Note that some OUTPUT typemaps look like:

    T_BOOL
            ${"$var" eq "RETVAL" ? \"$arg = boolSV($var);" : \"sv_setsv($arg, 
boolSV($var));"}

which for now will carry on using the inefficient sv_setsv() branch for
non-RETVAL returns, so will copy rather than returning an immortal
directly.


  Commit: 4422e67636f87ddf5b66b3420e1f010373a49e18
      
https://github.com/Perl/perl5/commit/4422e67636f87ddf5b66b3420e1f010373a49e18
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/lib/ExtUtils/Typemaps/OutputMap.pm
    M dist/ExtUtils-ParseXS/t/517-t-targetable.t

  Log Message:
  -----------
  ParseXS: add OutputMap::targetable_legacy() method

Add a Typemaps::OutputMap::targetable_legacy() method which is,
initially, just an exact copy of the existing targetable() method. Then
use the legacy method to determine whether to emit an early dXSTARG,
while continue to use the targetable() method to determine whether to
emit a late dXSTARG.

Background: until recently, the TARG optimisation was used specifically
only where the typemap entry for RETVAL's type was one of
sv_set{iv,uv,nv,pv,pvn}. This was detected by the targetable() method,
and if true, a dXSTARG was emitted near the start of the XSUB's body,
then the sv_setiv(ST(0)), RETVAL) or whatever near the end of the XSUB
was replaced with C<TARGi(RETVAL); PUSHs(TARG)> or similar.

Recent changes have expanded where TARG can be used, sometimes where the
usage can't be detected early. In these cases, a dXSTARG is instead
emitted in a tight scope near the end of the XSUB, e.g.

    { dXSTARG; sv_setfoo(TARG, bar); PUSHs(TARG); }

Ideally the early dXSTARG would never be emitted and dXSTARG would just
be emitted where and when it is required. However, some CPAN XS code
assumes that TARG has been declared, e.g. in order to override the
normal C<OUTPUT: RETVAL> behaviour, or to add a PERL_UNUSED_ARG(TARG) in
PPCODE for an XSUB which has a declared return value.

So the idea behind this commit is that targetable_legacy() will become
fossilised and will cause an early dXSTARG to continue being emitted
under the same circumstances; while targetable() will change over time,
allowing a late dXSTARG in more circumstances.


  Commit: a2758bbe19ad8fe3012e2429ca44e91e7376f112
      
https://github.com/Perl/perl5/commit/a2758bbe19ad8fe3012e2429ca44e91e7376f112
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/lib/ExtUtils/Typemaps/OutputMap.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t
    M dist/ExtUtils-ParseXS/t/517-t-targetable.t

  Log Message:
  -----------
  ParseXS: make OutputMap::targetable a class method

Currently, ExtUtils::Typemaps::OutputMap::targetable() is an object
method which examines the typemap template associated with the object
and determines whether it is suitable for the TARG optimisation. If so,
it returns a hash containing the parsed components of the
sv_setXv(...,...) string that were found in the typemap.

This commit changes this method in two ways.

First, targetable() now just returns a boolean, as the components are no
longer used.

Second, it converts targetable() into a class method, where the template
string is instead passed as a parameter.

This second change allows us to use the TARG optimisation even for
template code which wasn't derived from a typemap. In particular, for
the array() pseduo-type. For example in:

    array(int,5)
    foo(...)
        CODE:
            ...

Formerly the 'array(int,5)' pseudo-type was converted into a template
like:

    sv_setpvn($arg, (char*)$var, 5 * sizeof(int))

which was evalled and emitted as normal. But because that template
wasn't derived from a typemap, it wasn't eligible for TARG. Following
this commit, it is.


  Commit: d8176da3fdd6c2398328c9f26232265b5852ed66
      
https://github.com/Perl/perl5/commit/d8176da3fdd6c2398328c9f26232265b5852ed66
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/Typemaps/OutputMap.pm
    M dist/ExtUtils-ParseXS/t/517-t-targetable.t

  Log Message:
  -----------
  ParseXS: targetable(): split into 2- and 3-arg

The code in ExtUtils::Typemaps::OutputMap->targetable() which looks
for typemap template code like

    sv_setiv($arg, RETVAL);
    sv_setpvn($arg, RETVAL, strlen(RETVAL));

is currently a bit rough and matches against various badly-formed
strings.

This commit changes it so that 2-arg functions like sv_setiv() are only
matched if they have 2 args, and sv_setpvn() only if it has three args.
Previously it would allow either to have 2 or 3 args.

This commit breaks a couple of recently-added tests for embedded
double-quoted strings because it turns out the regexes didn't actually
handle quotes, but matched anyway due to the laxness of the match.
This will be fixed shortly.

This commit is unlikely to affect any real XS code, because the code in
typemaps tends to be well-formed.


  Commit: 6cb1e6c8fc7bbf8d854738f63e666cb9c4479fe1
      
https://github.com/Perl/perl5/commit/6cb1e6c8fc7bbf8d854738f63e666cb9c4479fe1
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/Typemaps/OutputMap.pm
    M dist/ExtUtils-ParseXS/t/517-t-targetable.t

  Log Message:
  -----------
  ParseXS: targetable(): parse C strings

In the pattern-matching code which looks for candidates for the TARG
optinisation in typemap entries like:

    sv_setiv($arg, RETVAL);
    sv_setpvn($arg, RETVAL, strlen(RETVAL));

make C double-quoted strings such as "a,b" and "a,\",c" be parsed,
so that for example commas within double-quotes aren't mis-parsed
as an arg separator.

This commit is unlikely to affect any real XS code, but is added for
completeness.

It also changes a (??{ $bal }) to $bal_no_comma because
a) the third arg shouldn't have any commas;
b) there's no need for the (??{}) recursion yet - that's already
done within $bal/$bal_no_comma.


  Commit: bc5d9a83c336aa8af63b4777bd2ca7e215a528d9
      
https://github.com/Perl/perl5/commit/bc5d9a83c336aa8af63b4777bd2ca7e215a528d9
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/lib/ExtUtils/Typemaps/OutputMap.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t
    M dist/ExtUtils-ParseXS/t/517-t-targetable.t

  Log Message:
  -----------
  ParseXS: test for targetable *after* eval

Previously, checking for whether a typemap code entry was suitable
for the TARG optimisation was done *before* eval-expanding the template;
so it would look for code like, e.g.

    sv_setiv($arg, ...);

This commit changes it so that it now examines the code string *after*
expansion, so it now looks for strings like

    sv_setiv(RETVALSV, ...);

The advantage of this is that a complex typemap entry such as

    T_MYINT
        ${ "$var" eq "RETVAL" ? \"$arg = myint($var)"
                              : \"sv_setiv($arg, $var);" }

would now be a candidate.

Note that nothing in the current standard typemap, nor in any of the
XS code bundled with perl, actually benefits from this currently. So
it's more of a potential rather than an actual efficiency improvement.

Note also that ParseXS currently always expands $arg to 'RETVALSV', but
I've included a few other options to match, such as 'ST(N)', in case
that ever changes.


  Commit: 9e5a392d07e7830e7ce37a53743b794fc7c94ef5
      
https://github.com/Perl/perl5/commit/9e5a392d07e7830e7ce37a53743b794fc7c94ef5
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/lib/ExtUtils/Typemaps/OutputMap.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t
    M dist/ExtUtils-ParseXS/t/517-t-targetable.t

  Log Message:
  -----------
  ParseXS: make more sv_setfoo() fns TARG candidates

Currently sv_set(iv|uv|nv|pv|pvn) are candidates for using TARG for the
return SV  rather than creating a new mortal. In addition,
sv_set(iv|uv|nv) are candidates for using TARG[iun] to more efficiently
set the value of that TARG SV.

This commit does two things.

First, it extends the list of eligible functions to use TARG.
I basically went through embed.fnc looking for functions of the form
sv_set* and ignored the weird ones or ones which could leave TARG as
anything other than a simple scalar (in particular, TARG mustn't become
an RV or the referent will have its life extended to the life of the
TARG). I added:

- the _mg variants of the sv_set(iv|uv|nv|pv|pvn) functions.
  Since TARG shouldn't have set magic, it should make no difference
  whether we call set magic or not.

- the 1-arg sv_set_(undef|false|true) functions. These relatively new
  functions don't take a parameter and so are unlikely to be used in a
  typemap, but are included for completeness.

- sv_set_bool(). This is a relatively new function but might start to
  appear in typemaps in future.

- sv_setpv_bufsize(). A bit obscure, but why not!

Secondly, it extends the candidates for the use of TARG[iuv] to the _mg
variants of sv_set[iun]v.

Currently no typemaps or XS code in core uses these extra functions,
but they might on CPAN or in the future.


  Commit: 10a715170f6cae359f9defd4e6528ab4dc91414b
      
https://github.com/Perl/perl5/commit/10a715170f6cae359f9defd4e6528ab4dc91414b
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm

  Log Message:
  -----------
  ParseXS: refactor: flatten if/else

The tail half of generate_output() looks like

    if (cond) {
        long block of code
    }
    else {
        short block of code
    }
    return;

This commit refactors it to be

    if (!cond) {
        short block of code
        return;
    }
    long block of code
    return;

Next commit will reindent


  Commit: d5f4878784b3e144b90cec0b6ab5e0ff69a70a51
      
https://github.com/Perl/perl5/commit/d5f4878784b3e144b90cec0b6ab5e0ff69a70a51
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm

  Log Message:
  -----------
  ParseXS: refactor: re-indent code block

Re-indent block after previous commit removed a scope.
Whitespace-only.


  Commit: 8baa849f3fdee76c8e2efc9d2cfe7dde7bdc800c
      
https://github.com/Perl/perl5/commit/8baa849f3fdee76c8e2efc9d2cfe7dde7bdc800c
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: don't always extend stack with OUTLIST

Normally when an XSUB returns a *single* RETVAL value, we skip
emitting an EXTEND(SP,1), because the pp_entersub() will have earlier
been called with at least a GV or CV on the stack.

But it always extended the stack if there were any OUTLIST values that
needed pushing and returning. This commit makes it take into account
that a GV/CV plus at least min_args arguments were already on the stack
when pp_entersub() was called, so only extend the stack if more values
than that need returning.

So for example this no longer emits an EXTEND(SP,1)

    void
    foo(OUTLIST int i)

(This is unlikely to speed up much real-life code, as nobody seems to
actually use OUTLIST.)


  Commit: 9057927d8b0f133d8b51e76ce381bfbc784f6c0b
      
https://github.com/Perl/perl5/commit/9057927d8b0f133d8b51e76ce381bfbc784f6c0b
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/t/typemap

  Log Message:
  -----------
  ParseXS: sync test typemap with system typemap

The typemap file used for testing ExtUtils::ParseXS, t/typemap, hasn't
(for many years) been updated when the typemap bundled with perl,
lib/ExtUtils/typemap, gets updated.

This commit resyncs them by overwriting the test file with the system
file.

In the long term they really aught to be unified in some fashion.


  Commit: e2b471a5f13f08f6410d5fea8761d495846fae29
      
https://github.com/Perl/perl5/commit/e2b471a5f13f08f6410d5fea8761d495846fae29
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: fix OUTLIST code gen for SV*

About 12 commits ago in this branch, I moved OUTLIST return-code
generation into the same code path as for that done for RETVAL.
This allows OUTLIST vars to potentially take advantage of some of the
optimisations done for RETVAL, such as using TARG rather than
sv_newmortal().

Unfortunately that commit missed a couple of places in the RETVAL code
path which had the variable name hard-coded as 'RETVAL'. This commit
fixes that by always using $var.

It would only have affected code which used an OUTLIST var of type SV*
on a non-void XSUB where the T_SV OUTPUT typemap entry had also been
overridden to:

    T_SV
        $arg = $var;

In that specific case, an XSUB like:

    int
    foo(OUTLIST SV* A)

was generating bad code like:

    int RETVAL;
    SV* A;
    ...
    RETVAL = A;
    RETVAL = sv_2mortal(RETVAL);
    ST(1) = RETVAL;

It now emits:

    int RETVAL;
    SV* A;
    ...
    A = sv_2mortal(A);
    ST(1) = A;

This commit also adds a number of new tests for OUTLIST vars where the
typemap has an assign.

It also fixes the test framework in t/001-basic.t to capture and
display the error if the test code gives an eval error.


  Commit: b1b252f750135c4aade1808861ad5dfe064d1257
      
https://github.com/Perl/perl5/commit/b1b252f750135c4aade1808861ad5dfe064d1257
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm

  Log Message:
  -----------
  ParseXS: update code comments for generate_output()

Do a general rewrite of all the code comments directly above and in this
sub, to reflect all the recent refactoring work.


  Commit: 4c2698c5ac008b9f89aab99883d8fcfbc1f69b37
      
https://github.com/Perl/perl5/commit/4c2698c5ac008b9f89aab99883d8fcfbc1f69b37
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm

  Log Message:
  -----------
  ParseXS: refactor: tweak xsub_targ_* fields

I recently added two fields to the ParseXS object,

    xsub_targ_declared
    xsub_targ_usable

and a few weeks later I found myself confused by them, so this commit
renames them and changes their functionality slightly.

    xsub_targ_declared  -> xsub_targ_declared_early

This flag now indicates solely that a dXSTARG was emitted at the *start*
of the XSUB in a wide scope. It no longer indicates also that a dXSTARG
been emitted later in a narrow scope.

    xsub_targ_usable   -> xsub_targ_used

Inverts the logic, and now indicates purely whether we've already
used TARG to return a value, rather than whether it's still available
to be used. That was getting muddied up with whether dXSTARG had been
emitted early (because if it hadn't, is TARG usable?).

Should be no functional change to the emitted C code.


  Commit: af45c94ddd0d80df6bd1f12ac865a0967218ec0f
      
https://github.com/Perl/perl5/commit/af45c94ddd0d80df6bd1f12ac865a0967218ec0f
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm

  Log Message:
  -----------
  ParseXS: refactor: make generate_output Param meth

Rename generate_output() to as_output_code() and make it a method
in the ExtUtils::ParseXS::Node::Param class (it was formerly
an ExtUtils::ParseXS method).

As well as the rename, this commit mainly does s/$self/$pxs/g and
s/$param/$self/g.

The next commit will move this method into Node.pm.


  Commit: f94f0449d0aa36252df3deedaec02b93640f70c3
      
https://github.com/Perl/perl5/commit/f94f0449d0aa36252df3deedaec02b93640f70c3
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS/Node.pm

  Log Message:
  -----------
  ParseXS: refactor move as_output_code into Node.pm

The previous commit made as_output_code() be a method of
ExtUtils::ParseXS::Node::Param; now move it into Node.pm where it
belongs.

No functional changes; just a literal cut+paste, except for no longer
needing the full package name in the sub declaration, so

    sub ExtUtils::ParseXS::Node::Param::as_output_code { ... }
becomes
    sub as_output_code { ... }

It also updates the code comments for as_code() to add mention that
there's now also a related  as_output_code() method.


  Commit: c4ed3ea024b76a2d5d9b0bae5edb3c10c89d33b1
      
https://github.com/Perl/perl5/commit/c4ed3ea024b76a2d5d9b0bae5edb3c10c89d33b1
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS/Node.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: fix some comment typo/thinkos

Based on a PR review of this branch, fix a couple of typos and improve
the description of when as_output_code() is called to handle an OUTLIST
param (it's when $out_num is *defined*).


  Commit: 6a6848287c0d12d4ccf85b875902e8e0c48e05ed
      
https://github.com/Perl/perl5/commit/6a6848287c0d12d4ccf85b875902e8e0c48e05ed
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/Typemaps/OutputMap.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t
    M dist/ExtUtils-ParseXS/t/517-t-targetable.t

  Log Message:
  -----------
  ParseXS: rm sv_setpv_bufsize() as TARG candidate

Earlier in this branch I added sv_setpv_bufsize() to the list of
candidate functions which can use the TARG optimisation, but Tony C
pointed out in code review that it doesn't make much sense, so I've
removed it again.


  Commit: 26a8e183349a2837c715d63fc4d983bc3f3df691
      
https://github.com/Perl/perl5/commit/26a8e183349a2837c715d63fc4d983bc3f3df691
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: t/001-basic.t: add done_testing()

It's annoying to keep incrementing the number of tests.


  Commit: 22b2ca71c401eb14e1bc5e41c6ee386a525570e2
      
https://github.com/Perl/perl5/commit/22b2ca71c401eb14e1bc5e41c6ee386a525570e2
  Author: David Mitchell <da...@iabyn.com>
  Date:   2025-01-20 (Mon, 20 Jan 2025)

  Changed paths:
    M dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS/Node.pm
    M dist/ExtUtils-ParseXS/t/001-basic.t

  Log Message:
  -----------
  ParseXS: fix OUTLIST/OUTPUT override issue

I introduced a bug during recent code refactoring. For the specific
(and unusual) case of a void XSUB with a single parameter which was
both OUTLIST and also had an OUTPUT entry with a code override:

    foo(IN_OUTLIST int A)
        OUTPUT:
            A    setA(ST[99], A);

the OUTLIST would fail to emit the code to set the new mortal to be
stored at ST(0) to the value of A.


Compare: https://github.com/Perl/perl5/compare/c6a18e7c6320...22b2ca71c401

To unsubscribe from these emails, change your notification settings at 
https://github.com/Perl/perl5/settings/notifications

Reply via email to