Various tweaks to Encode
[p5sagit/p5-mst-13.2.git] / universal.c
index a9cb4cc..926d1c3 100644 (file)
@@ -169,7 +169,7 @@ XS(XS_utf8_unicode_to_native);
 XS(XS_utf8_native_to_unicode);
 XS(XS_Internals_SvREADONLY);
 XS(XS_Internals_SvREFCNT);
-XS(XS_Internals_hv_clear_placeholders);
+XS(XS_Internals_hv_clear_placehold);
 
 void
 Perl_boot_core_UNIVERSAL(pTHX)
@@ -189,7 +189,7 @@ Perl_boot_core_UNIVERSAL(pTHX)
     newXSproto("Internals::SvREADONLY",XS_Internals_SvREADONLY, file, "\\[$%@];$");
     newXSproto("Internals::SvREFCNT",XS_Internals_SvREFCNT, file, "\\[$%@];$");
     newXSproto("Internals::hv_clear_placeholders",
-               XS_Internals_hv_clear_placeholders, file, "\\%");
+               XS_Internals_hv_clear_placehold, file, "\\%");
 }
 
 
@@ -505,7 +505,7 @@ XS(XS_Internals_SvREFCNT)   /* This is dangerous stuff. */
 
 /* Maybe this should return the number of placeholders found in scalar context,
    and a list of them in list context.  */
-XS(XS_Internals_hv_clear_placeholders)
+XS(XS_Internals_hv_clear_placehold)
 {
     dXSARGS;
     HV *hv = (HV *) SvRV(ST(0));
@@ -520,9 +520,16 @@ XS(XS_Internals_hv_clear_placeholders)
         I32 riter = HvRITER(hv);
         HE *eiter = HvEITER(hv);
         hv_iterinit(hv);
-        while (items
-               && (entry
-                   = hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS))) {
+        /* This may look suboptimal with the items *after* the iternext, but
+           it's quite deliberate. We only get here with items==0 if we've
+           just deleted the last placeholder in the hash. If we've just done
+           that then it means that the hash is in lazy delete mode, and the
+           HE is now only referenced in our iterator. If we just quit the loop
+           and discarded our iterator then the HE leaks. So we do the && the
+           other way to ensure iternext is called just one more time, which
+           has the side effect of triggering the lazy delete.  */
+        while ((entry = hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS))
+            && items) {
             SV *val = hv_iterval(hv, entry);
 
             if (val == &PL_sv_undef) {