Front page | perl.perl5.porters |
Postings from December 2014
[perl #36051] LVALUE magic should know how to assign to globs
Thread Next
From:
Father Chrysostomos via RT
Date:
December 30, 2014 05:59
Subject:
[perl #36051] LVALUE magic should know how to assign to globs
Message ID:
rt-4.0.18-17024-1419919166-1495.36051-15-0@perl.org
On Mon Dec 29 19:59:35 2014, bulk88 wrote:
> On Mon Dec 29 14:41:37 2014, sprout wrote:
> > On Mon Dec 29 13:57:37 2014, bulk88 wrote:
> > > I am currently rewriting Perl_gv_add_by_type but I see something
> > > strange
> > > in the existing code.
> > >
> > > http://perl5.git.perl.org/perl.git/commitdiff/13be902cef8b01c085a6b8b1b59fa2754a10cdfb
> > > https://rt.perl.org/Ticket/Display.html?id=77362
> > >
> > > So what is the sv_u of a PVLV? Why would a LV have a GP ptr?
> >
> > If you assign a typeglob to a deferred element or to an element of a
> > tied aggregate, then you get a PVLV that is a typeglob.
>
> Wouldn't that cause a "Bizzare copy of" panic later, since aggregate
> slices are scalars (you can only place a RV to an aggregate in a
> aggregate slice)?
I don’t follow.
This is what I am talking about:
use Devel::Peek;
sub { $_[0] = *foo; Dump $_[0] }->($h{nonexistent_elem});
>
> -------------------------------------------------------------------
> C:\>perl -MDevel::Peek=Dump -E"my $s = ' '; Dump($s); $s = *ARGV::;
> Dump($s); $s
> ='h'; Dump($s)"
> SV = PV(0x369a0c) at 0x8fbebc
> REFCNT = 1
> FLAGS = (POK,IsCOW,pPOK)
> PV = 0x90667c " "\0
> CUR = 1
> LEN = 10
> COW_REFCNT = 1
> SV = PVGV(0x9010a4) at 0x8fbebc
> REFCNT = 1
> FLAGS = (FAKE,MULTI)
> NAME = "ARGV::"
> NAMELEN = 6
> GvSTASH = 0x368bbc "main"
> FLAGS = 0x2
> GP = 0x9084cc
> SV = 0x0
> REFCNT = 2
> IO = 0x0
> FORM = 0x0
> AV = 0x0
> HV = 0x8fbe8c
> CV = 0x0
> CVGEN = 0x0
> GPFLAGS = 0x0 ()
> LINE = 1
> FILE = "-e"
> EGV = 0x368d5c "ARGV::"
> SV = PVMG(0x8f453c) at 0x8fbebc
> REFCNT = 1
> FLAGS = (POK,IsCOW,pPOK)
> IV = 9463952
> NV = 0
> PV = 0x91ad74 "h"\0
> CUR = 1
> LEN = 10
> COW_REFCNT = 1
>
> C:\>
> ---------------------------------------------------------
>
> This is breaking the rule you can't downgrade an SV.
I have heard of that rule before, but I don’t remember the source. I think it I read it in illguts. But it’s actually not true, and never was.
http://perl5.git.perl.org/perl.git/blob/perl-5.000:/sv.c#l3170
> Also this doesnt SEGVs since sv_upgrade leaves the PVX buffer of a PV
> intact, sv_clear falls through from case SVt_PVGV" to the regular PV
> type, and there is no SEGV clearing the GP since this half GV fails
> isGV_with_GP(sv). I know Perl_gv_init_pvn does black magic to make
> sv_upgrade(sv, SVt_PVGV); safe.
>
> void t3()
> PREINIT:
> volatile SV* sv;
> int i;
> PPCODE:
> for(i =0; i < 40000000; i++) {
> sv = newSVpvn("camel", 5);
> sv_upgrade(sv, SVt_PVGV);
> //sv_dump(GvSVn((GV*)sv)); /* crash */
> SvREFCNT_dec_NN(sv);
> }
>
> But here I defeated all the logic and made a leak
This part of the core is a bit confusing. You see, scalars with BM magic used to be of type SVt_PVGV, but were later changed to SVt_PVMG. Some parts of the core still account for the latter, but others expect SVt_PVGV always to be a genuine GV with GP.
> void t4()
> PREINIT:
> volatile SV* sv;
> int i;
> PPCODE:
>
> for(i =0; i < 400000000; i++) {
> sv = gv_fetchpv("camelpack", GV_ADD, SVt_PVAV);
> sv_setpvn(sv, "\x00\x00\x00\x00\x00\x00\x00\x00"
> "\x00\x00\x00\x00\x00\x00\x00\x00"
> "\x00\x00\x00\x00\x00\x00\x00\x00"
> "\x00\x00\x00\x00\x00\x00\x00\x00"
> "\x00\x00\x00\x00\x00\x00\x00\x00"
> "\x00\x00\x00\x00\x00\x00\x00\x00"
> "\x00\x00\x00\x00\x00\x00\x00\x00"
> "\x00\x00\x00\x00\x00\x00\x00\x00"
> "\x00\x00\x00\x00\x00\x00\x00\x00"
> "\x00\x00\x00\x00\x00\x00\x00\x00"
> "\x00\x00\x00\x00\x00\x00\x00\x00", sizeof(GP));
> }
Ouch. That should probably croak or fail an assertion.
> >
> > > I thought
> > > the sv_u of a PVLV was a PV buffer.
> >
> > The sv_u of a PVLV may differ just as much as the sv_u of a PVMG. It
> > can hold an SV pointer if you assigned a reference to a PVLV.
> >
> > Actually, it can differ more. A PVLV can also be a REGEXP thingy
> > (with sv_u pointing to the regexp struct) even though the internal
> > type is SVt_PVLV, not SVt_REGEXP. This is because PVLV needs to be
> > able to hold any type of scalar.
>
> You said scalar. GV/HV/AV are aggregates.
GV is also a type of scalar. (This goes back at least to perl 5.) You can bind the $ sigil to any typeglob.
use Devel::Peek;
foreach (*foo) { $_ = \&bar; Dump $_ }
A typeglob created by assignment ($_ = *foo) is coercible.
Yes, this is a design flaw.
> I recently encountered "$v =
> int(${qr||});" in the test suite so I know regexps are scalars.
>
> >
> > > I have some old XS code to
> > > de-magic/vivify a hash slice, since otherwise I need to croak.
> > >
> > > if (SvREADONLY(buffer)) {
> > > croak(PL_no_modify);
> > > }
> > > if(SvTYPE(buffer) == SVt_PVLV && LvTYPE(buffer) == 'y'){
> > > sv_setpv_mg(buffer, " ");
> > > if(LvTARG(buffer)) buffer = LvTARG(buffer);
> > > }
> > > if (SvMAGICAL(buffer)) {
> > > DumpSV(buffer);
> > > croak("%s: magic scalar as buffer not supported.", cvname);
> > > }
> >
> > I am confused as to why that code would be affected by the sv_u field
> > of a PVLV.
>
> Wouldn't sv_setpv_mg(buffer, " ") leak or croak panic if its done on a
> GV, AV or HV, or my "LvTYPE(buffer) == 'y'" guarantees the PVLV is a
> scalar type? I already have 1 memleak above.
That it is an SVt_PVLV guarantees it is a scalar. When a PVLV is a GV, it should always be of the coercible type.
Hmmm.
use experimental 'refaliasing';
\$::{foo} = \substr $_, 1;
*{"foo"};
Oh no. I don’t want to think about that.
--
Father Chrysostomos
---
via perlbug: queue: perl5 status: resolved
https://rt.perl.org/Ticket/Display.html?id=36051
Thread Next