Skip to content

Commit 0bed19a

Browse files
committed
Move pp_entersub DIE() code into S_croak_undefined_subroutine
In `pp_entersub`, when trying to find the subroutine `CV` to execute, there are three nearby code paths that can result in a `DIE()`. This commit extracts the DIE() logic to a helper subroutine, `S_croak_undefined_subroutine`. This is partly in anticipation of additional warning logic, but also generally reduces the size of this hot function.
1 parent df4d5e8 commit 0bed19a

File tree

1 file changed

+32
-11
lines changed

1 file changed

+32
-11
lines changed

pp_hot.c

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6212,6 +6212,33 @@ Perl_clear_defarray(pTHX_ AV* av, bool abandon)
62126212
}
62136213
}
62146214

6215+
/* S_croak_undefined_subroutine is a helper function for pp_entersub.
6216+
* It takes assorted DIE() logic out of that hot function.
6217+
*/
6218+
static void
6219+
S_croak_undefined_subroutine(pTHX_ CV const *cv, GV const *gv)
6220+
{
6221+
if (cv) {
6222+
if (CvLEXICAL(cv) && CvHASGV(cv))
6223+
croak("Undefined subroutine &%" SVf " called",
6224+
SVfARG(cv_name((CV*)cv, NULL, 0)));
6225+
else /* pp_entersub triggers when (CvANON(cv) || !CvHASGV(cv)) */
6226+
croak("Undefined subroutine called");
6227+
} else { /* pp_entersub triggers when (!cv) after `try_autoload` */
6228+
SV *sub_name = newSV_type_mortal(SVt_PV);
6229+
gv_efullname3(sub_name, gv, NULL);
6230+
6231+
/* Heuristic to spot BOOP:boop() typo, when the intention was
6232+
* to call BOOP::boop(). */
6233+
const char * label = CopLABEL(PL_curcop);
6234+
if (label) {
6235+
croak("Undefined subroutine &%" SVf " called, close to label '%s'",
6236+
SVfARG(sub_name), label);
6237+
}
6238+
croak("Undefined subroutine &%" SVf " called", SVfARG(sub_name));
6239+
}
6240+
NOT_REACHED; /* NOTREACHED */
6241+
}
62156242

62166243
PP(pp_entersub)
62176244
{
@@ -6306,15 +6333,12 @@ PP(pp_entersub)
63066333
assert((void*)&CvROOT(cv) == (void*)&CvXSUB(cv));
63076334
while (UNLIKELY(!CvROOT(cv))) {
63086335
GV* autogv;
6309-
SV* sub_name;
63106336

63116337
/* anonymous or undef'd function leaves us no recourse */
63126338
if (CvLEXICAL(cv) && CvHASGV(cv))
6313-
DIE(aTHX_ "Undefined subroutine &%" SVf " called",
6314-
SVfARG(cv_name(cv, NULL, 0)));
6315-
if (CvANON(cv) || !CvHASGV(cv)) {
6316-
DIE(aTHX_ "Undefined subroutine called");
6317-
}
6339+
S_croak_undefined_subroutine(aTHX_ cv, NULL);
6340+
if (CvANON(cv) || !CvHASGV(cv))
6341+
S_croak_undefined_subroutine(aTHX_ cv, NULL);
63186342

63196343
/* autoloaded stub? */
63206344
if (cv != GvCV(gv = CvGV(cv))) {
@@ -6330,11 +6354,8 @@ PP(pp_entersub)
63306354
: 0));
63316355
cv = autogv ? GvCV(autogv) : NULL;
63326356
}
6333-
if (!cv) {
6334-
sub_name = sv_newmortal();
6335-
gv_efullname3(sub_name, gv, NULL);
6336-
DIE(aTHX_ "Undefined subroutine &%" SVf " called", SVfARG(sub_name));
6337-
}
6357+
if (!cv)
6358+
S_croak_undefined_subroutine(aTHX_ NULL, gv);
63386359
}
63396360

63406361
/* unrolled "CvCLONE(cv) && ! CvCLONED(cv)" */

0 commit comments

Comments
 (0)