Store the stash for our in the magic slot. This will allow us to use
Nicholas Clark [Fri, 24 Feb 2006 13:59:57 +0000 (13:59 +0000)]
PVMGs in pad names where previously PVGVs were used. In turn, this
gives much greater flexibility for the layout of PVGVs.

p4raw-id: //depot/perl@27312

av.h
cv.h
hv.h
pad.c
sv.c
sv.h

diff --git a/av.h b/av.h
index 15ca697..61a01f0 100644 (file)
--- a/av.h
+++ b/av.h
@@ -17,7 +17,10 @@ struct xpvav {
        UV      xivu_uv;
        void *  xivu_p1;
     }          xiv_u;
-    MAGIC*     xmg_magic;      /* magic for scalar array */
+    union {
+       MAGIC*  xmg_magic;      /* linked list of magicalness */
+       HV*     xmg_ourstash;   /* Stash for our (when SvPAD_OUR is true) */
+    } xmg_u;
     HV*                xmg_stash;      /* class package */
 };
 
@@ -32,7 +35,10 @@ typedef struct {
        UV      xivu_uv;
        void *  xivu_p1;
     }          xiv_u;
-    MAGIC*     xmg_magic;      /* magic for scalar array */
+    union {
+       MAGIC*  xmg_magic;      /* linked list of magicalness */
+       HV*     xmg_ourstash;   /* Stash for our (when SvPAD_OUR is true) */
+    } xmg_u;
     HV*                xmg_stash;      /* class package */
 } xpvav_allocated;
 #endif
diff --git a/cv.h b/cv.h
index dd4e3ec..960e727 100644 (file)
--- a/cv.h
+++ b/cv.h
@@ -20,7 +20,10 @@ struct xpvcv {
        void *  xivu_p1;
        I32     xivu_i32;       /* depth, >= 2 indicates recursive call */
     }          xiv_u;
-    MAGIC*     xmg_magic;      /* magic for scalar array */
+    union {
+       MAGIC*  xmg_magic;      /* linked list of magicalness */
+       HV*     xmg_ourstash;   /* Stash for our (when SvPAD_OUR is true) */
+    } xmg_u;
     HV*                xmg_stash;      /* class package */
 
     HV *       xcv_stash;
@@ -51,7 +54,10 @@ typedef struct {
        void *  xivu_p1;
        I32     xivu_i32;       /* depth, >= 2 indicates recursive call */
     }          xiv_u;
-    MAGIC*     xmg_magic;      /* magic for scalar array */
+    union {
+       MAGIC*  xmg_magic;      /* linked list of magicalness */
+       HV*     xmg_ourstash;   /* Stash for our (when SvPAD_OUR is true) */
+    } xmg_u;
     HV*                xmg_stash;      /* class package */
 
     HV *       xcv_stash;
diff --git a/hv.h b/hv.h
index 9f9c1e3..0fd0e6b 100644 (file)
--- a/hv.h
+++ b/hv.h
@@ -57,7 +57,10 @@ struct xpvhv {
        UV      xivu_uv;
        void *  xivu_p1;
     }          xiv_u;
-    MAGIC*     xmg_magic;      /* magic for scalar array */
+    union {
+       MAGIC*  xmg_magic;      /* linked list of magicalness */
+       HV*     xmg_ourstash;   /* Stash for our (when SvPAD_OUR is true) */
+    } xmg_u;
     HV*                xmg_stash;      /* class package */
 };
 
@@ -74,7 +77,10 @@ typedef struct {
        UV      xivu_uv;
        void *  xivu_p1;
     }          xiv_u;
-    MAGIC*     xmg_magic;      /* magic for scalar array */
+    union {
+       MAGIC*  xmg_magic;      /* linked list of magicalness */
+       HV*     xmg_ourstash;   /* Stash for our (when SvPAD_OUR is true) */
+    } xmg_u;
     HV*                xmg_stash;      /* class package */
 } xpvhv_allocated;
 #endif
