gv_efullname3() could return NULL, so mro::_nextcan() must cope (and croak()).
[gitmo/Class-C3-XS.git] / XS.xs
diff --git a/XS.xs b/XS.xs
index 0d22ac8..4ced6b8 100644 (file)
--- a/XS.xs
+++ b/XS.xs
@@ -184,15 +184,16 @@ __mro_linear_isa_c3(pTHX_ HV* stash, HV* cache, I32 level)
                 SV** seq_ptr = AvARRAY(seq) + 1;
                 while(seq_items--) {
                     SV* const seqitem = *seq_ptr++;
-                    HE* const he = hv_fetch_ent(tails, seqitem, 0, 0);
-                    if(!he) {
-                        if(!hv_store_ent(tails, seqitem, newSViv(1), 0)) {
-                            croak("failed to store value in hash");
-                        }
-                    }
-                    else {
+                    /* LVALUE fetch will create a new undefined SV if necessary
+                     */
+                    HE* const he = hv_fetch_ent(tails, seqitem, 1, 0);
+                    if(he) {
                         SV* const val = HeVAL(he);
+                        /* This will increment undef to 1, which is what we
+                           want for a newly created entry.  */
                         sv_inc(val);
+                    } else {
+                        croak("failed to store value in hash");
                     }
                 }
             }
@@ -406,12 +407,18 @@ XS(XS_Class_C3_XS_nextcan)
             }
 
             /* we found a real sub here */
-            sv = sv_2mortal(newSV(0));
+            sv = sv_newmortal();
 
             gv_efullname3(sv, cvgv, NULL);
 
-            fq_subname = SvPVX(sv);
-            fq_subname_len = SvCUR(sv);
+            if (SvPOK(sv)) {
+                fq_subname = SvPVX(sv);
+                fq_subname_len = SvCUR(sv);
+
+                subname = strrchr(fq_subname, ':');
+            } else {
+                subname = NULL;
+            }
 
             subname = strrchr(fq_subname, ':');
             if(!subname)
@@ -513,7 +520,7 @@ XS(XS_Class_C3_XS_nextcan)
             if (SvTYPE(candidate) == SVt_PVGV && (cand_cv = GvCV(candidate)) && !GvCVGEN(candidate)) {
                 SvREFCNT_dec(linear_av);
                 SvREFCNT_inc((SV*)cand_cv);
-                if (!hv_store_ent(nmcache, newSVsv(cachekey), (SV*)cand_cv, 0)) {
+                if (!hv_store_ent(nmcache, cachekey, (SV*)cand_cv, 0)) {
                     croak("failed to store value in hash");
                 }
                 XPUSHs(sv_2mortal(newRV_inc((SV*)cand_cv)));
@@ -523,7 +530,7 @@ XS(XS_Class_C3_XS_nextcan)
     }
 
     SvREFCNT_dec(linear_av);
-    if (!hv_store_ent(nmcache, newSVsv(cachekey), &PL_sv_undef, 0)) {
+    if (!hv_store_ent(nmcache, cachekey, &PL_sv_undef, 0)) {
         croak("failed to store value in hash");
     }
     if(throw_nomethod)