This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
SAVEt_CLEARSV: simplify SvREADONLY_off() condition
[perl5.git] / pad.c
diff --git a/pad.c b/pad.c
index d8d9322..419b403 100644 (file)
--- a/pad.c
+++ b/pad.c
@@ -89,9 +89,9 @@ sometimes hijacked to store the generation number during compilation.
 
 If PADNAME_OUTER (SvFAKE) is set on the
 name SV, then that slot in the frame AV is
-a REFCNT'ed reference to a lexical from "outside". In this case,
+a REFCNT'ed reference to a lexical from "outside".  In this case,
 the name SV does not use xlow and xhigh to store a cop_seq range, since it is
-in scope throughout. Instead xhigh stores some flags containing info about
+in scope throughout.  Instead xhigh stores some flags containing info about
 the real lexical (is it declared in an anon, and is it capable of being
 instantiated multiple times?), and for fake ANONs, xlow contains the index
 within the parent's pad where the lexical's value is stored, to make
@@ -285,6 +285,7 @@ Perl_pad_new(pTHX_ int flags)
        av_store(pad, 0, NULL);
        padname = newAV();
        AvPAD_NAMELIST_on(padname);
+       av_store(padname, 0, &PL_sv_undef);
     }
 
     /* Most subroutines never recurse, hence only need 2 entries in the padlist
@@ -327,7 +328,7 @@ Perl_pad_new(pTHX_ int flags)
 
 =for apidoc cv_undef
 
-Clear out all the active components of a CV. This can happen either
+Clear out all the active components of a CV.  This can happen either
 by an explicit C<undef &foo>, or by the reference count going to zero.
 In the former case, we keep the CvOUTSIDE pointer, so that any anonymous
 children can still follow the full lexical scope chain.
@@ -1109,20 +1110,21 @@ Perl_find_rundefsv2(pTHX_ CV *cv, U32 seq)
 /*
 =for apidoc m|PADOFFSET|pad_findlex|const char *namepv|STRLEN namelen|U32 flags|const CV* cv|U32 seq|int warn|SV** out_capture|SV** out_name_sv|int *out_flags
 
-Find a named lexical anywhere in a chain of nested pads. Add fake entries
+Find a named lexical anywhere in a chain of nested pads.  Add fake entries
 in the inner pads if it's found in an outer one.
 
 Returns the offset in the bottom pad of the lex or the fake lex.
 cv is the CV in which to start the search, and seq is the current cop_seq
-to match against. If warn is true, print appropriate warnings.  The out_*
+to match against.  If warn is true, print appropriate warnings.  The out_*
 vars return values, and so are pointers to where the returned values
-should be stored. out_capture, if non-null, requests that the innermost
+should be stored.  out_capture, if non-null, requests that the innermost
 instance of the lexical is captured; out_name_sv is set to the innermost
 matched namesv or fake namesv; out_flags returns the flags normally
 associated with the IVX field of a fake namesv.
 
 Note that pad_findlex() is recursive; it recurses up the chain of CVs,
-then comes back down, adding fake entries as it goes. It has to be this way
+then comes back down, adding fake entries
+as it goes.  It has to be this way
 because fake namesvs in anon protoypes have to store in xlow the index into
 the parent pad.
 
@@ -1651,11 +1653,13 @@ Perl_pad_swipe(pTHX_ PADOFFSET po, bool refadjust)
     PL_curpad[po] = newSV(0);
     SvPADTMP_on(PL_curpad[po]);
 #else
-    PL_curpad[po] = &PL_sv_undef;
+    PL_curpad[po] = NULL;
 #endif
     if (PadnamelistMAX(PL_comppad_name) != -1
      && (PADOFFSET)PadnamelistMAX(PL_comppad_name) >= po) {
-       assert(!PadnameLEN(PadnamelistARRAY(PL_comppad_name)[po]));
+       if (PadnamelistARRAY(PL_comppad_name)[po]) {
+           assert(!PadnameLEN(PadnamelistARRAY(PL_comppad_name)[po]));
+       }
        PadnamelistARRAY(PL_comppad_name)[po] = &PL_sv_undef;
     }
     if ((I32)po < PL_padix)
@@ -1767,21 +1771,23 @@ Perl_pad_tidy(pTHX_ padtidy_type type)
        av_store(PL_comppad_name, AvFILLp(PL_comppad), NULL);
 
     if (type == padtidy_SUBCLONE) {
-       SV * const * const namep = AvARRAY(PL_comppad_name);
+       SV ** const namep = AvARRAY(PL_comppad_name);
        PADOFFSET ix;
 
        for (ix = AvFILLp(PL_comppad); ix > 0; ix--) {
            SV *namesv;
+           if (!namep[ix]) namep[ix] = &PL_sv_undef;
 
            /*
             * The only things that a clonable function needs in its
             * pad are anonymous subs, constants and GVs.
             * The rest are created anew during cloning.
             */
