diff options
author | Paul "LeoNerd" Evans <leonerd@leonerd.org.uk> | 2021-08-07 14:46:48 +0100 |
---|---|---|
committer | Paul Evans <leonerd@leonerd.org.uk> | 2021-09-10 20:08:40 +0100 |
commit | 914bb57489325d34ddbb7c0557c53df7baa84d86 (patch) | |
tree | 71f2abe766af31e734c2f6e22b82df71bdcf4f12 /t | |
parent | 170944218d18492ce2141ac45166c62ec99ba1a7 (diff) | |
download | perl-914bb57489325d34ddbb7c0557c53df7baa84d86.tar.gz |
Define a third kind of COW state; STATIC
Previously, when IsCOW flag was set there were two cases:
SvLEN()==0:
PV is really a shared HEK
SvLEN()!=0:
PV is a COW structure with 1..256 refcount stored in its extra final byte
This change adds a third state:
SvLEN()==0 && SvFLAGS() & SVppv_STATIC:
PV is a shared static const pointer and must not be modified
sv_setsv_flags() and sv_setsv_cow() will preserve this state
sv_uncow() will copy it out to a regular string buffer
sv_dup() will preserve the static pointer into cloned threads
Diffstat (limited to 't')
-rw-r--r-- | t/op/bool.t | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/t/op/bool.t b/t/op/bool.t new file mode 100644 index 0000000000..21f6d3b7d5 --- /dev/null +++ b/t/op/bool.t @@ -0,0 +1,37 @@ +#!./perl + +BEGIN { + chdir 't' if -d 't'; + require './test.pl'; + set_up_inc('../lib'); +} + +use strict; +use warnings; + +my $truevar = (5 == 5); +my $falsevar = (5 == 6); + +cmp_ok($truevar, '==', 1); +cmp_ok($truevar, 'eq', "1"); + +cmp_ok($falsevar, '==', 0); +cmp_ok($falsevar, 'eq', ""); + +{ + # Check that boolean COW string buffer is safe to copy into new SVs and + # doesn't get corrupted by inplace mutations + my $x = $truevar; + $x =~ s/1/t/; + + cmp_ok($x, 'eq', "t"); + cmp_ok($truevar, 'eq', "1"); + + my $y = $truevar; + substr($y, 0, 1, "T"); + + cmp_ok($y, 'eq', "T"); + cmp_ok($truevar, 'eq', "1"); +} + +done_testing(); |