This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Re: perldoc, temp files, async pagers
[perl5.git] / scope.c
diff --git a/scope.c b/scope.c
index 03cdddd..3ca31aa 100644 (file)
--- a/scope.c
+++ b/scope.c
 #include "EXTERN.h"
 #include "perl.h"
 
+/*
+ * This value determines how small an SV is "small enough" to keep
+ * in a lexical variable in anticipation of the next invocation.
+ */
+#define PADVAL_SMALL_ENOUGH 240
+
 SV**
 stack_grow(sp, p, n)
 SV** sp;
@@ -107,19 +113,14 @@ free_tmps()
     }
 }
 
-SV *
-save_scalar(gv)
-GV *gv;
+static SV *
+save_scalar_at(sptr)
+SV **sptr;
 {
     register SV *sv;
-    SV *osv = GvSV(gv);
-
-    SSCHECK(3);
-    SSPUSHPTR(gv);
-    SSPUSHPTR(osv);
-    SSPUSHINT(SAVEt_SV);
+    SV *osv = *sptr;
 
-    sv = GvSV(gv) = NEWSV(0,0);
+    sv = *sptr = NEWSV(0,0);
     if (SvTYPE(osv) >= SVt_PVMG && SvMAGIC(osv) && SvTYPE(osv) != SVt_PVGV) {
        sv_upgrade(sv, SvTYPE(osv));
        if (SvGMAGICAL(osv)) {
@@ -143,62 +144,51 @@ GV *gv;
     return sv;
 }
 
-#ifdef INLINED_ELSEWHERE
-void
-save_gp(gv)
+SV *
+save_scalar(gv)
 GV *gv;
 {
-    register GP *gp;
-    GP *ogp = GvGP(gv);
-
     SSCHECK(3);
-    SSPUSHPTR(SvREFCNT_inc(gv));
-    SSPUSHPTR(ogp);
-    SSPUSHINT(SAVEt_GP);
-
-    Newz(602,gp, 1, GP);
-    GvGP(gv) = gp;
-    GvREFCNT(gv) = 1;
-    GvSV(gv) = NEWSV(72,0);
-    GvLINE(gv) = curcop->cop_line;
-    GvEGV(gv) = gv;
+    SSPUSHPTR(gv);
+    SSPUSHPTR(GvSV(gv));
+    SSPUSHINT(SAVEt_SV);
+    return save_scalar_at(&GvSV(gv));
 }
-#endif
 
 SV*
 save_svref(sptr)
 SV **sptr;
 {
-    register SV *sv;
-    SV *osv = *sptr;
-
     SSCHECK(3);
-    SSPUSHPTR(*sptr);
     SSPUSHPTR(sptr);
+    SSPUSHPTR(*sptr);
     SSPUSHINT(SAVEt_SVREF);
+    return save_scalar_at(sptr);
+}
 
-    sv = *sptr = NEWSV(0,0);
-    if (SvTYPE(osv) >= SVt_PVMG && SvMAGIC(osv) && SvTYPE(osv) != SVt_PVGV) {
-       sv_upgrade(sv, SvTYPE(osv));
-       if (SvGMAGICAL(osv)) {
-           MAGIC* mg;
-           bool oldtainted = tainted;
-           mg_get(osv);
-           if (tainting && tainted && (mg = mg_find(osv, 't'))) {
-               SAVESPTR(mg->mg_obj);
-               mg->mg_obj = osv;
-           }
-           SvFLAGS(osv) |= (SvFLAGS(osv) &
-               (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
-           tainted = oldtainted;
-       }
-       SvMAGIC(sv) = SvMAGIC(osv);
-       SvFLAGS(sv) |= SvMAGICAL(osv);
-       localizing = 1;
-       SvSETMAGIC(sv);
-       localizing = 0;
+void
+save_gp(gv, empty)
+GV *gv;
+I32 empty;
+{
+    SSCHECK(3);
+    SSPUSHPTR(SvREFCNT_inc(gv));
+    SSPUSHPTR(GvGP(gv));
+    SSPUSHINT(SAVEt_GP);
+
+    if (empty) {
+       register GP *gp;
+       Newz(602, gp, 1, GP);
+       GvGP(gv) = gp;
+       GvREFCNT(gv) = 1;
+       GvSV(gv) = NEWSV(72,0);
+       GvLINE(gv) = curcop->cop_line;
+       GvEGV(gv) = gv;
+    }
+    else {
+       GvGP(gv)->gp_refcnt++;
+       GvINTRO_on(gv);
     }
-    return sv;
 }
 
 AV *
@@ -272,6 +262,16 @@ I32 *intp;
 }
 
 void
+save_I16(intp)
+I16 *intp;
+{
+    SSCHECK(3);
+    SSPUSHINT(*intp);
+    SSPUSHPTR(intp);
+    SSPUSHINT(SAVEt_I16);
+}
+
+void
 save_iv(ivp)
 IV *ivp;
 {
@@ -437,26 +437,13 @@ I32 base;
         case SAVEt_SV:                         /* scalar reference */
            value = (SV*)SSPOPPTR;
            gv = (GV*)SSPOPPTR;
-           sv = GvSV(gv);
-           if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv) &&
-               SvTYPE(sv) != SVt_PVGV)
-           {
-               (void)SvUPGRADE(value, SvTYPE(sv));
-               SvMAGIC(value) = SvMAGIC(sv);
-               SvFLAGS(value) |= SvMAGICAL(sv);
-               SvMAGICAL_off(sv);
-               SvMAGIC(sv) = 0;
-           }
-            SvREFCNT_dec(sv);
-            GvSV(gv) = value;
-           localizing = 2;
-           SvSETMAGIC(value);
-           localizing = 0;
-            break;
+           ptr = &GvSV(gv);
+           goto restore_sv;
         case SAVEt_SVREF:                      /* scalar reference */
+           value = (SV*)SSPOPPTR;
            ptr = SSPOPPTR;
+       restore_sv:
            sv = *(SV**)ptr;
-           value = (SV*)SSPOPPTR;
            if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv) &&
                SvTYPE(sv) != SVt_PVGV)
            {
@@ -466,6 +453,14 @@ I32 base;
                SvMAGICAL_off(sv);
                SvMAGIC(sv) = 0;
            }
+           else if (SvTYPE(value) >= SVt_PVMG && SvMAGIC(value) &&
+                    SvTYPE(value) != SVt_PVGV)
+           {
+               SvFLAGS(value) |= (SvFLAGS(value) &
+                                  (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
+               SvMAGICAL_off(value);
+               SvMAGIC(value) = 0;
+           }
             SvREFCNT_dec(sv);
            *(SV**)ptr = value;
            localizing = 2;
@@ -496,6 +491,10 @@ I32 base;
            ptr = SSPOPPTR;
            *(I32*)ptr = (I32)SSPOPINT;
            break;
+       case SAVEt_I16:                         /* I16 reference */
+           ptr = SSPOPPTR;
+           *(I16*)ptr = (I16)SSPOPINT;
+           break;
        case SAVEt_IV:                          /* IV reference */
            ptr = SSPOPPTR;
            *(IV*)ptr = (IV)SSPOPIV;
@@ -557,19 +556,33 @@ I32 base;
                case SVt_NULL:
                    break;
                case SVt_PVAV:
-                   av_clear((AV*)sv);
+                   if (AvMAX(sv) < (PADVAL_SMALL_ENOUGH / sizeof(SV*)))
+                       av_clear((AV*)sv);
+                   else
+                       av_undef((AV*)sv);
                    break;
                case SVt_PVHV:
-                   hv_clear((HV*)sv);
+                   if (HvMAX(sv) < (PADVAL_SMALL_ENOUGH / sizeof(SV*)))
+                       hv_clear((HV*)sv);
+                   else
+                       hv_undef((HV*)sv);
                    break;
                case SVt_PVCV:
-                   sub_generation++;
-                   cv_undef((CV*)sv);
+                   croak("panic: leave_scope pad code");
+               case SVt_RV:
+               case SVt_IV:
+               case SVt_NV:
+                   (void)SvOK_off(sv);
                    break;
                default:
-                   if (SvPOK(sv) && SvLEN(sv))
-                       (void)SvOOK_off(sv);
                    (void)SvOK_off(sv);
+                   (void)SvOOK_off(sv);
+                   if (SvPVX(sv) && SvLEN(sv) > PADVAL_SMALL_ENOUGH) {
+                       Safefree(SvPVX(sv));
+                       SvPVX(sv) = Nullch;
+                       SvLEN(sv) = 0;
+                       SvCUR(sv) = 0;
+                   }
                    break;
                }
            }
@@ -601,6 +614,12 @@ I32 base;
                savestack_ix -= delta;  /* regexp must have croaked */
            }
            break;
+       case SAVEt_STACK_POS:           /* Position on Perl stack */
+           {
+               I32 delta = SSPOPINT;
+               stack_sp = stack_base + delta;
+           }
+           break;
        default:
            croak("panic: leave_scope inconsistency");
        }
@@ -671,6 +690,8 @@ CONTEXT* cx;
        if (cx->blk_loop.itervar)
            PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERSAVE = 0x%lx\n",
                (long)cx->blk_loop.itersave);
+       PerlIO_printf(Perl_debug_log, "BLK_LOOP.ITERLVAL = 0x%lx\n",
+               (long)cx->blk_loop.iterlval);
        break;
 
     case CXt_SUBST: