This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
regexec.c: Fix "\x{FB01}\x{FB00}" =~ /ff/i
[perl5.git] / sv.h
diff --git a/sv.h b/sv.h
index 04a45c2..72cd887 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -65,6 +65,11 @@ typedef enum {
        SVt_LAST        /* keep last in enum. used to size arrays */
 } svtype;
 
+/* *** any alterations to the SV types above need to be reflected in
+ * SVt_MASK and the various PL_valid_types_* tables */
+
+#define SVt_MASK 0xf   /* smallest bitmask that covers all types */
+
 #ifndef PERL_CORE
 /* Although Fast Boyer Moore tables are now being stored in PVGVs, for most
    purposes eternal code wanting to consider PVBM probably needs to think of
@@ -304,10 +309,10 @@ perform the upgrade if necessary.  See C<svtype>.
                                       subroutine in another package. Set the
                                       CvIMPORTED_CV_ON() if it needs to be
                                       expanded to a real GV */
-
-#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 */
+/*                      0x00010000  *** FREE SLOT */
+#define SVs_PADTMP     0x00020000  /* in use as tmp; only if ! SVs_PADMY */
+#define SVs_PADSTALE   0x00020000  /* lexical has gone out of scope;
+                                       only valid for SVs_PADMY */
 #define SVpad_TYPED    0x00020000  /* pad name is a Typed Lexical */
 #define SVs_PADMY      0x00040000  /* in use a "my" variable */
 #define SVpad_OUR      0x00040000  /* pad name is "our" instead of "my" */
@@ -404,6 +409,8 @@ perform the upgrade if necessary.  See C<svtype>.
 #define SVpbm_TAIL     0x80000000
 /* RV upwards. However, SVf_ROK and SVp_IOK are exclusive  */
 #define SVprv_WEAKREF   0x80000000  /* Weak reference */
+/* pad name vars only */
+#define SVpad_STATE    0x80000000  /* pad name is a "state" var */
 
 #define _XPV_HEAD                                                      \
     HV*                xmg_stash;      /* class package */                     \
@@ -419,8 +426,7 @@ union _xnvu {
        U32 xhigh;
     }      xpad_cop_seq;       /* used by pad.c for cop_sequence */
     struct {
-       U32 xbm_previous;       /* how many characters in string before rare? */
-       U8  xbm_flags;
+       I32 xbm_useful;
        U8  xbm_rare;           /* rarest character in string */
     }      xbm_s;              /* fields from PVBM */
 };
