This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
handy.h: Create nBIT_UMAX() macro
[perl5.git] / sv.h
diff --git a/sv.h b/sv.h
index 490cab4..2f4a85f 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -432,7 +432,7 @@ perform the upgrade if necessary.  See C<L</svtype>>.
 
 #define PRIVSHIFT 4    /* (SVp_?OK >> PRIVSHIFT) == SVf_?OK */
 
-/* SVf_AMAGIC means that the stash *may* have have overload methods. It's
+/* SVf_AMAGIC means that the stash *may* have overload methods. It's
  * set each time a function is compiled into a stash, and is reset by the
  * overload code when called for the first time and finds that there are
  * no overload methods. Note that this used to be set on the object; but
@@ -702,12 +702,12 @@ Tells an SV that it is an unsigned integer and disables all other C<OK> bits.
 =for apidoc Am|bool|SvIOK_UV|SV* sv
 Returns a boolean indicating whether the SV contains an integer that must be
 interpreted as unsigned.  A non-negative integer whose value is within the
-range of both an IV and a UV may be be flagged as either C<SvUOK> or C<SvIOK>.
+range of both an IV and a UV may be flagged as either C<SvUOK> or C<SvIOK>.
 
 =for apidoc Am|bool|SvUOK|SV* sv
 Returns a boolean indicating whether the SV contains an integer that must be
 interpreted as unsigned.  A non-negative integer whose value is within the
-range of both an IV and a UV may be be flagged as either C<SvUOK> or C<SvIOK>.
+range of both an IV and a UV may be flagged as either C<SvUOK> or C<SvIOK>.
 
 =for apidoc Am|bool|SvIOK_notUV|SV* sv
 Returns a boolean indicating whether the SV contains a signed integer.
@@ -1098,7 +1098,7 @@ C<sv_force_normal> does nothing.
 /*
 =for apidoc Am|U32|SvREADONLY|SV* sv
 Returns true if the argument is readonly, otherwise returns false.
-Exposed to to perl code via Internals::SvREADONLY().
+Exposed to perl code via Internals::SvREADONLY().
 
 =for apidoc Am|U32|SvREADONLY_on|SV* sv
 Mark an object as readonly. Exactly what this means depends on the object
@@ -1607,20 +1607,18 @@ false.  See C<L</SvOK>> for a defined/undefined test.  Handles 'get' magic
 unless the scalar is already C<SvPOK>, C<SvIOK> or C<SvNOK> (the public, not the
 private flags).
 
-See C<L</SvTRUEx>> for a version which guarantees to evaluate C<sv> only once.
+As of Perl 5.32, this is guaranteed to evaluate C<sv> only once.  Prior to that
+release, use C<L</SvTRUEx>> for single evaluation.
 
 =for apidoc Am|bool|SvTRUE_nomg|SV* sv
 Returns a boolean indicating whether Perl would evaluate the SV as true or
 false.  See C<L</SvOK>> for a defined/undefined test.  Does not handle 'get' magic.
 
 =for apidoc Am|bool|SvTRUEx|SV* sv
-Returns a boolean indicating whether Perl would evaluate the SV as true or
-false.  See C<L</SvOK>> for a defined/undefined test.  Handles 'get' magic
-unless the scalar is already C<SvPOK>, C<SvIOK> or C<SvNOK> (the public, not the
-private flags).
-
-This form guarantees to evaluate C<sv> only once.  Only use this if C<sv> is an
-expression with side effects, otherwise use the more efficient C<SvTRUE>.
+Identical to C<L</SvTRUE>>.  Prior to 5.32, they differed in that only this one
+was guaranteed to evaluate C<sv> only once; in 5.32 they both evaluated it
+once, but C<SvTRUEx> was slightly slower on some platforms; now they are
+identical.
 
 =for apidoc Am|char*|SvPVutf8_force|SV* sv|STRLEN len
 Like C<SvPV_force>, but converts C<sv> to UTF-8 first if necessary.
@@ -1711,50 +1709,50 @@ Like C<sv_catsv> but doesn't process magic.
 #define SvNV(sv) (SvNOK_nog(sv) ? SvNVX(sv) : sv_2nv(sv))
 
 #define SvIV_nomg(sv) (SvIOK(sv) ? SvIVX(sv) : sv_2iv_flags(sv, 0))
-#define SvUV_nomg(sv) (SvIOK(sv) ? SvUVX(sv) : sv_2uv_flags(sv, 0))
+#define SvUV_nomg(sv) (SvUOK(sv) ? SvUVX(sv) : sv_2uv_flags(sv, 0))
 #define SvNV_nomg(sv) (SvNOK(sv) ? SvNVX(sv) : sv_2nv_flags(sv, 0))
 
 /* ----*/
 
