summaryrefslogtreecommitdiff
path: root/pp_ctl.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2011-06-02 21:18:50 -0700
committerFather Chrysostomos <sprout@cpan.org>2011-06-03 09:17:14 -0700
commit3bdf583b182847cb5998e0240312d5adc2210b53 (patch)
tree0464ef45054490bf8ebf6a60d682dd02f7bb65cd /pp_ctl.c
parent0984e55ea51a3030ba112fb0dd331061c5b0acf5 (diff)
downloadperl-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.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index 4780ead2ac..4413587db6 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -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: */