Front page | perl.perl5.porters |
Postings from July 2012
Re: [perl.git] branch doy/runtime_isa_manipulation_bug, created.v5.17.1-337-gbd8c24f
Thread Previous
|
Thread Next
From:
Jesse Luehrs
Date:
July 9, 2012 22:40
Subject:
Re: [perl.git] branch doy/runtime_isa_manipulation_bug, created.v5.17.1-337-gbd8c24f
Message ID:
20120710054017.GQ30375@tozt.net
On Tue, Jul 10, 2012 at 05:05:45AM -0000, Father Chrysostomos wrote:
> Jesse Luehrs "wrote":
> > In perl.git, the branch doy/runtime_isa_manipulation_bug has been created
> >
> > <http://perl5.git.perl.org/perl.git/commitdiff/bd8c24fc226ff85a7dd42547f065b628d320d104?hp=0000000000000000000000000000000000000000>
> >
> > at bd8c24fc226ff85a7dd42547f065b628d320d104 (commit)
> >
> > - Log -----------------------------------------------------------------
> > commit bd8c24fc226ff85a7dd42547f065b628d320d104
> > Author: Jesse Luehrs <doy@tozt.net>
> > Date: Mon Jul 9 18:05:32 2012 -0500
> >
> > test for runtime @ISA manipulation bug
> > -----------------------------------------------------------------------
> >
> > --
> > Perl5 Master Repository
>
> There is a reason why perlmod.pod says this:
>
> The results of creating new symbol table entries directly or modifying
> any entries that are not already typeglobs are undefined and subject to
> change between releases of perl.
>
> Every GV that is an element of a stash must have its GvSTASH pointing
> to the stash itself, and must reside in the element with the same real
> name (GvNAME(gv), as opposed to GvENAME(gv), which is used in string-
> ification) as the GV itself. Anything else is madness.
I'm fine with this. My question is - how do you do this from perl space,
if you don't know the name of the stash (as in, you just have the
hashref)? I had been using Symbol::gensym in my code to generate new
stash entries, but that's clearly wrong, because they have the wrong
name. So... how do they get the right name? (If this isn't currently
possible, should Symbol be rewritten with some XS to allow for doing
the right thing?)
> If those
> assumptions were to stop being true, then GVs would have to carry
> lists of stashes and element names to which they belong (so that
> *ISA = [] would call mro_isa_changed_in on all the stashes to which
> *ISA could belong). And generating that information could not be done efficiently, because all stash elements returned to Perl space would
> have to be magical, and then we end up with strange interactions with
> other parts of the internals. I actually tried making that work at
> one point, but came to know the error of my ways.
Yes, this is what I was starting to find. I had tracked the issue down
to glob creation in a new stash slot, but it wasn't really clear where
to go from there in terms of fixing it (should storing a glob in the ISA
entry of any hash at all involve copying magic over? that seems wrong).
> If you are trying to create new stash elements without going through
> gv lookup, gv_init* is an API function that provides a workaround.
> perlapi.pod says (guess who wrote it):
>
> =item gv_init
> X<gv_init>
>
> The old form of gv_init_pvn(). It does not work with UTF8 strings, as it
> has no flags parameter. If the C<multi> parameter is set, the
> GV_ADDMULTI flag will be passed to gv_init_pvn().
>
> voidgv_init(GV* gv, HV* stash, const char* name,
> voidgv_init(GV* gv, HV* stash, const char* name, STRLEN len, int multi)
>
> ...
>
> =item gv_init_pvn
> X<gv_init_pvn>
>
> Converts a scalar into a typeglob. This is an incoercible typeglob;
> assigning a reference to it will assign to one of its slots, instead of
> overwriting it as happens with typeglobs created by SvSetSV. Converting
> any scalar that is SvOK() may produce unpredictable results and is reserved
> for perl's internal use.
>
> C<gv> is the scalar to be converted.
>
> C<stash> is the parent stash/package, if any.
>
> C<name> and C<len> give the name. The name must be unqualified;
> that is, it must not include the package name. If C<gv> is a
> stash element, it is the caller's responsibility to ensure that the name
> passed to this function matches the name of the element. If it does not
> match, perl's internal bookkeeping will get out of sync.
>
> C<flags> can be set to SVf_UTF8 if C<name> is a UTF8 string, or
> the return value of SvUTF8(sv). It can also take the
> GV_ADDMULTI flag, which means to pretend that the GV has been
> seen before (i.e., suppress "Used once" warnings).
>
> voidgv_init(GV* gv, HV* stash, const char* name, STRLEN len, int multi)gv_init_pvn(GV* gv, HV* stash, const char* name,
> voidgv_init(GV* gv, HV* stash, const char* name, STRLEN len, int multi)gv_init_pvn(GV* gv, HV* stash, const char* name, STRLEN len, U32 flags)
Yes, the XS version of the code already does this. This is not without
its (serious) issues though... the entire API for manipulating stashes
and typeglobs is a pretty huge mess. Every time I start working with it,
I remember how much I want to just rewrite the whole thing, but I
haven't quite wrapped my head around it quite enough to do that. Maybe
I'll get around to it one of these days.
-doy
Thread Previous
|
Thread Next