This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
regcomp.c: Remove unnecessary 'if' test
[perl5.git] / scope.c
diff --git a/scope.c b/scope.c
index 4a1b399..2a9b3d5 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -181,13 +181,13 @@ S_save_scalar_at(pTHX_ SV **sptr, const U32 flags)
     osv = *sptr;
     sv  = (flags & SAVEf_KEEPOLDELEM) ? osv : (*sptr = newSV(0));
 
-    if (SvTYPE(osv) >= SVt_PVMG && SvMAGIC(osv) && SvTYPE(osv) != SVt_PVGV) {
+    if (SvTYPE(osv) >= SVt_PVMG && SvMAGIC(osv)) {
        if (SvGMAGICAL(osv)) {
            SvFLAGS(osv) |= (SvFLAGS(osv) &
               (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
        }
        if (!(flags & SAVEf_KEEPOLDELEM))
-           mg_localize(osv, sv, (flags & SAVEf_SETMAGIC) != 0);
+           mg_localize(osv, sv, cBOOL(flags & SAVEf_SETMAGIC));
     }
 
     return sv;
@@ -279,15 +279,7 @@ Perl_save_gp(pTHX_ GV *gv, I32 empty)
 
     PERL_ARGS_ASSERT_SAVE_GP;
 
-    SSCHECK(4);
-    SSPUSHINT(SvFAKE(gv));
-    SSPUSHPTR(GvGP(gv));
-    SSPUSHPTR(SvREFCNT_inc(gv));
-    SSPUSHUV(SAVEt_GP);
-
-    /* Don't let the localized GV coerce into non-glob, otherwise we would
-     * not be able to restore GP upon leave from context if that happened */
-    SvFAKE_off(gv);
+    save_pushptrptr(SvREFCNT_inc(gv), GvGP(gv), SAVEt_GP);
 
     if (empty) {
        GP *gp = Perl_newGP(aTHX_ gv);
@@ -306,7 +298,7 @@ Perl_save_gp(pTHX_ GV *gv, I32 empty)
            gp->gp_sv = newSV(0);
        }
 #endif
-       GvGP(gv) = gp;
+       GvGP_set(gv,gp);
     }
     else {
        gp_ref(GvGP(gv));
@@ -325,7 +317,7 @@ Perl_save_ary(pTHX_ GV *gv)
 
     if (!AvREAL(oav) && AvREIFY(oav))
        av_reify(oav);
-    save_pushptrptr(gv, oav, SAVEt_AV);
+    save_pushptrptr(SvREFCNT_inc_simple_NN(gv), oav, SAVEt_AV);
 
     GvAV(gv) = NULL;
     av = GvAVn(gv);
@@ -342,7 +334,9 @@ Perl_save_hash(pTHX_ GV *gv)
 
     PERL_ARGS_ASSERT_SAVE_HASH;
 
-    save_pushptrptr(gv, (ohv = GvHVn(gv)), SAVEt_HV);
+    save_pushptrptr(
+       SvREFCNT_inc_simple_NN(gv), (ohv = GvHVn(gv)), SAVEt_HV
+    );
 
     GvHV(gv) = NULL;
     hv = GvHVn(gv);
@@ -600,8 +594,10 @@ Perl_save_hints(pTHX)
     dVAR;
     COPHH *save_cophh = cophh_copy(CopHINTHASH_get(&PL_compiling));
     if (PL_hints & HINT_LOCALIZE_HH) {
-       save_pushptri32ptr(GvHV(PL_hintgv), PL_hints, save_cophh, SAVEt_HINTS);
-       GvHV(PL_hintgv) = hv_copy_hints_hv(GvHV(PL_hintgv));
+       HV *oldhh = GvHV(PL_hintgv);
+       save_pushptri32ptr(oldhh, PL_hints, save_cophh, SAVEt_HINTS);
+       GvHV(PL_hintgv) = NULL; /* in case copying dies */
+       GvHV(PL_hintgv) = hv_copy_hints_hv(oldhh);
     } else {
        save_pushi32ptr(PL_hints, save_cophh, SAVEt_HINTS);
     }
@@ -715,10 +711,10 @@ Perl_leave_scope(pTHX_ I32 base)
     register char* str;
     I32 i;
     /* Localise the effects of the TAINT_NOT inside the loop.  */
-    const bool was = PL_tainted;
+    bool was = PL_tainted;
 
     if (base < -1)
-       Perl_croak(aTHX_ "panic: corrupt saved stack index");
+       Perl_croak(aTHX_ "panic: corrupt saved stack index %ld", (long) base);
     DEBUG_l(Perl_deb(aTHX_ "savestack: releasing items %ld -> %ld\n",
                        (long)PL_savestack_ix, (long)base));
     while (PL_savestack_ix > base) {
@@ -748,8 +744,7 @@ Perl_leave_scope(pTHX_ I32 base)
            SvSETMAGIC(value);
            PL_localizing = 0;
            SvREFCNT_dec(value);
-           if (av) /* actually an av, hv or gv */
-               SvREFCNT_dec(av);
+           SvREFCNT_dec(av); /* av may actually be an AV, HV or GV */
            break;
        case SAVEt_GENERIC_PVREF:               /* generic pv */
            ptr = SSPOPPTR;
@@ -795,6 +790,7 @@ Perl_leave_scope(pTHX_ I32 base)
                SvSETMAGIC(MUTABLE_SV(av));
                PL_localizing = 0;
            }
+           SvREFCNT_dec(gv);
            break;
        case SAVEt_HV:                          /* hash reference */
            hv = MUTABLE_HV(SSPOPPTR);
@@ -806,6 +802,7 @@ Perl_leave_scope(pTHX_ I32 base)
                SvSETMAGIC(MUTABLE_SV(hv));
                PL_localizing = 0;
            }
+           SvREFCNT_dec(gv);
            break;
        case SAVEt_INT_SMALL:
            ptr = SSPOPPTR;
@@ -818,6 +815,15 @@ Perl_leave_scope(pTHX_ I32 base)
        case SAVEt_BOOL:                        /* bool reference */
            ptr = SSPOPPTR;
            *(bool*)ptr = cBOOL(uv >> 8);
+
+           if (ptr == &PL_tainted) {
+               /* If we don't update <was>, to reflect what was saved on the
+                * stack for PL_tainted, then we will overwrite this attempt to
+                * restore it when we exit this routine.  Note that this won't
+                * work if this value was saved in a wider-than necessary type,
+                * such as I32 */
+               was = *(bool*)ptr;
+           }
            break;
        case SAVEt_I32_SMALL:
            ptr = SSPOPPTR;
@@ -853,11 +859,10 @@ Perl_leave_scope(pTHX_ I32 base)
            *(AV**)ptr = MUTABLE_AV(SSPOPPTR);
            break;
        case SAVEt_GP:                          /* scalar reference */
+           ptr = SSPOPPTR;
            gv = MUTABLE_GV(SSPOPPTR);
            gp_free(gv);
-           GvGP(gv) = (GP*)SSPOPPTR;
-           if (SSPOPINT)
-               SvFAKE_on(gv);
+           GvGP_set(gv, (GP*)ptr);
             /* putting a method back into circulation ("local")*/
            if (GvCVu(gv) && (hv=GvSTASH(gv)) && HvENAME_get(hv))
                 mro_method_changed_in(hv);
@@ -907,7 +912,10 @@ Perl_leave_scope(pTHX_ I32 base)
 
                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)) {
@@ -928,7 +936,8 @@ Perl_leave_scope(pTHX_ I32 base)
                SvPADSTALE_on(sv); /* mark as no longer live */
            }
            else {      /* Someone has a claim on this, so abandon it. */
-               const U32 padflags = SvFLAGS(sv) & (SVs_PADMY|SVs_PADTMP);
+               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;
@@ -937,7 +946,7 @@ Perl_leave_scope(pTHX_ I32 base)
                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) |= padflags | SVs_PADSTALE;
