This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
eval"" should reset %^H in more cases
This is scary:
#use sort 'stable';
require re; re->import('/x');
eval '
print "a b" =~ /a b/ ? "ok\n" : "nokay\n";
use re "/m";
print "a b" =~ /a b/ ? "ok\n" : "nokay\n";
';
It prints:
ok
nokay
The re->import statement is supposed to apply to the caller that
is currently being compiled, but it makes ‘use re "/m"’ enable
/x as well.
Uncomment the ‘use sort’ line, and you get:
ok
ok
which is even scarier.
eval"" is supposed to compile its argument with the hints under which
the eval itself was compiled.
Whenever %^H is modified, a flag (HINT_LOCALIZE_HH; LHH hereinafter)
is set in $^H.
When eval is called, it checks the LHH flag in the hints from the time
it was compiled, to determine whether to reset %^H. If LHH is set,
it creates a new %^H based on the hints under which it was compiled.
Otherwise, it just leaves %^H alone.
The problem is that %^H and LHH may be set some time later
(re->import), so when the eval runs there is junk in %^H that
does not apply to the contents of the eval.
There are two layers at which the hints hash is stored. There is the
Perl-level hash, %^H, and then there is a faster cop-hints-hash struc-
ture underneath. It’s the latter that is actually used during compi-
lation. %^H is just a Perl front-end to it.
When eval does not reset %^H and %^H has junk in it, the two get
out of sync, because eval always sets the cop-hints-hash correctly.
Hence the first print in the first example above compiles without
‘use re "/x"’. The ‘use re’ statement after it modifies the %^H-with-
junk-in-it, which then gets synchronised with the cop-hints-hash,
turning on /x for the next print statement.
Adding ‘use sort’ to the top of the program makes the problem go
away, because, since sort.pm uses %^H, LHH is set when eval() itself
is compiled.
This commit fixes this by having pp_entereval check not only the LHH
flag from the hints under which it was compiled, but also the hints of
the currently compiling code ($^H / PL_hints).