This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Re-implement the SvOOK() hack to store the offset as a BER encoded
[perl5.git] / sv.h
diff --git a/sv.h b/sv.h
index 63eccbd..afa18dc 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -48,11 +48,12 @@ typedef enum {
        SVt_BIND,       /* 1 */
        SVt_IV,         /* 2 */
        SVt_NV,         /* 3 */
-       SVt_RV,         /* 4 */
-       SVt_PV,         /* 5 */
-       SVt_PVIV,       /* 6 */
-       SVt_PVNV,       /* 7 */
-       SVt_PVMG,       /* 8 */
+       /* RV was here, before it was merged with IV.  */
+       SVt_PV,         /* 4 */
+       SVt_PVIV,       /* 5 */
+       SVt_PVNV,       /* 6 */
+       SVt_PVMG,       /* 7 */
+       SVt_REGEXP,     /* 8 */
        /* PVBM was here, before BIND replaced it.  */
        SVt_PVGV,       /* 9 */
        SVt_PVLV,       /* 10 */
@@ -69,6 +70,9 @@ typedef enum {
    purposes eternal code wanting to consider PVBM probably needs to think of
    PVMG instead.  */
 #  define SVt_PVBM     SVt_PVMG
+/* Anything wanting to create a reference from clean should ensure that it has
+   a scalar of type SVt_IV now:  */
+#  define SVt_RV       SVt_IV
 #endif
 
 /* There is collusion here with sv_clear - sv_clear exits early for SVt_NULL
@@ -388,179 +392,88 @@ perform the upgrade if necessary.  See C<svtype>.
 /* RV upwards. However, SVf_ROK and SVp_IOK are exclusive  */
 #define SVprv_WEAKREF   0x80000000  /* Weak reference */
 
+#define _XPV_ALLOCATED_HEAD                                            \
+    STRLEN     xpv_cur;        /* length of svu_pv as a C string */    \
+    STRLEN     xpv_len         /* allocated size */
+
+#define _XPV_HEAD      \
+    union _xnvu xnv_u; \
+    _XPV_ALLOCATED_HEAD
+
+union _xnvu {
+    NV     xnv_nv;             /* numeric value, if any */
+    HV *    xgv_stash;
+    struct {
+       U32 xlow;
+       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;
+       U8  xbm_rare;           /* rarest character in string */
+    }      xbm_s;              /* fields from PVBM */
+};
+
+union _xivu {
+    IV     xivu_iv;            /* integer value */
+                               /* xpvfm: pv offset */
+    UV     xivu_uv;
+    void *  xivu_p1;
+    I32            xivu_i32;
+    HEK *   xivu_namehek;      /* xpvlv, xpvgv: GvNAME */
+};
+
+union _xmgu {
+    MAGIC*  xmg_magic;         /* linked list of magicalness */
+    HV*            xmg_ourstash;       /* Stash for our (when SvPAD_OUR is true) */
+};
 
 struct xpv {
-    union {
-       NV      xnv_nv;         /* numeric value, if any */
-       HV *    xgv_stash;
-       struct {
-           U32 xlow;
-           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;
-           U8  xbm_rare;       /* rarest character in string */
-       }       xbm_s;          /* fields from PVBM */
-    }          xnv_u;
-    STRLEN     xpv_cur;        /* length of svu_pv as a C string */
-    STRLEN     xpv_len;        /* allocated size */
+    _XPV_HEAD;
 };
 
 typedef struct {
-    STRLEN     xpv_cur;        /* length of svu_pv as a C string */
-    STRLEN     xpv_len;        /* allocated size */
+    _XPV_ALLOCATED_HEAD;
 } xpv_allocated;
 
 struct xpviv {
-    union {
-       NV      xnv_nv;         /* numeric value, if any */
-       HV *    xgv_stash;
-       struct {
-           U32 xlow;
-           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;
-           U8  xbm_rare;       /* rarest character in string */
-       }       xbm_s;          /* fields from PVBM */
-    }          xnv_u;
-    STRLEN     xpv_cur;        /* length of svu_pv as a C string */
-    STRLEN     xpv_len;        /* allocated size */
-    union {
-       IV      xivu_iv;        /* integer value or pv offset */
-       UV      xivu_uv;
-       void *  xivu_p1;
-       I32     xivu_i32;
-       HEK *   xivu_namehek;
-    }          xiv_u;
+    _XPV_HEAD;
+    union _xivu xiv_u;
 };
 
 typedef struct {
-    STRLEN     xpv_cur;        /* length of svu_pv as a C string */
-    STRLEN     xpv_len;        /* allocated size */
-    union {
-       IV      xivu_iv;        /* integer value or pv offset */
-       UV      xivu_uv;
-       void *  xivu_p1;
-       I32     xivu_i32;
-       HEK *   xivu_namehek;
-    }          xiv_u;
+    _XPV_ALLOCATED_HEAD;
+    union _xivu xiv_u;
 } xpviv_allocated;
 
 #define xiv_iv xiv_u.xivu_iv
 
 struct xpvuv {
-    union {
-       NV      xnv_nv;         /* numeric value, if any */
-       HV *    xgv_stash;
-       struct {
-           U32 xlow;
-           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;
-           U8  xbm_rare;       /* rarest character in string */
-       }       xbm_s;          /* fields from PVBM */
-    }          xnv_u;
-    STRLEN     xpv_cur;        /* length of svu_pv as a C string */
-    STRLEN     xpv_len;        /* allocated size */
-    union {
-       IV      xuvu_iv;
-       UV      xuvu_uv;        /* unsigned value or pv offset */
-       void *  xuvu_p1;
-       HEK *   xivu_namehek;
-    }          xuv_u;
+    _XPV_HEAD;
+    union _xivu xuv_u;
 };
 
-#define xuv_uv xuv_u.xuvu_uv
+#define xuv_uv xuv_u.xivu_uv
 
 struct xpvnv {
-    union {
-       NV      xnv_nv;         /* numeric value, if any */
-       HV *    xgv_stash;
-       struct {
-           U32 xlow;
-           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;
-           U8  xbm_rare;       /* rarest character in string */
-       }       xbm_s;          /* fields from PVBM */
-    }          xnv_u;
-    STRLEN     xpv_cur;        /* length of svu_pv as a C string */
-    STRLEN     xpv_len;        /* allocated size */
-    union {
-       IV      xivu_iv;        /* integer value or pv offset */
-       UV      xivu_uv;
-       void *  xivu_p1;
-       I32     xivu_i32;
-       HEK *   xivu_namehek;
-    }          xiv_u;
+    _XPV_HEAD;
+    union _xivu xiv_u;
 };
 
+#define _XPVMG_HEAD                                \
+    union _xivu xiv_u;                             \
+    union _xmgu        xmg_u;                              \
+    HV*                xmg_stash       /* class package */
+
 /* These structure must match the beginning of struct xpvhv in hv.h. */
 struct xpvmg {
-    union {
-       NV      xnv_nv;         /* numeric value, if any */
-       HV *    xgv_stash;
-       struct {
-           U32 xlow;
-           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;
-           U8  xbm_rare;       /* rarest character in string */
-       }       xbm_s;          /* fields from PVBM */
-    }          xnv_u;
-    STRLEN     xpv_cur;        /* length of svu_pv as a C string */
-    STRLEN     xpv_len;        /* allocated size */
-    union {
-       IV      xivu_iv;        /* integer value or pv offset */
-       UV      xivu_uv;
-       void *  xivu_p1;
-       I32     xivu_i32;
-       HEK *   xivu_namehek;
-    }          xiv_u;
-    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 */
+    _XPV_HEAD;
+    _XPVMG_HEAD;
 };
 
 struct xpvlv {
-    union {
-       NV      xnv_nv;         /* numeric value, if any */
-       HV *    xgv_stash;
-       struct {
-           U32 xlow;
-           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;
-           U8  xbm_rare;       /* rarest character in string */
-       }       xbm_s;          /* fields from PVBM */
-    }          xnv_u;
-    STRLEN     xpv_cur;        /* length of svu_pv as a C string */
-    STRLEN     xpv_len;        /* allocated size */
-    union {
-       IV      xivu_iv;        /* integer value or pv offset */
-       UV      xivu_uv;
-       void *  xivu_p1;
-       I32     xivu_i32;
-       HEK *   xivu_namehek;   /* GvNAME */
-    }          xiv_u;
-    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 */
+    _XPV_HEAD;
+    _XPVMG_HEAD;
 
     STRLEN     xlv_targoff;
     STRLEN     xlv_targlen;
@@ -572,153 +485,50 @@ struct xpvlv {
 /* This structure works in 3 ways - regular scalar, GV with GP, or fast
    Boyer-Moore.  */
 struct xpvgv {
-    union {
-       NV      xnv_nv;
-       HV *    xgv_stash;      /* The stash of this GV */
-       struct {
-           U32 xlow;
-           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;
-           U8  xbm_rare;       /* rarest character in string */
-       }       xbm_s;          /* fields from PVBM */
-    }          xnv_u;
-    STRLEN     xpv_cur;        /* xgv_flags */
-    STRLEN     xpv_len;        /* 0 */
-    union {
-       IV      xivu_iv;
-       UV      xivu_uv;
-       void *  xivu_p1;
-       I32     xivu_i32;       /* is this constant pattern being useful? */
-       HEK *   xivu_namehek;   /* GvNAME */
-    }          xiv_u;
-    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 */
-
+    _XPV_HEAD;
+    _XPVMG_HEAD;
 };
 
 /* This structure must match XPVCV in cv.h */
 
 typedef U16 cv_flags_t;
 
-struct xpvfm {
-    union {
-       NV      xnv_nv;         /* numeric value, if any */
-       HV *    xgv_stash;
-       struct {
-           U32 xlow;
-           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;
-           U8  xbm_rare;       /* rarest character in string */
-       }       xbm_s;          /* fields from PVBM */
-    }          xnv_u;
-    STRLEN     xpv_cur;        /* length of svu_pv as a C string */
-    STRLEN     xpv_len;        /* allocated size */
-    union {
-       IV      xivu_iv;        /* PVFMs use the pv offset */
-       UV      xivu_uv;
-       void *  xivu_p1;
-       I32     xivu_i32;
-       HEK *   xivu_namehek;
-    }          xiv_u;
-    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 */
+#define _XPVCV_COMMON                                                          \
+    HV *       xcv_stash;                                                      \
+    union {                                                                    \
+       OP *    xcv_start;                                                      \
+       ANY     xcv_xsubany;                                                    \
+    }          xcv_start_u;                                                    \
+    union {                                                                    \
+       OP *    xcv_root;                                                       \
+       void    (*xcv_xsub) (pTHX_ CV*);                                        \
+    }          xcv_root_u;                                                     \
+    GV *       xcv_gv;                                                         \
+    char *     xcv_file;                                                       \
+    AV *       xcv_padlist;                                                    \
+    CV *       xcv_outside;                                                    \
+    U32                xcv_outside_seq; /* the COP sequence (at the point of our       \
+                                 * compilation) in the lexically enclosing     \
+                                 * sub */                                      \
+    cv_flags_t xcv_flags
 
-    HV *       xcv_stash;
-    union {
-       OP *    xcv_start;
-       ANY     xcv_xsubany;
-    }          xcv_start_u;
-    union {
-       OP *    xcv_root;
-       void    (*xcv_xsub) (pTHX_ CV*);
-    }          xcv_root_u;
-    GV *       xcv_gv;
-    char *     xcv_file;
-    AV *       xcv_padlist;
-    CV *       xcv_outside;
-    U32                xcv_outside_seq; /* the COP sequence (at the point of our
-                                 * compilation) in the lexically enclosing
-                                 * sub */
-    cv_flags_t xcv_flags;
+struct xpvfm {
+    _XPV_HEAD;
+    _XPVMG_HEAD;
+    _XPVCV_COMMON;
     IV         xfm_lines;
 };
 
 typedef struct {
-    STRLEN     xpv_cur;        /* length of svu_pv as a C string */
-    STRLEN     xpv_len;        /* allocated size */
-    union {
-       IV      xivu_iv;        /* PVFMs use the pv offset */
-       UV      xivu_uv;
-       void *  xivu_p1;
-       I32     xivu_i32;
-       HEK *   xivu_namehek;
-    }          xiv_u;
-    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;
-    union {
-       OP *    xcv_start;
-       ANY     xcv_xsubany;
-    }          xcv_start_u;
-    union {
-       OP *    xcv_root;
-       void    (*xcv_xsub) (pTHX_ CV*);
-    }          xcv_root_u;
-    GV *       xcv_gv;
-    char *     xcv_file;
-    AV *       xcv_padlist;
-    CV *       xcv_outside;
-    U32                xcv_outside_seq; /* the COP sequence (at the point of our
-                                 * compilation) in the lexically enclosing
-                                 * sub */
-    cv_flags_t xcv_flags;
+    _XPV_ALLOCATED_HEAD;
+    _XPVMG_HEAD;
+    _XPVCV_COMMON;
     IV         xfm_lines;
 } xpvfm_allocated;
 
 struct xpvio {
-    union {
-       NV      xnv_nv;         /* numeric value, if any */
-       HV *    xgv_stash;
-       struct {
-           U32 xlow;
-           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;
-           U8  xbm_rare;       /* rarest character in string */
-       }       xbm_s;          /* fields from PVBM */
-    }          xnv_u;
-    STRLEN     xpv_cur;        /* length of svu_pv as a C string */
-    STRLEN     xpv_len;        /* allocated size */
-    union {
-       IV      xivu_iv;        /* integer value or pv offset */
-       UV      xivu_uv;
-       void *  xivu_p1;
-       I32     xivu_i32;
-       HEK *   xivu_namehek;
-    }          xiv_u;
-    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 */
+    _XPV_HEAD;
+    _XPVMG_HEAD;
 
     PerlIO *   xio_ifp;        /* ifp and ofp are normally the same */
     PerlIO *   xio_ofp;        /* but sockets need separate streams */
@@ -951,7 +761,7 @@ Set the actual length of the string which is in the SV.  See C<SvIV_set>.
 
 #define SvOKp(sv)              (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK))
 #define SvIOKp(sv)             (SvFLAGS(sv) & SVp_IOK)
-#define SvIOKp_on(sv)          (assert_not_glob(sv) SvRELEASE_IVX(sv), \
+#define SvIOKp_on(sv)          (assert_not_glob(sv) SvRELEASE_IVX_(sv) \
                                    SvFLAGS(sv) |= SVp_IOK)
 #define SvNOKp(sv)             (SvFLAGS(sv) & SVp_NOK)
 #define SvNOKp_on(sv)          (assert_not_glob(sv) SvFLAGS(sv) |= SVp_NOK)
@@ -960,7 +770,7 @@ Set the actual length of the string which is in the SV.  See C<SvIV_set>.
                                 SvFLAGS(sv) |= SVp_POK)
 
 #define SvIOK(sv)              (SvFLAGS(sv) & SVf_IOK)
-#define SvIOK_on(sv)           (assert_not_glob(sv) SvRELEASE_IVX(sv), \
+#define SvIOK_on(sv)           (assert_not_glob(sv) SvRELEASE_IVX_(sv) \
                                    SvFLAGS(sv) |= (SVf_IOK|SVp_IOK))
 #define SvIOK_off(sv)          (SvFLAGS(sv) &= ~(SVf_IOK|SVp_IOK|SVf_IVisUV))
 #define SvIOK_only(sv)         (SvOK_off(sv), \
@@ -1298,7 +1108,7 @@ the scalar's value cannot change unless written to.
         }))
 #    define SvRV(sv)                                                   \
        (*({ SV *const _svi = (SV *) (sv);                              \
-           assert(SvTYPE(_svi) >= SVt_RV);                             \
+           assert(SvTYPE(_svi) >= SVt_PV || SvTYPE(_svi) == SVt_IV);   \
            assert(SvTYPE(_svi) != SVt_PVAV);                           \
            assert(SvTYPE(_svi) != SVt_PVHV);                           \
            assert(SvTYPE(_svi) != SVt_PVCV);                           \
@@ -1383,7 +1193,7 @@ the scalar's value cannot change unless written to.
                assert(!isGV_with_GP(sv));              \
                (((XPVUV*)SvANY(sv))->xuv_uv = (val)); } STMT_END
 #define SvRV_set(sv, val) \
-        STMT_START { assert(SvTYPE(sv) >=  SVt_RV); \
+        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);         \
@@ -1430,13 +1240,28 @@ the scalar's value cannot change unless written to.
                     if (SvLEN(sv)) {                                   \
                         assert(!SvROK(sv));                            \
                         if(SvOOK(sv)) {                                \
-                            SvPV_set(sv, SvPVX_mutable(sv) - SvIVX(sv)); \
+                            SvPV_set(sv, SvPVX_mutable(sv)             \
+                                         - sv_read_offset(sv));        \
                             SvFLAGS(sv) &= ~SVf_OOK;                   \
                         }                                              \
                         Safefree(SvPVX(sv));                           \
                     }                                                  \
                 } STMT_END
 
+#ifdef PERL_CORE
+/* Code that crops up in three places to take a scalar and ready it to hold
+   a reference */
+#  define prepare_SV_for_RV(sv)                                                \
+    STMT_START {                                                       \
+                   if (SvTYPE(sv) < SVt_PV && SvTYPE(sv) != SVt_IV)    \
+                       sv_upgrade(sv, SVt_IV);                         \
+                   else if (SvTYPE(sv) >= SVt_PV) {                    \
+                       SvPV_free(sv);                                  \
+                       SvLEN_set(sv, 0);                               \
+                        SvCUR_set(sv, 0);                              \
+                   }                                                   \
+                } STMT_END
+#endif
 
 #define PERL_FBM_TABLE_OFFSET 1        /* Number of bytes between EOS and table */
 
@@ -1742,7 +1567,7 @@ Like C<sv_catsv> but doesn't process magic.
      ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvutf8(sv, &lp))
 
 #define SvPVutf8_force(sv, lp) \
