fix handling of mayhaps-extended @_ in goto &sub
Gurusamy Sarathy [Wed, 21 Oct 1998 04:22:53 +0000 (04:22 +0000)]
p4raw-id: //depot/perl@2030

av.c
pp_ctl.c
t/op/goto.t

diff --git a/av.c b/av.c
index af463cb..5242ffc 100644 (file)
--- a/av.c
+++ b/av.c
@@ -41,6 +41,7 @@ av_reify(AV *av)
     key = AvARRAY(av) - AvALLOC(av);
     while (key)
        AvALLOC(av)[--key] = &PL_sv_undef;
+    AvREIFY_off(av);
     AvREAL_on(av);
 }
 
index c882e9e..04efce6 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1873,6 +1873,7 @@ PP(pp_goto)
            SV** mark;
            I32 items = 0;
            I32 oldsave;
+           int arg_was_real = 0;
 
        retry:
            if (!CvROOT(cv) && !CvXSUB(cv)) {
@@ -1917,7 +1918,10 @@ PP(pp_goto)
                SvREFCNT_dec(GvAV(PL_defgv));
                GvAV(PL_defgv) = cx->blk_sub.savearray;
 #endif /* USE_THREADS */
-               AvREAL_off(av);
+               if (AvREAL(av)) {
+                   arg_was_real = 1;
+                   AvREAL_off(av);     /* so av_clear() won't clobber elts */
+               }
                av_clear(av);
            }
            else if (CvXSUB(cv)) {      /* put GvAV(defgv) back onto stack */
@@ -2073,7 +2077,11 @@ PP(pp_goto)
                    }
                    Copy(mark,AvARRAY(av),items,SV*);
                    AvFILLp(av) = items - 1;
-                   
+                   /* preserve @_ nature */
+                   if (arg_was_real) {
+                       AvREIFY_off(av);
+                       AvREAL_on(av);
+                   }
                    while (items--) {
                        if (*mark)
                            SvTEMP_off(*mark);
index 1b34acd..a62c899 100755 (executable)
@@ -1,10 +1,8 @@
 #!./perl
 
-# $RCSfile: goto.t,v $$Revision: 4.1 $$Date: 92/08/07 18:27:56 $
-
 # "This IS structured code.  It's just randomly structured."
 
-print "1..9\n";
+print "1..12\n";
 
 while ($?) {
     $foo = 1;
@@ -56,7 +54,7 @@ sub bar {
 exit;
 
 FINALE:
-print "ok 9\n";
+print "ok 12\n";
 exit;
 
 bypass:
@@ -86,5 +84,14 @@ $wherever = NOWHERE;
 eval { goto $wherever };
 print $@ =~ /Can't find label NOWHERE/ ? "ok 8\n" : "not ok 8\n";
 
+# see if a modified @_ propagates
+{
+  package Foo;
+  sub DESTROY  { my $s = shift; print "ok $s->[0]\n"; }
+  sub show     { print "# @_\nnot ok $_[0][0]\n" if @_ != 5; }
+  sub start    { push @_, 1, "foo", {}; goto &show; }
+  for (9..11)  { start(bless([$_]), 'bar'); }
+}
+
 $wherever = FINALE;
 goto $wherever;