New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(resent) Typeglobs vs. SUPER:: (Hook::LexWrap failure) #9054
Comments
From @CorionThis is a bug report for perl from corion@cpan.org, package main; =head1 DESCRIPTION This test program shows a difference in behaviour Under 5.10, the wrapper only gets called once. =cut use Test::More tests => 4; for my $name (1..2) { # Install the request dumper : for my $line (@lines) { # Release the hook sub Dummy::UserAgent::new { bless {}, shift }; package Dummy::Mechanize; # If you comment out this line, all is well: Flags: Site configuration information for perl 5.10.0: Configured by corion at Sat Oct 6 20:19:19 CEST 2007. Summary of my perl5 (revision 5 version 10 subversion 0 patch 32052) Locally applied patches: @INC for perl 5.10.0: Environment for perl 5.10.0: PATH=/home/corion/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/home/corion/bin:/home/corion/bin |
From blblack@gmail.comOn 10/7/07, via RT Max Maischein <perlbug-followup@perl.org> wrote:
I think you've found a buggy interaction between SUPER and the new Recap of SUPER (skip this if you know how it works): When code The problem is that the special SUPER package isn't tied into the new There are a few different ways to go about fixing this. This simplest I've attached a patch for what I think is a reasonable compromise What do you guys think? -- Brandon |
From blblack@gmail.comsupercache.patch=== embed.fnc
==================================================================
--- embed.fnc (revision 55697)
+++ embed.fnc (local)
@@ -1133,6 +1133,7 @@
#if defined(PERL_IN_GV_C) || defined(PERL_DECL_PROT)
s |void |gv_init_sv |NN GV *gv|I32 sv_type
+s |HV* |gv_get_super_pkg|NN const char* name|I32 namelen
s |HV* |require_tie_mod|NN GV *gv|NN const char *varpv|NN SV* namesv \
|NN const char *methpv|const U32 flags
#endif
=== embed.h
==================================================================
--- embed.h (revision 55697)
+++ embed.h (local)
@@ -1123,6 +1123,7 @@
#if defined(PERL_IN_GV_C) || defined(PERL_DECL_PROT)
#ifdef PERL_CORE
#define gv_init_sv S_gv_init_sv
+#define gv_get_super_pkg S_gv_get_super_pkg
#define require_tie_mod S_require_tie_mod
#endif
#endif
@@ -3391,6 +3392,7 @@
#if defined(PERL_IN_GV_C) || defined(PERL_DECL_PROT)
#ifdef PERL_CORE
#define gv_init_sv(a,b) S_gv_init_sv(aTHX_ a,b)
+#define gv_get_super_pkg(a,b) S_gv_get_super_pkg(aTHX_ a,b)
#define require_tie_mod(a,b,c,d,e) S_require_tie_mod(aTHX_ a,b,c,d,e)
#endif
#endif
=== gv.c
==================================================================
--- gv.c (revision 55697)
+++ gv.c (local)
@@ -528,6 +528,32 @@
=cut
*/
+STATIC HV*
+S_gv_get_super_pkg(pTHX_ const char* name, I32 namelen)
+{
+ AV* superisa;
+ GV** gvp;
+ GV* gv;
+ HV* stash;
+
+ stash = gv_stashpvn(name, namelen, 0);
+ if(stash) return stash;
+
+ /* If we must create it, give it an @ISA array containing
+ the real package this SUPER is for, so that it's tied
+ into the cache invalidation code correctly */
+ stash = gv_stashpvn(name, namelen, GV_ADD);
+ gvp = (GV**)hv_fetchs(stash, "ISA", TRUE);
+ gv = *gvp;
+ gv_init(gv, stash, "ISA", 3, TRUE);
+ superisa = GvAVn(gv);
+ GvMULTI_on(gv);
+ sv_magic((SV*)superisa, (SV*)gv, PERL_MAGIC_isa, NULL, 0);
+ av_push(superisa, newSVpv(CopSTASHPV(PL_curcop), 0));
+
+ return stash;
+}
+
GV *
Perl_gv_fetchmethod_autoload(pTHX_ HV *stash, const char *name, I32 autoload)
{
@@ -556,7 +582,7 @@
SV * const tmpstr = sv_2mortal(Perl_newSVpvf(aTHX_ "%s::SUPER",
CopSTASHPV(PL_curcop)));
/* __PACKAGE__::SUPER stash should be autovivified */
- stash = gv_stashpvn(SvPVX_const(tmpstr), SvCUR(tmpstr), GV_ADD);
+ stash = gv_get_super_pkg(SvPVX_const(tmpstr), SvCUR(tmpstr));
DEBUG_o( Perl_deb(aTHX_ "Treating %s as %s::%s\n",
origname, HvNAME_get(stash), name) );
}
@@ -569,7 +595,7 @@
if (!stash && (nsplit - origname) >= 7 &&
strnEQ(nsplit - 7, "::SUPER", 7) &&
gv_stashpvn(origname, nsplit - origname - 7, 0))
- stash = gv_stashpvn(origname, nsplit - origname, GV_ADD);
+ stash = gv_get_super_pkg(origname, nsplit - origname);
}
ostash = stash;
}
=== proto.h
==================================================================
--- proto.h (revision 55697)
+++ proto.h (local)
@@ -3009,6 +3009,9 @@
STATIC void S_gv_init_sv(pTHX_ GV *gv, I32 sv_type)
__attribute__nonnull__(pTHX_1);
+STATIC HV* S_gv_get_super_pkg(pTHX_ const char* name, I32 namelen)
+ __attribute__nonnull__(pTHX_1);
+
STATIC HV* S_require_tie_mod(pTHX_ GV *gv, const char *varpv, SV* namesv, const char *methpv, const U32 flags)
__attribute__nonnull__(pTHX_1)
__attribute__nonnull__(pTHX_2)
|
The RT System itself - Status changed from 'new' to 'open' |
From @rgsOn 08/10/2007, Brandon Black <blblack@gmail.com> wrote:
Sounds like something not too expensive, performance-wise. Thanks,
Maybe we could get a regression test for this, too ? :) |
@rgs - Status changed from 'open' to 'resolved' |
From blblack@gmail.comOn 10/8/07, Rafael Garcia-Suarez <rgarciasuarez@gmail.com> wrote:
Here's three new tests in t/mro/basic.t. The last two fail without 32065. -- Brandon |
From blblack@gmail.comsupercache_tests.patch=== t/mro/basic.t
==================================================================
--- t/mro/basic.t (revision 55697)
+++ t/mro/basic.t (local)
@@ -3,7 +3,7 @@
use strict;
use warnings;
-require q(./test.pl); plan(tests => 35);
+require q(./test.pl); plan(tests => 38);
{
package MRO_A;
@@ -190,3 +190,31 @@
}
}
+# Check that SUPER caches get invalidated correctly
+{
+ {
+ package SUPERTEST;
+ sub new { bless {} => shift }
+ sub foo { $_[1]+1 }
+
+ package SUPERTEST::MID;
+ our @ISA = 'SUPERTEST';
+
+ package SUPERTEST::KID;
+ our @ISA = 'SUPERTEST::MID';
+ sub foo { my $s = shift; $s->SUPER::foo(@_) }
+
+ package SUPERTEST::REBASE;
+ sub foo { $_[1]+3 }
+ }
+
+ my $stk_obj = SUPERTEST::KID->new();
+ is($stk_obj->foo(1), 2);
+ { no warnings 'redefine';
+ *SUPERTEST::foo = sub { $_[1]+2 };
+ }
+ is($stk_obj->foo(2), 4);
+ @SUPERTEST::MID::ISA = 'SUPERTEST::REBASE';
+ is($stk_obj->foo(3), 6);
+}
+
|
From @rgsOn 08/10/2007, Brandon Black <blblack@gmail.com> wrote:
Thanks, applied. |
Migrated from rt.perl.org#46217 (status was 'resolved')
Searchable as RT46217$
The text was updated successfully, but these errors were encountered: