diff options
author | David Mitchell <davem@iabyn.com> | 2015-07-17 14:44:32 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2016-02-03 08:59:37 +0000 |
commit | 8e90e786101d3edc1f7b5ad4b735860d4667dcd4 (patch) | |
tree | ae3b2deeed0b2520048ff688e330349a3fca3abf /perl.c | |
parent | 9aa350eb0f0c75e5d5ac3fbccd708064f23d6795 (diff) | |
download | perl-8e90e786101d3edc1f7b5ad4b735860d4667dcd4.tar.gz |
call_sv(), fold_const(): different CX pop test
Perl_call_sv() and S_fold_constants() both have similar code that:
pushes an EVAL context, does a JMPENV_PUSH() and CALLRUNOPS(), then
optionally pops the EVAL context.
The optionally part depends on whether what's doing the dying
has already popped the context before long-jumping. Currently the decision
on whether to pop is based on whether the scope stack has already been
popped.
This commit changes that to whether the context stack has already been
popped, since shortly we're going to change eval contexts so that the old
savestack_ix is stored in the CX struct rather than on the scope stack.
I ran this code with some asserts that the two conditions were identical,
and nothing failed.
Diffstat (limited to 'perl.c')
-rw-r--r-- | perl.c | 11 |
1 files changed, 8 insertions, 3 deletions
@@ -2711,7 +2711,6 @@ Perl_call_sv(pTHX_ SV *sv, VOL I32 flags) METHOP method_op; I32 oldmark; VOL I32 retval = 0; - I32 oldscope; bool oldcatch = CATCH_GET; int ret; OP* const oldop = PL_op; @@ -2743,7 +2742,6 @@ Perl_call_sv(pTHX_ SV *sv, VOL I32 flags) PUTBACK; } oldmark = TOPMARK; - oldscope = PL_scopestack_ix; if (PERLDB_SUB && PL_curstash != PL_debstash /* Handle first BEGIN of -d. */ @@ -2777,8 +2775,10 @@ Perl_call_sv(pTHX_ SV *sv, VOL I32 flags) CATCH_SET(oldcatch); } else { + I32 old_cxix; myop.op_other = (OP*)&myop; (void)POPMARK; + old_cxix = cxstack_ix; create_eval_scope(flags|G_FAKINGEVAL); (void)INCMARK; @@ -2820,8 +2820,13 @@ Perl_call_sv(pTHX_ SV *sv, VOL I32 flags) break; } - if (PL_scopestack_ix > oldscope) + /* if we croaked, depending on how we croaked the eval scope + * may or may not have already been popped */ + if (cxstack_ix > old_cxix) { + assert(cxstack_ix == old_cxix + 1); + assert(CxTYPE(&cxstack[cxstack_ix]) == CXt_EVAL); delete_eval_scope(); + } JMPENV_POP; } |