@@ -428,7 +434,6 @@ union _xnvu {
 union _xivu {
     IV     xivu_iv;            /* integer value */
     UV     xivu_uv;
-    I32            xivu_i32;           /* BmUSEFUL */
     HEK *   xivu_namehek;      /* xpvlv, xpvgv: GvNAME */
 };
 
@@ -680,6 +685,9 @@ Only use when you are sure SvNOK is true. See also C<SvNV()>.
 Returns a pointer to the physical string in the SV.  The SV must contain a
 string.
 
+This is also used to store the name of an autoloaded subroutine in an XS
+AUTOLOAD routine.  See L<perlguts/Autoloading with XSUBs>.
+
 =for apidoc Am|STRLEN|SvCUR|SV* sv
 Returns the length of the string which is in the SV.  See C<SvLEN>.
 
@@ -688,9 +696,14 @@ Returns the size of the string buffer in the SV, not including any part
 attributable to C<SvOOK>.  See C<SvCUR>.
 
 =for apidoc Am|char*|SvEND|SV* sv
-Returns a pointer to the last character in the string which is in the SV.
+Returns a pointer to the spot just after the last character in
+the string which is in the SV, where there is usually a trailing
+null (even though Perl scalars do not strictly require it).
 See C<SvCUR>.  Access the character as *(SvEND(sv)).
 
+Warning: If C<SvCUR> is equal to C<SvLEN>, then C<SvEND> points to
+unallocated memory.
+
 =for apidoc Am|HV*|SvSTASH|SV* sv
 Returns the stash of the SV.
 
@@ -906,17 +919,43 @@ the scalar's value cannot change unless written to.
 
 #define SvTHINKFIRST(sv)       (SvFLAGS(sv) & SVf_THINKFIRST)
 
-#define SvPADSTALE(sv)         (SvFLAGS(sv) & SVs_PADSTALE)
-#define SvPADSTALE_on(sv)      (SvFLAGS(sv) |= SVs_PADSTALE)
-#define SvPADSTALE_off(sv)     (SvFLAGS(sv) &= ~SVs_PADSTALE)
-
-#define SvPADTMP(sv)           (SvFLAGS(sv) & SVs_PADTMP)
-#define SvPADTMP_on(sv)                (SvFLAGS(sv) |= SVs_PADTMP)
-#define SvPADTMP_off(sv)       (SvFLAGS(sv) &= ~SVs_PADTMP)
-
 #define SvPADMY(sv)            (SvFLAGS(sv) & SVs_PADMY)
 #define SvPADMY_on(sv)         (SvFLAGS(sv) |= SVs_PADMY)
 
+/* SVs_PADTMP and SVs_PADSTALE share the same bit, mediated by SVs_PADMY */
+
+#define SvPADTMP(sv)   ((SvFLAGS(sv) & (SVs_PADMY|SVs_PADTMP)) == SVs_PADTMP)
+#define SvPADSTALE(sv) ((SvFLAGS(sv) & (SVs_PADMY|SVs_PADSTALE)) \
+                                   == (SVs_PADMY|SVs_PADSTALE))
+
+#if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
+#  define SvPADTMP_on(sv)      ({                      \
+           SV *const _svpad = MUTABLE_SV(sv);          \
+           assert(!(SvFLAGS(_svpad) & SVs_PADMY));     \
+           SvFLAGS(_svpad) |= SVs_PADTMP;              \
+       })
+#  define SvPADTMP_off(sv)     ({                      \
+           SV *const _svpad = MUTABLE_SV(sv);          \
+           assert(!(SvFLAGS(_svpad) & SVs_PADMY));     \
+           SvFLAGS(_svpad) &= ~SVs_PADTMP;             \
+       })
+#  define SvPADSTALE_on(sv)    ({                      \
+           SV *const _svpad = MUTABLE_SV(sv);          \
+           assert(SvFLAGS(_svpad) & SVs_PADMY);        \
+           SvFLAGS(_svpad) |= SVs_PADSTALE;            \
+       })
+#  define SvPADSTALE_off(sv)   ({                      \
+           SV *const _svpad = MUTABLE_SV(sv);          \
+           assert(SvFLAGS(_svpad) & SVs_PADMY);        \
+           SvFLAGS(_svpad) &= ~SVs_PADSTALE;           \
+       })
+#else
+#  define SvPADTMP_on(sv)      (SvFLAGS(sv) |= SVs_PADTMP)
+#  define SvPADTMP_off(sv)     (SvFLAGS(sv) &= ~SVs_PADTMP)
+#  define SvPADSTALE_on(sv)    (SvFLAGS(sv) |= SVs_PADSTALE)
+#  define SvPADSTALE_off(sv)   (SvFLAGS(sv) &= ~SVs_PADSTALE)
+#endif
+
 #define SvTEMP(sv)             (SvFLAGS(sv) & SVs_TEMP)
 #define SvTEMP_on(sv)          (SvFLAGS(sv) |= SVs_TEMP)
 #define SvTEMP_off(sv)         (SvFLAGS(sv) &= ~SVs_TEMP)
