Front page | perl.perl5.porters |
Postings from November 2016
Re: Confused by eval behavior
Thread Previous
|
Thread Next
From:
Dave Mitchell
Date:
November 14, 2016 15:50
Subject:
Re: Confused by eval behavior
Message ID:
20161114155013.GF24916@iabyn.com
On Mon, Aug 22, 2016 at 05:37:16PM +0100, Dave Mitchell wrote:
> On Mon, Jul 18, 2016 at 01:29:19PM -0300, Vincent Pit (VPIT) wrote:
> > Le 18/07/2016 à 12:37, Dave Mitchell a écrit :
> > > > The failing Variable::Magic test can be reduced to:
> > > >
> > > > use Variable::Magic qw<wizard cast>;
> > > >
> > > > my $wiz2 = wizard;
> > > > my $wiz1 = wizard free => sub { warn "recasting\n"; &cast($_[0], $wiz2); die; };
> > > >
> > > > eval {
> > > > my $v = do { my $val = 123; \$val };
> > > > &cast($v, $wiz1);
> > > > };
> > > >
> > > > When $v goes out scope, the free magic method is called, which attached
> > > > new magic then dies. vmg_call_sv catches the error, then croaks.
> > > > The croak calls die_unwind, which now does FREETMPS, which triggers
> > > > another call to the free method, and so it recurses infinitely.
> > > >
> > > > I haven't looked closely to see what is being freed by the FREETMPS and
> > > > why.
> > >
> > > Vincent, will you have any opportunity to look at this?
> > >
> >
> > I looked at it but I have no definite answer about how to solve it.
> >
> > The part of the code that goes into infinite recursion is there to ensure
> > that the Variable::Magic objects survive long enough that it is possible to
> > still manipulate magic during free callbacks (note that in particular magic
> > vtables have to be handled with extra care because they are shared across
> > threads). In order to work around the issue covered by this very "Confused
> > by eval behaviour" bug, the case where the free callback is invoked at the
> > end of an eval scope is treated specifically in vmg_svt_free_cleanup() (in
> > the branch where ud->in_eval is true). Then it uses different strategies
> > (trampoline op, destructor added to $@) to delay magic cleanup after eval is
> > done. Prior to your change, ud->in_eval was true in your example, but now
> > it's false. I guess that the heuristic used to see if the destruction
> > happens at the eval boundary has to be adjusted. I reckon that all this
> > stuff is pretty hacky and brittle, but it used to work well enough that
> > nobody complained.
> >
> > As a data point, note that if you change the eval part of your test case by
> >
> > eval {
> > my $v = 123;
> > cast($v, $wiz1);
> > };
> >
> > then the infinite recursion disappears but the free magic is called twice.
>
> Well, in an ideal world with a perfect perl and a perfect V::M,
> what is the code at the top of this email supposed to do? In particular:
>
> At the point where die is about to be called, is the magic var supposed
> to have both wizards still attached, or just wiz2? (Or with both attached,
> but $wiz1 in some way deactivated?).
>
> And when exactly is the magic var supposed to be freed for the second
> time (after having been temporarily resurrected by the free magic
> creating a mortal reference to it)?
>
> And is it intended that the free anon sub should called exactly once?
Hi Vincent,
are you able to answer my above questions? Until I know what the intended
behaviour is, I can't fix (or suggest how to fix) Variable::Magic, which
means I can't pull my fix into blead since it break V::M.
--
print+qq&$}$"$/$s$,$a$d$g$s$@$.$q$,$:$.$q$^$,$@$a$~$;$.$q$m&if+map{m,^\d{0\,},,${$::{$'}}=chr($"+=$&||1)}q&10m22,42}6:17a2~2.3@3;^2dg3q/s"&=~m*\d\*.*g
Thread Previous
|
Thread Next