Front page | perl.perl5.porters |
Postings from August 2016
Re: Confused by eval behavior
Thread Previous
|
Thread Next
From:
Dave Mitchell
Date:
August 22, 2016 16:37
Subject:
Re: Confused by eval behavior
Message ID:
20160822163716.GR3173@iabyn.com
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?
--
Any [programming] language that doesn't occasionally surprise the
novice will pay for it by continually surprising the expert.
-- Larry Wall
Thread Previous
|
Thread Next