diff --git a/pad.c b/pad.c
index 97e2615..1cad444 100644 (file)
--- a/pad.c
+++ b/pad.c
@@ -348,7 +348,7 @@ Perl_pad_add_name(pTHX_ const char *name, HV* typestash, HV* ourstash, bool fake
     if (ourstash) {
        SvPAD_OUR_on(namesv);
        OURSTASH_set(namesv, ourstash);
-       Perl_sv_add_backref(aTHX_ (SV*)ourstash, namesv);
+       SvREFCNT_inc(ourstash);
     }
 
     av_store(PL_comppad_name, offset, namesv);
diff --git a/sv.c b/sv.c
index 1f17c76..ca61ada 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -1309,7 +1309,7 @@ Perl_sv_upgrade(pTHX_ register SV *sv, U32 new_type)
        SvPV_set(sv, NULL);
 
        if (old_type >= SVt_PVMG) {
-           SvMAGIC_set(sv, ((XPVMG*)old_body)->xmg_magic);
+           SvMAGIC_set(sv, ((XPVMG*)old_body)->xmg_u.xmg_magic);
            SvSTASH_set(sv, ((XPVMG*)old_body)->xmg_stash);
        }
        break;
@@ -5043,7 +5043,11 @@ Perl_sv_clear(pTHX_ register SV *sv)
        }
     }
     if (type >= SVt_PVMG) {
-       if (SvMAGIC(sv))
+       HV *ourstash;
+       if ((type == SVt_PVMG || type == SVt_PVGV) &&
+           (ourstash = OURSTASH(sv))) {
+           SvREFCNT_dec(ourstash);
+       } else if (SvMAGIC(sv))
            mg_free(sv);
        if (type == SVt_PVMG && SvPAD_TYPED(sv))
            SvREFCNT_dec(SvSTASH(sv));
@@ -9779,7 +9783,11 @@ Perl_sv_dup(pTHX_ const SV *sstr, CLONE_PARAMS* param)
               missing by always going for the destination.
               FIXME - instrument and check that assumption  */
            if (sv_type >= SVt_PVMG) {
-               if (SvMAGIC(dstr))
+               HV *ourstash;
+               if ((sv_type == SVt_PVMG || sv_type == SVt_PVGV) &&
+                   (ourstash = OURSTASH(dstr))) {
+                   OURSTASH_set(dstr, hv_dup_inc(ourstash, param));
+               } else if (SvMAGIC(dstr))
                    SvMAGIC_set(dstr, mg_dup(SvMAGIC(dstr), param));
                if (SvSTASH(dstr))
                    SvSTASH_set(dstr, hv_dup_inc(SvSTASH(dstr), param));
diff --git a/sv.h b/sv.h
index 9e5ae2b..159fd1a 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -379,7 +379,10 @@ struct xpvmg {
        void *  xivu_p1;
        I32     xivu_i32;
     }          xiv_u;
-    MAGIC*     xmg_magic;      /* linked list of magicalness */
+    union {
+       MAGIC*  xmg_magic;      /* linked list of magicalness */
+       HV*     xmg_ourstash;   /* Stash for our (when SvPAD_OUR is true) */
+    } xmg_u;
     HV*                xmg_stash;      /* class package */
 };
 
@@ -393,7 +396,10 @@ struct xpvlv {
        void *  xivu_p1;
        I32     xivu_i32;
     }          xiv_u;
-    MAGIC*     xmg_magic;      /* linked list of magicalness */
+    union {
+       MAGIC*  xmg_magic;      /* linked list of magicalness */
+       HV*     xmg_ourstash;   /* Stash for our (when SvPAD_OUR is true) */
+    } xmg_u;
     HV*                xmg_stash;      /* class package */
 
     /* a full glob fits into this */
@@ -420,7 +426,10 @@ struct xpvgv {
        void *  xivu_p1;
        I32     xivu_i32;
     }          xiv_u;
-    MAGIC*     xmg_magic;      /* linked list of magicalness */
+    union {
+       MAGIC*  xmg_magic;      /* linked list of magicalness */
+       HV*     xmg_ourstash;   /* Stash for our (when SvPAD_OUR is true) */
+    } xmg_u;
     HV*                xmg_stash;      /* class package */
 
     GP*                xgv_gp;
@@ -440,7 +449,10 @@ struct xpvbm {
        void *  xivu_p1;
        I32     xivu_i32;
     }          xiv_u;
-    MAGIC*     xmg_magic;      /* linked list of magicalness */
+    union {
+       MAGIC*  xmg_magic;      /* linked list of magicalness */
+       HV*     xmg_ourstash;   /* Stash for our (when SvPAD_OUR is true) */
+    } xmg_u;
     HV*                xmg_stash;      /* class package */
 
     I32                xbm_useful;     /* is this constant pattern being useful? */
@@ -462,7 +474,10 @@ struct xpvfm {
        void *  xivu_p1;
        I32     xivu_i32;
     }          xiv_u;
-    MAGIC*     xmg_magic;      /* linked list of magicalness */
+    union {
+       MAGIC*  xmg_magic;      /* linked list of magicalness */
+       HV*     xmg_ourstash;   /* Stash for our (when SvPAD_OUR is true) */
+    } xmg_u;
     HV*                xmg_stash;      /* class package */
 
     HV *       xcv_stash;
@@ -494,7 +509,10 @@ typedef struct {
        void *  xivu_p1;
        I32     xivu_i32;
     }          xiv_u;
-    MAGIC*     xmg_magic;      /* linked list of magicalness */
+    union {
+       MAGIC*  xmg_magic;      /* linked list of magicalness */
+       HV*     xmg_ourstash;   /* Stash for our (when SvPAD_OUR is true) */
+    } xmg_u;
     HV*                xmg_stash;      /* class package */
 
     HV *       xcv_stash;
@@ -527,7 +545,10 @@ struct xpvio {
        void *  xivu_p1;
        I32     xivu_i32;
     }          xiv_u;
-    MAGIC*     xmg_magic;      /* linked list of magicalness */
+    union {
+       MAGIC*  xmg_magic;      /* linked list of magicalness */
+       HV*     xmg_ourstash;   /* Stash for our (when SvPAD_OUR is true) */
+    } xmg_u;
     HV*                xmg_stash;      /* class package */
 
     PerlIO *   xio_ifp;        /* ifp and ofp are normally the same */
@@ -937,11 +958,12 @@ in gv.h: */
        ((SvFLAGS(sv) & (SVpad_NAME|SVpad_OUR)) == (SVpad_NAME|SVpad_OUR))
 #define SvPAD_OUR_on(sv)       (SvFLAGS(sv) |= SVpad_NAME|SVpad_OUR)
 
-#define OURSTASH(sv)   (SvPAD_OUR(sv) ? GvSTASH(sv) : NULL)
-#define OURSTASH_set(sv, st)                   \
-        STMT_START {                           \
-           assert(SvTYPE(sv) == SVt_PVGV);     \
-           GvSTASH(sv) = st;                   \
+#define OURSTASH(sv)   \
+       (SvPAD_OUR(sv) ? ((XPVMG*) SvANY(sv))->xmg_u.xmg_ourstash : NULL)
+#define OURSTASH_set(sv, st)                                   \
+        STMT_START {                                           \
+           assert(SvTYPE(sv) == SVt_PVGV);                     \
+           ((XPVMG*) SvANY(sv))->xmg_u.xmg_ourstash = st;      \
        } STMT_END
 
 #ifdef PERL_DEBUG_COW
@@ -970,16 +992,16 @@ in gv.h: */
 #  ifdef DEBUGGING
 #    ifdef PERL_IN_SV_C
 /* Can't make this RVALUE because of Perl_sv_unmagic.  */
-#      define SvMAGIC(sv)      (*(assert(SvTYPE(sv) >= SVt_PVMG), &((XPVMG*)  SvANY(sv))->xmg_magic))
+#      define SvMAGIC(sv)      (*(assert(SvTYPE(sv) >= SVt_PVMG), &((XPVMG*)  SvANY(sv))->xmg_u.xmg_magic))
 #    else
-#      define SvMAGIC(sv)      (0 + *(assert(SvTYPE(sv) >= SVt_PVMG), &((XPVMG*)  SvANY(sv))->xmg_magic))
+#      define SvMAGIC(sv)      (0 + *(assert(SvTYPE(sv) >= SVt_PVMG), &((XPVMG*)  SvANY(sv))->xmg_u.xmg_magic))
 #    endif
 #  define SvSTASH(sv)  (0 + *(assert(SvTYPE(sv) >= SVt_PVMG), &((XPVMG*)  SvANY(sv))->xmg_stash))
 #  else
 #    ifdef PERL_IN_SV_C
-#      define SvMAGIC(sv) ((XPVMG*)  SvANY(sv))->xmg_magic
+#      define SvMAGIC(sv) ((XPVMG*)  SvANY(sv))->xmg_u.xmg_magic
 #    else
-#      define SvMAGIC(sv) (0 + ((XPVMG*)  SvANY(sv))->xmg_magic)
+#      define SvMAGIC(sv) (0 + ((XPVMG*)  SvANY(sv))->xmg_u.xmg_magic)
 #    endif
 #  define SvSTASH(sv)     (0 + ((XPVMG*)  SvANY(sv))->xmg_stash)
 #  endif
@@ -1018,9 +1040,7 @@ in gv.h: */
 #    define SvMAGIC(sv)                                                        \
        (*({ SV *const _svi = (SV *) sv;                                \
            assert(SvTYPE(_svi) >= SVt_PVMG);                           \
-           if (SvTYPE(_svi) == SVt_PVMG && (SvFLAGS(_svi) & SVpad_NAME)) \
-               assert (!((XPVMG*) SvANY(_svi))->xmg_magic); \
-           &(((XPVMG*) SvANY(_svi))->xmg_magic);                       \
+           &(((XPVMG*) SvANY(_svi))->xmg_u.xmg_magic);                 \
          }))
 #    define SvSTASH(sv)                                                        \
        (*({ SV *const _svi = (SV *) sv;                                \
@@ -1031,7 +1051,7 @@ in gv.h: */
 #    define SvIVX(sv) ((XPVIV*) SvANY(sv))->xiv_iv
 #    define SvUVX(sv) ((XPVUV*) SvANY(sv))->xuv_uv
 #    define SvNVX(sv) ((XPVNV*) SvANY(sv))->xnv_nv
-#    define SvMAGIC(sv)        ((XPVMG*)  SvANY(sv))->xmg_magic
+#    define SvMAGIC(sv)        ((XPVMG*)  SvANY(sv))->xmg_u.xmg_magic
 #    define SvSTASH(sv)        ((XPVMG*)  SvANY(sv))->xmg_stash
 #  endif
 #endif
@@ -1080,7 +1100,7 @@ in gv.h: */
                 ((sv)->sv_u.svu_rv = (val)); } STMT_END
 #define SvMAGIC_set(sv, val) \
         STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \
-                (((XPVMG*)SvANY(sv))->xmg_magic = (val)); } STMT_END
+                (((XPVMG*)SvANY(sv))->xmg_u.xmg_magic = (val)); } STMT_END
 #define SvSTASH_set(sv, val) \
         STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \
                 (((XPVMG*)  SvANY(sv))->xmg_stash = (val)); } STMT_END