@@ -1050,9 +1089,7 @@ the scalar's value cannot change unless written to.
 /* These get expanded inside other macros that already use a variable _sv  */
 #    define SvPVX(sv)                                                  \
        (*({ SV *const _svpvx = MUTABLE_SV(sv);                         \
-           assert(SvTYPE(_svpvx) >= SVt_PV);                           \
-           assert(SvTYPE(_svpvx) != SVt_PVAV);                         \
-           assert(SvTYPE(_svpvx) != SVt_PVHV);                         \
+           assert(PL_valid_types_PVX[SvTYPE(_svpvx) & SVt_MASK]);      \
            assert(!isGV_with_GP(_svpvx));                              \
            assert(!(SvTYPE(_svpvx) == SVt_PVIO                         \
                     && !(IoFLAGS(_svpvx) & IOf_FAKE_DIRP)));           \
@@ -1060,9 +1097,7 @@ the scalar's value cannot change unless written to.
         }))
 #    define SvCUR(sv)                                                  \
        (*({ const SV *const _svcur = (const SV *)(sv);                 \
-           assert(SvTYPE(_svcur) >= SVt_PV);                           \
-           assert(SvTYPE(_svcur) != SVt_PVAV);                         \
-           assert(SvTYPE(_svcur) != SVt_PVHV);                         \
+           assert(PL_valid_types_PVX[SvTYPE(_svcur) & SVt_MASK]);      \
            assert(!isGV_with_GP(_svcur));                              \
            assert(!(SvTYPE(_svcur) == SVt_PVIO                         \
                     && !(IoFLAGS(_svcur) & IOf_FAKE_DIRP)));           \
@@ -1070,47 +1105,25 @@ the scalar's value cannot change unless written to.
         }))
 #    define SvIVX(sv)                                                  \
        (*({ const SV *const _svivx = (const SV *)(sv);                 \
-           assert(SvTYPE(_svivx) == SVt_IV || SvTYPE(_svivx) >= SVt_PVIV); \
-           assert(SvTYPE(_svivx) != SVt_PVAV);                         \
-           assert(SvTYPE(_svivx) != SVt_PVHV);                         \
-           assert(SvTYPE(_svivx) != SVt_PVCV);                         \
-           assert(SvTYPE(_svivx) != SVt_PVFM);                         \
-           assert(SvTYPE(_svivx) != SVt_PVIO);                         \
-           assert(SvTYPE(_svivx) != SVt_REGEXP);                       \
+           assert(PL_valid_types_IVX[SvTYPE(_svivx) & SVt_MASK]);      \
            assert(!isGV_with_GP(_svivx));                              \
            &(((XPVIV*) MUTABLE_PTR(SvANY(_svivx)))->xiv_iv);           \
         }))
 #    define SvUVX(sv)                                                  \
        (*({ const SV *const _svuvx = (const SV *)(sv);                 \
-           assert(SvTYPE(_svuvx) == SVt_IV || SvTYPE(_svuvx) >= SVt_PVIV); \
-           assert(SvTYPE(_svuvx) != SVt_PVAV);                         \
-           assert(SvTYPE(_svuvx) != SVt_PVHV);                         \
-           assert(SvTYPE(_svuvx) != SVt_PVCV);                         \
-           assert(SvTYPE(_svuvx) != SVt_PVFM);                         \
-           assert(SvTYPE(_svuvx) != SVt_PVIO);                         \
-           assert(SvTYPE(_svuvx) != SVt_REGEXP);                       \
+           assert(PL_valid_types_IVX[SvTYPE(_svuvx) & SVt_MASK]);      \
            assert(!isGV_with_GP(_svuvx));                              \
            &(((XPVUV*) MUTABLE_PTR(SvANY(_svuvx)))->xuv_uv);           \
         }))
 #    define SvNVX(sv)                                                  \
        (*({ const SV *const _svnvx = (const SV *)(sv);                 \
-           assert(SvTYPE(_svnvx) == SVt_NV || SvTYPE(_svnvx) >= SVt_PVNV); \
-           assert(SvTYPE(_svnvx) != SVt_PVAV);                         \
-           assert(SvTYPE(_svnvx) != SVt_PVHV);                         \
-           assert(SvTYPE(_svnvx) != SVt_PVCV);                         \
-           assert(SvTYPE(_svnvx) != SVt_PVFM);                         \
-           assert(SvTYPE(_svnvx) != SVt_PVIO);                         \
-           assert(SvTYPE(_svnvx) != SVt_REGEXP);                       \
+           assert(PL_valid_types_NVX[SvTYPE(_svnvx) & SVt_MASK]);      \
            assert(!isGV_with_GP(_svnvx));                              \
            &(((XPVNV*) MUTABLE_PTR(SvANY(_svnvx)))->xnv_u.xnv_nv);     \
         }))
 #    define SvRV(sv)                                                   \
        (*({ SV *const _svrv = MUTABLE_SV(sv);                          \
-           assert(SvTYPE(_svrv) >= SVt_PV || SvTYPE(_svrv) == SVt_IV); \
-           assert(SvTYPE(_svrv) != SVt_PVAV);                          \
-           assert(SvTYPE(_svrv) != SVt_PVHV);                          \
-           assert(SvTYPE(_svrv) != SVt_PVCV);                          \
-           assert(SvTYPE(_svrv) != SVt_PVFM);                          \
+           assert(PL_valid_types_RV[SvTYPE(_svrv) & SVt_MASK]);        \
            assert(!isGV_with_GP(_svrv));                               \
            assert(!(SvTYPE(_svrv) == SVt_PVIO                          \
                     && !(IoFLAGS(_svrv) & IOf_FAKE_DIRP)));            \
@@ -1118,11 +1131,7 @@ the scalar's value cannot change unless written to.
         }))
 #    define SvRV_const(sv)                                             \
        ({ const SV *const _svrv = (const SV *)(sv);                    \
-           assert(SvTYPE(_svrv) >= SVt_PV || SvTYPE(_svrv) == SVt_IV); \
-           assert(SvTYPE(_svrv) != SVt_PVAV);                          \
-           assert(SvTYPE(_svrv) != SVt_PVHV);                          \
-           assert(SvTYPE(_svrv) != SVt_PVCV);                          \
-           assert(SvTYPE(_svrv) != SVt_PVFM);                          \
+           assert(PL_valid_types_RV[SvTYPE(_svrv) & SVt_MASK]);        \
            assert(!isGV_with_GP(_svrv));                               \
            assert(!(SvTYPE(_svrv) == SVt_PVIO                          \
                     && !(IoFLAGS(_svrv) & IOf_FAKE_DIRP)));            \
@@ -1183,40 +1192,30 @@ the scalar's value cannot change unless written to.
        STMT_START {if (!SvIOKp(sv) && (SvNOK(sv) || SvPOK(sv))) \
                (void) SvIV_nomg(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);         \
+       STMT_START { \
+               assert(PL_valid_types_IV_set[SvTYPE(sv) & SVt_MASK]);   \
                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(SvTYPE(sv) != SVt_PVIO);         \
+       STMT_START { \
+               assert(PL_valid_types_NV_set[SvTYPE(sv) & SVt_MASK]);   \
                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);         \
+       STMT_START { \
+               assert(PL_valid_types_PVX[SvTYPE(sv) & SVt_MASK]);      \
                assert(!isGV_with_GP(sv));              \
                assert(!(SvTYPE(sv) == SVt_PVIO         \
                     && !(IoFLAGS(sv) & IOf_FAKE_DIRP))); \
                ((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);         \
+       STMT_START { \
+               assert(PL_valid_types_IV_set[SvTYPE(sv) & SVt_MASK]);   \
                assert(!isGV_with_GP(sv));              \
                (((XPVUV*)SvANY(sv))->xuv_uv = (val)); } STMT_END
 #define SvRV_set(sv, val) \
-        STMT_START { assert(SvTYPE(sv) >=  SVt_PV || SvTYPE(sv) ==  SVt_IV); \
-               assert(SvTYPE(sv) != SVt_PVAV);         \
-               assert(SvTYPE(sv) != SVt_PVHV);         \
-               assert(SvTYPE(sv) != SVt_PVCV);         \
-               assert(SvTYPE(sv) != SVt_PVFM);         \
+        STMT_START { \
+               assert(PL_valid_types_RV[SvTYPE(sv) & SVt_MASK]);       \
                assert(!isGV_with_GP(sv));              \
                assert(!(SvTYPE(sv) == SVt_PVIO         \
                     && !(IoFLAGS(sv) & IOf_FAKE_DIRP))); \
@@ -1228,17 +1227,15 @@ the scalar's value cannot change unless written to.
         STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \
                 (((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);         \
+       STMT_START { \
+               assert(PL_valid_types_PVX[SvTYPE(sv) & SVt_MASK]);      \
                assert(!isGV_with_GP(sv));              \
                assert(!(SvTYPE(sv) == SVt_PVIO         \
                     && !(IoFLAGS(sv) & IOf_FAKE_DIRP))); \
                (((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); \
+       STMT_START { \
+               assert(PL_valid_types_PVX[SvTYPE(sv) & SVt_MASK]);      \
                assert(!isGV_with_GP(sv));      \
                assert(!(SvTYPE(sv) == SVt_PVIO         \
                     && !(IoFLAGS(sv) & IOf_FAKE_DIRP))); \
@@ -1289,8 +1286,6 @@ the scalar's value cannot change unless written to.
                 } STMT_END
 #endif
 
-#define PERL_FBM_TABLE_OFFSET 1        /* Number of bytes between EOS and table */
-
 /* SvPOKp not SvPOK in the assertion because the string can be tainted! eg
    perl -T -e '/$^X/'
 */
@@ -1302,27 +1297,27 @@ the scalar's value cannot change unless written to.
 #if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
 #  define BmRARE(sv)                                                   \
        (*({ SV *const _bmrare = MUTABLE_SV(sv);                        \
-               assert(SvTYPE(_bmrare) == SVt_PVGV);                    \
+               assert(SvTYPE(_bmrare) == SVt_PVMG);                    \
                assert(SvVALID(_bmrare));                               \
-           &(((XPVGV*) SvANY(_bmrare))->xnv_u.xbm_s.xbm_rare);         \
+           &(((XPVMG*) SvANY(_bmrare))->xnv_u.xbm_s.xbm_rare);         \
         }))
 #  define BmUSEFUL(sv)                                                 \
        (*({ SV *const _bmuseful = MUTABLE_SV(sv);                      \
-           assert(SvTYPE(_bmuseful) == SVt_PVGV);                      \
+           assert(SvTYPE(_bmuseful) == SVt_PVMG);                      \
            assert(SvVALID(_bmuseful));                                 \
            assert(!SvIOK(_bmuseful));                                  \
-           &(((XPVGV*) SvANY(_bmuseful))->xiv_u.xivu_i32);             \
+           &(((XPVMG*) SvANY(_bmuseful))->xnv_u.xbm_s.xbm_useful);     \
         }))
 #  define BmPREVIOUS(sv)                                               \
     (*({ SV *const _bmprevious = MUTABLE_SV(sv);                       \
-               assert(SvTYPE(_bmprevious) == SVt_PVGV);                \
+               assert(SvTYPE(_bmprevious) == SVt_PVMG);                \
                assert(SvVALID(_bmprevious));                           \
-           &(((XPVGV*) SvANY(_bmprevious))->xnv_u.xbm_s.xbm_previous); \
+           &(((XPVMG*) SvANY(_bmprevious))->xiv_u.xivu_uv);            \
         }))
 #else
-#  define BmRARE(sv)           ((XPVGV*) SvANY(sv))->xnv_u.xbm_s.xbm_rare
-#  define BmUSEFUL(sv)         ((XPVGV*) SvANY(sv))->xiv_u.xivu_i32
-#  define BmPREVIOUS(sv)       ((XPVGV*) SvANY(sv))->xnv_u.xbm_s.xbm_previous
+#  define BmRARE(sv)           ((XPVMG*) SvANY(sv))->xnv_u.xbm_s.xbm_rare
+#  define BmUSEFUL(sv)         ((XPVMG*) SvANY(sv))->xnv_u.xbm_s.xbm_useful
+#  define BmPREVIOUS(sv)       ((XPVMG*) SvANY(sv))->xiv_u.xivu_uv
 
 #endif
 
@@ -1742,8 +1737,8 @@ Like sv_utf8_upgrade, but doesn't do magic on C<sv>
 #  define SvTRUEx(sv) ((PL_Sv = (sv)), SvTRUE(PL_Sv))
 #endif /* __GNU__ */
 
-#define SvIsCOW(sv)            ((SvFLAGS(sv) & (SVf_FAKE | SVf_READONLY)) == \
-                                   (SVf_FAKE | SVf_READONLY))
+#define SvIsCOW(sv)    ((SvFLAGS(sv) & (SVf_FAKE | SVf_READONLY)) == \
+                          (SVf_FAKE | SVf_READONLY) && !isGV_with_GP(sv))
 #define SvIsCOW_shared_hash(sv)        (SvIsCOW(sv) && SvLEN(sv) == 0)
 
 #define SvSHARED_HEK_FROM_PV(pvx) \
@@ -1772,6 +1767,12 @@ Like sv_utf8_upgrade, but doesn't do magic on C<sv>
 /* if (after resolving magic etc), the SV is found to be overloaded,
  * don't call the overload magic, just return as-is */
 #define SV_SKIP_OVERLOAD       8192
+/* It is not yet clear whether we want this as an API, or what the
+ * constants should be named. */
+#ifdef PERL_CORE
+# define SV_CATBYTES           16384
+# define SV_CATUTF8            32768
+#endif
 
 /* 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.
@@ -1941,7 +1942,7 @@ Returns a pointer to the character buffer.
 #define SvUNLOCK(sv) PL_unlockhook(aTHX_ sv)
 #define SvDESTROYABLE(sv) PL_destroyhook(aTHX_ sv)
 
-#define SvGETMAGIC(x) STMT_START { if (SvGMAGICAL(x)) mg_get(x); } STMT_END
+#define SvGETMAGIC(x) ((void)(SvGMAGICAL(x) && mg_get(x)))
 #define SvSETMAGIC(x) STMT_START { if (SvSMAGICAL(x)) mg_set(x); } STMT_END
 
 #define SvSetSV_and(dst,src,finally) \