summaryrefslogtreecommitdiff
path: root/pp_ctl.c
diff options
context:
space:
mode:
authorZefram <zefram@fysh.org>2010-10-24 14:57:21 +0100
committerFather Chrysostomos <sprout@cpan.org>2010-10-24 11:40:00 -0700
commit8f89e5a94a208b4017fb2fb80d6a0e23cd552ed9 (patch)
tree908f1376e69a56debccf3bfbc36f5cbd37743312 /pp_ctl.c
parentccbfef1989966a87df0683fb781de40d0fad1f84 (diff)
downloadperl-8f89e5a94a208b4017fb2fb80d6a0e23cd552ed9.tar.gz
don't rely on ghost contexts being unmolested
Dying and returning from a format both relied on the state of a just-popped context frame being preserved across a LEAVE. Don't rely on it. Test using an operator ripped off from Scope::Cleanup, which makes it easy to run arbitrary Perl code during cleanup, without isolating it on a separate context stack as the DESTROY mechanism does.
Diffstat (limited to 'pp_ctl.c')
-rw-r--r--pp_ctl.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index 46c6a0b0b2..9eebf43c65 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1653,6 +1653,9 @@ Perl_die_unwind(pTHX_ SV *msv)
SV *namesv;
register PERL_CONTEXT *cx;
SV **newsp;
+ COP *oldcop;
+ JMPENV *restartjmpenv;
+ OP *restartop;
if (cxix < cxstack_ix)
dounwind(cxix);
@@ -1667,6 +1670,9 @@ Perl_die_unwind(pTHX_ SV *msv)
}
POPEVAL(cx);
namesv = cx->blk_eval.old_namesv;
+ oldcop = cx->blk_oldcop;
+ restartjmpenv = cx->blk_eval.cur_top_env;
+ restartop = cx->blk_eval.retop;
if (gimme == G_SCALAR)
*++newsp = &PL_sv_undef;
@@ -1678,7 +1684,7 @@ Perl_die_unwind(pTHX_ SV *msv)
* XXX it might be better to find a way to avoid messing with
* PL_curcop in save_re_context() instead, but this is a more
* minimal fix --GSAR */
- PL_curcop = cx->blk_oldcop;
+ PL_curcop = oldcop;
if (optype == OP_REQUIRE) {
const char* const msg = SvPVx_nolen_const(exceptsv);
@@ -1699,9 +1705,8 @@ Perl_die_unwind(pTHX_ SV *msv)
else {
sv_setsv(ERRSV, exceptsv);
}
- assert(CxTYPE(cx) == CXt_EVAL);
- PL_restartjmpenv = cx->blk_eval.cur_top_env;
- PL_restartop = cx->blk_eval.retop;
+ PL_restartjmpenv = restartjmpenv;
+ PL_restartop = restartop;
JMPENV_JUMP(3);
/* NOTREACHED */
}