[perl #85026] Iterate hashes by hand during do_sv_dump
authorTon Hospel <me-02@ton.iguana.be>
Sat, 11 Jun 2011 19:28:00 +0000 (12:28 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 11 Jun 2011 20:19:31 +0000 (13:19 -0700)
A further note: while debugging this issue it was annoying that
Devel::Peek::Dump doesb't actually dump the HASH elements when an
iterator is active. Also added is a patch that does the iteration to
dump the HASH contents by iterating over it by hand (not disturbing
any active iterator). With that it also doesn't activate hash magic
during iteration, which I think is a feature

dump.c

diff --git a/dump.c b/dump.c
index a5d71bc..c32807c 100644 (file)
--- a/dump.c
+++ b/dump.c
@@ -1918,29 +1918,41 @@ Perl_do_sv_dump(pTHX_ I32 level, PerlIO *file, SV *sv, I32 nest, I32 maxnest, bo
                }
            }
        }
-       if (nest < maxnest && !HvEITER_get(sv)) { /* Try to preserve iterator */
-           HE *he;
+       if (nest < maxnest) {
            HV * const hv = MUTABLE_HV(sv);
-           int count = maxnest - nest;
+           STRLEN i;
+           HE *he;
 
-           hv_iterinit(hv);
-           while ((he = hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS))
-                   && count--) {
+           if (HvARRAY(hv)) {
+               int count = maxnest - nest;
+               for (i=0; i <= HvMAX(hv); i++) {
+                   for (he = HvARRAY(hv)[i]; he; he = HeNEXT(he)) {
+                       U32 hash;
+                       SV * keysv;
+                       const char * keypv;
+                       SV * elt;
                STRLEN len;
-               const U32 hash = HeHASH(he);
-               SV * const keysv = hv_iterkeysv(he);
-               const char * const keypv = SvPV_const(keysv, len);
-               SV * const elt = hv_iterval(hv, he);
+
+                       if (count-- <= 0) goto DONEHV;
+
+                       hash = HeHASH(he);
+                       keysv = hv_iterkeysv(he);
+                       keypv = SvPV_const(keysv, len);
+                       elt = HeVAL(he);
 
                Perl_dump_indent(aTHX_ level+1, file, "Elt %s ", pv_display(d, keypv, len, 0, pvlim));
                if (SvUTF8(keysv))
                    PerlIO_printf(file, "[UTF8 \"%s\"] ", sv_uni_display(d, keysv, 6 * SvCUR(keysv), UNI_DISPLAY_QQ));
+                       if (HvEITER_get(hv) == he)
+                           PerlIO_printf(file, "[CURRENT] ");
                if (HeKREHASH(he))
                    PerlIO_printf(file, "[REHASH] ");
-               PerlIO_printf(file, "HASH = 0x%"UVxf"\n", (UV)hash);
+                       PerlIO_printf(file, "HASH = 0x%"UVxf"\n", (UV) hash);
                do_sv_dump(level+1, file, elt, nest+1, maxnest, dumpops, pvlim);
            }
-           hv_iterinit(hv);            /* Return to status quo */
+               }
+             DONEHV:;
+           }
        }
        break;