This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Flatten vstrings modified in place
authorFather Chrysostomos <sprout@cpan.org>
Sat, 28 Jul 2012 06:46:07 +0000 (23:46 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 28 Jul 2012 06:46:33 +0000 (23:46 -0700)
commit4499db7385adf05fc8c5f6e28aa920d268b63435
treed44c8f9c0a2a84ccf98f701d09be2a67955ed1a9
parent5bbe7184a7198d6334733fd9eb3ca7db21bf04f2
Flatten vstrings modified in place

A substitution forces its target to a string upon successful substitu-
tion, even if the substitution did nothing:

$ ./perl -Ilib -le '$a = *f; $a =~ s/f/f/; print ref \$a'
SCALAR

Notice that $a is no longer a glob after s///.

But vstrings are different:

$ ./perl -Ilib -le '$a = v102; $a =~ s/f/f/; print ref \$a'
VSTRING

I fixed this in 5.16 (1e6bda93) for those cases where the vstring ends
up with a value that doesn’t correspond to the actual string:

$ ./perl -Ilib -le '$a = v102; $a =~ s/f/o/; print ref \$a'
SCALAR

It works through vstring set-magic, that does the check and removes
the magic if it doesn’t match.

I did it that way because I couldn’t think of any other way to fix
bug #29070, and I didn’t realise at the time that I hadn’t fixed
all the bugs.

By making SvTHINKFIRST true on a vstring, we force it through
sv_force_normal before any in-place string operations.  We can also
make sv_force_normal handle vstrings as well.  This fixes all the lin-
gering-vstring-magic bugs in just two lines, making the vstring set-
magic (which is also slow) redundant.  It also allows the special case
in sv_setsv_flags to be removed.

Or at least that was what I had hoped.

It turns out that pp_subst, twists and turns in tortuous ways, and
needs special treatment for things like this.

And do_trans functions wasn’t checking SvTHINKFIRST when arguably it
should have.

I tweaked sv_2pv{utf8,byte} to avoid copying magic variables that do
not need copying.
13 files changed:
doop.c
embed.fnc
embed.h
mg.c
mg_raw.h
mg_vtable.h
pod/perlguts.pod
pp_hot.c
proto.h
regen/mg_vtable.pl
sv.c
sv.h
t/op/ver.t