develooper Front page | perl.perl5.porters | Postings from June 2012

Re: [PATCH] v4: fix blead usage of OK flags vs. all magic

Thread Previous | Thread Next
From:
Rev. Chip
Date:
June 12, 2012 16:02
Subject:
Re: [PATCH] v4: fix blead usage of OK flags vs. all magic
Message ID:
20120612230045.GA19470@tytlal.tinsaucer.com
On Tue, Jun 12, 2012 at 03:16:24PM +0100, Dave Mitchell wrote:
> On Mon, Jun 11, 2012 at 11:46:30PM -0700, Reverend Chip wrote:
> > Turns out Perl has been cheating.  (Surprised?  Sure.)
> 
> First, I think the two uses of the private flags appeared in the opposite
> order to what you're describing.  The use since 5.000-ish has always been
> related to get magic; the indication that an NV has been approximated as
> an IV etc is a much later overloading of the meaning of those flag bits,
> added around 2000 (see e.g. 28e5dec85047e189010079efa89eed07bc9eddc8).

That commit doesn't seem probative, but thinking about how 5.000 worked,
this explanation makes sense:

> As to the original magic-related meaning of the p flags, AFAIKT, this
> has always been used to indicate that the slot only has a temporarily-valid
> value; and that magic objects should never have the public flags set....

I can reason from there to why the patch is good.  Here is my theory as to
how the status quo came to be, putting myself into Larry's Brain:

 1. We want to force mg_get to be called on magical values, but we want
    macro speed for SvPV() et al.  Conveniently enough if SVf_POK is not
    set, we have to call sv_2pv, so let's just put the mg_get() in there.
    Easiest way to make that happen is for magic values never to have
    SVf_*OK set.

 2. After mg_get has been called, we still can't set SVf_*OK, or mg_get will
    never be called again.  But we need some way to figure out which slots
    were set by the magic get.  So let's introduce a separate set of flags
    that indicate valid slots.  Thus are born SVp_*OK.  e.g. SvPVX() is
    meaningful if SVp_POK is set.  The shifting dynamic is obvious.

 3. Muggle values also set SVp_*OK whenever setting SVf_*OK, so as to keep
    slot validity a single-bit test.

 4. To summarize:
      For magic,  SVp_*OK is meaningful and SVf_*OK is always clear.
      For muggle, SVp_*OK is a precise mirror of SVf_*OK.

This does work as far as it goes.  It uses three bits where one would do,
but it works.  And the redundancy is why there was some room to encode
cached muggle conversions somewhat later in development.

But even before 5.000 was released the whole scheme went to shit.  When
references were invented it all should have been revisited, because:

 5. There is no SVp_ROK.  Fail.

Thus, the scheme is bankrupt.  Once SVf_ROK was introduced without a
corresponding SVp_ROK, SvROK() could be true on both magic and muggle.  It
became absolutely required for every user of a value to call SvGETMAGIC()
manually or else magical references would not function correctly.  At this
point, the old plan for making sure magic values never had SVf_[PIN]OK lots
its rationale, but for some reason (probably lack of understanding) it was
never fixed.

The above is, IMO, a strong argument in favor of the conceptual integrity of
the magic flags patch.  There is no point in leaving Sv[PIN]OK clear on
magic values if SvROK is not clear.  Thus, in the patch, SvOK() is nto
consulted when deciding to call mg_get().  And while cleaning up this wart,
the patch also gives us us something we've long wanted: distinguishing
number-used-as-a-string from string-used-as-a-number.
-- 
Chip Salzenberg

Thread Previous | Thread Next


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