This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
further updates to CoreList
[perl5.git] / pp_sort.c
index a27232f..b0f2be1 100644 (file)
--- a/pp_sort.c
+++ b/pp_sort.c
@@ -1291,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
@@ -1589,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++;
        }
@@ -1652,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);
@@ -1757,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;
@@ -1799,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;
@@ -1829,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;