From: Ton Hospel Date: Sat, 11 Jun 2011 19:28:00 +0000 (-0700) Subject: [perl #85026] Iterate hashes by hand during do_sv_dump X-Git-Tag: accepted/trunk/20130322.191538~3783 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b56985536ef770e44bf6493dc7da7eed7e5c61b2;p=platform%2Fupstream%2Fperl.git [perl #85026] Iterate hashes by hand during do_sv_dump 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 --- diff --git a/dump.c b/dump.c index a5d71bc..c32807c 100644 --- 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;