This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
regcomp.c: Properly dereference a ptr
[perl5.git] / pad.c
diff --git a/pad.c b/pad.c
index 285c204..58b4d92 100644 (file)
--- a/pad.c
+++ b/pad.c
@@ -319,10 +319,17 @@ children can still follow the full lexical scope chain.
 void
 Perl_cv_undef(pTHX_ CV *cv)
 {
+    PERL_ARGS_ASSERT_CV_UNDEF;
+    cv_undef_flags(cv, 0);
+}
+
+void
+Perl_cv_undef_flags(pTHX_ CV *cv, U32 flags)
+{
     const PADLIST *padlist = CvPADLIST(cv);
     bool const slabbed = !!CvSLABBED(cv);
 
-    PERL_ARGS_ASSERT_CV_UNDEF;
+    PERL_ARGS_ASSERT_CV_UNDEF_FLAGS;
 
     DEBUG_X(PerlIO_printf(Perl_debug_log,
          "CV undef: cv=0x%"UVxf" comppad=0x%"UVxf"\n",
@@ -365,8 +372,13 @@ Perl_cv_undef(pTHX_ CV *cv)
 #endif
     SvPOK_off(MUTABLE_SV(cv));         /* forget prototype */
     sv_unmagic((SV *)cv, PERL_MAGIC_checkcall);
-    if (CvNAMED(cv)) CvNAME_HEK_set(cv, NULL);
-    else            CvGV_set(cv, NULL);
+    if (!(flags & CV_UNDEF_KEEP_NAME)) {
+       if (CvNAMED(cv)) {
+           CvNAME_HEK_set(cv, NULL);
+           CvNAMED_off(cv);
+       }
+       else CvGV_set(cv, NULL);
+    }
 
     /* This statement and the subsequence if block was pad_undef().  */
     pad_peg("pad_undef");
@@ -469,10 +481,10 @@ Perl_cv_undef(pTHX_ CV *cv)
        CvXSUB(cv) = NULL;
     }
     /* delete all flags except WEAKOUTSIDE and CVGV_RC, which indicate the
-     * ref status of CvOUTSIDE and CvGV, and ANON and
-     * LEXICAL, which pp_entersub uses
-     * to choose an error message */
-    CvFLAGS(cv) &= (CVf_WEAKOUTSIDE|CVf_CVGV_RC|CVf_ANON|CVf_LEXICAL);
+     * ref status of CvOUTSIDE and CvGV, and ANON, NAMED and
+     * LEXICAL, which are used to determine the sub's name.  */
+    CvFLAGS(cv) &= (CVf_WEAKOUTSIDE|CVf_CVGV_RC|CVf_ANON|CVf_LEXICAL
+                  |CVf_NAMED);
 }
 
 /*
@@ -726,7 +738,7 @@ Perl_pad_alloc(pTHX_ I32 optype, U32 tmptype)
                   AvARRAY(PL_comppad), PL_curpad);
     if (PL_pad_reset_pending)
        pad_reset();
-    if (tmptype & SVs_PADMY) {
+    if (tmptype == SVs_PADMY) { /* Not & because this ‘flag’ is 0.  */
        /* For a my, simply push a null SV onto the end of PL_comppad. */
        sv = *av_fetch(PL_comppad, AvFILLp(PL_comppad) + 1, TRUE);
        retval = AvFILLp(PL_comppad);
@@ -757,12 +769,11 @@ Perl_pad_alloc(pTHX_ I32 optype, U32 tmptype)
            sv = *av_fetch(PL_comppad, retval, TRUE);
            if (!(SvFLAGS(sv) &
 #ifdef USE_PAD_RESET
-                   (SVs_PADMY|(konst ? SVs_PADTMP : 0))
+                   (konst ? SVs_PADTMP : 0))
 #else
-                   (SVs_PADMY|SVs_PADTMP)
+                   SVs_PADTMP
 #endif
-                ) &&
-               !IS_PADGV(sv))
+                ))
                break;
        }
        if (konst) {
@@ -829,7 +840,6 @@ Perl_pad_add_anon(pTHX_ CV* func, I32 optype)
        assert (SvTYPE(func) == SVt_PVFM);
        av_store(PL_comppad, ix, rv);
     }
-    SvPADMY_on((SV*)func);
 
     /* to avoid ref loops, we never have parent + child referencing each
      * other simultaneously */
@@ -1767,8 +1777,7 @@ Perl_pad_tidy(pTHX_ padtidy_type type)
             * pad are anonymous subs, constants and GVs.
             * The rest are created anew during cloning.
             */
-           if (!PL_curpad[ix] || SvIMMORTAL(PL_curpad[ix])
-                || IS_PADGV(PL_curpad[ix]))
+           if (!PL_curpad[ix] || SvIMMORTAL(PL_curpad[ix]))
                continue;
            namesv = namep[ix];
            if (!(PadnamePV(namesv) &&
@@ -1791,12 +1800,9 @@ Perl_pad_tidy(pTHX_ padtidy_type type)
        PADOFFSET ix;
        for (ix = AvFILLp(PL_comppad); ix > 0; 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]))
+           if (!PL_curpad[ix] || SvIMMORTAL(PL_curpad[ix]))
                continue;
