Fix some compilation warnings
[p5sagit/p5-mst-13.2.git] / sv.h
diff --git a/sv.h b/sv.h
index 6983f45..f2bbe10 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -59,22 +59,43 @@ typedef enum {
        SVt_PVHV,       /* 12 */
        SVt_PVCV,       /* 13 */
        SVt_PVFM,       /* 14 */
-       SVt_PVIO        /* 15 */
+       SVt_PVIO,       /* 15 */
+       SVt_LAST        /* keep last in enum. used to size arrays */
 } svtype;
 
+#ifdef PERL_IN_SV_C
+#define PTE_SVSLOT     SVt_RV
+#endif
+#if defined(PERL_IN_HV_C) || defined(PERL_IN_XS_APITEST)
+#define HE_SVSLOT      SVt_NULL
+#endif
+
+/* typedefs to eliminate some typing */
+typedef struct he HE;
+typedef struct hek HEK;
+
 /* Using C's structural equivalence to help emulate C++ inheritance here... */
 
+/* start with 2 sv-head building blocks */
+#define _SV_HEAD(ptrtype) \
+    ptrtype    sv_any;         /* pointer to body */   \
+    U32                sv_refcnt;      /* how many references to us */ \
+    U32                sv_flags        /* what we are */
+
+#define _SV_HEAD_UNION \
+    union {                            \
+       IV      svu_iv;                 \
+       UV      svu_uv;                 \
+       SV*     svu_rv;         /* pointer to another SV */             \
+       char*   svu_pv;         /* pointer to malloced string */        \
+       SV**    svu_array;              \
+       HE**    svu_hash;               \
+    }  sv_u
+
+
 struct STRUCT_SV {             /* struct sv { */
-    void*      sv_any;         /* pointer to something */
-    U32                sv_refcnt;      /* how many references to us */
-    U32                sv_flags;       /* what we are */
-    union {
-       IV      svu_iv;
-       UV      svu_uv;
-       SV*     svu_rv;         /* pointer to another SV */
-       char*   svu_pv;         /* pointer to malloced string */
-       SV**    svu_array;
-    }          sv_u;
+    _SV_HEAD(void*);
+    _SV_HEAD_UNION;
 #ifdef DEBUG_LEAKING_SCALARS
     unsigned   sv_debug_optype:9;      /* the type of OP that allocated us */
     unsigned   sv_debug_inpad:1;       /* was allocated in a pad for an OP */
@@ -85,70 +106,33 @@ struct STRUCT_SV {         /* struct sv { */
 };
 
 struct gv {
-    XPVGV*     sv_any;         /* pointer to something */
-    U32                sv_refcnt;      /* how many references to us */
-    U32                sv_flags;       /* what we are */
-    union {
-       IV      svu_iv;
-       UV      svu_uv;
-       SV*     svu_rv;
-       char*   svu_pv;
-       SV**    svu_array;
-    }          sv_u;
+    _SV_HEAD(XPVGV*);          /* pointer to xpvgv body */
+    _SV_HEAD_UNION;
 };
 
 struct cv {
-    XPVCV*     sv_any;         /* pointer to something */
-    U32                sv_refcnt;      /* how many references to us */
-    U32                sv_flags;       /* what we are */
-    union {
-       IV      svu_iv;
-       UV      svu_uv;
-       SV*     svu_rv;
-       char*   svu_pv;
-       SV**    svu_array;
-    }          sv_u;
+    _SV_HEAD(XPVCV*);          /* pointer to xpvcv body */
+    _SV_HEAD_UNION;
 };
 
 struct av {
-    XPVAV*     sv_any;         /* pointer to something */
-    U32                sv_refcnt;      /* how many references to us */
-    U32                sv_flags;       /* what we are */
-    union {
-       IV      svu_iv;
-       UV      svu_uv;
-       SV*     svu_rv;
-       char*   svu_pv;         /* pointer to first array element */
-       SV**    svu_array;
-    }          sv_u;
+    _SV_HEAD(XPVAV*);          /* pointer to xpvav body */
+    _SV_HEAD_UNION;
 };
 
 struct hv {
-    XPVHV*     sv_any;         /* pointer to something */
-    U32                sv_refcnt;      /* how many references to us */
-    U32                sv_flags;       /* what we are */
-    union {
-       IV      svu_iv;
-       UV      svu_uv;
-       SV*     svu_rv;
-       char*   svu_pv;
-       SV**    svu_array;
-    }          sv_u;
+    _SV_HEAD(XPVHV*);          /* pointer to xpvhv body */
+    _SV_HEAD_UNION;
 };
 
 struct io {
-    XPVIO*     sv_any;         /* pointer to something */
-    U32                sv_refcnt;      /* how many references to us */
-    U32                sv_flags;       /* what we are */
-    union {
-       IV      svu_iv;
-       UV      svu_uv;
-       SV*     svu_rv;
-       char*   svu_pv;
-       SV**    svu_array;
-    }          sv_u;
+    _SV_HEAD(XPVIO*);          /* pointer to xpvio body */
+    _SV_HEAD_UNION;
 };
 
+#undef _SV_HEAD
+#undef _SV_HEAD_UNION          /* ensure no pollution */
+
 /*
 =head1 SV Manipulation Functions
 
@@ -185,7 +169,7 @@ perform the upgrade if necessary.  See C<svtype>.
     })
 #else
 #  define SvREFCNT_inc(sv)     \
-       ((PL_Sv=(SV*)(sv)), (PL_Sv && ++(SvREFCNT(PL_Sv))), (SV*)PL_Sv)
+       ((PL_Sv=(SV*)(sv)) ? ((++(SvREFCNT(PL_Sv))),(PL_Sv)) : NULL)
 #endif
 
 #if defined(__GNUC__) && !defined(__STRICT_ANSI__) && !defined(PERL_GCC_PEDANTIC)
@@ -208,6 +192,11 @@ perform the upgrade if necessary.  See C<svtype>.
 #define SVTYPEMASK     0xff
 #define SvTYPE(sv)     ((sv)->sv_flags & SVTYPEMASK)
 
+/* Sadly there are some parts of the core that have pointers to already-freed
+   SV heads, and rely on being able to tell that they are now free. So mark
+   them all by using a consistent macro.  */
+#define SvIS_FREED(sv) ((sv)->sv_flags == SVTYPEMASK)
+
 #define SvUPGRADE(sv, mt) (SvTYPE(sv) >= (mt) || (sv_upgrade(sv, mt), 1))
 
 #define SVs_PADSTALE   0x00000100      /* lexical has gone out of scope */
@@ -881,8 +870,6 @@ in gv.h: */
 #  else
 #  define SvPVX(sv) SvPVX_mutable(sv)
 #  endif
-#  define SvPVX_mutable(sv)    (0 + (sv)->sv_u.svu_pv)
-#  define SvPVX_const(sv)      ((const char*)(0 + (sv)->sv_u.svu_pv))
 #  define SvCUR(sv) (0 + ((XPV*) SvANY(sv))->xpv_cur)
 #  define SvLEN(sv) (0 + ((XPV*) SvANY(sv))->xpv_len)
 #  define SvEND(sv) ((sv)->sv_u.svu_pv + ((XPV*)SvANY(sv))->xpv_cur)
@@ -908,8 +895,6 @@ in gv.h: */
 #  define SvUVX(sv) ((XPVUV*) SvANY(sv))->xuv_uv
 #  define SvNVX(sv) ((XPVNV*) SvANY(sv))->xnv_nv
 #  define SvPVX(sv) ((sv)->sv_u.svu_pv)
-#  define SvPVX_mutable(sv)    SvPVX(sv)
-#  define SvPVX_const(sv)      ((const char*)SvPVX(sv))
 #  define SvCUR(sv) ((XPV*) SvANY(sv))->xpv_cur
 #  define SvLEN(sv) ((XPV*) SvANY(sv))->xpv_len
 #  define SvEND(sv) ((sv)->sv_u.svu_pv + ((XPV*)SvANY(sv))->xpv_cur)
@@ -923,6 +908,18 @@ in gv.h: */
 #  endif
 #endif
 
+#ifndef PERL_POISON
+/* Given that these two are new, there can't be any existing code using them
+ *  as LVALUEs  */
+#  define SvPVX_mutable(sv)    (0 + (sv)->sv_u.svu_pv)
+#  define SvPVX_const(sv)      ((const char*)(0 + (sv)->sv_u.svu_pv))
+#else
+/* Except for the poison code, which uses & to scribble over the pointer after
+   free() is called.  */
+#  define SvPVX_mutable(sv)    ((sv)->sv_u.svu_pv)
+#  define SvPVX_const(sv)      ((const char*)((sv)->sv_u.svu_pv))
+#endif
+
 #define SvIVXx(sv) SvIVX(sv)
 #define SvUVXx(sv) SvUVX(sv)
 #define SvNVXx(sv) SvNVX(sv)
@@ -1056,6 +1053,8 @@ Taints an SV if tainting is enabled.
 =cut
 */
 
+#define sv_taint(sv)     sv_magic((sv), Nullsv, PERL_MAGIC_taint, Nullch, 0)
+
 #define SvTAINTED(sv)    (SvMAGICAL(sv) && sv_tainted(sv))
 #define SvTAINTED_on(sv)  STMT_START{ if(PL_tainting){sv_taint(sv);}   }STMT_END
 #define SvTAINTED_off(sv) STMT_START{ if(PL_tainting){sv_untaint(sv);} }STMT_END
@@ -1210,6 +1209,10 @@ Like C<sv_catsv> but doesn't process magic.
     ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
      ? ((lp = SvCUR(sv)), SvPVX_const(sv)) : \
      (const char*) sv_2pv_flags(sv, &lp, flags|SV_CONST_RETURN))
