summaryrefslogtreecommitdiff
path: root/pp_hot.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2017-11-20 15:19:59 +0000
committerDavid Mitchell <davem@iabyn.com>2017-11-20 15:26:47 +0000
commit1a98acd9b14cfb3953d2b14eee2394454f92f0c8 (patch)
tree807379a5b20e24270946167bef8793d3027ada1e /pp_hot.c
parent326c4aeb76b24dfac855bc9662b5143d3a2dbdfe (diff)
downloadperl-1a98acd9b14cfb3953d2b14eee2394454f92f0c8.tar.gz
MULTICONCAT - use distinct TMPS for const overload
Because OP_MULTICONCAT optimises away any const SVs, they have to be recreated if a concat overload method is called. Up until now (for efficiency) the same SvTEMP was used to create each const TEMP. This caused problems if an overload method saved a ref to the argument. This is easily fixed by not reusing the TEMP (and the extra inefficiency is small compared to the overall burden of calling out to an overloaded method). With this patch, the following test code changes from getting "BB" to getting "AB": my @a; use overload '.' => sub { push @a, \$_[1]; $_[0] }; my $o = bless []; my $x = $o . "A" . $o . 'B'; is "${$a[0]}${$a[2]}", "AB", "RT #132385";
Diffstat (limited to 'pp_hot.c')
-rw-r--r--pp_hot.c15
1 files changed, 2 insertions, 13 deletions
diff --git a/pp_hot.c b/pp_hot.c
index 61f742f298..d1d02257ed 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1047,7 +1047,6 @@ PP(pp_multiconcat)
SV *left, *right, *res;
int i;
bool getmg = FALSE;
- SV *constsv = NULL;
/* number of args already concatted */
SSize_t n = (nargs - 1) - (toparg - SP);
/* current arg is either the first
@@ -1074,19 +1073,9 @@ PP(pp_multiconcat)
if ((SSize_t)len < 0)
continue;
- /* set constsv to the next constant string segment */
- if (constsv) {
- sv_setpvn(constsv, const_pv, len);
- if (dst_utf8)
- SvUTF8_on(constsv);
- else
- SvUTF8_off(constsv);
- }
- else
- constsv = newSVpvn_flags(const_pv, len,
+ /* set right to the next constant string segment */
+ right = newSVpvn_flags(const_pv, len,
(dst_utf8 | SVs_TEMP));
-
- right = constsv;
const_pv += len;
}
else {