This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
MULTICALL should clear scope after each call
authorDavid Mitchell <davem@iabyn.com>
Fri, 25 Dec 2015 22:03:10 +0000 (22:03 +0000)
committerDavid Mitchell <davem@iabyn.com>
Wed, 3 Feb 2016 09:19:17 +0000 (09:19 +0000)
RT #116577

Lexicals etc were only being freed at the end of the MULTICALL, not
after each individual call to the sub.

cop.h
ext/XS-APItest/t/multicall.t
regexec.c

diff --git a/cop.h b/cop.h
index 6ffd514..54a5b1c 100644 (file)
--- a/cop.h
+++ b/cop.h
@@ -1327,6 +1327,7 @@ See L<perlcall/LIGHTWEIGHT CALLBACKS>.
     CV *multicall_cv;                                                  \
     OP *multicall_cop;                                                 \
     bool multicall_oldcatch;                                           \
+    I32 saveix_floor;                                                   \
     U8 hasargs = 0             /* used by PUSHSUB */
 
 #define PUSH_MULTICALL(the_cv) \
@@ -1347,6 +1348,7 @@ See L<perlcall/LIGHTWEIGHT CALLBACKS>.
        PUSHSUB(cx);                                                    \
         cx->blk_oldsaveix = PL_savestack_ix;                            \
        SAVEVPTR(PL_op);                                                \
+        saveix_floor = PL_savestack_ix;                                 \
         if (!(flags & CXp_SUB_RE_FAKE))                                 \
             CvDEPTH(cv)++;                                             \
        if (CvDEPTH(cv) >= 2) {                                         \
@@ -1363,6 +1365,8 @@ See L<perlcall/LIGHTWEIGHT CALLBACKS>.
     STMT_START {                                                       \
        PL_op = multicall_cop;                                          \
        CALLRUNOPS(aTHX);                                               \
+        cx = CX_CUR();                                                 \
+        LEAVE_SCOPE(saveix_floor);                                      \
     } STMT_END
 
 #define POP_MULTICALL \
index 6c033b7..d152644 100644 (file)
@@ -7,7 +7,7 @@
 use warnings;
 use strict;
 
-use Test::More tests => 79;
+use Test::More tests => 80;
 use XS::APItest;
 
 
@@ -162,3 +162,14 @@ use XS::APItest;
         gimme_check($gimme, \@a, ["one", "two"], "for-return two args lval");
     }
 }
+
+# RT #116577: MULTICALL should clear scope after each call
+
+{
+    my @r;
+
+    my $s = sub { my $x; push @r, \$x; 1 };
+
+    XS::APItest::multicall_each \&$s, 1,2;
+    isnt($r[0], $r[1], "#116577");
+}
index 9aec6c3..a196e7a 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -6664,6 +6664,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
                before = (IV)(SP-PL_stack_base);
                PL_op = nop;
                CALLRUNOPS(aTHX);                       /* Scalar context. */
+                PERL_UNUSED_VAR(saveix_floor); /* used by MULTICALL */
                SPAGAIN;
                if ((IV)(SP-PL_stack_base) == before)
                    ret = &PL_sv_undef;   /* protect against empty (?{}) blocks. */