develooper Front page | perl.perl5.porters | Postings from June 2017

Re: Confused by eval behavior

Thread Previous | Thread Next
From:
Dave Mitchell
Date:
June 5, 2017 14:11
Subject:
Re: Confused by eval behavior
Message ID:
20170605141101.GI3083@iabyn.com
On Tue, Jan 24, 2017 at 04:15:42PM +0000, Dave Mitchell wrote:
> On Tue, Jan 24, 2017 at 04:34:54PM +0100, Vincent Pit (VPIT) wrote:
> > It has already been in git for a while. I was waiting for more feedback
> > about why free callbacks could end up being called twice when recasting, but
> > since it seems like an unrelated issue (it appeared somewhere during 5.23.x)
> > I've just released a new version with your change.

So I've now been able to push this:

commit b66d79a6843486dbfe3a6f0a5fb78ffb86dd82e2
Author:     David Mitchell <davem@iabyn.com>
AuthorDate: Mon Aug 22 09:50:43 2016 +0100
Commit:     David Mitchell <davem@iabyn.com>
CommitDate: Mon Jun 5 14:59:25 2017 +0100

    FREETMPS when leaving eval, even when void/dying
    
    [ This commit was originally added as v5.25.2-77-g214949f then reverted
    by v5.25.2-89-gcc040a9, since it broke Variable::Magic. That distribution
    has since been fixed, so this fix can be re-applied to blead ]
    
    When a scope is exited normally (e.g. pp_leavetry, pp_leavesub),
    we do a FREETMPS only in scalar or list context; in void context
    we don't bother for efficiency reasons. Similarly, when there's an
    exception and we unwind to (and then pop) an EVAL context, we haven't
    been bothering to FREETMPS.
    
    The problem with this in try/eval (exiting normally or via an exception)
    is that it can delay some SVs getting freed until *after* $@ has been
    set. If that freeing calls a destructor which happens to set $@,
    then that overwrites the "real" value of $@.
    
    For example
    
        sub DESTROY { eval { die "died in DESTROY"; } }
        eval { bless []; };
        is ($@, "");
    
    Before this commit, that test would fail because $@ is "died in DESTROY".
    
    This commit ensures that leaving an eval/try by whatever means always
    clears the tmps stack before setting $@.
    
    See http://nntp.perl.org/group/perl.perl5.porters/237380.
    
    For now, I haven't added a FREETMPS to the other pp_leavefoo()
    void context cases, since I can't think of a case where it would
    matter.


Affected files ...
    M	pp_ctl.c
    M	t/op/eval.t


-- 
Music lesson: a symbiotic relationship whereby a pupil's embellishments
concerning the amount of practice performed since the last lesson are
rewarded with embellishments from the teacher concerning the pupil's
progress over the corresponding period.

Thread Previous | Thread Next


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