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

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

Thread Previous | Thread Next
From:
Nicholas Clark
Date:
May 3, 2008 11:28
Subject:
Re: [perl #51370] Clearing magic (was: [#perl 51370] length($@)>0 for empty $@ if utf8 is in use)
Message ID:
20080503171938.GP84051@plum.flirble.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?

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.
 
> 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?

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);

> 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.

> 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.

Nicholas Clark

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