Fix Attribute::Handlers to cope with proxy constant subroutines.
[p5sagit/p5-mst-13.2.git] / sv.h
diff --git a/sv.h b/sv.h
index ec6184b..57911d3 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -158,11 +158,11 @@ Same as SvREFCNT_inc, but can only be used if you know I<sv>
 is not NULL.  Since we don't have to check the NULLness, it's faster
 and smaller.
 
-=for apidoc Am|SV*|SvREFCNT_inc_void|SV* sv
+=for apidoc Am|void|SvREFCNT_inc_void|SV* sv
 Same as SvREFCNT_inc, but can only be used if you don't need the
 return value.  The macro doesn't need to return a meaningful value.
 
-=for apidoc Am|SV*|SvREFCNT_inc_void_NN|SV* sv
+=for apidoc Am|void|SvREFCNT_inc_void_NN|SV* sv
 Same as SvREFCNT_inc, but can only be used if you don't need the return
 value, and you know that I<sv> is not NULL.  The macro doesn't need
 to return a meaningful value, or check for NULLness, so it's smaller
@@ -178,12 +178,15 @@ Same as SvREFCNT_inc_simple, but can only be used if you know I<sv>
 is not NULL.  Since we don't have to check the NULLness, it's faster
 and smaller.
 
-=for apidoc Am|SV*|SvREFCNT_inc_simple_void|SV* sv
+=for apidoc Am|void|SvREFCNT_inc_simple_void|SV* sv
 Same as SvREFCNT_inc_simple, but can only be used if you don't need the
 return value.  The macro doesn't need to return a meaningful value.
 
-=for apidoc Am|SV*|SvREFCNT_inc|SV* sv
-Increments the reference count of the given SV.
+=for apidoc Am|void|SvREFCNT_inc_simple_void_NN|SV* sv
+Same as SvREFCNT_inc, but can only be used if you don't need the return
+value, and you know that I<sv> is not NULL.  The macro doesn't need
+to return a meaningful value, or check for NULLness, so it's smaller
+and faster.
 
 =for apidoc Am|void|SvREFCNT_dec|SV* sv
 Decrements the reference count of the given SV.
@@ -240,7 +243,7 @@ perform the upgrade if necessary.  See C<svtype>.
 #endif
 
 /* These guys don't need the curly blocks */
-#define SvREFCNT_inc_simple_void(sv)   if (sv) (SvREFCNT(sv)++);
+#define SvREFCNT_inc_simple_void(sv)   STMT_START { if (sv) SvREFCNT(sv)++; } STMT_END
 #define SvREFCNT_inc_simple_NN(sv)     (++(SvREFCNT(sv)),(SV*)(sv))
 #define SvREFCNT_inc_void_NN(sv)       (void)(++SvREFCNT((SV*)(sv)))
 #define SvREFCNT_inc_simple_void_NN(sv)        (void)(++SvREFCNT((SV*)(sv)))
@@ -263,7 +266,7 @@ perform the upgrade if necessary.  See C<svtype>.
 #endif
 
 #define SVTYPEMASK     0xff
-#define SvTYPE(sv)     ((sv)->sv_flags & SVTYPEMASK)
+#define SvTYPE(sv)     (svtype)((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
@@ -284,6 +287,7 @@ perform the upgrade if necessary.  See C<svtype>.
 #define SVphv_CLONEABLE        0x00008000      /* PVHV (stashes) clone its objects */
 
 #define SVs_PADSTALE   0x00010000      /* lexical has gone out of scope */
+#define SVpad_STATE    0x00010000      /* pad name is a "state" var */
 #define SVs_PADTMP     0x00020000      /* in use as tmp */
 #define SVpad_TYPED    0x00020000      /* pad name is a Typed Lexical */
 #define SVs_PADMY      0x00040000      /* in use a "my" variable */
@@ -339,7 +343,8 @@ perform the upgrade if necessary.  See C<svtype>.
                                           keys live on shared string table */
 /* PVNV, PVMG, PVGV, presumably only inside pads */
 #define SVpad_NAME     0x40000000      /* This SV is a name in the PAD, so
-                                          SVpad_TYPED and SVpad_OUR apply */
+                                          SVpad_TYPED, SVpad_OUR and
+                                          SVpad_STATE apply */
 /* PVAV */
 #define SVpav_REAL     0x40000000      /* free old entries */
 /* PVHV */
