]> git.vpit.fr Git - perl/modules/Variable-Magic.git/commit
Handle self destruction manually rt115792
authorDave Mitchell <davem@iabyn.com>
Tue, 6 Dec 2016 23:45:35 +0000 (21:45 -0200)
committerVincent Pit <perl@profvince.com>
Wed, 7 Dec 2016 01:04:13 +0000 (23:04 -0200)
commit92d785f98afb5bd5707e622ba9cc68818b8f0b33
tree5bda65b1aa1b7c3587ea239eb7ff410a07e49a3a
parentecc16f5aeded896b3ab1f0019fc489bb5e15bc08
Handle self destruction manually

A slightly modified version of the failing test code is as follows:

    use Variable::Magic qw<wizard cast>;

    my $wiz2 = wizard;
    my $wiz1 = wizard free =>
            sub { warn "recasting\n"; &cast($_[0], $wiz2); die ; };

    warn "result of eval = [" . eval {
     my $v = do { my $val = 123; \$val };
     study;
     &cast($v, $wiz1);
     warn "just at end of eval\n";
    } . "]\n";
    warn "just after eval\n";

On 5.24.0, this gives:

    just at end of eval
    recasting
    result of eval = []
    recasting
    just after eval

The mortal RV that is created to temporarily point at the scalar being
freed (the IV(123) above) to pass to the free method, isn't initially
freed, and is only freed by the FREETMPS in the nextstate following the
eval. When freed, it triggers another free of the IV(123), which although
it should now be under the influence of $wiz2 rather than $wiz1, it still
calls the 'free' anon sub (I don't understand why its still called, and I
haven't looked into it).

The TEMP not getting freed until after the statement following the eval is
the bug my blead patch was supposed to fix (which it does), but which
caused infinite recursion.

My fix avoids making the temporary mortal RV a TEMP on the tmps stack,
and instead stores a pointer to it in the vmg_svt_free_cleanup_ud struct.
This RV is then manually freed in both the normal and exception cleanup
paths.
Magic.xs