diff options
author | Father Chrysostomos <sprout@cpan.org> | 2011-06-02 21:18:50 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2011-06-03 09:17:14 -0700 |
commit | 3bdf583b182847cb5998e0240312d5adc2210b53 (patch) | |
tree | 0464ef45054490bf8ebf6a60d682dd02f7bb65cd /pp_ctl.c | |
parent | 0984e55ea51a3030ba112fb0dd331061c5b0acf5 (diff) | |
download | perl-3bdf583b182847cb5998e0240312d5adc2210b53.tar.gz |
Move the lvalue code from pp_return into a separate func
so that upcoming commits can add more conditions without
slowing down the most common cases, and so that it can
eventually be merged with pp_leavesublv.
Diffstat (limited to 'pp_ctl.c')
-rw-r--r-- | pp_ctl.c | 43 |
1 files changed, 36 insertions, 7 deletions
@@ -2212,6 +2212,32 @@ PP(pp_leaveloop) return NORMAL; } +STATIC void +S_return_lvalues(pTHX_ SV **mark, SV **sp, SV **newsp, I32 gimme, + PERL_CONTEXT *cx) +{ + if (gimme == G_SCALAR) { + if (MARK < SP) { + if (cx->blk_sub.cv && CvDEPTH(cx->blk_sub.cv) > 1) { + *++newsp = SvREFCNT_inc(*SP); + FREETMPS; + sv_2mortal(*newsp); + } + else + *++newsp = *SP; + } + else + *++newsp = &PL_sv_undef; + } + else if (gimme == G_ARRAY) { + while (++MARK <= SP) { + *++newsp = *MARK; + TAINT_NOT; /* Each item is independent */ + } + } + PL_stack_sp = newsp; +} + PP(pp_return) { dVAR; dSP; dMARK; @@ -2290,11 +2316,13 @@ PP(pp_return) } TAINT_NOT; - if (gimme == G_SCALAR) { + if (lval) S_return_lvalues(aTHX_ MARK, SP, newsp, gimme, cx); + else { + if (gimme == G_SCALAR) { if (MARK < SP) { if (popsub2) { if (cx->blk_sub.cv && CvDEPTH(cx->blk_sub.cv) > 1) { - if (lval || SvTEMP(TOPs)) { + if (SvTEMP(TOPs)) { *++newsp = SvREFCNT_inc(*SP); FREETMPS; sv_2mortal(*newsp); @@ -2308,22 +2336,23 @@ PP(pp_return) } else *++newsp = - (lval || SvTEMP(*SP)) ? *SP : sv_mortalcopy(*SP); + SvTEMP(*SP) ? *SP : sv_mortalcopy(*SP); } else *++newsp = sv_mortalcopy(*SP); } else *++newsp = &PL_sv_undef; - } - else if (gimme == G_ARRAY) { + } + else if (gimme == G_ARRAY) { while (++MARK <= SP) { - *++newsp = popsub2 && (lval || SvTEMP(*MARK)) + *++newsp = popsub2 && SvTEMP(*MARK) ? *MARK : sv_mortalcopy(*MARK); TAINT_NOT; /* Each item is independent */ } + } + PL_stack_sp = newsp; } - PL_stack_sp = newsp; LEAVE; /* Stack values are safe: */ |