diff options
-rw-r--r-- | op.c | 3 | ||||
-rw-r--r-- | scope.c | 7 | ||||
-rw-r--r-- | scope.h | 14 | ||||
-rwxr-xr-x | t/op/closure.t | 11 | ||||
-rw-r--r-- | toke.c | 3 |
5 files changed, 33 insertions, 5 deletions
@@ -4084,8 +4084,7 @@ S_cv_clone2(pTHX_ CV *proto, CV *outside) assert(!CvUNIQUE(proto)); ENTER; - SAVEVPTR(PL_curpad); - SAVESPTR(PL_comppad); + SAVECOMPPAD(); SAVESPTR(PL_comppad_name); SAVESPTR(PL_compcv); @@ -934,6 +934,13 @@ Perl_leave_scope(pTHX_ I32 base) } *(I32*)&PL_hints = (I32)SSPOPINT; break; + case SAVEt_COMPPAD: + PL_comppad = (AV*)SSPOPPTR; + if (PL_comppad) + PL_curpad = AvARRAY(PL_comppad); + else + PL_curpad = Null(SV**); + break; default: Perl_croak(aTHX_ "panic: leave_scope inconsistency"); } @@ -31,6 +31,7 @@ #define SAVEt_DESTRUCTOR_X 30 #define SAVEt_VPTR 31 #define SAVEt_I8 32 +#define SAVEt_COMPPAD 33 #define SSCHECK(need) if (PL_savestack_ix + need > PL_savestack_max) savestack_grow() #define SSPUSHINT(i) (PL_savestack[PL_savestack_ix++].any_i32 = (I32)(i)) @@ -132,6 +133,19 @@ Closing bracket on a callback. See C<ENTER> and L<perlcall>. } \ } STMT_END +#define SAVECOMPPAD() \ + STMT_START { \ + if (PL_comppad && PL_curpad == AvARRAY(PL_comppad)) { \ + SSCHECK(2); \ + SSPUSHPTR((SV*)PL_comppad); \ + SSPUSHINT(SAVEt_COMPPAD); \ + } \ + else { \ + SAVEVPTR(PL_curpad); \ + SAVESPTR(PL_comppad); \ + } \ + } STMT_END + #ifdef USE_ITHREADS # define SAVECOPSTASH(cop) SAVEPPTR(CopSTASHPV(cop)) # define SAVECOPFILE(cop) SAVEPPTR(CopFILE(cop)) diff --git a/t/op/closure.t b/t/op/closure.t index 52d2272b80..c691d6f034 100755 --- a/t/op/closure.t +++ b/t/op/closure.t @@ -12,7 +12,7 @@ BEGIN { use Config; -print "1..170\n"; +print "1..171\n"; my $test = 1; sub test (&) { @@ -172,6 +172,15 @@ test { $foo[4]->()->(4) }; +{ + my $w; + $w = sub { + my ($i) = @_; + test { $i == 10 }; + sub { $w }; + }; + $w->(10); +} # Additional tests by Tom Phoenix <rootbeer@teleport.com>. @@ -7039,8 +7039,7 @@ Perl_start_subparse(pTHX_ I32 is_format, U32 flags) SAVEI32(PL_subline); save_item(PL_subname); SAVEI32(PL_padix); - SAVEVPTR(PL_curpad); - SAVESPTR(PL_comppad); + SAVECOMPPAD(); SAVESPTR(PL_comppad_name); SAVESPTR(PL_compcv); SAVEI32(PL_comppad_name_fill); |