diff options
author | David Mitchell <davem@iabyn.com> | 2015-06-29 11:27:36 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2016-02-03 08:59:33 +0000 |
commit | 3b21fb5de4ab74fae93a27637e67b3b330ee514d (patch) | |
tree | e6e30298b66bde462cb3cc3780a65f9fc5b0b0cb /regexec.c | |
parent | eaf95e614f1e9d5d965a0fafcbac033baef2b5bb (diff) | |
download | perl-3b21fb5de4ab74fae93a27637e67b3b330ee514d.tar.gz |
save old PL_comppad in CXt_SUB/FORMAT block
Currently when we call a sub, the old value of PL_comppad is
saved on the save stack using SAVECOMPPAD(). Instead, save it in
a new field in the context struct, called prevcomppad. This is simpler
and more efficient.
Note that there is already a confusingly-named field in the CXt_SUB
context struct called oldcomppad, which holds the value of PL_comppad for
the *current* sub, not for its caller. So the new field had to be called
something else.
One side effect of this is that an existing bug - which causes too much
to be popped off the savestack when dieing while leaving a sub scope - is
now more noticeable, since PL_curpad and SAVEt_CLEARSV are now out of
sync: formerly, the unwinding of the save stack restored PL_curpad in
lockstep. The fix for this will come later in this branch, when the whole
issue of context stack popping order and reentrancy is addressed; for
now, a TODO test has been added.
Diffstat (limited to 'regexec.c')
-rw-r--r-- | regexec.c | 7 |
1 files changed, 7 insertions, 0 deletions
@@ -6590,6 +6590,13 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog) U8 flags = (CXp_SUB_RE | ((newcv == caller_cv) ? CXp_SUB_RE_FAKE : 0)); if (last_pushed_cv) { + /* PUSH/POP_MULTICALL save and restore the + * caller's PL_comppad; if we call multiple subs + * using the same CX block, we have to save and + * unwind the varying PL_comppad's ourselves, + * especially restoring the right PL_comppad on + * backtrack - so save it on the save stack */ + SAVECOMPPAD(); CHANGE_MULTICALL_FLAGS(newcv, flags); } else { |