diff options
-rw-r--r-- | cop.h | 5 | ||||
-rw-r--r-- | inline.h | 9 | ||||
-rw-r--r-- | pp_ctl.c | 6 | ||||
-rw-r--r-- | scope.c | 1 | ||||
-rw-r--r-- | sv.c | 1 |
5 files changed, 21 insertions, 1 deletions
@@ -585,6 +585,7 @@ C<*len>. Upon return, C<*flags> will be set to either C<SVf_UTF8> or 0. /* subroutine context */ struct block_sub { OP * retop; /* op to execute on exit from sub */ + I32 old_cxsubix; /* previous value of si_cxsubix */ /* Above here is the same for sub, format and eval. */ PAD *prevcomppad; /* the caller's PL_comppad */ CV * cv; @@ -597,6 +598,7 @@ struct block_sub { /* format context */ struct block_format { OP * retop; /* op to execute on exit from sub */ + I32 old_cxsubix; /* previous value of si_cxsubix */ /* Above here is the same for sub, format and eval. */ PAD *prevcomppad; /* the caller's PL_comppad */ CV * cv; @@ -663,6 +665,7 @@ struct block_format { /* eval context */ struct block_eval { OP * retop; /* op to execute on exit from eval */ + I32 old_cxsubix; /* previous value of si_cxsubix */ /* Above here is the same for sub, format and eval. */ SV * old_namesv; OP * old_eval_root; @@ -1026,6 +1029,7 @@ struct stackinfo { struct stackinfo * si_next; I32 si_cxix; /* current context index */ I32 si_cxmax; /* maximum allocated index */ + I32 si_cxsubix; /* topmost sub/eval/format */ I32 si_type; /* type of runlevel */ I32 si_markoff; /* offset where markstack begins for us. * currently used only with DEBUGGING, @@ -1072,6 +1076,7 @@ typedef struct stackinfo PERL_SI; } \ next->si_type = type; \ next->si_cxix = -1; \ + next->si_cxsubix = -1; \ PUSHSTACK_INIT_HWM(next); \ AvFILLp(next->si_stack) = 0; \ SWITCHSTACK(PL_curstack,next->si_stack); \ @@ -2134,6 +2134,8 @@ Perl_cx_pushsub(pTHX_ PERL_CONTEXT *cx, CV *cv, OP *retop, bool hasargs) PERL_ARGS_ASSERT_CX_PUSHSUB; PERL_DTRACE_PROBE_ENTRY(cv); + cx->blk_sub.old_cxsubix = PL_curstackinfo->si_cxsubix; + PL_curstackinfo->si_cxsubix = cx - PL_curstackinfo->si_cxstack; cx->blk_sub.cv = cv; cx->blk_sub.olddepth = CvDEPTH(cv); cx->blk_sub.prevcomppad = PL_comppad; @@ -2160,6 +2162,7 @@ Perl_cx_popsub_common(pTHX_ PERL_CONTEXT *cx) CvDEPTH(cv) = cx->blk_sub.olddepth; cx->blk_sub.cv = NULL; SvREFCNT_dec(cv); + PL_curstackinfo->si_cxsubix = cx->blk_sub.old_cxsubix; } @@ -2206,6 +2209,8 @@ Perl_cx_pushformat(pTHX_ PERL_CONTEXT *cx, CV *cv, OP *retop, GV *gv) { PERL_ARGS_ASSERT_CX_PUSHFORMAT; + cx->blk_format.old_cxsubix = PL_curstackinfo->si_cxsubix; + PL_curstackinfo->si_cxsubix= cx - PL_curstackinfo->si_cxstack; cx->blk_format.cv = cv; cx->blk_format.retop = retop; cx->blk_format.gv = gv; @@ -2239,6 +2244,7 @@ Perl_cx_popformat(pTHX_ PERL_CONTEXT *cx) cx->blk_format.cv = NULL; --CvDEPTH(cv); SvREFCNT_dec_NN(cv); + PL_curstackinfo->si_cxsubix = cx->blk_format.old_cxsubix; } @@ -2247,6 +2253,8 @@ Perl_cx_pusheval(pTHX_ PERL_CONTEXT *cx, OP *retop, SV *namesv) { PERL_ARGS_ASSERT_CX_PUSHEVAL; + cx->blk_eval.old_cxsubix = PL_curstackinfo->si_cxsubix; + PL_curstackinfo->si_cxsubix= cx - PL_curstackinfo->si_cxstack; cx->blk_eval.retop = retop; cx->blk_eval.old_namesv = namesv; cx->blk_eval.old_eval_root = PL_eval_root; @@ -2282,6 +2290,7 @@ Perl_cx_popeval(pTHX_ PERL_CONTEXT *cx) cx->blk_eval.old_namesv = NULL; SvREFCNT_dec_NN(sv); } + PL_curstackinfo->si_cxsubix = cx->blk_eval.old_cxsubix; } @@ -37,7 +37,11 @@ #define RUN_PP_CATCHABLY(thispp) \ STMT_START { if (CATCH_GET) return docatch(thispp); } STMT_END -#define dopopto_cursub() dopoptosub_at(cxstack, cxstack_ix) +#define dopopto_cursub() \ + (PL_curstackinfo->si_cxsubix >= 0 \ + ? PL_curstackinfo->si_cxsubix \ + : dopoptosub_at(cxstack, cxstack_ix)) + #define dopoptosub(plop) dopoptosub_at(cxstack, (plop)) PP(pp_wantarray) @@ -82,6 +82,7 @@ Perl_new_stackinfo(pTHX_ I32 stitems, I32 cxitems) si->si_next = 0; si->si_cxmax = cxitems - 1; si->si_cxix = -1; + si->si_cxsubix = -1; si->si_type = PERLSI_UNDEF; Newx(si->si_cxstack, cxitems, PERL_CONTEXT); /* Without any kind of initialising CX_PUSHSUBST() @@ -14690,6 +14690,7 @@ Perl_si_dup(pTHX_ PERL_SI *si, CLONE_PARAMS* param) nsi->si_stack = av_dup_inc(si->si_stack, param); nsi->si_cxix = si->si_cxix; + nsi->si_cxsubix = si->si_cxsubix; nsi->si_cxmax = si->si_cxmax; nsi->si_cxstack = cx_dup(si->si_cxstack, si->si_cxix, si->si_cxmax, param); nsi->si_type = si->si_type; |