+               SvFLAGS(*(SV**)ptr) |= (SVs_PADMY|SVs_PADSTALE);
            }
            break;
        case SAVEt_DELETE:
@@ -1014,9 +1023,12 @@ Perl_leave_scope(pTHX_ I32 base)
            PL_op = (OP*)SSPOPPTR;
            break;
        case SAVEt_HINTS:
-           if ((PL_hints & HINT_LOCALIZE_HH) && GvHV(PL_hintgv)) {
-               SvREFCNT_dec(MUTABLE_SV(GvHV(PL_hintgv)));
+           if ((PL_hints & HINT_LOCALIZE_HH)) {
+             while (GvHV(PL_hintgv)) {
+               HV *hv = GvHV(PL_hintgv);
                GvHV(PL_hintgv) = NULL;
+               SvREFCNT_dec(MUTABLE_SV(hv));
+             }
            }
            cophh_free(CopHINTHASH_get(&PL_compiling));
            CopHINTHASH_set(&PL_compiling, (COPHH*)SSPOPPTR);
@@ -1024,23 +1036,10 @@ Perl_leave_scope(pTHX_ I32 base)
            if (PL_hints & HINT_LOCALIZE_HH) {
                SvREFCNT_dec(MUTABLE_SV(GvHV(PL_hintgv)));
                GvHV(PL_hintgv) = MUTABLE_HV(SSPOPPTR);
-               assert(GvHV(PL_hintgv));
-           } else if (!GvHV(PL_hintgv)) {
-               /* Need to add a new one manually, else gv_fetchpv() can
-                  add one in this code:
-                  
-                  if (SvTYPE(gv) == SVt_PVGV) {
-                      if (add) {
-                      GvMULTI_on(gv);
-                      gv_init_sv(gv, sv_type);
-                      if (*name=='!' && sv_type == SVt_PVHV && len==1)
-                          require_errno(gv);
-                      }
-                      return gv;
-                  }
-
-                  and it won't have the magic set.  */
-
+           }
+           if (!GvHV(PL_hintgv)) {
+               /* Need to add a new one manually, else rv2hv can
+                  add one via GvHVn and it won't have the magic set.  */
                HV *const hv = newHV();
                hv_magic(hv, NULL, PERL_MAGIC_hints);
                GvHV(PL_hintgv) = hv;
@@ -1121,11 +1120,6 @@ Perl_leave_scope(pTHX_ I32 base)
            ptr = SSPOPPTR;
            (*SSPOPDPTR)(ptr);
            break;
-       case SAVEt_COP_ARYBASE:
-           ptr = SSPOPPTR;
-           i = SSPOPINT;
-           CopARYBASE_set((COP *)ptr, i);
-           break;
        case SAVEt_COMPILE_WARNINGS:
            ptr = SSPOPPTR;
 
@@ -1142,9 +1136,6 @@ Perl_leave_scope(pTHX_ I32 base)
                     - SAVESTACK_ALLOC_FOR_RE_SAVE_STATE);
                PL_savestack_ix -= SAVESTACK_ALLOC_FOR_RE_SAVE_STATE;
 
-               if (PL_reg_start_tmp != state->re_state_reg_start_tmp) {
-                   Safefree(PL_reg_start_tmp);
-               }
                if (PL_reg_poscache != state->re_state_reg_poscache) {
                    Safefree(PL_reg_poscache);
                }
@@ -1156,7 +1147,7 @@ Perl_leave_scope(pTHX_ I32 base)
            parser_free((yy_parser *) ptr);
            break;
        default:
-           Perl_croak(aTHX_ "panic: leave_scope inconsistency");
+           Perl_croak(aTHX_ "panic: leave_scope inconsistency %u", type);
        }
     }
 
@@ -1279,8 +1270,8 @@ Perl_cx_dump(pTHX_ PERL_CONTEXT *cx)
  * Local variables:
  * c-indentation-style: bsd
  * c-basic-offset: 4
- * indent-tabs-mode: t
+ * indent-tabs-mode: nil
  * End:
  *
- * ex: set ts=8 sts=4 sw=4 noet:
+ * ex: set ts=8 sts=4 sw=4 et:
  */