With PAD_COMPNAME_GEN in SvUVX, SvCUR is trustworthy once more.
Nicholas Clark [Thu, 28 Dec 2006 22:40:37 +0000 (22:40 +0000)]
p4raw-id: //depot/perl@29633

op.c
pad.h
sv.c

diff --git a/op.c b/op.c
index 814c5e2..ecff57f 100644 (file)
--- a/op.c
+++ b/op.c
@@ -4526,8 +4526,14 @@ Perl_newFOROP(pTHX_ I32 flags, char *label, line_t forline, OP *sv, OP *expr, OP
        }
        else
            Perl_croak(aTHX_ "Can't use %s for loop variable", PL_op_desc[sv->op_type]);
-       if (padoff && strEQ(PAD_COMPNAME_PV(padoff), "$_"))
-           iterpflags |= OPpITER_DEF;
+       if (padoff) {
+           SV *const namesv = PAD_COMPNAME_SV(padoff);
+           STRLEN len;
+           const char *const name = SvPV_const(namesv, len);
+
+           if (len == 2 && name[0] == '$' && name[1] == '_')
+               iterpflags |= OPpITER_DEF;
+       }
     }
     else {
         const PADOFFSET offset = pad_findmy("$_");
@@ -6447,13 +6453,9 @@ Perl_ck_fun(pTHX_ OP *o)
                             */
                            priv = OPpDEREF;
                            if (kid->op_type == OP_PADSV) {
-                               name = PAD_COMPNAME_PV(kid->op_targ);
-                               /* SvCUR of a pad namesv can't be trusted
-                                * (see PL_generation), so calc its length
-                                * manually */
-                               if (name)
-                                   len = strlen(name);
-
+                               SV *const namesv
+                                   = PAD_COMPNAME_SV(kid->op_targ);
+                               name = SvPV_const(namesv, len);
                            }
                            else if (kid->op_type == OP_RV2SV
                                     && kUNOP->op_first->op_type == OP_GV)
diff --git a/pad.h b/pad.h
index 6e06955..81a1312 100644 (file)
--- a/pad.h
+++ b/pad.h
@@ -286,15 +286,16 @@ ling pad (lvalue) to C<gen>.  Note that C<SvUV_set> is hijacked for this purpose
 
 */
 
-#define PAD_COMPNAME_FLAGS(po) SvFLAGS(*av_fetch(PL_comppad_name, (po), FALSE))
+#define PAD_COMPNAME_SV(po) (*av_fetch(PL_comppad_name, (po), FALSE))
+#define PAD_COMPNAME_FLAGS(po) SvFLAGS(PAD_COMPNAME_SV(po))
 #define PAD_COMPNAME_FLAGS_isOUR(po) \
   ((PAD_COMPNAME_FLAGS(po) & (SVpad_NAME|SVpad_OUR)) == (SVpad_NAME|SVpad_OUR))
-#define PAD_COMPNAME_PV(po) SvPV_nolen(*av_fetch(PL_comppad_name, (po), FALSE))
+#define PAD_COMPNAME_PV(po) SvPV_nolen(PAD_COMPNAME_SV(po))
 
 #define PAD_COMPNAME_TYPE(po) pad_compname_type(po)
 
 #define PAD_COMPNAME_OURSTASH(po) \
-    (OURSTASH(*av_fetch(PL_comppad_name, (po), FALSE)))
+    (OURSTASH(PAD_COMPNAME_SV(po)))
 
 #define PAD_COMPNAME_GEN(po) ((STRLEN)SvUVX(AvARRAY(PL_comppad_name)[po]))
 
diff --git a/sv.c b/sv.c
index 7e327d4..65060fa 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -11691,8 +11691,7 @@ S_varname(pTHX_ GV *gv, const char gvtype, PADOFFSET targ,
            return NULL;
        av = (AV*)(*av_fetch(CvPADLIST(cv), 0, FALSE));
        sv = *av_fetch(av, targ, FALSE);
-       /* SvLEN in a pad name is not to be trusted */
-       sv_setpv(name, SvPV_nolen_const(sv));
+       sv_setpvn(name, SvPV_nolen_const(sv), SvCUR(sv));
     }
 
     if (subscript_type == FUV_SUBSCRIPT_HASH) {