+#define SvPV_flags_const_nolen(sv, flags) \
+    ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
+     ? SvPVX_const(sv) : \
+     (const char*) sv_2pv_flags(sv, 0, flags|SV_CONST_RETURN))
 #define SvPV_flags_mutable(sv, lp, flags) \
     ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
      ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) : \
@@ -1220,6 +1223,7 @@ Like C<sv_catsv> but doesn't process magic.
 #define SvPV_force_mutable(sv, lp) SvPV_force_flags_mutable(sv, lp, SV_GMAGIC)
 
 #define SvPV_force_nomg(sv, lp) SvPV_force_flags(sv, lp, 0)
+#define SvPV_force_nomg_nolen(sv) SvPV_force_flags_nolen(sv, 0)
 
 #define SvPV_force_flags(sv, lp, flags) \
     ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \
@@ -1242,6 +1246,7 @@ Like C<sv_catsv> but doesn't process magic.
 
 #define SvPV_nomg(sv, lp) SvPV_flags(sv, lp, 0)
 #define SvPV_nomg_const(sv, lp) SvPV_flags_const(sv, lp, 0)
+#define SvPV_nomg_const_nolen(sv) SvPV_flags_const_nolen(sv, 0)
 
 /* ----*/
 
@@ -1362,6 +1367,10 @@ Like C<sv_catsv> but doesn't process magic.
 #define SV_NOSTEAL             16
 #define SV_CONST_RETURN                32
 #define SV_MUTABLE_RETURN      64