-#define SvPV(sv, lp)         SvPV_flags(sv, lp, SV_GMAGIC)
-#define SvPV_const(sv, lp)   SvPV_flags_const(sv, lp, SV_GMAGIC)
-#define SvPV_mutable(sv, lp) SvPV_flags_mutable(sv, lp, SV_GMAGIC)
+#define SvPV(sv, len)         SvPV_flags(sv, len, SV_GMAGIC)
+#define SvPV_const(sv, len)   SvPV_flags_const(sv, len, SV_GMAGIC)
+#define SvPV_mutable(sv, len) SvPV_flags_mutable(sv, len, SV_GMAGIC)
 
-#define SvPV_flags(sv, lp, flags) \
+#define SvPV_flags(sv, len, flags) \
     (SvPOK_nog(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv_flags(sv, &lp, flags))
-#define SvPV_flags_const(sv, lp, flags) \
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : sv_2pv_flags(sv, &len, flags))
+#define SvPV_flags_const(sv, len, flags) \
     (SvPOK_nog(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX_const(sv)) : \
-     (const char*) sv_2pv_flags(sv, &lp, (flags|SV_CONST_RETURN)))
+     ? ((len = SvCUR(sv)), SvPVX_const(sv)) : \
+     (const char*) sv_2pv_flags(sv, &len, (flags|SV_CONST_RETURN)))
 #define SvPV_flags_const_nolen(sv, flags) \
     (SvPOK_nog(sv) \
      ? SvPVX_const(sv) : \
      (const char*) sv_2pv_flags(sv, 0, (flags|SV_CONST_RETURN)))
-#define SvPV_flags_mutable(sv, lp, flags) \
+#define SvPV_flags_mutable(sv, len, flags) \
     (SvPOK_nog(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) : \
-     sv_2pv_flags(sv, &lp, (flags|SV_MUTABLE_RETURN)))
+     ? ((len = SvCUR(sv)), SvPVX_mutable(sv)) : \
+     sv_2pv_flags(sv, &len, (flags|SV_MUTABLE_RETURN)))
 
-#define SvPV_force(sv, lp) SvPV_force_flags(sv, lp, SV_GMAGIC)
+#define SvPV_force(sv, len) SvPV_force_flags(sv, len, SV_GMAGIC)
 #define SvPV_force_nolen(sv) SvPV_force_flags_nolen(sv, SV_GMAGIC)
-#define SvPV_force_mutable(sv, lp) SvPV_force_flags_mutable(sv, lp, SV_GMAGIC)
+#define SvPV_force_mutable(sv, len) SvPV_force_flags_mutable(sv, len, SV_GMAGIC)
 
-#define SvPV_force_nomg(sv, lp) SvPV_force_flags(sv, lp, 0)
+#define SvPV_force_nomg(sv, len) SvPV_force_flags(sv, len, 0)
 #define SvPV_force_nomg_nolen(sv) SvPV_force_flags_nolen(sv, 0)
 
-#define SvPV_force_flags(sv, lp, flags) \
+#define SvPV_force_flags(sv, len, flags) \
     (SvPOK_pure_nogthink(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvn_force_flags(sv, &lp, flags))
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : sv_pvn_force_flags(sv, &len, flags))
 
 #define SvPV_force_flags_nolen(sv, flags) \
     (SvPOK_pure_nogthink(sv) \
      ? SvPVX(sv) : sv_pvn_force_flags(sv, 0, flags))
 
