summaryrefslogtreecommitdiff
path: root/regexec.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2015-06-29 11:27:36 +0100
committerDavid Mitchell <davem@iabyn.com>2016-02-03 08:59:33 +0000
commit3b21fb5de4ab74fae93a27637e67b3b330ee514d (patch)
treee6e30298b66bde462cb3cc3780a65f9fc5b0b0cb /regexec.c
parenteaf95e614f1e9d5d965a0fafcbac033baef2b5bb (diff)
downloadperl-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.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/regexec.c b/regexec.c
index 8e1c1f68f2..9aec6c3ca5 100644
--- a/regexec.c
+++ b/regexec.c
@@ -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 {