From: Brandon Black Date: Tue, 26 Jun 2007 11:05:31 +0000 (-0500) Subject: First patch from: X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=9b43931120d41c17896bde0d0bb619d0e701b0ad;p=p5sagit%2Fp5-mst-13.2.git First patch from: Subject: Re: [perl #43357] *DESTROY = sub {} at runtime From: "Brandon Black" Message-ID: <84621a60706260905x2da6eaf1x4bd7d5223951e52@mail.gmail.com> Fix problem recently introduced with loosing a DESTROY when redefined at runtime. p4raw-id: //depot/perl@31472 --- diff --git a/gv.c b/gv.c index 8f98f00..9751afa 100644 --- a/gv.c +++ b/gv.c @@ -1509,9 +1509,10 @@ Perl_Gv_AMupdate(pTHX_ HV *stash) dVAR; MAGIC* const mg = mg_find((SV*)stash, PERL_MAGIC_overload_table); AMT amt; + const struct mro_meta* stash_meta = HvMROMETA(stash); U32 newgen; - newgen = PL_sub_generation + HvMROMETA(stash)->cache_gen; + newgen = PL_sub_generation + stash_meta->pkg_gen + stash_meta->cache_gen; if (mg) { const AMT * const amtp = (AMT*)mg->mg_ptr; if (amtp->was_ok_am == PL_amagic_generation @@ -1638,11 +1639,13 @@ Perl_gv_handler(pTHX_ HV *stash, I32 id) MAGIC *mg; AMT *amtp; U32 newgen; + struct mro_meta* stash_meta; if (!stash || !HvNAME_get(stash)) return NULL; - newgen = PL_sub_generation + HvMROMETA(stash)->cache_gen; + stash_meta = HvMROMETA(stash); + newgen = PL_sub_generation + stash_meta->pkg_gen + stash_meta->cache_gen; mg = mg_find((SV*)stash, PERL_MAGIC_overload_table); if (!mg) { diff --git a/t/mro/basic.t b/t/mro/basic.t index 0871d19..b514a04 100644 --- a/t/mro/basic.t +++ b/t/mro/basic.t @@ -3,7 +3,7 @@ use strict; use warnings; -require q(./test.pl); plan(tests => 12); +require q(./test.pl); plan(tests => 18); { package MRO_A; @@ -69,3 +69,59 @@ is(eval { MRO_N->testfunc() }, 123); # XXX TODO (when there's a way to backtrack through a glob's aliases) # push(@MRO_M::ISA, 'MRO_TestOtherBase'); # is(eval { MRO_N->testfunctwo() }, 321); + +# Simple DESTROY Baseline +{ + my $x = 0; + my $obj; + + { + package DESTROY_MRO_Baseline; + sub new { bless {} => shift } + sub DESTROY { $x++ } + + package DESTROY_MRO_Baseline_Child; + our @ISA = qw/DESTROY_MRO_Baseline/; + } + + $obj = DESTROY_MRO_Baseline->new(); + undef $obj; + is($x, 1); + + $obj = DESTROY_MRO_Baseline_Child->new(); + undef $obj; + is($x, 2); +} + +# Dynamic DESTROY +{ + my $x = 0; + my $obj; + + { + package DESTROY_MRO_Dynamic; + sub new { bless {} => shift } + + package DESTROY_MRO_Dynamic_Child; + our @ISA = qw/DESTROY_MRO_Dynamic/; + } + + $obj = DESTROY_MRO_Dynamic->new(); + undef $obj; + is($x, 0); + + $obj = DESTROY_MRO_Dynamic_Child->new(); + undef $obj; + is($x, 0); + + no warnings 'once'; + *DESTROY_MRO_Dynamic::DESTROY = sub { $x++ }; + + $obj = DESTROY_MRO_Dynamic->new(); + undef $obj; + is($x, 1); + + $obj = DESTROY_MRO_Dynamic_Child->new(); + undef $obj; + is($x, 2); +}