Front page | perl.perl5.porters |
Postings from April 2008
Re: [perl #51370] Clearing magic (was: [#perl 51370] length($@)>0 for empty $@ if utf8 is in use)
Thread Previous
|
Thread Next
From:
Rafael Garcia-Suarez
Date:
April 27, 2008 14:38
Subject:
Re: [perl #51370] Clearing magic (was: [#perl 51370] length($@)>0 for empty $@ if utf8 is in use)
Message ID:
b77c1dce0804271438r39964095mfcc5c196d31b9cae@mail.gmail.com
2008/4/26 Animator via RT <perlbug-followup@perl.org>:
> I took a look at this bug-report and the magic assoicated with $@ does
> not get cleared.
>
> I did some testing on how to turn it off but I'm not sure what 'the
> correct way' is. (Therefor there is no patch)
> Can someone offer some guidance?
>
>
> The test case:
>
> #!/usr/bin/perl -l
>
> use utf8;
> use Devel::Peek
> eval { 1 };
> Dump($@);
> eval { die "\x{a10d}"};
> $_ = length $@;
> eval { 1 };
> Dump($@);
>
>
> The current output (on blead):
>
> SV = PV(0x8130f04) at 0x812ffd8
> REFCNT = 1
> FLAGS = (POK,pPOK)
> PV = 0x813d8d0 ""\0
> CUR = 0
> LEN = 240
> SV = PVMG(0x813d390) at 0x812ffd8
> REFCNT = 1
> FLAGS = (SMG,POK,pPOK,UTF8)
> IV = 0
> NV = 0
> PV = 0x813d8d0 ""\0 [UTF8 ""]
> CUR = 0
> LEN = 240
> MAGIC = 0x8145e38
> MG_VIRTUAL = &PL_vtbl_utf8
> MG_TYPE = PERL_MAGIC_utf8(w)
> MG_LEN = 23
>
> Which shows that the flags SMG and UTF8 are (still) set and the
> IV,NV,MAGIC is also set.
>
>
>
> In pp_ctl.c, Perl_create_eval_scope I modified this code:
>
> if (flags & G_KEEPERR)
> PL_in_eval |= EVAL_KEEPERR;
> else
> sv_setpvn_mg(ERRSV,"",0);
>
> Into:
>
> if (flags & G_KEEPERR)
> PL_in_eval |= EVAL_KEEPERR;
> else {
> sv_setpvn_mg(ERRSV,"",0);
> }
The first one should be sv_setpvn actually.
> Which turned the output into:
>
> SV = PV(0x814e3a8) at 0x81504f8
> REFCNT = 1
> FLAGS = (POK,pPOK)
> PV = 0x815cbc0 ""\0
> CUR = 0
> LEN = 240
> SV = PVMG(0x815c870) at 0x81504d8
> REFCNT = 1
> FLAGS = (SMG,POK,pPOK,UTF8)
> IV = 0
> NV = 0
> PV = 0x815cba0 ""\0 [UTF8 ""]
> CUR = 0
> LEN = 240
> MAGIC = 0x8167638
> MG_VIRTUAL = &PL_vtbl_utf8
> MG_TYPE = PERL_MAGIC_utf8(w)
> MG_LEN = -1
>
>
> Which makes the length 0 but it stil lhas all the extra flags attached
> to it.
>
>
> Next: I changed it into
>
> if (flags & G_KEEPERR)
> PL_in_eval |= EVAL_KEEPERR;
> else {
> sv_setpvn_mg(ERRSV,"",0);
> if (SvMAGICAL(ERRSV)) {
> mg_clear(ERRSV);
> }
> }
>
> Output:
>
> SV = PV(0x814e3a8) at 0x81504f8
> REFCNT = 1
> FLAGS = (POK,pPOK)
> PV = 0x815cbc0 ""\0
> CUR = 0
> LEN = 240
> SV = PVMG(0x815c890) at 0x81504f8
> REFCNT = 1
> FLAGS = (SMG,POK,pPOK,UTF8)
> IV = 0
> NV = 0
> PV = 0x815cbc0 ""\0 [UTF8 ""]
> CUR = 0
> LEN = 240
> MAGIC = 0x8167658
> MG_VIRTUAL = &PL_vtbl_utf8
> MG_TYPE = PERL_MAGIC_utf8(w)
> MG_LEN = -1
>
>
> Which is the same as the previous output.
>
>
>
> Next:
>
> if (flags & G_KEEPERR)
> PL_in_eval |= EVAL_KEEPERR;
> else {
> sv_setpvn_mg(ERRSV,"",0);
> if (SvMAGICAL(ERRSV)) {
> mg_free(ERRSV);
> }
> }
>
> Output:
>
> SV = PV(0x814e3a8) at 0x81504f8
> REFCNT = 1
> FLAGS = (POK,pPOK)
> PV = 0x815cbc0 ""\0
> CUR = 0
> LEN = 240
> SV = PVMG(0x815c890) at 0x81504f8
> REFCNT = 1
> FLAGS = (SMG,POK,pPOK,UTF8)
> IV = 0
> NV = 0
> PV = 0x815cbc0 ""\0 [UTF8 ""]
> CUR = 0
> LEN = 240
>
>
> Now the MAGIC is gone, but the UTF8 and the flags are still set.
>
>
>
> Next:
>
> 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
>
>
> Now the MAGIC and the UTF8 are gone but the SMG flag is still there.
>
>
>
> Next:
>
> 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);
> }
>
>
> Output:
>
> 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
>
> The MAGIC is gone, the UTF8 is gone, the SMG flag is gone.
>
>
> Next: (back to sv_setpvn instead of sv_setpvn_mg)
>
> if (flags & G_KEEPERR)
> PL_in_eval |= EVAL_KEEPERR;
> else {
> sv_setpvn(ERRSV,"",0);
> if (SvMAGICAL(ERRSV)) {
> mg_free(ERRSV);
> mg_clear(ERRSV);
> }
> SvPOK_only(ERRSV);
> }
>
>
> Output:
>
> 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
>
>
> So, is this the correct way?
Might be correct. Do all tests pass including the new ones you'll
probably have written for this bug ? :)
However there might be a more concise way to achieve more or less the
same thing, maybe along the macro SvPVbyte_force or another similar one
(sorry, I always have to check the code when I dabble in the SV
internals, this is not the part of the core I know the most.)
> And: should this be changed in every place where sv_setpvn(ERRSV,"",0)
> is used?
Probably, yes.
> grep -r 'sv_setpvn(ERRSV,"",0);' * # shows that it is used in 9 other
> places
>
>
> 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, ...)
>
>
> (If I know the correct way I'll create a patch with a test case for it)
Thread Previous
|
Thread Next