-           if (!SvPADMY(PL_curpad[ix])) {
-               SvPADTMP_on(PL_curpad[ix]);
-           } else if (!SvFAKE(namep[ix])) {
+           if (SvPADMY(PL_curpad[ix]) && !SvFAKE(namep[ix])) {
                /* This is a work around for how the current implementation of
                   ?{ } blocks in regexps interacts with lexicals.
 
@@ -2115,14 +2121,13 @@ S_cv_clone_pad(pTHX_ CV *proto, CV *cv, CV *outside, bool newcv)
                    sv = MUTABLE_SV(newHV());
                else
                    sv = newSV(0);
-               SvPADMY_on(sv);
                /* reset the 'assign only once' flag on each state var */
                if (sigil != '&' && SvPAD_STATE(namesv))
                    SvPADSTALE_on(sv);
            }
          }
        }
-       else if (IS_PADGV(ppad[ix]) || (namesv && PadnamePV(namesv))) {
+       else if (namesv && PadnamePV(namesv)) {
            sv = SvREFCNT_inc_NN(ppad[ix]);
        }
        else {
@@ -2233,18 +2238,22 @@ Perl_cv_clone_into(pTHX_ CV *proto, CV *target)
 
 Returns an SV containing the name of the CV, mainly for use in error
 reporting.  The CV may actually be a GV instead, in which case the returned
-SV holds the GV's name.  Anything other than a GV or CV will be treated as
-a string already holding the sub name.
+SV holds the GV's name.  Anything other than a GV or CV is treated as a
+string already holding the sub name, but this could change in the future.
 
 An SV may be passed as a second argument.  If so, the name will be assigned
 to it and it will be returned.  Otherwise the returned SV will be a new
 mortal.
 
+If the I<flags> include CV_NAME_NOTQUAL, then the package name will not be
+included.  If the first argument is neither a CV nor a GV, this flag is
+ignored (subject to change).
+
 =cut
 */
 
 SV *
-Perl_cv_name(pTHX_ CV *cv, SV *sv)
+Perl_cv_name(pTHX_ CV *cv, SV *sv, U32 flags)
 {
     PERL_ARGS_ASSERT_CV_NAME;
     if (!isGV_with_GP(cv) && SvTYPE(cv) != SVt_PVCV) {
@@ -2252,20 +2261,22 @@ Perl_cv_name(pTHX_ CV *cv, SV *sv)
        return sv ? (sv) : (SV *)cv;
     }
     {
-       SV * const retsv = sv ? sv : sv_newmortal();
+       SV * const retsv = sv ? (sv) : sv_newmortal();
        if (SvTYPE(cv) == SVt_PVCV) {
            if (CvNAMED(cv)) {
-               if (CvLEXICAL(cv)) sv_sethek(retsv, CvNAME_HEK(cv));
+               if (CvLEXICAL(cv) || flags & CV_NAME_NOTQUAL)
+                   sv_sethek(retsv, CvNAME_HEK(cv));
                else {
                    sv_sethek(retsv, HvNAME_HEK(CvSTASH(cv)));
                    sv_catpvs(retsv, "::");
                    sv_cathek(retsv, CvNAME_HEK(cv));
                }
            }
-           else if (CvLEXICAL(cv))
+           else if (CvLEXICAL(cv) || flags & CV_NAME_NOTQUAL)
                sv_sethek(retsv, GvNAME_HEK(GvEGV(CvGV(cv))));
            else gv_efullname3(retsv, CvGV(cv), NULL);
        }
+       else if (flags & CV_NAME_NOTQUAL) sv_sethek(retsv, GvNAME_HEK(cv));
        else gv_efullname3(retsv,(GV *)cv,NULL);
        return retsv;
     }
@@ -2368,12 +2379,16 @@ Perl_pad_push(pTHX_ PADLIST *padlist, int depth)
                    else if (sigil == '%')
                        sv = MUTABLE_SV(newHV());
                    else
+                   {
                        sv = newSV(0);
+                       /* For flip-flop targets: */
+                       if (oldpad[ix] && SvPADTMP(oldpad[ix]))
+                           SvPADTMP_on(sv);
+                   }
                    av_store(newpad, ix, sv);
-                   SvPADMY_on(sv);
                }
            }
-           else if (IS_PADGV(oldpad[ix]) || PadnamePV(names[ix])) {
+           else if (PadnamePV(names[ix])) {
                av_store(newpad, ix, SvREFCNT_inc_NN(oldpad[ix]));
            }
            else {
@@ -2505,12 +2520,10 @@ Perl_padlist_dup(pTHX_ PADLIST *srcpad, CLONE_PARAMS *param)
                            else
                                sv = newSV(0);
                            pad1a[ix] = sv;
-                           SvPADMY_on(sv);
                        }
                    }
                }
-               else if (IS_PADGV(oldpad[ix])
-                     || (  names_fill >= ix && names[ix]
+               else if ((  names_fill >= ix && names[ix]
                         && PadnamePV(names[ix])  )) {
                    pad1a[ix] = sv_dup_inc(oldpad[ix], param);
                }
@@ -2522,9 +2535,7 @@ Perl_padlist_dup(pTHX_ PADLIST *srcpad, CLONE_PARAMS *param)
                    /* SvREFCNT(oldpad[ix]) != 1 for some code in threads.xs
                       FIXTHAT before merging this branch.
                       (And I know how to) */
-                   if (SvPADMY(oldpad[ix]))
-                       SvPADMY_on(sv);
-                   else
+                   if (SvPADTMP(oldpad[ix]))
                        SvPADTMP_on(sv);
                }
            }