This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Install perlfaq and perlglossary manpages in section 1 of the manual
[perl5.git] / scope.c
diff --git a/scope.c b/scope.c
index 2d9e383..cb0e8c5 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -77,10 +77,10 @@ Perl_cxinc(pTHX)
     dVAR;
     const IV old_max = cxstack_max;
     cxstack_max = GROW(cxstack_max);
-    Renew(cxstack, cxstack_max, PERL_CONTEXT);
+    Renew(cxstack, cxstack_max + 1, PERL_CONTEXT);
     /* Without any kind of initialising deep enough recursion
      * will end up reading uninitialised PERL_CONTEXTs. */
-    PoisonNew(cxstack + old_max, cxstack_max - old_max, PERL_CONTEXT);
+    PoisonNew(cxstack + old_max + 1, cxstack_max - old_max, PERL_CONTEXT);
     return cxstack_ix + 1;
 }
 
@@ -181,15 +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)) {
-           const bool oldtainted = PL_tainted;
            SvFLAGS(osv) |= (SvFLAGS(osv) &
               (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
-           PL_tainted = oldtainted;
        }
        if (!(flags & SAVEf_KEEPOLDELEM))
-           mg_localize(osv, sv, (flags & SAVEf_SETMAGIC) != 0);
+           mg_localize(osv, sv, cBOOL(flags & SAVEf_SETMAGIC));
     }
 
     return sv;
@@ -281,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);
@@ -308,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));
@@ -327,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);
@@ -344,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,17 +592,12 @@ void
 Perl_save_hints(pTHX)
 {
     dVAR;
-    if (PL_compiling.cop_hints_hash) {
-       HINTS_REFCNT_LOCK;
-           PL_compiling.cop_hints_hash->refcounted_he_refcnt++;
-           HINTS_REFCNT_UNLOCK;
-    }
+    COPHH *save_cophh = cophh_copy(CopHINTHASH_get(&PL_compiling));
     if (PL_hints & HINT_LOCALIZE_HH) {
-       save_pushptri32ptr(GvHV(PL_hintgv), PL_hints,
-                          PL_compiling.cop_hints_hash, SAVEt_HINTS);
-       GvHV(PL_hintgv) = Perl_hv_copy_hints_hv(aTHX_ GvHV(PL_hintgv));
+       save_pushptri32ptr(GvHV(PL_hintgv), PL_hints, save_cophh, SAVEt_HINTS);
+       GvHV(PL_hintgv) = hv_copy_hints_hv(GvHV(PL_hintgv));
     } else {
-       save_pushi32ptr(PL_hints, PL_compiling.cop_hints_hash, SAVEt_HINTS);
+       save_pushi32ptr(PL_hints, save_cophh, SAVEt_HINTS);
     }
 }
 
@@ -755,8 +742,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;
@@ -778,9 +764,15 @@ Perl_leave_scope(pTHX_ I32 base)
                *(char**)ptr = str;
            }
            break;
+       case SAVEt_GVSV:                        /* scalar slot in GV */
+           value = MUTABLE_SV(SSPOPPTR);
+           gv = MUTABLE_GV(SSPOPPTR);
+           ptr = &GvSV(gv);
+           goto restore_svp;
        case SAVEt_GENERIC_SVREF:               /* generic sv */
            value = MUTABLE_SV(SSPOPPTR);
            ptr = SSPOPPTR;
+       restore_svp:
            sv = *(SV**)ptr;
            *(SV**)ptr = value;
            SvREFCNT_dec(sv);
@@ -796,6 +788,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);
@@ -807,6 +800,7 @@ Perl_leave_scope(pTHX_ I32 base)
                SvSETMAGIC(MUTABLE_SV(hv));
                PL_localizing = 0;
            }
+           SvREFCNT_dec(gv);
            break;
        case SAVEt_INT_SMALL:
            ptr = SSPOPPTR;
@@ -854,13 +848,12 @@ 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)) && HvNAME_get(hv))
+           if (GvCVu(gv) && (hv=GvSTASH(gv)) && HvENAME_get(hv))
                 mro_method_changed_in(hv);
            SvREFCNT_dec(gv);
            break;
@@ -868,6 +861,10 @@ Perl_leave_scope(pTHX_ I32 base)
            ptr = SSPOPPTR;
            SvREFCNT_dec(MUTABLE_SV(ptr));
            break;
+       case SAVEt_FREECOPHH:
+           ptr = SSPOPPTR;
+           cophh_free((COPHH *)ptr);
+           break;
        case SAVEt_MORTALIZESV:
            ptr = SSPOPPTR;
            sv_2mortal(MUTABLE_SV(ptr));
@@ -904,7 +901,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)) {
@@ -925,7 +925,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;
@@ -934,7 +935,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:
@@ -1015,8 +1016,8 @@ Perl_leave_scope(pTHX_ I32 base)
                SvREFCNT_dec(MUTABLE_SV(GvHV(PL_hintgv)));
                GvHV(PL_hintgv) = NULL;
            }
-           Perl_refcounted_he_free(aTHX_ PL_compiling.cop_hints_hash);
-           PL_compiling.cop_hints_hash = (struct refcounted_he *) SSPOPPTR;
+           cophh_free(CopHINTHASH_get(&PL_compiling));
+           CopHINTHASH_set(&PL_compiling, (COPHH*)SSPOPPTR);
            *(I32*)&PL_hints = (I32)SSPOPINT;
            if (PL_hints & HINT_LOCALIZE_HH) {
                SvREFCNT_dec(MUTABLE_SV(GvHV(PL_hintgv)));
@@ -1118,11 +1119,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;
 
@@ -1232,8 +1228,6 @@ Perl_cx_dump(pTHX_ PERL_CONTEXT *cx)
                (long)cx->blk_loop.resetsp);
        PerlIO_printf(Perl_debug_log, "BLK_LOOP.MY_OP = 0x%"UVxf"\n",
                PTR2UV(cx->blk_loop.my_op));
-       PerlIO_printf(Perl_debug_log, "BLK_LOOP.NEXT_OP = 0x%"UVxf"\n",
-               PTR2UV(CX_LOOP_NEXTOP_GET(cx)));
        /* XXX: not accurate for LAZYSV/IV */
        PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERARY = 0x%"UVxf"\n",
                PTR2UV(cx->blk_loop.state_u.ary.ary));