summaryrefslogtreecommitdiff
path: root/pp_hot.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-01-04 23:28:54 -0800
committerFather Chrysostomos <sprout@cpan.org>2012-01-04 23:54:59 -0800
commit6f48390ab209d16ee8f795f0a83677c8bd9ac69c (patch)
tree2fce76bff8a761818c80901e79ea952253f21173 /pp_hot.c
parentb5ed8c445e54e524b4713aa7b79e2f5aa3ed19ef (diff)
downloadperl-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.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/pp_hot.c b/pp_hot.c
index cbdcb90f77..ec7674ea85 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -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 */
}