Fix AUTOLOAD, or kill me
Chip Salzenberg [Wed, 2 Apr 1997 22:03:18 +0000 (10:03 +1200)]
gv.c
pp.c
t/op/method.t

diff --git a/gv.c b/gv.c
index 98526ca..9aa4c54 100644 (file)
--- a/gv.c
+++ b/gv.c
@@ -285,8 +285,19 @@ I32 autoload;
     }
     else if (autoload) {
        CV* cv = GvCV(gv);
-       if (!cv || (!CvROOT(cv) && !CvXSUB(cv))) {
-           GV* autogv = gv_autoload4(GvSTASH(gv), name, nend - name, TRUE);
+       if (!CvROOT(cv) && !CvXSUB(cv)) {
+           GV* stubgv;
+           GV* autogv;
+
+           if (CvANON(cv))
+               stubgv = gv;
+           else {
+               stubgv = CvGV(cv);
+               if (GvCV(stubgv) != cv)         /* orphaned import */
+                   stubgv = gv;
+           }
+           autogv = gv_autoload4(GvSTASH(stubgv),
+                                 GvNAME(stubgv), GvNAMELEN(stubgv), TRUE);
            if (autogv)
                gv = autogv;
        }
diff --git a/pp.c b/pp.c
index 84b393b..357f91e 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -557,7 +557,9 @@ PP(pp_undef)
                 CvANON((CV*)sv) ? "(anonymous)" : GvENAME(CvGV((CV*)sv)));
        /* FALL THROUGH */
     case SVt_PVFM:
-       cv_undef((CV*)sv);
+       { GV* gv = (GV*)SvREFCNT_inc(CvGV((CV*)sv));
+         cv_undef((CV*)sv);
+         CvGV((CV*)sv) = gv; }   /* let user-undef'd sub keep its identity */
        break;
     case SVt_PVGV:
        if (SvFAKE(sv))
index bdbc8a9..21d7c8f 100755 (executable)
@@ -64,6 +64,7 @@ test (eval { A->x } || "nope", "nope");
 
 eval <<'EOF';
 sub C::e;
+BEGIN { *B::e = \&C::e }       # Shouldn't prevent AUTOLOAD in original pkg
 sub Y::f;
 $counter = 0;
 
@@ -73,14 +74,16 @@ $counter = 0;
 sub B::AUTOLOAD {
   my $c = ++$counter;
   my $method = $B::AUTOLOAD; 
-  *$B::AUTOLOAD = sub { "B: In $method, $c" };
-  goto &$B::AUTOLOAD;
+  my $msg = "B: In $method, $c";
+  eval "sub $method { \$msg }";
+  goto &$method;
 }
 sub C::AUTOLOAD {
   my $c = ++$counter;
   my $method = $C::AUTOLOAD; 
-  *$C::AUTOLOAD = sub { "C: In $method, $c" };
-  goto &$C::AUTOLOAD;
+  my $msg = "C: In $method, $c";
+  eval "sub $method { \$msg }";
+  goto &$method;
 }
 EOF