diff options
author | Father Chrysostomos <sprout@cpan.org> | 2012-01-04 23:28:54 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2012-01-04 23:54:59 -0800 |
commit | 6f48390ab209d16ee8f795f0a83677c8bd9ac69c (patch) | |
tree | 2fce76bff8a761818c80901e79ea952253f21173 /pp_hot.c | |
parent | b5ed8c445e54e524b4713aa7b79e2f5aa3ed19ef (diff) | |
download | perl-6f48390ab209d16ee8f795f0a83677c8bd9ac69c.tar.gz |
[perl #95548] Returned magical temps are not copied
return and leavesub, for speed, were not copying temp variables with a
refcount of 1, which is fine as long as the fact that it was not cop-
ied is not observable.
With magical variables, that *can* be observed, so we have to forego
the optimisation and copy the variable if it’s magical.
This obviously applies only to rvalue subs.
Diffstat (limited to 'pp_hot.c')
-rw-r--r-- | pp_hot.c | 9 |
1 files changed, 6 insertions, 3 deletions
@@ -2492,7 +2492,8 @@ PP(pp_leavesub) MARK = newsp + 1; if (MARK <= SP) { if (cx->blk_sub.cv && CvDEPTH(cx->blk_sub.cv) > 1) { - if (SvTEMP(TOPs) && SvREFCNT(TOPs) == 1) { + if (SvTEMP(TOPs) && SvREFCNT(TOPs) == 1 + && !SvMAGICAL(TOPs)) { *MARK = SvREFCNT_inc(TOPs); FREETMPS; sv_2mortal(*MARK); @@ -2504,7 +2505,8 @@ PP(pp_leavesub) SvREFCNT_dec(sv); } } - else if (SvTEMP(TOPs) && SvREFCNT(TOPs) == 1) { + else if (SvTEMP(TOPs) && SvREFCNT(TOPs) == 1 + && !SvMAGICAL(TOPs)) { *MARK = TOPs; } else @@ -2518,7 +2520,8 @@ PP(pp_leavesub) } else if (gimme == G_ARRAY) { for (MARK = newsp + 1; MARK <= SP; MARK++) { - if (!SvTEMP(*MARK) || SvREFCNT(*MARK) != 1) { + if (!SvTEMP(*MARK) || SvREFCNT(*MARK) != 1 + || SvMAGICAL(*MARK)) { *MARK = sv_mortalcopy(*MARK); TAINT_NOT; /* Each item is independent */ } |