develooper Front page | perl.perl5.porters | Postings from February 2004

Re: [possible PATCH] (was: Returning a typeglob from FETCH a tied hash - broken as of 5.8.1)

Thread Previous | Thread Next
Tassilo von Parseval
February 13, 2004 02:26
Re: [possible PATCH] (was: Returning a typeglob from FETCH a tied hash - broken as of 5.8.1)
Message ID:
On Tue, Feb 10, 2004 at 08:16:07PM +0000 Dave Mitchell wrote:

> On Tue, Feb 10, 2004 at 08:47:45PM +0100, Rafael Garcia-Suarez wrote:
> > Also sprach Tassilo :
> > > The attached patch against blead (actually against @22297) should again
> > > allow to assign a GLOB to a an element of a tied hash or array. There
> > > are several ways of fixing it and I am not sure mine is the best.
> > > 
> > > Since a SVt_PVLV thing cannot be upgraded to hold a GV, there had to be
> > > another way to squeeze the glob into the tied thingy. My patch abuses
> > > the PV slot for that. Later, in Perl_magic_setpack where the STORE is
> > > triggered, it checks whether the PV slot is non-NULL and whether it
> > > contains a GV. The test for a proper GV had to be added since there
> > > appear to be cases in which the PV slot holds an HV (and possibly other
> > > things; I couldn't find out where these assignments happen). In this
> > > case, there was no glob-assignment and the whole scalar can be passed as
> > > is to S_magic_methcall.
> > 
> > Scary. Have you tried to trace what the LvTYPE is ? Have you tried to
> > add a new LvTYPE for your hacked GV/PVLV ? This would probably be
> > cleaner.
> > 
> > > This is not a very clean way of doing it. A more thorough approach
> > > would be introducing a new type that is large enough to hold the magic
> > > plus anything that was assigned. This would have required some
> > > significant changes to the core so I took the other route.
> > 
> > I'd not withdraw this a priori. Do not trade maintainability for thrift :)
> > (I don't consider your patch to be applicable as-is.)
> I think the only sane solution is to expand the PVLV structure so that
> it can incorporate all the fields of a  PVGV. This is because LVs can
> have an extended lifetime and may get assigned to on several occasions.
> For example in the folowing:
>     sub f { $_[0] = 1; $_[0] = "a"; $_[0] = *FOO }
>     my %h; f($h{foo});
> $_[0] is an LV, and it gets assigned to (and its set magic called) three
> times. In this case, the set magic causes the current contents of
> $_[0] to be copied to $f{foo}.
> A similar thing happens if %h happens to be tied.
> At the moment the above code fails with the same
> cant-upgrade-an-LV-to-a-GV error.
> By making an LV struct a superset of GV, we *can* then do the upgrade.
> Of course this breaks bincompat.

I think it breaks it only in a very subtle manner (although subtle might
already be enough to call it a breaking). I just did expand XPVLV to
contain the five additionals xgv_ fields from an XPVGV. The only two
modules I had to change were B (it relies on the ordering of 'svtype' in
sv.h) and Devel::Peek. Those are modules that deal with the internals of
perl so breaking them looks tolerable.

The others should remain compatible as I understand it.

Anyway, please review the attached patch (I hope I didn't forget any
patched file; so it's not to be applied yet). It finally allows

    $_[0] = *FOO;

and thus also fixes the issues with tied variables en-passant. The
problem I see with it is that things such as

    if (SvTYPE(sv) <= SVt_PVLV) {
        SvPVX(sv) = ...;

can break because now an XPVAV and XPVHV are also smaller than an XPVLV
but don't contain an IV or PV slot. That means there are some new
special cases that need to be dealt with thusly (see the new dump.c for

    if (SvTYPE(sv) <= SVt_PVLV 
        && SvTYPE(sv) != SVt_PVAV 
        && SvTYPE(sv) != SVt_PVHV) 


Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About