@@ -837,7 +842,7 @@ Set the value of the RV pointer in sv to val.  See C<SvIV_set>.
 =for apidoc Am|void|SvMAGIC_set|SV* sv|MAGIC* val
 Set the value of the MAGIC pointer in sv to val.  See C<SvIV_set>.
 
-=for apidoc Am|void|SvSTASH_set|SV* sv|STASH* val
+=for apidoc Am|void|SvSTASH_set|SV* sv|HV* val
 Set the value of the STASH pointer in sv to val.  See C<SvIV_set>.
 
 =for apidoc Am|void|SvCUR_set|SV* sv|STRLEN len
@@ -947,7 +952,11 @@ in gv.h: */
                                    SvFLAGS(sv) |= (SVf_POK|SVp_POK))
 
 #define SvVOK(sv)              (SvMAGICAL(sv)                          \
+                                && mg_find(sv,PERL_MAGIC_vstring))
+/* returns the vstring magic, if any */
+#define SvVSTRING_mg(sv)       (SvMAGICAL(sv) \
                                 ? mg_find(sv,PERL_MAGIC_vstring) : NULL)
+
 #define SvOOK(sv)              (SvFLAGS(sv) & SVf_OOK)
 #define SvOOK_on(sv)           ((void)SvIOK_off(sv), SvFLAGS(sv) |= SVf_OOK)
 #define SvOOK_off(sv)          ((void)(SvOOK(sv) && sv_backoff(sv)))
@@ -1074,6 +1083,10 @@ the scalar's value cannot change unless written to.
        ((SvFLAGS(sv) & (SVpad_NAME|SVpad_OUR)) == (SVpad_NAME|SVpad_OUR))
 #define SvPAD_OUR_on(sv)       (SvFLAGS(sv) |= SVpad_NAME|SVpad_OUR)
 
+#define SvPAD_STATE(sv)        \
+       ((SvFLAGS(sv) & (SVpad_NAME|SVpad_STATE)) == (SVpad_NAME|SVpad_STATE))
+#define SvPAD_STATE_on(sv)     (SvFLAGS(sv) |= SVpad_NAME|SVpad_STATE)
+
 #define OURSTASH(sv)   \
        (SvPAD_OUR(sv) ? ((XPVMG*) SvANY(sv))->xmg_u.xmg_ourstash : NULL)
 #define OURSTASH_set(sv, st)                                   \
@@ -1157,6 +1170,7 @@ the scalar's value cannot change unless written to.
            assert(SvTYPE(_svi) == SVt_NV || SvTYPE(_svi) >= SVt_PVNV); \
            assert(SvTYPE(_svi) != SVt_PVAV);                           \
            assert(SvTYPE(_svi) != SVt_PVHV);                           \
+           assert(SvTYPE(_svi) != SVt_PVCV);                           \
            assert(SvTYPE(_svi) != SVt_PVFM);                           \
            assert(!isGV_with_GP(_svi));                                \
           &(((XPVNV*) SvANY(_svi))->xnv_u.xnv_nv);                     \
@@ -1212,19 +1226,28 @@ the scalar's value cannot change unless written to.
                (void) SvIV(sv); } STMT_END
 #define SvIV_set(sv, val) \
        STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \
+               assert(SvTYPE(sv) != SVt_PVAV);         \
+               assert(SvTYPE(sv) != SVt_PVHV);         \
+               assert(SvTYPE(sv) != SVt_PVCV);         \
                assert(!isGV_with_GP(sv));              \
                (((XPVIV*)  SvANY(sv))->xiv_iv = (val)); } STMT_END
 #define SvNV_set(sv, val) \
        STMT_START { assert(SvTYPE(sv) == SVt_NV || SvTYPE(sv) >= SVt_PVNV); \
            assert(SvTYPE(sv) != SVt_PVAV); assert(SvTYPE(sv) != SVt_PVHV); \
+           assert(SvTYPE(sv) != SVt_PVCV); assert(SvTYPE(sv) != SVt_PVFM); \
                assert(!isGV_with_GP(sv));              \
                (((XPVNV*)SvANY(sv))->xnv_u.xnv_nv = (val)); } STMT_END
 #define SvPV_set(sv, val) \
        STMT_START { assert(SvTYPE(sv) >= SVt_PV); \
+               assert(SvTYPE(sv) != SVt_PVAV);         \
+               assert(SvTYPE(sv) != SVt_PVHV);         \
                assert(!isGV_with_GP(sv));              \
                ((sv)->sv_u.svu_pv = (val)); } STMT_END
 #define SvUV_set(sv, val) \
        STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \
