diff options
-rw-r--r-- | gv.c | 17 | ||||
-rw-r--r-- | hv.h | 2 | ||||
-rw-r--r-- | sv.h | 1 |
3 files changed, 14 insertions, 6 deletions
@@ -2258,23 +2258,30 @@ Perl_gv_check(pTHX_ HV *stash) { dVAR; I32 i; + struct xpvhv_aux *aux; PERL_ARGS_ASSERT_GV_CHECK; if (!HvARRAY(stash)) return; + + assert(SvOOK(stash)); + aux = HvAUX(stash); + for (i = 0; i <= (I32) HvMAX(stash); i++) { const HE *entry; - /* SvIsCOW is unused on HVs, so we can use it to mark stashes we - are currently searching through recursively. */ - SvIsCOW_on(stash); + /* mark stash is being scanned, to avoid recursing */ + aux->xhv_aux_flags |= HvAUXf_SCAN_STASH; for (entry = HvARRAY(stash)[i]; entry; entry = HeNEXT(entry)) { GV *gv; HV *hv; if (HeKEY(entry)[HeKLEN(entry)-1] == ':' && (gv = MUTABLE_GV(HeVAL(entry))) && isGV(gv) && (hv = GvHV(gv))) { - if (hv != PL_defstash && hv != stash && !SvIsCOW(hv)) + if (hv != PL_defstash && hv != stash + && !(SvOOK(hv) + && (HvAUX(hv)->xhv_aux_flags & HvAUXf_SCAN_STASH)) + ) gv_check(hv); /* nested package */ } else if ( *HeKEY(entry) != '_' @@ -2298,7 +2305,7 @@ Perl_gv_check(pTHX_ HV *stash) HEKfARG(GvNAME_HEK(gv))); } } - SvIsCOW_off(stash); + aux->xhv_aux_flags &= ~HvAUXf_SCAN_STASH; } } @@ -122,6 +122,8 @@ struct xpvhv_aux { U32 xhv_aux_flags; /* assorted extra flags */ }; +#define HvAUXf_SCAN_STASH 0x1 /* stash is being scanned by gv_check */ + /* hash structure: */ /* This structure must match the beginning of struct xpvmg in sv.h. */ struct xpvhv { @@ -364,7 +364,6 @@ perform the upgrade if necessary. See C<svtype>. #define SVpad_NAMELIST SVp_SCREAM /* AV is a padnamelist */ #define SVf_IsCOW 0x00010000 /* copy on write (shared hash key if SvLEN == 0) */ - /* Also used on HVs in gv.c:gv_check */ #define SVs_PADTMP 0x00020000 /* in use as tmp; only if ! SVs_PADMY */ #define SVs_PADSTALE 0x00020000 /* lexical has gone out of scope; only valid for SVs_PADMY */ |