summaryrefslogtreecommitdiff
path: root/pp_sort.c
diff options
context:
space:
mode:
authorRobin Houston <robin@cpan.org>2005-10-29 22:33:07 +0100
committerH.Merijn Brand <h.m.brand@xs4all.nl>2005-11-02 12:49:54 +0000
commit9850bf21fc4ed69d8ddb0293df59411f891c62df (patch)
tree047a29a8cd2d04148aa15000e1307651d86afe8a /pp_sort.c
parentbda6ed216cf53718fff278193bffd2c4078fb377 (diff)
downloadperl-9850bf21fc4ed69d8ddb0293df59411f891c62df.tar.gz
sort/multicall patch
Message-ID: <20051029203307.GA8869@rpc142.cs.man.ac.uk> p4raw-id: //depot/perl@25953
Diffstat (limited to 'pp_sort.c')
-rw-r--r--pp_sort.c63
1 files changed, 39 insertions, 24 deletions
diff --git a/pp_sort.c b/pp_sort.c
index 3dda7cc67e..68ad610f10 100644
--- a/pp_sort.c
+++ b/pp_sort.c
@@ -1542,14 +1542,8 @@ PP(pp_sort)
if (is_xsub)
PL_sortcop = (OP*)cv;
- else {
+ else
PL_sortcop = CvSTART(cv);
- SAVEVPTR(CvROOT(cv)->op_ppaddr);
- CvROOT(cv)->op_ppaddr = PL_ppaddr[OP_NULL];
-
- SAVECOMPPAD();
- PAD_SET_CUR_NOSAVE(CvPADLIST(cv), 1);
- }
}
}
else {
@@ -1574,6 +1568,10 @@ PP(pp_sort)
}
}
else {
+ if (SvREADONLY(av))
+ Perl_croak(aTHX_ PL_no_modify);
+ else
+ SvREADONLY_on(av);
p1 = p2 = AvARRAY(av);
sorting_av = 1;
}
@@ -1645,13 +1643,12 @@ PP(pp_sort)
CATCH_SET(TRUE);
PUSHSTACKi(PERLSI_SORT);
if (!hasargs && !is_xsub) {
- if (PL_sortstash != stash || !PL_firstgv || !PL_secondgv) {
- SAVESPTR(PL_firstgv);
- SAVESPTR(PL_secondgv);
- PL_firstgv = gv_fetchpv("a", TRUE, SVt_PV);
- PL_secondgv = gv_fetchpv("b", TRUE, SVt_PV);
- PL_sortstash = stash;
- }
+ SAVESPTR(PL_firstgv);
+ SAVESPTR(PL_secondgv);
+ SAVESPTR(PL_sortstash);
+ PL_firstgv = gv_fetchpv("a", TRUE, SVt_PV);
+ PL_secondgv = gv_fetchpv("b", TRUE, SVt_PV);
+ PL_sortstash = stash;
SAVESPTR(GvSV(PL_firstgv));
SAVESPTR(GvSV(PL_secondgv));
}
@@ -1661,23 +1658,39 @@ PP(pp_sort)
cx->cx_type = CXt_SUB;
cx->blk_gimme = G_SCALAR;
PUSHSUB(cx);
- }
- PL_sortcxix = cxstack_ix;
+ if (!is_xsub) {
+ AV* padlist = CvPADLIST(cv);
+
+ if (++CvDEPTH(cv) >= 2) {
+ PERL_STACK_OVERFLOW_CHECK();
+ pad_push(padlist, CvDEPTH(cv));
+ }
+ SAVECOMPPAD();
+ PAD_SET_CUR_NOSAVE(padlist, CvDEPTH(cv));
- if (hasargs && !is_xsub) {
- /* This is mostly copied from pp_entersub */
- AV *av = (AV*)PAD_SVl(0);
+ if (hasargs) {
+ /* This is mostly copied from pp_entersub */
+ AV *av = (AV*)PAD_SVl(0);
- cx->blk_sub.savearray = GvAV(PL_defgv);
- GvAV(PL_defgv) = (AV*)SvREFCNT_inc(av);
- CX_CURPAD_SAVE(cx->blk_sub);
- cx->blk_sub.argarray = av;
+ cx->blk_sub.savearray = GvAV(PL_defgv);
+ GvAV(PL_defgv) = (AV*)SvREFCNT_inc(av);
+ CX_CURPAD_SAVE(cx->blk_sub);
+ cx->blk_sub.argarray = av;
+ }
+
+ }
}
+ cx->cx_type |= CXp_MULTICALL;
start = p1 - max;
sortsvp(aTHX_ start, max,
is_xsub ? sortcv_xsub : hasargs ? sortcv_stacked : sortcv);
+ if (!(flags & OPf_SPECIAL)) {
+ LEAVESUB(cv);
+ if (!is_xsub)
+ CvDEPTH(cv)--;
+ }
POPBLOCK(cx,PL_curpm);
PL_stack_sp = newsp;
POPSTACK;
@@ -1706,7 +1719,9 @@ PP(pp_sort)
}
}
}
- if (av && !sorting_av) {
+ if (sorting_av)
+ SvREADONLY_off(av);
+ else if (av && !sorting_av) {
/* simulate pp_aassign of tied AV */
SV** const base = ORIGMARK+1;
for (i=0; i < max; i++) {