summaryrefslogtreecommitdiff
path: root/pp_sys.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-08-05 01:05:45 -0700
committerFather Chrysostomos <sprout@cpan.org>2012-08-05 16:02:01 -0700
commitf32c7e864b6210c7dabe6a78f842c37aa73c56c3 (patch)
treeb6a222fda29c83ac85ef9cdd7a423c31907b3578 /pp_sys.c
parentbb02a38febc60a289c616282d720015be97842a4 (diff)
downloadperl-f32c7e864b6210c7dabe6a78f842c37aa73c56c3.tar.gz
Recursive formats and closures in formats.
Formats called recursively were using the same set of lexicals, so the inner call would stomp on the outer calls vars, usually clearing them when exiting. Previous commits prepared a CvDEPTH field for formats. This commit sets it in P(USH|OP)FORMAT and pushes a new pad in enterwrite. This also allows closures to work properly in formats. Formerly they caused assertion failures in cv_clone. Now cv_clone’s assumptions about CvDEPTH on CvOUTSIDE and find_runcv are met when subs are embed- ded in formats.
Diffstat (limited to 'pp_sys.c')
-rw-r--r--pp_sys.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/pp_sys.c b/pp_sys.c
index a11eced866..cccbff3cd1 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -1335,8 +1335,12 @@ S_doform(pTHX_ CV *cv, GV *gv, OP *retop)
PUSHBLOCK(cx, CXt_FORMAT, PL_stack_sp);
PUSHFORMAT(cx, retop);
+ if (CvDEPTH(cv) >= 2) {
+ PERL_STACK_OVERFLOW_CHECK();
+ pad_push(CvPADLIST(cv), CvDEPTH(cv));
+ }
SAVECOMPPAD();
- PAD_SET_CUR_NOSAVE(CvPADLIST(cv), 1);
+ PAD_SET_CUR_NOSAVE(CvPADLIST(cv), CvDEPTH(cv));
setdefout(gv); /* locally select filehandle so $% et al work */
return CvSTART(cv);