diff options
author | Father Chrysostomos <sprout@cpan.org> | 2011-06-22 18:37:59 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2011-06-23 06:04:00 -0700 |
commit | 80422e24c8b2c134c9ee2ac7d87aa9f750192f20 (patch) | |
tree | e494feb847da892a228ffb382421b6cb854786a3 /pp_ctl.c | |
parent | 37395ff5f2b5fa17c5b7cebede056b6742e28e46 (diff) | |
download | perl-80422e24c8b2c134c9ee2ac7d87aa9f750192f20.tar.gz |
Copy PADTMPs explicitly returned from lv subs
I don’t believe this changes any observable behaviour, Devel::Peek
aside. If it does, it fixes bugs.
I am making this change for two reasons:
• PADTMPs can be a bit buggy and letting them escape their subroutines
can make the bugs harder to fix.
• This brings explicit and implicit return from lvalue subroutines one
step closer (for the sake of merging the code).
Diffstat (limited to 'pp_ctl.c')
-rw-r--r-- | pp_ctl.c | 7 |
1 files changed, 5 insertions, 2 deletions
@@ -2226,6 +2226,7 @@ STATIC void S_return_lvalues(pTHX_ SV **mark, SV **sp, SV **newsp, I32 gimme, PERL_CONTEXT *cx) { + const bool ref = !!(CxLVAL(cx) & OPpENTERSUB_INARGS); if (gimme == G_SCALAR) { if (MARK < SP) { if (cx->blk_sub.cv && CvDEPTH(cx->blk_sub.cv) > 1) { @@ -2260,12 +2261,14 @@ S_return_lvalues(pTHX_ SV **mark, SV **sp, SV **newsp, I32 gimme, } else if (gimme == G_ARRAY) { assert (!(CxLVAL(cx) & OPpENTERSUB_DEREF)); - if (!CxLVAL(cx) || CxLVAL(cx) & OPpENTERSUB_INARGS) + if (ref || !CxLVAL(cx)) while (++MARK <= SP) *++newsp = SvTEMP(*MARK) ? *MARK - : sv_2mortal(SvREFCNT_inc_simple_NN(*MARK)); + : ref && SvFLAGS(*MARK) & SVs_PADTMP + ? sv_mortalcopy(*MARK) + : sv_2mortal(SvREFCNT_inc_simple_NN(*MARK)); else while (++MARK <= SP) { *++newsp = *MARK; } |