Skip to content

Commit dcabdfc

Browse files
committed
dump.c: add S_get_cv_from_op() function
The existing S_get_sv_from_pad() function does two things: it finds the CV associated with the specified op, and then extracts something from that CV's pad. This commit splits the 'find the associated CV' part of the code out into a separate function, which will be used elsewhere shortly.
1 parent 899a356 commit dcabdfc

File tree

1 file changed

+54
-36
lines changed

1 file changed

+54
-36
lines changed

dump.c

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,13 +1099,13 @@ S_pm_description(pTHX_ const PMOP *pm)
10991099
}
11001100

11011101

1102-
/* S_get_sv_from_pad(): a helper function for op_dump().
1102+
/* S_get_cv_from_op(): a helper function for op_dump().
1103+
*
1104+
* Find the CV which the OP o is contained within.
11031105
*
1104-
* On threaded builds, try to find the SV indexed by the OP o (e.g. via
1105-
* op_targ or op_padix) at pad offset po.
11061106
* Since an op can be dumped at any time, there is no guarantee that the
1107-
* OP is associated with the current PL_curpad. So try to find the currently
1108-
* running CV or eval, and see if it contains the OP. Or if it's
1107+
* OP is associated with the current PL_curpad. So try to find the
1108+
* currently running CV or eval, and see if it contains the OP. Or if it's
11091109
* compile-time, see if the op is contained within one of the op subtrees
11101110
* on the parser stack.
11111111
*
@@ -1118,32 +1118,20 @@ S_pm_description(pTHX_ const PMOP *pm)
11181118
* sane state, be conservative, and if in doubt, return NULL.
11191119
*/
11201120

1121-
#ifdef USE_ITHREADS
1122-
static SV *
1123-
S_get_sv_from_pad(pTHX_ const OP *o, PADOFFSET po, CV *rootcv)
1121+
static CV *
1122+
S_get_cv_from_op(pTHX_ const OP *o, CV *rootcv)
11241123
{
1125-
PADLIST *padlist; /* declare early to work round compiler quirks */
1126-
1127-
if (!po)
1128-
return NULL;
1129-
1130-
CV *cv = NULL;
1131-
int n;
1132-
OP *oproot;
1133-
1134-
if (rootcv) {
1135-
cv = rootcv;
1136-
goto got_cv;
1137-
}
1124+
if (rootcv)
1125+
return rootcv;
11381126

11391127
/* Find the root of the optree this op is embedded in. For a compiled
11401128
* sub, this root will typically be a leavesub or similar attached to
11411129
* a CV. If compiling, this may be a small subtree on the parser
11421130
* stack. Limit the number of hops, in case there is some sort of
11431131
* loop or other weirdness.
11441132
*/
1145-
n = 100;
1146-
oproot = (OP*)o;
1133+
int n = 100;
1134+
OP *oproot = (OP*)o;
11471135
while (1) {
11481136
if (--n <= 0)
11491137
return NULL;
@@ -1159,12 +1147,8 @@ S_get_sv_from_pad(pTHX_ const OP *o, PADOFFSET po, CV *rootcv)
11591147
yy_stack_frame *ps;
11601148

11611149
for (ps = PL_parser->ps; ps > PL_parser->stack; ps--) {
1162-
if (ps->val.opval == oproot) {
1163-
cv = ps->compcv;
1164-
if (!cv)
1165-
return NULL; /* this shouldn't actually happen */
1166-
goto got_cv;
1167-
}
1150+
if (ps->val.opval == oproot)
1151+
return ps->compcv;
11681152
}
11691153
}
11701154

@@ -1174,6 +1158,7 @@ S_get_sv_from_pad(pTHX_ const OP *o, PADOFFSET po, CV *rootcv)
11741158
*/
11751159
I32 i;
11761160
for (i = cxstack_ix; i >= 0; i--) {
1161+
CV *cv;
11771162
const PERL_CONTEXT * const cx = &cxstack[i];
11781163
switch (CxTYPE(cx)) {
11791164
default:
@@ -1187,7 +1172,7 @@ S_get_sv_from_pad(pTHX_ const OP *o, PADOFFSET po, CV *rootcv)
11871172
* does instead */
11881173
if (!cv || !CvEVAL(cv) || oproot != PL_eval_root)
11891174
continue;
1190-
goto got_cv;
1175+
return cv;
11911176
case CXt_SUB:
11921177
if (cx->cx_type & CXp_SUB_RE_FAKE)
11931178
continue;
@@ -1196,21 +1181,54 @@ S_get_sv_from_pad(pTHX_ const OP *o, PADOFFSET po, CV *rootcv)
11961181
cv = cxstack[i].blk_sub.cv;
11971182
if (!cv || CvISXSUB(cv) || oproot != CvROOT(cv))
11981183
continue;
1199-
goto got_cv;
1184+
return cv;
12001185
}
12011186
}
12021187

1203-
if (PL_main_cv && PL_main_root == oproot) {
1204-
cv = PL_main_cv;
1205-
goto got_cv;
1206-
}
1188+
if (PL_main_cv && PL_main_root == oproot)
1189+
return PL_main_cv;
1190+
12071191
return NULL;
1192+
}
1193+
1194+
1195+
/* S_get_sv_from_pad(): a helper function for op_dump().
1196+
*
1197+
* On threaded builds, try to find the SV indexed by the OP o (e.g. via
1198+
* op_targ or op_padix) at pad offset po.
1199+
* Since an op can be dumped at any time, there is no guarantee that the
1200+
* OP is associated with the current PL_curpad. So try to find the currently
1201+
* running CV or eval, and see if it contains the OP. Or if it's
1202+
* compile-time, see if the op is contained within one of the op subtrees
1203+
* on the parser stack.
1204+
*
1205+
* Return NULL if it can't be found.
1206+
*
1207+
* Sometimes the caller *does* know what CV is being dumped; if so, it
1208+
* is passed as rootcv.
1209+
*
1210+
* Since this may be called during debugging and things may not be in a
1211+
* sane state, be conservative, and if in doubt, return NULL.
1212+
*/
1213+
1214+
#ifdef USE_ITHREADS
1215+
static SV *
1216+
S_get_sv_from_pad(pTHX_ const OP *o, PADOFFSET po, CV *rootcv)
1217+
{
1218+
PADLIST *padlist; /* declare early to work round compiler quirks */
1219+
1220+
if (!po)
1221+
return NULL;
1222+
1223+
CV *cv = S_get_cv_from_op(aTHX_ o, rootcv);
1224+
if (!cv)
1225+
return NULL;
12081226

12091227
/* Lookup the entry in the pad associated with this CV.
12101228
* Note that for SVs moved into the pad, they are shared at all pad
12111229
* depths, so we only have to look at depth 1 and not worry about
12121230
* CvDEPTH(). */
1213-
got_cv:
1231+
12141232
padlist = CvPADLIST(cv);
12151233
if (!padlist)
12161234
return NULL;

0 commit comments

Comments
 (0)