-    ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == (SVf_POK|SVf_UTF8) \
+    ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVf_THINKFIRST)) == (SVf_POK|SVf_UTF8) \
      ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvutf8n_force(sv, &lp))
 
 
@@ -1890,10 +1715,16 @@ Like C<sv_catsv> but doesn't process magic.
 
 #ifdef PERL_OLD_COPY_ON_WRITE
 #define SvRELEASE_IVX(sv)   \
-    ((SvIsCOW(sv) ? sv_force_normal_flags(sv, 0) : (void) 0), SvOOK_off(sv))
+    ((SvIsCOW(sv) ? sv_force_normal_flags(sv, 0) : (void) 0), 0)
 #  define SvIsCOW_normal(sv)   (SvIsCOW(sv) && SvLEN(sv))
+#  define SvRELEASE_IVX_(sv)   SvRELEASE_IVX(sv),
 #else
-#  define SvRELEASE_IVX(sv)   SvOOK_off(sv)
+#  define SvRELEASE_IVX(sv)   0
+/* This little game brought to you by the need to shut this warning up:
+mg.c: In function `Perl_magic_get':
+mg.c:1024: warning: left-hand operand of comma expression has no effect
+*/
+#  define SvRELEASE_IVX_(sv)  /**/
 #endif /* PERL_OLD_COPY_ON_WRITE */
 
 #define CAN_COW_MASK   (SVs_OBJECT|SVs_GMG|SVs_SMG|SVs_RMG|SVf_IOK|SVf_NOK| \
@@ -1937,7 +1768,7 @@ Like C<sv_catsv> but doesn't process magic.
 #define sv_catpvn_utf8_upgrade(dsv, sstr, slen, nsv)   \
        STMT_START {                                    \
            if (!(nsv))                                 \
-               nsv = sv_2mortal(newSVpvn(sstr, slen)); \
+               nsv = newSVpvn_flags(sstr, slen, SVs_TEMP);     \
            else                                        \
                sv_setpvn(nsv, sstr, slen);             \
            SvUTF8_off(nsv);                            \
@@ -2087,6 +1918,17 @@ struct clone_params {
 };
 
 /*
+=for apidoc Am|SV*|newSVpvn_utf8|NULLOK const char* s|STRLEN len|U32 utf8
+
+Creates a new SV and copies a string into it.  If utf8 is true, calls
+C<SvUTF8_on> on the new SV.  Implemented as a wrapper around C<newSVpvn_flags>.
+
+=cut
+*/
+
+#define newSVpvn_utf8(s, len, u) newSVpvn_flags((s), (len), (u) ? SVf_UTF8 : 0)
+
+/*
  * Local variables:
  * c-indentation-style: bsd
  * c-basic-offset: 4