diff options
author | David Mitchell <davem@iabyn.com> | 2017-11-20 15:19:59 +0000 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2017-11-20 15:26:47 +0000 |
commit | 1a98acd9b14cfb3953d2b14eee2394454f92f0c8 (patch) | |
tree | 807379a5b20e24270946167bef8793d3027ada1e /pp_hot.c | |
parent | 326c4aeb76b24dfac855bc9662b5143d3a2dbdfe (diff) | |
download | perl-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.c | 15 |
1 files changed, 2 insertions, 13 deletions
@@ -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 { |