- ptr = (void*)&PL_curpad[uv >> SAVE_TIGHT_SHIFT];
- sv = *(SV**)ptr;
-
- DEBUG_Xv(PerlIO_printf(Perl_debug_log,
- "Pad 0x%"UVxf"[0x%"UVxf"] clearsv: %ld sv=0x%"UVxf"<%"IVdf"> %s\n",
- PTR2UV(PL_comppad), PTR2UV(PL_curpad),
- (long)((SV **)ptr-PL_curpad), PTR2UV(sv), (IV)SvREFCNT(sv),
- (SvREFCNT(sv) <= 1 && !SvOBJECT(sv)) ? "clear" : "abandon"
- ));
-
- /* Can clear pad variable in place? */
- if (SvREFCNT(sv) <= 1 && !SvOBJECT(sv)) {
- /*
- * if a my variable that was made readonly is going out of
- * scope, we want to remove the readonlyness so that it can
- * go out of scope quietly
- */
- if (SvPADMY(sv) && !SvFAKE(sv))
- SvREADONLY_off(sv);
-
- if (SvTHINKFIRST(sv))
- sv_force_normal_flags(sv, SV_IMMEDIATE_UNREF);
- if (SvTYPE(sv) == SVt_PVHV)
- Perl_hv_kill_backrefs(aTHX_ MUTABLE_HV(sv));
- if (SvMAGICAL(sv))
- sv_unmagic(sv, PERL_MAGIC_backref),
- mg_free(sv);
-
- switch (SvTYPE(sv)) {
- case SVt_NULL:
- break;
- case SVt_PVAV:
- av_clear(MUTABLE_AV(sv));
- break;
- case SVt_PVHV:
- hv_clear(MUTABLE_HV(sv));
- break;
- case SVt_PVCV:
- Perl_croak(aTHX_ "panic: leave_scope pad code");
- default:
- SvOK_off(sv);
- break;
- }
- SvPADSTALE_on(sv); /* mark as no longer live */
- }
- else { /* Someone has a claim on this, so abandon it. */
- assert( SvFLAGS(sv) & SVs_PADMY);
- assert(!(SvFLAGS(sv) & SVs_PADTMP));
- switch (SvTYPE(sv)) { /* Console ourselves with a new value */
- case SVt_PVAV: *(SV**)ptr = MUTABLE_SV(newAV()); break;
- case SVt_PVHV: *(SV**)ptr = MUTABLE_SV(newHV()); break;
- default: *(SV**)ptr = newSV(0); break;
- }
- SvREFCNT_dec(sv); /* Cast current value to the winds. */
- /* preserve pad nature, but also mark as not live
- * for any closure capturing */
- SvFLAGS(*(SV**)ptr) |= (SVs_PADMY|SVs_PADSTALE);
- }
+ svp = &PL_curpad[uv >> SAVE_TIGHT_SHIFT];
+ i = 1;
+ clearsv:
+ for (; i; i--, svp--) {
+ sv = *svp;
+
+ DEBUG_Xv(PerlIO_printf(Perl_debug_log,
+ "Pad 0x%"UVxf"[0x%"UVxf"] clearsv: %ld sv=0x%"UVxf"<%"IVdf"> %s\n",
+ PTR2UV(PL_comppad), PTR2UV(PL_curpad),
+ (long)(svp-PL_curpad), PTR2UV(sv), (IV)SvREFCNT(sv),
+ (SvREFCNT(sv) <= 1 && !SvOBJECT(sv)) ? "clear" : "abandon"
+ ));
+
+ /* Can clear pad variable in place? */
+ if (SvREFCNT(sv) == 1 && !SvOBJECT(sv)) {
+
+ /* these flags are the union of all the relevant flags
+ * in the individual conditions within */
+ if (UNLIKELY(SvFLAGS(sv) & (
+ SVf_READONLY|SVf_PROTECT /*for SvREADONLY_off*/
+ | (SVs_GMG|SVs_SMG|SVs_RMG) /* SvMAGICAL() */
+ | SVf_OOK
+ | SVf_THINKFIRST)))
+ {
+ /* if a my variable that was made readonly is
+ * going out of scope, we want to remove the
+ * readonlyness so that it can go out of scope
+ * quietly
+ */
+ if (SvREADONLY(sv))
+ SvREADONLY_off(sv);
+
+ if (SvOOK(sv)) { /* OOK or HvAUX */
+ if (SvTYPE(sv) == SVt_PVHV)
+ Perl_hv_kill_backrefs(aTHX_ MUTABLE_HV(sv));
+ else
+ sv_backoff(sv);
+ }
+
+ if (SvMAGICAL(sv)) {
+ /* note that backrefs (either in HvAUX or magic)
+ * must be removed before other magic */
+ sv_unmagic(sv, PERL_MAGIC_backref);
+ if (SvTYPE(sv) != SVt_PVCV)
+ mg_free(sv);
+ }
+ if (SvTHINKFIRST(sv))
+ sv_force_normal_flags(sv, SV_IMMEDIATE_UNREF
+ |SV_COW_DROP_PV);
+
+ }
+ switch (SvTYPE(sv)) {
+ case SVt_NULL:
+ break;
+ case SVt_PVAV:
+ av_clear(MUTABLE_AV(sv));
+ break;
+ case SVt_PVHV:
+ hv_clear(MUTABLE_HV(sv));
+ break;
+ case SVt_PVCV:
+ {
+ HEK *hek =
+ CvNAMED(sv)
+ ? CvNAME_HEK((CV *)sv)
+ : GvNAME_HEK(CvGV(sv));
+ assert(hek);
+ (void)share_hek_hek(hek);
+ cv_undef((CV *)sv);
+ CvNAME_HEK_set(sv, hek);
+ CvLEXICAL_on(sv);
+ break;
+ }
+ default:
+ /* This looks odd, but these two macros are for use in
+ expressions and finish with a trailing comma, so
+ adding a ; after them would be wrong. */
+ assert_not_ROK(sv)
+ assert_not_glob(sv)
+ SvFLAGS(sv) &=~ (SVf_OK|SVf_IVisUV|SVf_UTF8);
+ break;
+ }
+ SvPADTMP_off(sv);
+ SvPADSTALE_on(sv); /* mark as no longer live */
+ }
+ else { /* Someone has a claim on this, so abandon it. */
+ switch (SvTYPE(sv)) { /* Console ourselves with a new value */
+ case SVt_PVAV: *svp = MUTABLE_SV(newAV()); break;
+ case SVt_PVHV: *svp = MUTABLE_SV(newHV()); break;
+ case SVt_PVCV:
+ {
+ HEK * const hek = CvNAMED(sv)
+ ? CvNAME_HEK((CV *)sv)
+ : GvNAME_HEK(CvGV(sv));
+
+ /* Create a stub */
+ *svp = newSV_type(SVt_PVCV);
+
+ /* Share name */
+ CvNAME_HEK_set(*svp,
+ share_hek_hek(hek));
+ CvLEXICAL_on(*svp);
+ break;
+ }
+ default: *svp = newSV(0); break;
+ }
+ SvREFCNT_dec_NN(sv); /* Cast current value to the winds. */
+ /* preserve pad nature, but also mark as not live
+ * for any closure capturing */
+ SvFLAGS(*svp) |= SVs_PADSTALE;
+ }
+ }