This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
PUSHSUB: make retop a parameter
[perl5.git] / pp_sort.c
index 1e48042..5f7ae22 100644 (file)
--- a/pp_sort.c
+++ b/pp_sort.c
@@ -1640,10 +1640,9 @@ PP(pp_sort)
        SV **start;
        if (PL_sortcop) {
            PERL_CONTEXT *cx;
-           SV** newsp;
            const bool oldcatch = CATCH_GET;
+            I32 old_savestack_ix = PL_savestack_ix;
 
-           SAVETMPS;
            SAVEOP();
 
            CATCH_SET(TRUE);
@@ -1669,17 +1668,15 @@ PP(pp_sort)
            }
 
             gimme = G_SCALAR;
-           PUSHBLOCK(cx, CXt_NULL, PL_stack_base);
+           PUSHBLOCK(cx, CXt_NULL, gimme, PL_stack_base, old_savestack_ix);
            if (!(flags & OPf_SPECIAL)) {
-               cx->cx_type = CXt_SUB;
-               PUSHSUB(cx);
+               cx->cx_type = CXt_SUB|CXp_MULTICALL;
+               PUSHSUB(cx, cv, NULL, hasargs);
                if (!is_xsub) {
                    PADLIST * const padlist = CvPADLIST(cv);
 
-                   if (++CvDEPTH(cv) >= 2) {
-                       PERL_STACK_OVERFLOW_CHECK();
+                   if (++CvDEPTH(cv) >= 2)
                        pad_push(padlist, CvDEPTH(cv));
-                   }
                    PAD_SET_CUR_NOSAVE(padlist, CvDEPTH(cv));
 
                    if (hasargs) {
@@ -1692,23 +1689,28 @@ PP(pp_sort)
 
                }
            }
-           cx->cx_type |= CXp_MULTICALL;
-           
+
            start = p1 - max;
            sortsvp(aTHX_ start, max,
                    (is_xsub ? S_sortcv_xsub : hasargs ? S_sortcv_stacked : S_sortcv),
                    sort_flags);
 
+            /* Reset cx, in case the context stack has been reallocated. */
+            cx = CX_CUR();
+
+           PL_stack_sp = PL_stack_base + cx->blk_oldsp;
+
+            CX_LEAVE_SCOPE(cx);
            if (!(flags & OPf_SPECIAL)) {
-               SV *sv;
-               /* Reset cx, in case the context stack has been
-                  reallocated. */
-               cx = &cxstack[cxstack_ix];
-               POPSUB(cx, sv);
-               LEAVESUB(sv);
+                assert(CxTYPE(cx) == CXt_SUB);
+                CX_POPSUB(cx);
            }
-           POPBLOCK(cx,PL_curpm);
-           PL_stack_sp = newsp;
+            else
+                assert(CxTYPE(cx) == CXt_NULL);
+                /* there isn't a POPNULL ! */
+
+           CX_POPBLOCK(cx);
+            CX_POP(cx);
            POPSTACK;
            CATCH_SET(oldcatch);
        }
@@ -1768,7 +1770,6 @@ static I32
 S_sortcv(pTHX_ SV *const a, SV *const b)
 {
     const I32 oldsaveix = PL_savestack_ix;
-    const I32 oldscopeix = PL_scopestack_ix;
     I32 result;
     PMOP * const pm = PL_curpm;
     COP * const cop = PL_curcop;
@@ -1786,10 +1787,7 @@ S_sortcv(pTHX_ SV *const a, SV *const b)
     assert(PL_stack_sp > PL_stack_base || *PL_stack_base == &PL_sv_undef);
     result = SvIV(*PL_stack_sp);
 
-    while (PL_scopestack_ix > oldscopeix) {
-       LEAVE;
-    }
-    leave_scope(oldsaveix);
+    LEAVE_SCOPE(oldsaveix);
     PL_curpm = pm;
     return result;
 }
@@ -1798,7 +1796,6 @@ static I32
 S_sortcv_stacked(pTHX_ SV *const a, SV *const b)
 {
     const I32 oldsaveix = PL_savestack_ix;
-    const I32 oldscopeix = PL_scopestack_ix;
     I32 result;
     AV * const av = GvAV(PL_defgv);
     PMOP * const pm = PL_curpm;
@@ -1837,10 +1834,7 @@ S_sortcv_stacked(pTHX_ SV *const a, SV *const b)
     assert(PL_stack_sp > PL_stack_base || *PL_stack_base == &PL_sv_undef);
     result = SvIV(*PL_stack_sp);
 
-    while (PL_scopestack_ix > oldscopeix) {
-       LEAVE;
-    }
-    leave_scope(oldsaveix);
+    LEAVE_SCOPE(oldsaveix);
     PL_curpm = pm;
     return result;
 }
@@ -1850,7 +1844,6 @@ S_sortcv_xsub(pTHX_ SV *const a, SV *const b)
 {
     dSP;
     const I32 oldsaveix = PL_savestack_ix;
-    const I32 oldscopeix = PL_scopestack_ix;
     CV * const cv=MUTABLE_CV(PL_sortcop);
     I32 result;
     PMOP * const pm = PL_curpm;
@@ -1869,10 +1862,7 @@ S_sortcv_xsub(pTHX_ SV *const a, SV *const b)
     assert(PL_stack_sp > PL_stack_base || *PL_stack_base == &PL_sv_undef);
     result = SvIV(*PL_stack_sp);
 
-    while (PL_scopestack_ix > oldscopeix) {
-       LEAVE;
-    }
-    leave_scope(oldsaveix);
+    LEAVE_SCOPE(oldsaveix);
     PL_curpm = pm;
     return result;
 }