develooper Front page | perl.perl5.porters | Postings from May 2013

Re: [perl #116407] SvPVutf8 != SvPVX, and sv_2pvutf8

Thread Previous
From:
Dave Mitchell
Date:
May 22, 2013 18:36
Subject:
Re: [perl #116407] SvPVutf8 != SvPVX, and sv_2pvutf8
Message ID:
20130522145936.GU2069@iabyn.com
On Fri, May 17, 2013 at 03:14:16PM +0100, Dave Mitchell wrote:
> It won't be in time for perl 5.18.0 now, but in terms of what we need to add
> to perlguts, my feeling is that the general outline should be something
> like the following.

No-ones provided any feedback yet, but I think I've already spotted an
error in my own text:

> I'm happy to be corrected however; this isn't an
> area I work with much. In particular, I'm not sure whether we need to
> mention SV_CHECK_THINKFIRST/SvTHINKFIRST/sv_force_normal_flags(), SvIsCOW
> etc?
> 
>     Given an arbitrary SV,
> 
>     1) if you want to *read* its string value
[snip]
>     As a shortcut, if you've already done any get magic processing that was
>     required, and if the SV is SvPOK, then its okay to use SvCUR and to
>     directly read from the SvPVX buffer.

I still think that's true
> 
>     2) If you want to *modify* the string value of an SV by writing into its
>     string buffer
[snip]
>     As a shortcut, if you've already done any get magic processing that was
>     required, and if the SV is SvPOK, then its okay to use SvCUR and to
>     directly read from and write to the SvPVX buffer, and to use SvGROW()
>     if you want to write beyond the end of the string. You'll still need
>     to call SvSETMAGIC afterwards.

I don't think that's true. COW vars have SvPOK set, but you still
shouldn't directly write to them. This has always been true, since it used
to apply to shared-hash keys as well: although we've changed in it in 5.18
so that the RO flag is no longer set:

    $ perl5163 -MDevel::Peek -e '%h=qw(a 1); Dump $_ for keys %h'
    SV = PV(0xd0c140) at 0xd0dfe0
      REFCNT = 2
      FLAGS = (POK,FAKE,READONLY,pPOK)
      PV = 0xd244d0 "a"
      CUR = 1
      LEN = 0
    $ perl5180 -MDevel::Peek -e '%h=qw(a 1); Dump $_ for keys %h'
    SV = PV(0x19a9e30) at 0x19a91c0
      REFCNT = 2
      FLAGS = (POK,IsCOW,pPOK)
      PV = 0x19c0250 "a"
      CUR = 1
      LEN = 0

So, I *suspect* that the correct answer is that if POK is set, you still
need to test SvTHINKFIRST() (rather than SvREADONLY()) ,then call
sv_force_normal() or similar (or use SV_CHECK_THINKFIRST or
SV_CHECK_THINKFIRST_COW_DROP), although frankly this is where I start to
get confused and become unclear exactly what we should be recommending to
XS writers.

-- 
If life gives you lemons, you'll probably develop a citric acid allergy.

Thread Previous


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About