Subject: | [PATCH] Fix for 5.21.4 |
Here is a patch, but it is pretty ugly. I added cv_name to perl 5.21.4 to try to avoid this ternary mess, but it does not meet Devel::Declare’s needs, as it includes the package name.
Do you think perhaps I should extend cv_name to take an extra parameter and let the latter choose whether the package is included?
In that case, you could hold off on applying the patch, unless you want it to work with every dev version of perl.
What do you think?
Subject: | open_s1NmRrb1.txt |
--- Devel-Declare-0.006016-G6Ji81-orig/Declare.xs 2014-09-23 22:41:09.000000000 -0700
+++ Devel-Declare-0.006016-G6Ji81/Declare.xs 2014-09-23 23:16:25.000000000 -0700
@@ -283,11 +283,22 @@ static void call_done_declare(pTHX) {
static int dd_handle_const(pTHX_ char *name);
+#ifdef CvNAMED
+# define Gv_or_CvNAME(g) (isGV(g) \
+ ? GvNAME(g) \
+ : CvNAMED(SvRV(g)) \
+ ? HEK_KEY(CvNAME_HEK((CV *)SvRV(g))) \
+ : GvNAME(CvGV(SvRV(g))))
+#else
+# define Gv_or_CvNAME(g) GvNAME(g)
+#endif
+
/* replacement PL_check rv2cv entry */
STATIC OP *dd_ck_rv2cv(pTHX_ OP *o, void *user_data) {
OP* kid;
int dd_flags;
+ char *gvname;
PERL_UNUSED_VAR(user_data);
@@ -304,11 +315,17 @@ STATIC OP *dd_ck_rv2cv(pTHX_ OP *o, void
if (kid->op_type != OP_GV) /* not a GV so ignore */
return o;
+ if (!isGV(kGVOP_gv)
+ && (!SvROK(kGVOP_gv) || SvTYPE(SvRV(kGVOP_gv)) != SVt_PVCV))
+ return o;
+
+ gvname = Gv_or_CvNAME(kGVOP_gv);
+
if (DD_DEBUG_TRACE) {
- printf("Checking GV %s -> %s\n", HvNAME(GvSTASH(kGVOP_gv)), GvNAME(kGVOP_gv));
+ printf("Checking GV %s -> %s\n", HvNAME(GvSTASH(kGVOP_gv)), gvname);
}
- dd_flags = dd_is_declarator(aTHX_ GvNAME(kGVOP_gv));
+ dd_flags = dd_is_declarator(aTHX_ gvname);
if (dd_flags == -1)
return o;
@@ -320,23 +337,23 @@ STATIC OP *dd_ck_rv2cv(pTHX_ OP *o, void
#if DD_CONST_VIA_RV2CV
if (PL_expect != XOPERATOR) {
- if (!dd_handle_const(aTHX_ GvNAME(kGVOP_gv)))
+ if (!dd_handle_const(aTHX_ Gv_or_CvNAME(kGVOP_gv)))
return o;
CopLINE(PL_curcop) = PL_copline;
/* The parser behaviour that we're simulating depends on what comes
after the declarator. */
- if (*skipspace(PL_bufptr + strlen(GvNAME(kGVOP_gv))) != '(') {
+ if (*skipspace(PL_bufptr + strlen(gvname)) != '(') {
if (in_declare) {
call_done_declare(aTHX);
} else {
- dd_linestr_callback(aTHX_ "rv2cv", GvNAME(kGVOP_gv));
+ dd_linestr_callback(aTHX_ "rv2cv", gvname);
}
}
return o;
}
#endif /* DD_CONST_VIA_RV2CV */
- dd_linestr_callback(aTHX_ "rv2cv", GvNAME(kGVOP_gv));
+ dd_linestr_callback(aTHX_ "rv2cv", gvname);
return o;
}