This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
simplify sort sub return arg processing
authorDavid Mitchell <davem@iabyn.com>
Mon, 8 Jun 2015 10:53:38 +0000 (11:53 +0100)
committerDavid Mitchell <davem@iabyn.com>
Fri, 19 Jun 2015 07:44:17 +0000 (08:44 +0100)
commit334112121fd381e21666f72ab06d79ef94f3f6a6
tree67d664468de4d9c499df8974d5f7687ffaa2ea6f
parent626ed49c374dc371a27e6734ce3d3399c07e2bb4
simplify sort sub return arg processing

This commit:

1) makes the  gimme of sort blocks, as specified by the pushed cx_gimme,
be G_SCALAR. Formerly it was likely to be G_ARRAY, as it inherited
whatever sort() was called as, and sort doesn't bother calling a sort
block unless sort was called in list context.

This change is largely cosmetic, as
    a) the sort block is already compiled in scalar context; and
    b) the code in S_sortcv() etc does its own return arg context
       processing anyway, and assumes scalar context.
But it makes it consistent with sort SUB, which *does* set gimme to
G_SCALAR.

2) Makes use of the fact that a sort sub or block will always be
called as the first context in a new stackinfo, and such stackinfos always
have PL_stack_base[0] set to &PL_sv_undef as a guard.
So handling scalar context return (where zero args returned needs to be
converted into 1 PL_sv_undef arg) can be simplified by just always
accessing the last arg, *PL_stack_sp, regardless of whether 0,1,2+ args
were returned.
Note that some code making use of MULTICALL (e.g. List::Util) has already
been (possibly inadvertently) relying on this fact.

3) Remove the "Sort subroutine didn't return single value" fatal error.
This croak was removed from the sort BLOCK and sort NON-XS-SUB variants
in v5.15.5-82-g1715fa6, but the croak was left for XS sort subs.
That commit incorrectly asserted that for "sort BLOCK" and "sort
NON-XS-SUB", more than 1 arg could never be returned, but:

    $ perl -e'sub f { return (1,2) } @a = sort f 1,2,3'
    perl: pp_sort.c:1789: S_sortcv: Assertion `PL_stack_sp ==
        PL_stack_base' failed.

That has been fixed by (2) above. By removing the croak from the XS branch
too, we make things consistent. This means that an XS sub which returns
more than 1 arg will just gets its return args be evaluated in scalar
context (so @return_args[-1] will be used), rather than being handled
specially.
pod/perldiag.pod
pp_ctl.c
pp_sort.c
t/op/sort.t