Change 34907 by [EMAIL PROTECTED] on 2008/11/25 06:28:40

        Subject: [perl #38809] return do { } : take 3 (or 4...)
        From: Vincent Pit <[EMAIL PROTECTED]>
        Date: Mon, 29 Sep 2008 17:36:09 +0200
        Message-ID: <[EMAIL PROTECTED]>

Affected files ...

... //depot/perl/op.c#1024 edit
... //depot/perl/op.h#215 edit
... //depot/perl/pp_hot.c#593 edit
... //depot/perl/t/op/do.t#20 edit

Differences ...

==== //depot/perl/op.c#1024 (text) ====
Index: perl/op.c
--- perl/op.c#1023~34905~       2008-11-24 19:51:41.000000000 -0800
+++ perl/op.c   2008-11-24 22:28:40.000000000 -0800
@@ -7644,14 +7644,28 @@
 Perl_ck_return(pTHX_ OP *o)
 {
     dVAR;
+    OP *kid;
 
     PERL_ARGS_ASSERT_CK_RETURN;
 
+    kid = cLISTOPo->op_first->op_sibling;
     if (CvLVALUE(PL_compcv)) {
-        OP *kid;
-       for (kid = cLISTOPo->op_first->op_sibling; kid; kid = kid->op_sibling)
+       for (; kid; kid = kid->op_sibling)
            mod(kid, OP_LEAVESUBLV);
+    } else {
+       for (; kid; kid = kid->op_sibling)
+           if ((kid->op_type == OP_NULL)
+               && (kid->op_flags & OPf_SPECIAL)) {
+               /* This is a do block */
+               OP *op = cUNOPx(kid)->op_first;
+               assert(op && (op->op_type == OP_LEAVE) && (op->op_flags & 
OPf_KIDS));
+               op = cUNOPx(op)->op_first;
+               assert(op->op_type == OP_ENTER && !(op->op_flags & 
OPf_SPECIAL));
+               /* Force the use of the caller's context */
+               op->op_flags |= OPf_SPECIAL;
+           }
     }
+
     return o;
 }
 

==== //depot/perl/op.h#215 (text) ====
Index: perl/op.h
--- perl/op.h#214~34819~        2008-11-12 02:37:46.000000000 -0800
+++ perl/op.h   2008-11-24 22:28:40.000000000 -0800
@@ -137,6 +137,7 @@
                                /*  On OP_SMARTMATCH, an implicit smartmatch */
                                /*  On OP_ANONHASH and OP_ANONLIST, create a
                                    reference to the new anon hash or array */
+                               /*  On OP_ENTER, store caller context */
                                /*  On OP_HELEM and OP_HSLICE, localization 
will be followed
                                    by assignment, so do not wipe the target if 
it is special
                                    (e.g. a glob or a magic SV) */

==== //depot/perl/pp_hot.c#593 (text) ====
Index: perl/pp_hot.c
--- perl/pp_hot.c#592~34833~    2008-11-14 06:29:53.000000000 -0800
+++ perl/pp_hot.c       2008-11-24 22:28:40.000000000 -0800
@@ -1754,9 +1754,13 @@
     I32 gimme = OP_GIMME(PL_op, -1);
 
     if (gimme == -1) {
-       if (cxstack_ix >= 0)
-           gimme = cxstack[cxstack_ix].blk_gimme;
-       else
+       if (cxstack_ix >= 0) {
+           /* If this flag is set, we're just inside a return, so we should
+            * store the caller's context */
+           gimme = (PL_op->op_flags & OPf_SPECIAL)
+               ? block_gimme()
+               : cxstack[cxstack_ix].blk_gimme;
+       } else
            gimme = G_SCALAR;
     }
 
@@ -1865,13 +1869,7 @@
 
     POPBLOCK(cx,newpm);
 
-    gimme = OP_GIMME(PL_op, -1);
-    if (gimme == -1) {
-       if (cxstack_ix >= 0)
-           gimme = cxstack[cxstack_ix].blk_gimme;
-       else
-           gimme = G_SCALAR;
-    }
+    gimme = OP_GIMME(PL_op, (cxstack_ix >= 0) ? gimme : G_SCALAR);
 
     TAINT_NOT;
     if (gimme == G_VOID)

==== //depot/perl/t/op/do.t#20 (xtext) ====
Index: perl/t/op/do.t
--- perl/t/op/do.t#19~34310~    2008-09-07 14:32:44.000000000 -0700
+++ perl/t/op/do.t      2008-11-24 22:28:40.000000000 -0800
@@ -29,7 +29,7 @@
     return $ok;
 }
 
-print "1..26\n";
+print "1..32\n";
 
 # Test do &sub and proper @_ handling.
 $_[0] = 0;
@@ -104,6 +104,23 @@
 $owww = do { 4 if not $zok };
 ok( $owww eq '', 'last is if not' );
 
+# [perl #38809]
[EMAIL PROTECTED] = (7, 8);
+$x = sub { do { return do { 1; @a } }; 3 }->();
+ok(defined $x && $x == 2, 'return do { } receives caller scalar context');
[EMAIL PROTECTED] = sub { do { return do { 1; @a } }; 3 }->();
+ok("@x" eq "7 8", 'return do { } receives caller list context');
[EMAIL PROTECTED] = (7, 8, 9);
+$x = sub { do { do { 1; return @a } }; 4 }->();
+ok(defined $x && $x == 3, 'do { return } receives caller scalar context');
[EMAIL PROTECTED] = sub { do { do { 1; return @a } }; 4 }->();
+ok("@x" eq "7 8 9", 'do { return } receives caller list context');
[EMAIL PROTECTED] = (7, 8, 9, 10);
+$x = sub { do { return do { 1; do { 2; @a } } }; 5 }->();
+ok(defined $x && $x == 4, 'return do { do { } } receives caller scalar 
context');
[EMAIL PROTECTED] = sub { do { return do { 1; do { 2; @a } } }; 5 }->();
+ok("@x" eq "7 8 9 10", 'return do { do { } } receives caller list context');
+
 END {
     1 while unlink("$$.16", "$$.17", "$$.18");
 }
End of Patch.

Reply via email to