In perl.git, the branch sprout/rocox has been updated <http://perl5.git.perl.org/perl.git/commitdiff/6d71bec0094bf85d21f58e8047ee2c8b7548f664?hp=df46ed3e692736c8c628dc33561b3de46221eb65>
- Log ----------------------------------------------------------------- commit 6d71bec0094bf85d21f58e8047ee2c8b7548f664 Author: Father Chrysostomos <[email protected]> Date: Sat Dec 28 06:06:27 2013 -0800 COW documentation plus read-only documentation, since hysterically the two are intertwined. M pod/perlguts.pod M sv.c commit 75ec6c329d2b866115b168013c2268af044f12f6 Author: Father Chrysostomos <[email protected]> Date: Thu Dec 12 15:26:01 2013 -0800 XS::APItest: Flatten src for utf16_to_utf8_reversed utf16_to_utf8_reversed (the C function) modifies its input, so the XS function of the same name should flatten the input to avoid modifying shared buffers. Brought to you by PERL_DEBUG_READONLY_COW. M ext/XS-APItest/APItest.xs ----------------------------------------------------------------------- Summary of changes: ext/XS-APItest/APItest.xs | 1 + pod/perlguts.pod | 48 +++++++++++++++++++++++++++++++++++++++++++++++ sv.c | 4 ++++ 3 files changed, 53 insertions(+) diff --git a/ext/XS-APItest/APItest.xs b/ext/XS-APItest/APItest.xs index f877047..f2021ce 100644 --- a/ext/XS-APItest/APItest.xs +++ b/ext/XS-APItest/APItest.xs @@ -2402,6 +2402,7 @@ utf16_to_utf8 (sv, ...) SV *dest; I32 got; /* Gah, badly thought out APIs */ CODE: + if (ix) (void)SvPV_force(sv); source = (U8 *)SvPVbyte(sv, len); /* Optionally only convert part of the buffer. */ if (items > 1) { diff --git a/pod/perlguts.pod b/pod/perlguts.pod index 70b9187..0afda17 100644 --- a/pod/perlguts.pod +++ b/pod/perlguts.pod @@ -908,6 +908,54 @@ following code: If the order of C<sv_setiv> and C<sv_setpv> had been reversed, then the macro C<SvPOK_on> would need to be called instead of C<SvIOK_on>. +=head2 Read-Only Values + +In Perl 5.16 and earlier, copy-on-write (see the next section) shared a +flag bit with read-only scalars. So the only way to test whether +C<sv_setsv>, etc., will raise a "Modification of a read-only value" error +in those versions is: + + SvREADONLY(sv) && !SvIsCOW(sv) + +Under Perl 5.18 and later, SvREADONLY only applies to read-only variables, +and, under 5.20, copy-on-write scalars can also be read-only, so the above +check is incorrect. You just want: + + SvREADONLY(sv) + +If you need to do this check often, define your own macro like this: + + #if PERL_VERSION >= 18 + # define SvTRULYREADONLY(sv) SvREADONLY(sv) + #else + # define SvTRULYREADONLY(sv) (SvREADONLY(sv) && !SvIsCOW(sv)) + #endif + +=head2 Copy on Write + +Perl implements a copy-on-write (COW) mechanism for scalars, in which +string copies are not immediately made when requested, but are deferred +until made necessary by one or the other scalar changing. This is mostly +transparent, but one must take care not to modify string buffers that are +shared by multiple SVs. + +You can test whether an SV is using copy-on-write with C<SvIsCOW(sv)>. + +You can force an SV to make its own copy of its string buffer by calling C<sv_force_normal(sv)> or SvPV_force_nolen(sv). + +If you want to make the SV drop its string buffer, use +C<sv_force_normal_flags(sv, SV_COW_DROP_PV)> or simply +C<sv_setsv(sv, NULL)>. + +All of these functions will croak on read-only scalars (see the previous +section for more on those). + +To test that your code is behaving correctly and not modifying COW buffers, +on systems that support L<mmap(2)> (i.e., Unix) you can configure perl with +C<-Accflags=-DPERL_DEBUG_READONLY_COW> and it will turn buffer violations +into crashes. You will find it to be marvellously slow, so you may want to +skip perl's own tests. + =head2 Magic Variables [This section still under construction. Ignore everything here. Post no diff --git a/sv.c b/sv.c index 18d7098..3d4a3d2 100644 --- a/sv.c +++ b/sv.c @@ -4951,6 +4951,10 @@ the C<flags> parameter gets passed to C<sv_unref_flags()> when unreffing. C<sv_force_normal> calls this function with flags set to 0. +This function is expected to be used to signal to perl that this SV is +about to be written to, and any extra book-keeping needs to be taken care +of. Hence, it croaks on read-only values. + =cut */ -- Perl5 Master Repository
