diff options
author | David Mitchell <davem@iabyn.com> | 2013-04-24 14:41:33 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2013-04-24 16:39:47 +0100 |
commit | 5fbe83117ea59ccad42477c465113c7550a3675d (patch) | |
tree | ffcf1737c4f5bb9c679653cc1e6df3a91c044e81 /pp_ctl.c | |
parent | b00652470bcd63ec9dee77ad3149214aebcee0df (diff) | |
download | perl-5fbe83117ea59ccad42477c465113c7550a3675d.tar.gz |
fix caller with re_evals.
(See RT #113928)
In code like
sub foo { /A(?{ bar; caller(); }B/; }
the regex /A(?{B})C/ is, from a scope point of view, supposed to
be compiled and executed as:
/A/ && do { B } && /C/;
i.e. the code block in B is part of the same sub as the code surrounding
the regex. Thus the result of caller() above should see the caller as
whoever called foo.
Due to an implementation detail, we actually push a hidden extra
sub CX before calling the pattern. This detail was leaking when caller()
was used. Fux it so that it ignores this extra context frame.
Conversely, for a qr//, that *is* supposed to be seen as an extra level
of anonymous sub, so add tests to ensure that is so.
i.e.
$r = qr/...(?{code}).../
/...$r.../
is supposed to behave like
$r = sub { code };
$r->();
Diffstat (limited to 'pp_ctl.c')
-rw-r--r-- | pp_ctl.c | 8 |
1 files changed, 7 insertions, 1 deletions
@@ -1438,8 +1438,14 @@ S_dopoptosub_at(pTHX_ const PERL_CONTEXT *cxstk, I32 startingblock) switch (CxTYPE(cx)) { default: continue; - case CXt_EVAL: case CXt_SUB: + /* in sub foo { /(?{...})/ }, foo ends up on the CX stack + * twice; the first for the normal foo() call, and the second + * for a faked up re-entry into the sub to execute the + * code block. Hide this faked entry from the world. */ + if (cx->cx_type & CXp_SUB_RE_FAKE) + continue; + case CXt_EVAL: case CXt_FORMAT: DEBUG_l( Perl_deb(aTHX_ "(dopoptosub_at(): found sub at cx=%ld)\n", (long)i)); return i; |