-#define SvPV_force_flags_mutable(sv, lp, flags) \
+#define SvPV_force_flags_mutable(sv, len, flags) \
     (SvPOK_pure_nogthink(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) \
-     : sv_pvn_force_flags(sv, &lp, flags|SV_MUTABLE_RETURN))
+     ? ((len = SvCUR(sv)), SvPVX_mutable(sv)) \
+     : sv_pvn_force_flags(sv, &len, flags|SV_MUTABLE_RETURN))
 
 #define SvPV_nolen(sv) \
     (SvPOK_nog(sv) \
@@ -1769,33 +1767,33 @@ Like C<sv_catsv> but doesn't process magic.
     (SvPOK_nog(sv) \
      ? SvPVX_const(sv) : sv_2pv_flags(sv, 0, SV_GMAGIC|SV_CONST_RETURN))
 
-#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(sv, len) SvPV_flags(sv, len, 0)
+#define SvPV_nomg_const(sv, len) SvPV_flags_const(sv, len, 0)
 #define SvPV_nomg_const_nolen(sv) SvPV_flags_const_nolen(sv, 0)
 
 /* ----*/
 
-#define SvPVutf8(sv, lp) \
+#define SvPVutf8(sv, len) \
     (SvPOK_utf8_nog(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvutf8(sv, &lp))
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : sv_2pvutf8(sv, &len))
 
-#define SvPVutf8_or_null(sv, lp) \
+#define SvPVutf8_or_null(sv, len) \
     (SvPOK_utf8_nog(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : (SvGETMAGIC(sv), SvOK(sv)) \
-     ? sv_2pvutf8_flags(sv, &lp, 0) : ((lp = 0), NULL))
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : (SvGETMAGIC(sv), SvOK(sv)) \
+     ? sv_2pvutf8_flags(sv, &len, 0) : ((len = 0), NULL))
 
-#define SvPVutf8_nomg(sv, lp) \
+#define SvPVutf8_nomg(sv, len) \
     (SvPOK_utf8_nog(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvutf8_flags(sv, &lp, 0))
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : sv_2pvutf8_flags(sv, &len, 0))
 
-#define SvPVutf8_or_null_nomg(sv, lp) \
+#define SvPVutf8_or_null_nomg(sv, len) \
     (SvPOK_utf8_nog(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : SvOK(sv) \
-     ? sv_2pvutf8_flags(sv, &lp, 0) : ((lp = 0), NULL))
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : SvOK(sv) \
+     ? sv_2pvutf8_flags(sv, &len, 0) : ((len = 0), NULL))
 
-#define SvPVutf8_force(sv, lp) \
+#define SvPVutf8_force(sv, len) \
     (SvPOK_utf8_pure_nogthink(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvutf8n_force(sv, &lp))
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : sv_pvutf8n_force(sv, &len))
 
 #define SvPVutf8_nolen(sv) \
     (SvPOK_utf8_nog(sv) \
@@ -1803,27 +1801,27 @@ Like C<sv_catsv> but doesn't process magic.
 
 /* ----*/
 
-#define SvPVbyte(sv, lp) \
+#define SvPVbyte(sv, len) \
     (SvPOK_byte_nog(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvbyte(sv, &lp))
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : sv_2pvbyte(sv, &len))
 
-#define SvPVbyte_or_null(sv, lp) \
+#define SvPVbyte_or_null(sv, len) \
     (SvPOK_byte_nog(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : (SvGETMAGIC(sv), SvOK(sv)) \
-     ? sv_2pvbyte_flags(sv, &lp, 0) : ((lp = 0), NULL))
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : (SvGETMAGIC(sv), SvOK(sv)) \
+     ? sv_2pvbyte_flags(sv, &len, 0) : ((len = 0), NULL))
 
-#define SvPVbyte_nomg(sv, lp) \
+#define SvPVbyte_nomg(sv, len) \
     (SvPOK_byte_nog(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvbyte_flags(sv, &lp, 0))
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : sv_2pvbyte_flags(sv, &len, 0))
 
-#define SvPVbyte_or_null_nomg(sv, lp) \
+#define SvPVbyte_or_null_nomg(sv, len) \
     (SvPOK_utf8_nog(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : SvOK(sv) \
-     ? sv_2pvbyte_flags(sv, &lp, 0) : ((lp = 0), NULL))
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : SvOK(sv) \
+     ? sv_2pvbyte_flags(sv, &len, 0) : ((len = 0), NULL))
 
-#define SvPVbyte_force(sv, lp) \
+#define SvPVbyte_force(sv, len) \
     (SvPOK_byte_pure_nogthink(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvbyten_force(sv, &lp))
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : sv_pvbyten_force(sv, &len))
 
 #define SvPVbyte_nolen(sv) \
     (SvPOK_byte_nog(sv) \
@@ -1835,11 +1833,12 @@ Like C<sv_catsv> but doesn't process magic.
  * failing that, call a function to do the work
  */
 
-#define SvPVx_force(sv, lp) sv_pvn_force(sv, &lp)
-#define SvPVutf8x_force(sv, lp) sv_pvutf8n_force(sv, &lp)
-#define SvPVbytex_force(sv, lp) sv_pvbyten_force(sv, &lp)
+#define SvPVx_force(sv, len) sv_pvn_force(sv, &len)
+#define SvPVutf8x_force(sv, len) sv_pvutf8n_force(sv, &len)
+#define SvPVbytex_force(sv, len) sv_pvbyten_force(sv, &len)
 
-#define SvTRUE(sv)         (LIKELY(sv) && SvTRUE_NN(sv))
+#define SvTRUE(sv)         Perl_SvTRUE(aTHX_ sv)
+#define SvTRUEx(sv)        SvTRUE(sv)
 #define SvTRUE_nomg(sv)    (LIKELY(sv) && SvTRUE_nomg_NN(sv))
 #define SvTRUE_NN(sv)      (SvGETMAGIC(sv), SvTRUE_nomg_NN(sv))
 #define SvTRUE_nomg_NN(sv) (SvTRUE_common(sv, sv_2bool_nomg(sv)))
@@ -1863,14 +1862,13 @@ Like C<sv_catsv> but doesn't process magic.
 #  define SvIVx(sv) ({SV *_sv = MUTABLE_SV(sv); SvIV(_sv); })
 #  define SvUVx(sv) ({SV *_sv = MUTABLE_SV(sv); SvUV(_sv); })
 #  define SvNVx(sv) ({SV *_sv = MUTABLE_SV(sv); SvNV(_sv); })
-#  define SvPVx(sv, lp) ({SV *_sv = (sv); SvPV(_sv, lp); })
-#  define SvPVx_const(sv, lp) ({SV *_sv = (sv); SvPV_const(_sv, lp); })
+#  define SvPVx(sv, len) ({SV *_sv = (sv); SvPV(_sv, len); })
+#  define SvPVx_const(sv, len) ({SV *_sv = (sv); SvPV_const(_sv, len); })
 #  define SvPVx_nolen(sv) ({SV *_sv = (sv); SvPV_nolen(_sv); })
 #  define SvPVx_nolen_const(sv) ({SV *_sv = (sv); SvPV_nolen_const(_sv); })
-#  define SvPVutf8x(sv, lp) ({SV *_sv = (sv); SvPVutf8(_sv, lp); })
-#  define SvPVbytex(sv, lp) ({SV *_sv = (sv); SvPVbyte(_sv, lp); })
+#  define SvPVutf8x(sv, len) ({SV *_sv = (sv); SvPVutf8(_sv, len); })
+#  define SvPVbytex(sv, len) ({SV *_sv = (sv); SvPVbyte(_sv, len); })
 #  define SvPVbytex_nolen(sv) ({SV *_sv = (sv); SvPVbyte_nolen(_sv); })
-#  define SvTRUEx(sv)      ({SV *_sv = (sv); SvTRUE(_sv); })
 #  define SvTRUEx_nomg(sv) ({SV *_sv = (sv); SvTRUE_nomg(_sv); })
 
 #else /* __GNUC__ */
@@ -1881,14 +1879,13 @@ Like C<sv_catsv> but doesn't process magic.
 #  define SvIVx(sv) ((PL_Sv = (sv)), SvIV(PL_Sv))
 #  define SvUVx(sv) ((PL_Sv = (sv)), SvUV(PL_Sv))
 #  define SvNVx(sv) ((PL_Sv = (sv)), SvNV(PL_Sv))
-#  define SvPVx(sv, lp) ((PL_Sv = (sv)), SvPV(PL_Sv, lp))
-#  define SvPVx_const(sv, lp) ((PL_Sv = (sv)), SvPV_const(PL_Sv, lp))
+#  define SvPVx(sv, len) ((PL_Sv = (sv)), SvPV(PL_Sv, len))
+#  define SvPVx_const(sv, len) ((PL_Sv = (sv)), SvPV_const(PL_Sv, len))
 #  define SvPVx_nolen(sv) ((PL_Sv = (sv)), SvPV_nolen(PL_Sv))
 #  define SvPVx_nolen_const(sv) ((PL_Sv = (sv)), SvPV_nolen_const(PL_Sv))
-#  define SvPVutf8x(sv, lp) ((PL_Sv = (sv)), SvPVutf8(PL_Sv, lp))
-#  define SvPVbytex(sv, lp) ((PL_Sv = (sv)), SvPVbyte(PL_Sv, lp))
+#  define SvPVutf8x(sv, len) ((PL_Sv = (sv)), SvPVutf8(PL_Sv, len))
+#  define SvPVbytex(sv, len) ((PL_Sv = (sv)), SvPVbyte(PL_Sv, len))
 #  define SvPVbytex_nolen(sv) ((PL_Sv = (sv)), SvPVbyte_nolen(PL_Sv))
-#  define SvTRUEx(sv)      ((PL_Sv = (sv)), SvTRUE(PL_Sv))
 #  define SvTRUEx_nomg(sv) ((PL_Sv = (sv)), SvTRUE_nomg(PL_Sv))
 #endif /* __GNU__ */
 
@@ -1976,7 +1973,7 @@ Like C<sv_catsv> but doesn't process magic.
                            && SvCUR(sv)+1 < SvLEN(sv))
    /* Note: To allow 256 COW "copies", a refcnt of 0 means 1. */
 #   define CowREFCNT(sv)       (*(U8 *)(SvPVX(sv)+SvLEN(sv)-1))
-#   define SV_COW_REFCNT_MAX   ((1 << sizeof(U8)*8) - 1)
+#   define SV_COW_REFCNT_MAX   nBIT_UMAX(sizeof(U8) * CHARBITS)
 #   define CAN_COW_MASK        (SVf_POK|SVf_ROK|SVp_POK|SVf_FAKE| \
                         SVf_OOK|SVf_BREAK|SVf_READONLY|SVf_PROTECT)
 #endif