+#define SV_SMAGIC              128
+
+#define sv_unref(sv)           sv_unref_flags(sv, 0)
+#define sv_force_normal(sv)    sv_force_normal_flags(sv, 0)
 
 /* We are about to replace the SV's current value. So if it's copy on write
    we need to normalise it. Use the SV_COW_DROP_PV flag hint to say that
@@ -1402,14 +1411,23 @@ Like C<sv_catsv> but doesn't process magic.
 #define sv_setsv_nomg(dsv, ssv) sv_setsv_flags(dsv, ssv, 0)
 #define sv_catsv(dsv, ssv) sv_catsv_flags(dsv, ssv, SV_GMAGIC)
 #define sv_catsv_nomg(dsv, ssv) sv_catsv_flags(dsv, ssv, 0)
+#define sv_catsv_mg(dsv, ssv) sv_catsv_flags(dsv, ssv, SV_GMAGIC|SV_SMAGIC)
 #define sv_catpvn(dsv, sstr, slen) sv_catpvn_flags(dsv, sstr, slen, SV_GMAGIC)
+#define sv_catpvn_mg(sv, sstr, slen) \
+       sv_catpvn_flags(sv, sstr, slen, SV_GMAGIC|SV_SMAGIC);
 #define sv_2pv(sv, lp) sv_2pv_flags(sv, lp, SV_GMAGIC)
+#define sv_2pv_nolen(sv) sv_2pv(sv, 0)
+#define sv_2pvbyte_nolen(sv) sv_2pvbyte(sv, 0)
+#define sv_2pvutf8_nolen(sv) sv_2pvutf8(sv, 0)
 #define sv_2pv_nomg(sv, lp) sv_2pv_flags(sv, lp, 0)
 #define sv_pvn_force(sv, lp) sv_pvn_force_flags(sv, lp, SV_GMAGIC)
 #define sv_utf8_upgrade(sv) sv_utf8_upgrade_flags(sv, SV_GMAGIC)
 #define sv_2iv(sv) sv_2iv_flags(sv, SV_GMAGIC)
 #define sv_2uv(sv) sv_2uv_flags(sv, SV_GMAGIC)
 
+#define newSVpvs(str) newSVpvn(STR_WITH_LEN(str))
+#define sv_catpvs(sv, str) sv_catpvn_flags(sv, STR_WITH_LEN(str), SV_GMAGIC)
+
 /* Should be named SvCatPVN_utf8_upgrade? */
 #define sv_catpvn_utf8_upgrade(dsv, sstr, slen, nsv)   \
        STMT_START {                                    \