diff options
-rw-r--r-- | cop.h | 2 | ||||
-rw-r--r-- | pp_ctl.c | 16 |
2 files changed, 16 insertions, 2 deletions
@@ -333,6 +333,7 @@ struct block_eval { SV * cur_text; CV * cv; OP * retop; /* op to execute on exit from eval */ + JMPENV * cur_top_env; /* value of PL_top_env when eval CX created */ }; #define PUSHEVAL(cx,n,fgv) \ @@ -344,6 +345,7 @@ struct block_eval { cx->blk_eval.cur_text = PL_linestr; \ cx->blk_eval.cv = Nullcv; /* set by doeval(), as applicable */ \ cx->blk_eval.retop = Nullop; \ + cx->blk_eval.cur_top_env = PL_top_env; \ } STMT_END #define POPEVAL(cx) \ @@ -2681,7 +2681,6 @@ S_docatch(pTHX_ OP *o) { int ret; OP * const oldop = PL_op; - volatile PERL_SI *cursi = PL_curstackinfo; dJMPENV; #ifdef DEBUGGING @@ -2692,12 +2691,25 @@ S_docatch(pTHX_ OP *o) JMPENV_PUSH(ret); switch (ret) { case 0: + assert(cxstack_ix >= 0); + assert(CxTYPE(&cxstack[cxstack_ix]) == CXt_EVAL); + cxstack[cxstack_ix].blk_eval.cur_top_env = PL_top_env; redo_body: docatch_body(); break; case 3: /* die caught by an inner eval - continue inner loop */ - if (PL_restartop && cursi == PL_curstackinfo) { + + /* NB XXX we rely on the old popped CxEVAL still being at the top + * of the stack; the way die_where() currently works, this + * assumption is valid. In theory The cur_top_env value should be + * returned in another global, the way retop (aka PL_restartop) + * is. */ + assert(CxTYPE(&cxstack[cxstack_ix+1]) == CXt_EVAL); + + if (PL_restartop + && cxstack[cxstack_ix+1].blk_eval.cur_top_env == PL_top_env) + { PL_op = PL_restartop; PL_restartop = 0; goto redo_body; |