+               assert(SvTYPE(sv) != SVt_PVAV);         \
+               assert(SvTYPE(sv) != SVt_PVHV);         \
+               assert(SvTYPE(sv) != SVt_PVCV);         \
                assert(!isGV_with_GP(sv));              \
                (((XPVUV*)SvANY(sv))->xuv_uv = (val)); } STMT_END
 #define SvRV_set(sv, val) \
@@ -1239,10 +1262,14 @@ the scalar's value cannot change unless written to.
                 (((XPVMG*)  SvANY(sv))->xmg_stash = (val)); } STMT_END
 #define SvCUR_set(sv, val) \
        STMT_START { assert(SvTYPE(sv) >= SVt_PV); \
+               assert(SvTYPE(sv) != SVt_PVAV);         \
+               assert(SvTYPE(sv) != SVt_PVHV);         \
                assert(!isGV_with_GP(sv));              \
                (((XPV*)  SvANY(sv))->xpv_cur = (val)); } STMT_END
 #define SvLEN_set(sv, val) \
        STMT_START { assert(SvTYPE(sv) >= SVt_PV); \
+               assert(SvTYPE(sv) != SVt_PVAV); \
+               assert(SvTYPE(sv) != SVt_PVHV); \
                assert(!isGV_with_GP(sv));      \
                (((XPV*)  SvANY(sv))->xpv_len = (val)); } STMT_END
 #define SvEND_set(sv, val) \
@@ -1652,6 +1679,21 @@ Like C<sv_catsv> but doesn't process magic.
 #define SV_MUTABLE_RETURN      64
 #define SV_SMAGIC              128
 #define SV_HAS_TRAILING_NUL    256
+#define SV_COW_SHARED_HASH_KEYS        512
+
+/* The core is safe for this COW optimisation. XS code on CPAN may not be.
+   So only default to doing the COW setup if we're in the core.
+ */
+#ifdef PERL_CORE
+#  ifndef SV_DO_COW_SVSETSV
+#    define SV_DO_COW_SVSETSV  SV_COW_SHARED_HASH_KEYS
+#  endif
+#endif
+
+#ifndef SV_DO_COW_SVSETSV
+#  define SV_DO_COW_SVSETSV    0
+#endif
+
 
 #define sv_unref(sv)           sv_unref_flags(sv, 0)
 #define sv_force_normal(sv)    sv_force_normal_flags(sv, 0)
@@ -1693,8 +1735,9 @@ Like C<sv_catsv> but doesn't process magic.
 #define sv_pvn_force_nomg(sv, lp) sv_pvn_force_flags(sv, lp, 0)
 #define sv_utf8_upgrade_nomg(sv) sv_utf8_upgrade_flags(sv, 0)
 #define sv_catpvn_nomg(dsv, sstr, slen) sv_catpvn_flags(dsv, sstr, slen, 0)
-#define sv_setsv(dsv, ssv) sv_setsv_flags(dsv, ssv, SV_GMAGIC)
-#define sv_setsv_nomg(dsv, ssv) sv_setsv_flags(dsv, ssv, 0)
+#define sv_setsv(dsv, ssv) \
+       sv_setsv_flags(dsv, ssv, SV_GMAGIC|SV_DO_COW_SVSETSV)
+#define sv_setsv_nomg(dsv, ssv) sv_setsv_flags(dsv, ssv, SV_DO_COW_SVSETSV)
 #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)
@@ -1801,7 +1844,7 @@ Returns a pointer to the character buffer.
 #define SvSetSV_nosteal_and(dst,src,finally) \
        STMT_START {                                    \
            if ((dst) != (src)) {                       \
-               sv_setsv_flags(dst, src, SV_GMAGIC | SV_NOSTEAL);       \
+               sv_setsv_flags(dst, src, SV_GMAGIC | SV_NOSTEAL | SV_DO_COW_SVSETSV);   \
                finally;                                \
            }                                           \
        } STMT_END