On Thu, Jul 12, 2012 at 04:40:14PM +0100, Dave Mitchell wrote: [ stuff about caller and __SUB__ in /(?{})? code blocks. ] I've just applied the following three commits to blead, which collectively fix up the behaviour of caller() / __SUB__ enough for 5.18.0 IMHO. commit b00652470bcd63ec9dee77ad3149214aebcee0df Author: David Mitchell <davem@iabyn.com> AuthorDate: Wed Apr 24 11:14:39 2013 +0100 Commit: David Mitchell <davem@iabyn.com> CommitDate: Wed Apr 24 16:39:47 2013 +0100 PUSH_MULTICALL_WITHDEPTH becomes ..._FLAGS Two non-API macros were added with 5.17.1 to support the more complex calling conventions required by /({})/ code blocks: PUSH_MULTICALL_WITHDEPTH(the_cv, depth) CHANGE_MULTICALL_WITHDEPTH(the_cv, depth) which allowed us to do the same as the API versions, but to optionally not increment the caller depth, and to change the current CV. Replace these with two new macros: PUSH_MULTICALL_FLAGS(the_cv, flags) CHANGE_MULTICALL_FLAGS(the_cv, flags) which instead allow us to set extra flags in cx->cx_type. The depth increment skip is handled by the new CXp_SUB_RE_FAKE flag, and all (?{}) calls set the new CXp_SUB_RE flag. These two new flags will shortly allow us to change how caller() and __SUB__ handle code blocks. commit 5fbe83117ea59ccad42477c465113c7550a3675d Author: David Mitchell <davem@iabyn.com> AuthorDate: Wed Apr 24 14:41:33 2013 +0100 Commit: David Mitchell <davem@iabyn.com> CommitDate: Wed Apr 24 16:39:47 2013 +0100 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->(); commit a453e28ae209e82ef2533e2e2bfe25490fd60654 Author: David Mitchell <davem@iabyn.com> AuthorDate: Wed Apr 24 16:29:42 2013 +0100 Commit: David Mitchell <davem@iabyn.com> CommitDate: Wed Apr 24 16:40:15 2013 +0100 make qr/(?{ __SUB__ })/ safe (See RT #113928) Formerly, __SUB__ within a code block within a qr// returned a pointer to the "hidden" anon CV that implements the qr// closure. Since this was never designed to be called directly, it would SEGV if you tried. The easiest way to make this safe is to skip any CXt_SUB frames that are marked as CXp_SUB_RE: i.e. skip any subs that are there just to execute code blocks. For a qr//, this means that we return the sub which the pattern match is embedded in. Also, document the behaviour of __SUB__ within code blocks as being subject to change. It could be argued for example that in these cases it should return undef. But with the 5.18.0 release a month or two away, just make it safe for now, and revisit the semantics later if necessary. -- "Procrastination grows to fill the available time" -- Mitchell's corollary to Parkinson's LawThread Previous