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

Re: [perl #51370] Clearing magic (was: [#perl 51370] length($@)>0for empty $@ if utf8 is in use)

Thread Previous | Thread Next
From:
Bram
Date:
May 3, 2008 13:07
Subject:
Re: [perl #51370] Clearing magic (was: [#perl 51370] length($@)>0for empty $@ if utf8 is in use)
Message ID:
20080503220510.o436a8tog0k8kcsg@horde.wizbit.be
Quoting Nicholas Clark <nick@ccl4.org>:

>
> On Wed, Apr 30, 2008 at 01:36:40PM +0200, Bram wrote:
>> >> And: if it has to change everywhere then what would the best approach
>> >> be?
>> >> Placing it in a separate function? (If so, in what file, what
>> >> name, ...)
>>
>> My current plan:
>>
>> Adding Perl_sv_setpvn_clearmg in sv.c which basically contains:
>>   sv_setpvn(sv,ptr,len);
>>   if (SvMAGICAL(sv)) {
>>     mg_free(sv);
>>     mg_clear(sv);
>>   }
>>   SvPOK_only(sv);
>
> In general, are you sure you want that order? Wouldn't it be   
> conceptually more
> logical to free up any magic, then do the assignment to the SV?

I'm not sure about it at all...
Hence the questions. :)

>
> Also, your order mg_free() then mg_clear() is backwards, as mg_clear() will
> have to be a no-op this way round, because mg_free will have just freed all
> the magic.

Copy from an earlier:

if (flags & G_KEEPERR)
   PL_in_eval |= EVAL_KEEPERR;
else {
   sv_setpvn_mg(ERRSV,"",0);
   if (SvMAGICAL(ERRSV)) {
     mg_free(ERRSV);
   }
   SvPOK_only(ERRSV);
}


Output:

SV = PV(0x814e3c8) at 0x8150518
   REFCNT = 1
   FLAGS = (POK,pPOK)
   PV = 0x815cbe0 ""\0
   CUR = 0
   LEN = 240
SV = PVMG(0x815c8b0) at 0x8150518
   REFCNT = 1
   FLAGS = (SMG,POK,pPOK)
   IV = 0
   NV = 0
   PV = 0x815cbe0 ""\0
   CUR = 0
   LEN = 240


With the mg_clear added after the mg_free:

if (flags & G_KEEPERR)
   PL_in_eval |= EVAL_KEEPERR;
else {
   sv_setpvn_mg(ERRSV,"",0);
   if (SvMAGICAL(ERRSV)) {
     mg_free(ERRSV);
     mg_clear(ERRSV);
   }
   SvPOK_only(ERRSV);
}


SV = PV(0x814e3e8) at 0x8150538
   REFCNT = 1
   FLAGS = (POK,pPOK)
   PV = 0x815cc00 ""\0
   CUR = 0
   LEN = 240
SV = PVMG(0x815c8d0) at 0x8150538
   REFCNT = 1
   FLAGS = (POK,pPOK)
   IV = 0
   NV = 0
   PV = 0x815cc00 ""\0
   CUR = 0
   LEN = 240

Whichs shows that it is not a no-op (the SMG flag is gone).
Or would that be a bug in mg_clear?

>
>> Defining sv_setpvn_clearmg in embed.h
>> #define sv_setpvn_clearmg            Perl_sv_setpvn_clearmg
>>
>> Changing: sv_setpvn(ERRSV,"",0) into sv_setpvn_clearmg(ERRSV,"",0);
>
> How many of these are there to change?

There are 9.

> I don't feel that comfortable with adding another "class" macro of macro for
> that one particular operation, because it will start to feel like we need
> *_clearmg variants for everything other one. It seems better to find a tight
> way of doing something like the mg_clear() then mg_free() then SvOK(off)
> implied by the above, and replace sv_setpvn(ERRSV,"",0) with
> this_clearing_thing(ERRSV); sv_setpvn(ERRSV,"",0);

Suggestions for the name of this_clearing_thing?


>> Testing-A:
>>
>> eval { 1 };
>> eval { die "\x{a10d};"; }
>> $_ = length $@;
>> eval { 1 };
>> print "ok" if (not $@ and not length $@);
>
> Well, not literally that as there isn't ; after the second eval.
>
> But, um, that example is interesting:
>
> $ ./perl -e 'eval { 1 };  eval { die "\x{a10d};"; }; $_ = length $@;  
>  eval { 1 }; length $@'
> panic: sv_len_utf8 cache 17 real 0 for  at -e line 1.
>
> I don't have time to investigate *that* right now.
>

What version/revision is that? (It never happend with me.)

But note, this is what would be fixed by clearing the magic...
The problem is that length still uses the old utf8 length and not the new one.
So either a new panic was added for it or something else is different...


>> The $@ + 0 is needed because the Dump of the second eval always includes:
>>   IV = 0
>>   NV = 0
>>
>> Which the first does not. (Or is there another way to get rid of it?)
>
> Assign something that is PVMG to $@ before starting, to ensure that it has
> already been upgraded?
>
> $ perl -MDevel::Peek -e '$@ = $!; eval "die"; Dump $@'
> SV = PVMG(0x80ba60) at 0x800138
>   REFCNT = 1
>   FLAGS = (POK,pPOK)
>   IV = 0
>   NV = 0
>   PV = 0x201290 "Died at (eval 2) line 1.\n"\0
>   CUR = 25
>   LEN = 240
>
> It's a bit of a hack, but it feels less hacky than a bonus eval.

I see.

Kind regards,

Bram



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