-           if (SvIMMORTAL(PL_curpad[ix]) || IS_PADGV(PL_curpad[ix]))
+           if (!PL_curpad[ix] || SvIMMORTAL(PL_curpad[ix])
+                || IS_PADGV(PL_curpad[ix]))
                continue;
-           if (!((namesv = namep[ix]) != NULL &&
-                 PadnamePV(namesv) &&
+           namesv = namep[ix];
+           if (!(PadnamePV(namesv) &&
                   (!PadnameLEN(namesv) || *SvPVX_const(namesv) == '&')))
            {
                SvREFCNT_dec(PL_curpad[ix]);
@@ -1797,10 +1803,12 @@ Perl_pad_tidy(pTHX_ padtidy_type type)
     }
 
     if (type == padtidy_SUB || type == padtidy_FORMAT) {
-       SV * const * const namep = AvARRAY(PL_comppad_name);
+       SV ** const namep = AvARRAY(PL_comppad_name);
        PADOFFSET ix;
        for (ix = AvFILLp(PL_comppad); ix > 0; ix--) {
-           if (SvIMMORTAL(PL_curpad[ix]) || IS_PADGV(PL_curpad[ix]) || IS_PADCONST(PL_curpad[ix]))
+           if (!namep[ix]) namep[ix] = &PL_sv_undef;
+           if (!PL_curpad[ix] || SvIMMORTAL(PL_curpad[ix])
+                || IS_PADGV(PL_curpad[ix]) || IS_PADCONST(PL_curpad[ix]))
                continue;
            if (!SvPADMY(PL_curpad[ix])) {
                SvPADTMP_on(PL_curpad[ix]);
@@ -2066,6 +2074,10 @@ S_cv_clone_pad(pTHX_ CV *proto, CV *cv, CV *outside, bool newcv)
        SV* const namesv = (ix <= fname) ? pname[ix] : NULL;
        SV *sv = NULL;
        if (namesv && PadnameLEN(namesv)) { /* lexical */
+         if (PadnameIsOUR(namesv)) { /* or maybe not so lexical */
+               NOOP;
+         }
+         else {
            if (SvFAKE(namesv)) {   /* lexical from outside? */
                /* formats may have an inactive, or even undefined, parent;
                   but state vars are always available. */
@@ -2119,6 +2131,7 @@ S_cv_clone_pad(pTHX_ CV *proto, CV *cv, CV *outside, bool newcv)
                if (sigil != '&' && SvPAD_STATE(namesv))
                    SvPADSTALE_on(sv);
            }
+         }
        }
        else if (IS_PADGV(ppad[ix]) || (namesv && PadnamePV(namesv))) {
            sv = SvREFCNT_inc_NN(ppad[ix]);
@@ -2209,7 +2222,7 @@ Perl_cv_clone_into(pTHX_ CV *proto, CV *target)
 =for apidoc m|void|pad_fixup_inner_anons|PADLIST *padlist|CV *old_cv|CV *new_cv
 
 For any anon CVs in the pad, change CvOUTSIDE of that CV from
-old_cv to new_cv if necessary. Needed when a newly-compiled CV has to be
+old_cv to new_cv if necessary.  Needed when a newly-compiled CV has to be
 moved to a pre-existing CV struct.
 
 =cut
@@ -2417,7 +2430,8 @@ Perl_padlist_dup(pTHX_ PADLIST *srcpad, CLONE_PARAMS *param)
            for ( ;ix > 0; ix--) {
                if (!oldpad[ix]) {
                    pad1a[ix] = NULL;
-               } else if (names_fill >= ix && PadnameLEN(names[ix])) {
+               } else if (names_fill >= ix && names[ix] &&
+                          PadnameLEN(names[ix])) {
                    const char sigil = SvPVX_const(names[ix])[0];
                    if ((SvFLAGS(names[ix]) & SVf_FAKE)
                        || (SvFLAGS(names[ix]) & SVpad_STATE)
@@ -2446,7 +2460,9 @@ Perl_padlist_dup(pTHX_ PADLIST *srcpad, CLONE_PARAMS *param)
                        }
                    }
                }
-               else if (IS_PADGV(oldpad[ix]) || PadnamePV(names[ix])) {
+               else if (IS_PADGV(oldpad[ix])
+                     || (  names_fill >= ix && names[ix]
+                        && PadnamePV(names[ix])  )) {
                    pad1a[ix] = sv_dup_inc(oldpad[ix], param);
                }
                else {