X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pp_sort.c;h=b0f2be1e8302b36c1c621b0c36532e8b1513ab7d;hb=1db366cc74404c47243e1d86efa59c6559db818e;hp=a75eab7608477a84dd6019764e63323cc0f0b7af;hpb=f1f66076265cc2bac3adabd54c01b0dea28ca3f0;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pp_sort.c b/pp_sort.c index a75eab7..b0f2be1 100644 --- a/pp_sort.c +++ b/pp_sort.c @@ -9,8 +9,10 @@ */ /* - * ...they shuffled back towards the rear of the line. 'No, not at the - * rear!' the slave-driver shouted. 'Three files up. And stay there... + * ...they shuffled back towards the rear of the line. 'No, not at the + * rear!' the slave-driver shouted. 'Three files up. And stay there... + * + * [p.931 of _The Lord of the Rings_, VI/ii: "The Land of Shadow"] */ /* This file contains pp ("push/pop") functions that @@ -204,7 +206,7 @@ dynprep(pTHX_ gptr *list1, gptr *list2, size_t nmemb, const SVCOMPARE_t cmp) if (r >= t) p = r = t; /* too short to care about */ else { while (((cmp(aTHX_ *(p-1), *p) > 0) == sense) && - ((p -= 2) > q)); + ((p -= 2) > q)) {} if (p <= q) { /* b through r is a (long) run. ** Extend it as far as possible. @@ -1289,7 +1291,7 @@ S_qsortsvu(pTHX_ SV ** array, size_t num_elts, SVCOMPARE_t compare) * by the original comparison routine on the elements pointed to. * Because we don't move the elements of list1 around through * this phase, we can break ties on elements that compare equal - * using their address in the list1 array, ensuring stabilty. + * using their address in the list1 array, ensuring stability. * This leaves us with something looking like * * indir list1 @@ -1587,33 +1589,23 @@ PP(pp_sort) if (!PL_sortcop) { if (priv & OPpSORT_NUMERIC) { if (priv & OPpSORT_INTEGER) { - if (!SvIOK(*p1)) { - if (SvAMAGIC(*p1)) - overloading = 1; - else - (void)sv_2iv(*p1); - } + if (!SvIOK(*p1)) + (void)sv_2iv_flags(*p1, SV_GMAGIC|SV_SKIP_OVERLOAD); } else { - if (!SvNSIOK(*p1)) { - if (SvAMAGIC(*p1)) - overloading = 1; - else - (void)sv_2nv(*p1); - } + if (!SvNSIOK(*p1)) + (void)sv_2nv_flags(*p1, SV_GMAGIC|SV_SKIP_OVERLOAD); if (all_SIVs && !SvSIOK(*p1)) all_SIVs = 0; } } else { - if (!SvPOK(*p1)) { - if (SvAMAGIC(*p1)) - overloading = 1; - else - (void)sv_2pv_flags(*p1, 0, - SV_GMAGIC|SV_CONST_RETURN); - } + if (!SvPOK(*p1)) + (void)sv_2pv_flags(*p1, 0, + SV_GMAGIC|SV_CONST_RETURN|SV_SKIP_OVERLOAD); } + if (SvAMAGIC(*p1)) + overloading = 1; } p1++; } @@ -1650,6 +1642,11 @@ PP(pp_sort) if (!(flags & OPf_SPECIAL)) { cx->cx_type = CXt_SUB; cx->blk_gimme = G_SCALAR; + /* If our comparison routine is already active (CvDEPTH is + * is not 0), then PUSHSUB does not increase the refcount, + * so we have to do it ourselves, because the LEAVESUB fur- + * ther down lowers it. */ + if (CvDEPTH(cv)) SvREFCNT_inc_simple_void_NN(cv); PUSHSUB(cx); if (!is_xsub) { AV* const padlist = CvPADLIST(cv); @@ -1755,8 +1752,6 @@ S_sortcv(pTHX_ SV *const a, SV *const b) CALLRUNOPS(aTHX); if (PL_stack_sp != PL_stack_base + 1) Perl_croak(aTHX_ "Sort subroutine didn't return single value"); - if (!SvNIOKp(*PL_stack_sp)) - Perl_croak(aTHX_ "Sort subroutine didn't return a numeric value"); result = SvIV(*PL_stack_sp); while (PL_scopestack_ix > oldscopeix) { LEAVE; @@ -1797,8 +1792,6 @@ S_sortcv_stacked(pTHX_ SV *const a, SV *const b) CALLRUNOPS(aTHX); if (PL_stack_sp != PL_stack_base + 1) Perl_croak(aTHX_ "Sort subroutine didn't return single value"); - if (!SvNIOKp(*PL_stack_sp)) - Perl_croak(aTHX_ "Sort subroutine didn't return a numeric value"); result = SvIV(*PL_stack_sp); while (PL_scopestack_ix > oldscopeix) { LEAVE; @@ -1827,8 +1820,6 @@ S_sortcv_xsub(pTHX_ SV *const a, SV *const b) (void)(*CvXSUB(cv))(aTHX_ cv); if (PL_stack_sp != PL_stack_base + 1) Perl_croak(aTHX_ "Sort subroutine didn't return single value"); - if (!SvNIOKp(*PL_stack_sp)) - Perl_croak(aTHX_ "Sort subroutine didn't return a numeric value"); result = SvIV(*PL_stack_sp); while (PL_scopestack_ix > oldscopeix) { LEAVE;