summaryrefslogtreecommitdiff
path: root/pp_ctl.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2013-04-24 14:41:33 +0100
committerDavid Mitchell <davem@iabyn.com>2013-04-24 16:39:47 +0100
commit5fbe83117ea59ccad42477c465113c7550a3675d (patch)
treeffcf1737c4f5bb9c679653cc1e6df3a91c044e81 /pp_ctl.c
parentb00652470bcd63ec9dee77ad3149214aebcee0df (diff)
downloadperl-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.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index aae200f74d..f08e3764c2 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -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;