develooper Front page | perl.perl5.porters | Postings from April 2013

Re: [perl #113928] caller behaving unexpectedly in re-evals

Thread Previous
From:
Dave Mitchell
Date:
April 24, 2013 16:18
Subject:
Re: [perl #113928] caller behaving unexpectedly in re-evals
Message ID:
20130424161717.GB2216@iabyn.com
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 Law

Thread Previous


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About