Front page | perl.perl5.porters |
Postings from April 2008
[perl #51370] Clearing magic (was: [#perl 51370] length($@)>0 for empty $@ if utf8 is in use)
Thread Next
From:
Animator via RT
Date:
April 27, 2008 05:30
Subject:
[perl #51370] Clearing magic (was: [#perl 51370] length($@)>0 for empty $@ if utf8 is in use)
Message ID:
rt-3.6.HEAD-23612-1209217552-38.51370-15-0@perl.org
On Mon Mar 03 06:41:54 2008, pajas@ufal.mff.cuni.cz wrote:
> Perl seems to cache character length of scalars, but in case of $@
> it does not reset it after a successfull eval. Here is an example.
>
> ...
Hello,
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);
}
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?
And: should this be changed in every place where sv_setpvn(ERRSV,"",0)
is used?
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)
Kind regards,
Bram
Thread Next
-
[perl #51370] Clearing magic (was: [#perl 51370] length($@)>0 for empty $@ if utf8 is in use)
by Animator via RT