diff options
author | David Mitchell <davem@iabyn.com> | 2011-07-16 11:45:53 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2011-07-16 12:13:14 +0100 |
commit | 9e103e2695edf4f2a3c0c3d8a12299ebcd30e37a (patch) | |
tree | d53a947864d09d06ea4c890cfaaa2b19809d1f25 /t/re | |
parent | 3347919d89133da6b41c1c3c5d0e06b063ad4e82 (diff) | |
download | perl-9e103e2695edf4f2a3c0c3d8a12299ebcd30e37a.tar.gz |
re_eval: clear lexicals in the right pad
(?{...}) deliberately doesn't introduce a new scope (so that the affects of
local() can accumulate across multiple calls to the code). This also means
that the SAVEt_CLEARSVs pushed onto the save stack by lexical declarations
(i.e. (?{ my $x; ... }) also accumulate, and are only processed en-mass at
the end, on exit from the regex. Currently they are usually processed in
the wrong pad (the caller of the pattern, rather than the pads of the
individual code block(s)), leading to random misbehaviour and SEGVs.
Hence the long-standing advice to avoid lexical declarations within
re_evals.
We fix this by wrapping a pair of SAVECOMPPADs around each call to a code
block. Eventually the save stack will be a long accumulation of
SAVEt_CLEARSV's interspersed with SAVEt_COMPPAD's, that when popped
en-mass should unwind in the right order with the right pad at the right
time.
The price to pay for this is two extra additions to the save stack (which
accumulate) for each code call.
A few TODO tests in reg_eval_scope.t now pass, so I'm probably doing the
right thing ;-)
Diffstat (limited to 't/re')
-rw-r--r-- | t/re/reg_eval_scope.t | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/t/re/reg_eval_scope.t b/t/re/reg_eval_scope.t index 860b4c80f7..a23321f2d2 100644 --- a/t/re/reg_eval_scope.t +++ b/t/re/reg_eval_scope.t @@ -16,7 +16,6 @@ plan 17; sub on { $::TODO = "(?{}) implementation is screwy" } sub off { undef $::TODO } -on; fresh_perl_is <<'CODE', '781745', {}, '(?{}) has its own lexical scope'; my $x = 7; my $a = 4; my $b = 5; @@ -24,6 +23,8 @@ fresh_perl_is <<'CODE', '781745', {}, '(?{}) has its own lexical scope'; print $x,$a,$b; CODE +on; + fresh_perl_is <<'CODE', for my $x("a".."c") { $y = 1; @@ -43,6 +44,8 @@ CODE {}, 'multiple (?{})s in loop with lexicals'; +off; + fresh_perl_is <<'CODE', '781745', {}, 'run-time re-eval has its own scope'; use re qw(eval); my $x = 7; my $a = 4; my $b = 5; @@ -85,6 +88,8 @@ fresh_perl_is <<'CODE', '178279371047857967101745', {}, CODE 'multiple (?{})s in "foo" =~ /$string/x'; +on; + fresh_perl_is <<'CODE', '123123', {}, for my $x(1..3) { push @regexps = qr/(?{ print $x })a/; |