summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cop.h5
-rw-r--r--inline.h9
-rw-r--r--pp_ctl.c6
-rw-r--r--scope.c1
-rw-r--r--sv.c1
5 files changed, 21 insertions, 1 deletions
diff --git a/cop.h b/cop.h
index 00396f04a4..f9bf85222d 100644
--- a/cop.h
+++ b/cop.h
@@ -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); \
diff --git a/inline.h b/inline.h
index aa4e7b8fdf..84b0bfc1fb 100644
--- a/inline.h
+++ b/inline.h
@@ -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;
}
diff --git a/pp_ctl.c b/pp_ctl.c
index 5dee09dddf..ef1ff8dd40 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -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)
diff --git a/scope.c b/scope.c
index 9b1393c69d..c6616440f6 100644
--- a/scope.c
+++ b/scope.c
@@ -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()
diff --git a/sv.c b/sv.c
index e088e5c419..0b878a4630 100644
--- a/sv.c
+++ b/sv.c
@@ -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;