This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
sv_2pv_flags and ROK and UTF8 flags
[perl5.git] / sv.h
diff --git a/sv.h b/sv.h
index bb18b0e..94366fe 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -1,6 +1,6 @@
 /*    sv.h
  *
- *    Copyright (c) 1991-2001, Larry Wall
+ *    Copyright (c) 1991-2002, Larry Wall
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
 #endif
 
 /*
+=head1 SV Flags
+
 =for apidoc AmU||svtype
-An enum of flags for Perl types.  These are found in the file B<sv.h> 
+An enum of flags for Perl types.  These are found in the file B<sv.h>
 in the C<svtype> enum.  Test these flags with the C<SvTYPE> macro.
 
 =for apidoc AmU||SVt_PV
@@ -98,6 +100,8 @@ struct io {
 };
 
 /*
+=head1 SV Manipulation Functions
+
 =for apidoc Am|U32|SvREFCNT|SV* sv
 Returns the value of the object's reference count.
 
@@ -157,7 +161,7 @@ perform the upgrade if necessary.  See C<svtype>.
        nsv;                            \
     })
 #else
-#  if defined(CRIPPLED_CC) || defined(USE_5005THREADS)
+#  ifdef USE_5005THREADS
 #    if defined(VMS) && defined(__ALPHA)
 #      define SvREFCNT_inc(sv) \
           (PL_Sv=(SV*)(sv), (PL_Sv && __ATOMIC_INCREMENT_LONG(&(SvREFCNT(PL_Sv)))), (SV *)PL_Sv)
@@ -170,7 +174,7 @@ perform the upgrade if necessary.  See C<svtype>.
 #  endif
 #endif
 
-#define SvREFCNT_dec(sv)       sv_free((SV*)sv)
+#define SvREFCNT_dec(sv)       sv_free((SV*)(sv))
 
 #define SVTYPEMASK     0xff
 #define SvTYPE(sv)     ((sv)->sv_flags & SVTYPEMASK)
@@ -203,7 +207,7 @@ perform the upgrade if necessary.  See C<svtype>.
 #define SVp_POK                0x04000000      /* has valid non-public pointer value */
 #define SVp_SCREAM     0x08000000      /* has been studied? */
 
-#define SVf_UTF8        0x20000000      /* SvPVX is UTF-8 encoded */
+#define SVf_UTF8        0x20000000      /* SvPV is UTF-8 encoded */
 
 #define SVf_THINKFIRST (SVf_READONLY|SVf_ROK|SVf_FAKE)
 
@@ -231,6 +235,7 @@ perform the upgrade if necessary.  See C<svtype>.
 
 #define SVphv_SHAREKEYS 0x20000000     /* keys live on shared string table */
 #define SVphv_LAZYDEL  0x40000000      /* entry in xhv_eiter must be deleted */
+#define SVphv_HASKFLAGS        0x80000000      /* keys have flag byte after hash */
 
 #define SVprv_WEAKREF   0x80000000      /* Weak reference */
 
@@ -338,7 +343,7 @@ struct xpvfm {
     HV *       xcv_stash;
     OP *       xcv_start;
     OP *       xcv_root;
-    void      (*xcv_xsub)(pTHXo_ CV*);
+    void      (*xcv_xsub)(pTHX_ CV*);
     ANY                xcv_xsubany;
     GV *       xcv_gv;
     char *     xcv_file;
@@ -351,7 +356,7 @@ struct xpvfm {
 #endif /* USE_5005THREADS */
     cv_flags_t xcv_flags;
 
-    I32                xfm_lines;
+    IV         xfm_lines;
 };
 
 struct xpvio {
@@ -378,10 +383,10 @@ struct xpvio {
        DIR *   xiou_dirp;      /* for opendir, readdir, etc */
        void *  xiou_any;       /* for alignment */
     } xio_dirpu;
-    long       xio_lines;      /* $. */
-    long       xio_page;       /* $% */
-    long       xio_page_len;   /* $= */
-    long       xio_lines_left; /* $- */
+    IV         xio_lines;      /* $. */
+    IV         xio_page;       /* $% */
+    IV         xio_page_len;   /* $= */
+    IV         xio_lines_left; /* $- */
     char *     xio_top_name;   /* $^ */
     GV *       xio_top_gv;     /* $^ */
     char *     xio_fmt_name;   /* $~ */
@@ -454,7 +459,7 @@ Returns a boolean indicating whether the SV contains an unsigned integer.
 Returns a boolean indicating whether the SV contains an unsigned integer.
 
 =for apidoc Am|void|SvIOK_notUV|SV* sv
-Returns a boolean indicating whether the SV contains an signed integer.
+Returns a boolean indicating whether the SV contains a signed integer.
 
 =for apidoc Am|bool|SvNOK|SV* sv
 Returns a boolean indicating whether the SV contains a double.
@@ -482,6 +487,9 @@ Unsets the PV status of an SV.
 Tells an SV that it is a string and disables all other OK bits.
 Will also turn off the UTF8 status.
 
+=for apidoc Am|bool|SvVOK|SV* sv
+Returns a boolean indicating whether the SV contains a v-string.
+
 =for apidoc Am|bool|SvOOK|SV* sv
 Returns a boolean indicating whether the SvIVX is a valid offset value for
 the SvPVX.  This hack is used internally to speed up removal of characters
@@ -551,14 +559,15 @@ Set the length of the string which is in the SV.  See C<SvCUR>.
 
 #define SvOKp(sv)              (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK))
 #define SvIOKp(sv)             (SvFLAGS(sv) & SVp_IOK)
-#define SvIOKp_on(sv)          ((void)SvOOK_off(sv), SvFLAGS(sv) |= SVp_IOK)
+#define SvIOKp_on(sv)          (SvRELEASE_IVX(sv), \
+                                   SvFLAGS(sv) |= SVp_IOK)
 #define SvNOKp(sv)             (SvFLAGS(sv) & SVp_NOK)
 #define SvNOKp_on(sv)          (SvFLAGS(sv) |= SVp_NOK)
 #define SvPOKp(sv)             (SvFLAGS(sv) & SVp_POK)
 #define SvPOKp_on(sv)          (SvFLAGS(sv) |= SVp_POK)
 
 #define SvIOK(sv)              (SvFLAGS(sv) & SVf_IOK)
-#define SvIOK_on(sv)           ((void)SvOOK_off(sv), \
+#define SvIOK_on(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)         ((void)SvOK_off(sv), \
@@ -614,6 +623,7 @@ and leaves the UTF8 status as it was.
                                                  SVf_IVisUV),          \
                                    SvFLAGS(sv) |= (SVf_POK|SVp_POK))
 
+#define SvVOK(sv)              (SvMAGICAL(sv) && mg_find(sv,'V'))
 #define SvOOK(sv)              (SvFLAGS(sv) & SVf_OOK)
 #define SvOOK_on(sv)           ((void)SvIOK_off(sv), SvFLAGS(sv) |= SVf_OOK)
 #define SvOOK_off(sv)          (SvOOK(sv) && sv_backoff(sv))
@@ -646,7 +656,7 @@ and leaves the UTF8 status as it was.
 #define SvAMAGIC_on(sv)                (SvFLAGS(sv) |= SVf_AMAGIC)
 #define SvAMAGIC_off(sv)       (SvFLAGS(sv) &= ~SVf_AMAGIC)
 
-#define SvGAMAGIC(sv)           (SvFLAGS(sv) & (SVs_GMG|SVf_AMAGIC)) 
+#define SvGAMAGIC(sv)           (SvFLAGS(sv) & (SVs_GMG|SVf_AMAGIC))
 
 /*
 #define Gv_AMG(stash) \
@@ -703,6 +713,14 @@ and leaves the UTF8 status as it was.
 #define SvVALID_on(sv)         (SvFLAGS(sv) |= SVpbm_VALID)
 #define SvVALID_off(sv)                (SvFLAGS(sv) &= ~SVpbm_VALID)
 
+#ifdef USE_ITHREADS
+/* The following uses the FAKE flag to show that a regex pointer is infact
+   its own offset in the regexpad for ithreads */
+#define SvREPADTMP(sv)         (SvFLAGS(sv) & SVf_FAKE)
+#define SvREPADTMP_on(sv)      (SvFLAGS(sv) |= SVf_FAKE)
+#define SvREPADTMP_off(sv)     (SvFLAGS(sv) &= ~SVf_FAKE)
+#endif
+
 #define SvRV(sv) ((XRV*)  SvANY(sv))->xrv_rv
 #define SvRVx(sv) SvRV(sv)
 
@@ -822,24 +840,28 @@ Taints an SV if tainting is enabled
 
 /*
 =for apidoc Am|char*|SvPV_force|SV* sv|STRLEN len
-Like <SvPV> but will force the SV into becoming a string (SvPOK).  You want
-force if you are going to update the SvPVX directly.
+Like C<SvPV> but will force the SV into containing just a string
+(C<SvPOK_only>).  You want force if you are going to update the C<SvPVX>
+directly.
 
 =for apidoc Am|char*|SvPV_force_nomg|SV* sv|STRLEN len
-Like <SvPV> but will force the SV into becoming a string (SvPOK).  You want
-force if you are going to update the SvPVX directly. Doesn't process magic.
+Like C<SvPV> but will force the SV into containing just a string
+(C<SvPOK_only>).  You want force if you are going to update the C<SvPVX>
+directly. Doesn't process magic.
 
 =for apidoc Am|char*|SvPV|SV* sv|STRLEN len
-Returns a pointer to the string in the SV, or a stringified form of the SV
-if the SV does not contain a string.  Handles 'get' magic. See also
+Returns a pointer to the string in the SV, or a stringified form of
+the SV if the SV does not contain a string.  The SV may cache the
+stringified version becoming C<SvPOK>.  Handles 'get' magic. See also
 C<SvPVx> for a version which guarantees to evaluate sv only once.
 
 =for apidoc Am|char*|SvPVx|SV* sv|STRLEN len
 A version of C<SvPV> which guarantees to evaluate sv only once.
 
 =for apidoc Am|char*|SvPV_nolen|SV* sv
-Returns a pointer to the string in the SV, or a stringified form of the SV
-if the SV does not contain a string.  Handles 'get' magic.
+Returns a pointer to the string in the SV, or a stringified form of
+the SV if the SV does not contain a string.  The SV may cache the
+stringified form becoming C<SvPOK>.  Handles 'get' magic.
 
 =for apidoc Am|IV|SvIV|SV* sv
 Coerces the given SV to an integer and returns it. See  C<SvIVx> for a
@@ -847,7 +869,7 @@ version which guarantees to evaluate sv only once.
 
 =for apidoc Am|IV|SvIVx|SV* sv
 Coerces the given SV to an integer and returns it. Guarantees to evaluate
-sv only once. Use the more efficent C<SvIV> otherwise.
+sv only once. Use the more efficient C<SvIV> otherwise.
 
 =for apidoc Am|NV|SvNV|SV* sv
 Coerce the given SV to a double and return it. See  C<SvNVx> for a version
@@ -855,7 +877,7 @@ which guarantees to evaluate sv only once.
 
 =for apidoc Am|NV|SvNVx|SV* sv
 Coerces the given SV to a double and returns it. Guarantees to evaluate
-sv only once. Use the more efficent C<SvNV> otherwise.
+sv only once. Use the more efficient C<SvNV> otherwise.
 
 =for apidoc Am|UV|SvUV|SV* sv
 Coerces the given SV to an unsigned integer and returns it.  See C<SvUVx>
@@ -863,20 +885,20 @@ for a version which guarantees to evaluate sv only once.
 
 =for apidoc Am|UV|SvUVx|SV* sv
 Coerces the given SV to an unsigned integer and returns it. Guarantees to
-evaluate sv only once. Use the more efficent C<SvUV> otherwise.
+evaluate sv only once. Use the more efficient C<SvUV> otherwise.
 
 =for apidoc Am|bool|SvTRUE|SV* sv
 Returns a boolean indicating whether Perl would evaluate the SV as true or
 false, defined or undefined.  Does not handle 'get' magic.
 
 =for apidoc Am|char*|SvPVutf8_force|SV* sv|STRLEN len
-Like C<SvPV_force>, but converts sv to uft8 first if necessary.
+Like C<SvPV_force>, but converts sv to utf8 first if necessary.
 
 =for apidoc Am|char*|SvPVutf8|SV* sv|STRLEN len
-Like C<SvPV>, but converts sv to uft8 first if necessary.
+Like C<SvPV>, but converts sv to utf8 first if necessary.
 
-=for apidoc Am|char*|SvPVutf8_nolen|SV* sv|STRLEN len
-Like C<SvPV_nolen>, but converts sv to uft8 first if necessary.
+=for apidoc Am|char*|SvPVutf8_nolen|SV* sv
+Like C<SvPV_nolen>, but converts sv to utf8 first if necessary.
 
 =for apidoc Am|char*|SvPVbyte_force|SV* sv|STRLEN len
 Like C<SvPV_force>, but converts sv to byte representation first if necessary.
@@ -884,182 +906,102 @@ Like C<SvPV_force>, but converts sv to byte representation first if necessary.
 =for apidoc Am|char*|SvPVbyte|SV* sv|STRLEN len
 Like C<SvPV>, but converts sv to byte representation first if necessary.
 
-=for apidoc Am|char*|SvPVbyte_nolen|SV* sv|STRLEN len
+=for apidoc Am|char*|SvPVbyte_nolen|SV* sv
 Like C<SvPV_nolen>, but converts sv to byte representation first if necessary.
 
 =for apidoc Am|char*|SvPVutf8x_force|SV* sv|STRLEN len
-Like C<SvPV_force>, but converts sv to uft8 first if necessary.
-Guarantees to evalute sv only once; use the more efficient C<SvPVutf8_force>
+Like C<SvPV_force>, but converts sv to utf8 first if necessary.
+Guarantees to evaluate sv only once; use the more efficient C<SvPVutf8_force>
 otherwise.
 
 =for apidoc Am|char*|SvPVutf8x|SV* sv|STRLEN len
-Like C<SvPV>, but converts sv to uft8 first if necessary.
-Guarantees to evalute sv only once; use the more efficient C<SvPVutf8>
+Like C<SvPV>, but converts sv to utf8 first if necessary.
+Guarantees to evaluate sv only once; use the more efficient C<SvPVutf8>
 otherwise.
 
 =for apidoc Am|char*|SvPVbytex_force|SV* sv|STRLEN len
 Like C<SvPV_force>, but converts sv to byte representation first if necessary.
-Guarantees to evalute sv only once; use the more efficient C<SvPVbyte_force>
+Guarantees to evaluate sv only once; use the more efficient C<SvPVbyte_force>
 otherwise.
 
 =for apidoc Am|char*|SvPVbytex|SV* sv|STRLEN len
 Like C<SvPV>, but converts sv to byte representation first if necessary.
-Guarantees to evalute sv only once; use the more efficient C<SvPVbyte>
+Guarantees to evaluate sv only once; use the more efficient C<SvPVbyte>
 otherwise.
 
 
 =cut
 */
 
-#define SvPV_force(sv, lp) sv_pvn_force(sv, &lp)
-#define SvPV(sv, lp) sv_pvn(sv, &lp)
-#define SvPV_nolen(sv) sv_pv(sv)
-
-#define SvPVutf8_force(sv, lp) sv_pvutf8n_force(sv, &lp)
-#define SvPVutf8(sv, lp) sv_pvutf8n(sv, &lp)
-#define SvPVutf8_nolen(sv) sv_pvutf8(sv)
-
-#define SvPVbyte_force(sv, lp) sv_pvbyte_force(sv, &lp)
-#define SvPVbyte(sv, lp) sv_pvbyten(sv, &lp)
-#define SvPVbyte_nolen(sv) sv_pvbyte(sv)
-
-#define SvPVx(sv, lp) sv_pvn(sv, &lp)
-#define SvPVx_force(sv, lp) sv_pvn_force(sv, &lp)
-#define SvPVutf8x(sv, lp) sv_pvutf8n(sv, &lp)
-#define SvPVutf8x_force(sv, lp) sv_pvutf8n_force(sv, &lp)
-#define SvPVbytex(sv, lp) sv_pvbyten(sv, &lp)
-#define SvPVbytex_force(sv, lp) sv_pvbyten_force(sv, &lp)
-
-#define SvIVx(sv) sv_iv(sv)
-#define SvUVx(sv) sv_uv(sv)
-#define SvNVx(sv) sv_nv(sv)
-
-#define SvTRUEx(sv) sv_true(sv)
-
-#define SvIV(sv) SvIVx(sv)
-#define SvNV(sv) SvNVx(sv)
-#define SvUV(sv) SvUVx(sv)
-#define SvTRUE(sv) SvTRUEx(sv)
-
-#ifndef CRIPPLED_CC
-/* redefine some things to more efficient inlined versions */
-
 /* Let us hope that bitmaps for UV and IV are the same */
-#undef SvIV
 #define SvIV(sv) (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv))
-
-#undef SvUV
 #define SvUV(sv) (SvIOK(sv) ? SvUVX(sv) : sv_2uv(sv))
-
-#undef SvNV
 #define SvNV(sv) (SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv))
 
-/* flag values for sv_*_flags functions */
-#define SV_IMMEDIATE_UNREF     1
-#define SV_GMAGIC              2
+/* ----*/
 
-#define sv_setsv_macro(dsv, ssv) sv_setsv_flags(dsv, ssv, SV_GMAGIC)
-#define sv_setsv_nomg(dsv, ssv) sv_setsv_flags(dsv, ssv, 0)
-#define sv_catsv_macro(dsv, ssv) sv_catsv_flags(dsv, ssv, SV_GMAGIC)
-#define sv_catsv_nomg(dsv, ssv) sv_catsv_flags(dsv, ssv, 0)
-#define sv_catpvn_macro(dsv, sstr, slen) sv_catpvn_flags(dsv, sstr, slen, SV_GMAGIC)
-#define sv_catpvn_nomg(dsv, sstr, slen) sv_catpvn_flags(dsv, sstr, slen, 0)
-#define sv_2pv_macro(sv, lp) sv_2pv_flags(sv, lp, SV_GMAGIC)
-#define sv_2pv_nomg(sv, lp) sv_2pv_flags(sv, lp, 0)
-#define sv_pvn_force_macro(sv, lp) sv_pvn_force_flags(sv, lp, SV_GMAGIC)
-#define sv_pvn_force_nomg(sv, lp) sv_pvn_force_flags(sv, lp, 0)
-#define sv_utf8_upgrade_macro(sv) sv_utf8_upgrade_flags(sv, SV_GMAGIC)
-#define sv_utf8_upgrade_nomg(sv) sv_utf8_upgrade_flags(sv, 0)
-
-/* function style also available for bincompat */
-#define sv_setsv(dsv, ssv) sv_setsv_macro(dsv, ssv)
-#define sv_catsv(dsv, ssv) sv_catsv_macro(dsv, ssv)
-#define sv_catpvn(dsv, sstr, slen) sv_catpvn_macro(dsv, sstr, slen)
-#define sv_2pv(sv, lp) sv_2pv_macro(sv, lp)
-#define sv_pvn_force(sv, lp) sv_pvn_force_macro(sv, lp)
-#define sv_utf8_upgrade(sv) sv_utf8_upgrade_macro(sv)
-
-#undef SvPV
 #define SvPV(sv, lp) SvPV_flags(sv, lp, SV_GMAGIC)
 
-#undef SvPV_nomg
-#define SvPV_nomg(sv, lp) SvPV_flags(sv, lp, 0)
-
-#undef SvPV_flags
 #define SvPV_flags(sv, lp, flags) \
     ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
      ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv_flags(sv, &lp, flags))
 
-#undef SvPV_force
 #define SvPV_force(sv, lp) SvPV_force_flags(sv, lp, SV_GMAGIC)
-#undef SvPV_force_nomg
+
 #define SvPV_force_nomg(sv, lp) SvPV_force_flags(sv, lp, 0)
 
-#undef SvPV_force_flags
 #define SvPV_force_flags(sv, lp, flags) \
     ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \
     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvn_force_flags(sv, &lp, flags))
 
-#undef SvPV_nolen
 #define SvPV_nolen(sv) \
     ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
      ? SvPVX(sv) : sv_2pv_nolen(sv))
 
-#undef SvPVutf8
-#define SvPVutf8(sv, lp) \
-    ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK|SVf_UTF8) \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvutf8(sv, &lp))
-
-#undef SvPVutf8_force
-#define SvPVutf8_force(sv, lp) \
-    ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == (SVf_POK|SVf_UTF8) \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvutf8n_force(sv, &lp))
+#define SvPV_nomg(sv, lp) SvPV_flags(sv, lp, 0)
 
-#undef SvPVutf8_nolen
-#define SvPVutf8_nolen(sv) \
-    ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK|SVf_UTF8)\
-     ? SvPVX(sv) : sv_2pvutf8_nolen(sv))
+/* ----*/
 
-#undef SvPVutf8
 #define SvPVutf8(sv, lp) \
     ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK|SVf_UTF8) \
      ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvutf8(sv, &lp))
 
-#undef SvPVutf8_force
 #define SvPVutf8_force(sv, lp) \
     ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == (SVf_POK|SVf_UTF8) \
      ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvutf8n_force(sv, &lp))
 
-#undef SvPVutf8_nolen
+
 #define SvPVutf8_nolen(sv) \
     ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK|SVf_UTF8)\
      ? SvPVX(sv) : sv_2pvutf8_nolen(sv))
 
-#undef SvPVbyte
+/* ----*/
+
 #define SvPVbyte(sv, lp) \
     ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK) \
      ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvbyte(sv, &lp))
 
-#undef SvPVbyte_force
 #define SvPVbyte_force(sv, lp) \
     ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVf_THINKFIRST)) == (SVf_POK) \
      ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvbyte_force(sv, &lp))
 
-#undef SvPVbyte_nolen
 #define SvPVbyte_nolen(sv) \
     ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK)\
      ? SvPVX(sv) : sv_2pvbyte_nolen(sv))
 
 
+    
+/* define FOOx(): idempotent versions of FOO(). If possible, use a local
+ * var to evaluate the arg once; failing that, use a global if possible;
+ * 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)
+
 #ifdef __GNUC__
-#  undef SvIVx
-#  undef SvUVx
-#  undef SvNVx
-#  undef SvPVx
-#  undef SvPVutf8x
-#  undef SvPVbytex
-#  undef SvTRUE
-#  undef SvTRUEx
+
 #  define SvIVx(sv) ({SV *nsv = (SV*)(sv); SvIV(nsv); })
 #  define SvUVx(sv) ({SV *nsv = (SV*)(sv); SvUV(nsv); })
 #  define SvNVx(sv) ({SV *nsv = (SV*)(sv); SvNV(nsv); })
@@ -1083,26 +1025,31 @@ otherwise.
                ? SvNVX(sv) != 0.0                              \
                : sv_2bool(sv) )
 #  define SvTRUEx(sv) ({SV *nsv = (sv); SvTRUE(nsv); })
+
 #else /* __GNUC__ */
-#ifndef USE_5005THREADS
+
+#  ifdef USE_5005THREADS
+#    define SvIVx(sv) sv_iv(sv)
+#    define SvUVx(sv) sv_uv(sv)
+#    define SvNVx(sv) sv_nv(sv)
+#    define SvPVx(sv, lp) sv_pvn(sv, &lp)
+#    define SvPVutf8x(sv, lp) sv_pvutf8n(sv, &lp)
+#    define SvPVbytex(sv, lp) sv_pvbyten(sv, &lp)
+#    define SvTRUE(sv) SvTRUEx(sv)
+#    define SvTRUEx(sv) sv_true(sv)
+
+#  else /* USE_5005THREADS */
+
 /* These inlined macros use globals, which will require a thread
  * declaration in user code, so we avoid them under threads */
 
-#  undef SvIVx
-#  undef SvUVx
-#  undef SvNVx
-#  undef SvPVx
-#  undef SvPVutf8x
-#  undef SvPVbytex
-#  undef SvTRUE
-#  undef SvTRUEx
-#  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 SvPVutf8x(sv, lp) ((PL_Sv = (sv)), SvPVutf8(PL_Sv, lp))
-#  define SvPVbytex(sv, lp) ((PL_Sv = (sv)), SvPVbyte(PL_Sv, lp))
-#  define SvTRUE(sv) (                                         \
+#    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 SvPVutf8x(sv, lp) ((PL_Sv = (sv)), SvPVutf8(PL_Sv, lp))
+#    define SvPVbytex(sv, lp) ((PL_Sv = (sv)), SvPVbyte(PL_Sv, lp))
+#    define SvTRUE(sv) (                                               \
     !sv                                                                \
     ? 0                                                                \
     :    SvPOK(sv)                                             \
@@ -1117,10 +1064,59 @@ otherwise.
            :   SvNOK(sv)                                       \
                ? SvNVX(sv) != 0.0                              \
                : sv_2bool(sv) )
-#  define SvTRUEx(sv) ((PL_Sv = (sv)), SvTRUE(PL_Sv))
-#endif /* !USE_5005THREADS */
-#endif /* !__GNU__ */
-#endif /* !CRIPPLED_CC */
+#    define SvTRUEx(sv) ((PL_Sv = (sv)), SvTRUE(PL_Sv))
+#  endif /* USE_5005THREADS */
+#endif /* __GNU__ */
+
+#define SvIsCOW(sv)            ((SvFLAGS(sv) & (SVf_FAKE | SVf_READONLY)) == \
+                                   (SVf_FAKE | SVf_READONLY))
+#define SvIsCOW_shared_hash(sv)        (SvIsCOW(sv) && SvLEN(sv) == 0)
+
+/* flag values for sv_*_flags functions */
+#define SV_IMMEDIATE_UNREF     1
+#define SV_GMAGIC              2
+#define SV_COW_DROP_PV         4
+
+/* 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
+   the value is about to get thrown away, so drop the PV rather than go to
+   the effort of making a read-write copy only for it to get immediately
+   discarded.  */
+
+#define SV_CHECK_THINKFIRST_COW_DROP(sv) if (SvTHINKFIRST(sv)) \
+                                   sv_force_normal_flags(sv, SV_COW_DROP_PV)
+
+#ifdef PERL_COPY_ON_WRITE
+#  define SvRELEASE_IVX(sv)   ((void)((SvFLAGS(sv) & (SVf_OOK|SVf_READONLY|SVf_FAKE)) \
+                               && sv_release_IVX(sv)))
+#  define SvIsCOW_normal(sv)   (SvIsCOW(sv) && SvLEN(sv))
+#else
+#  define SvRELEASE_IVX(sv)   ((void)SvOOK_off(sv))
+#endif /* PERL_COPY_ON_WRITE */
+
+#define SV_CHECK_THINKFIRST(sv) if (SvTHINKFIRST(sv)) \
+                                   sv_force_normal_flags(sv, 0)
+
+
+/* all these 'functions' are now just macros */
+
+#define sv_pv(sv) SvPV_nolen(sv)
+#define sv_pvutf8(sv) SvPVutf8_nolen(sv)
+#define sv_pvbyte(sv) SvPVbyte_nolen(sv)
+
+#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_catsv(dsv, ssv) sv_catsv_flags(dsv, ssv, SV_GMAGIC)
+#define sv_catsv_nomg(dsv, ssv) sv_catsv_flags(dsv, ssv, 0)
+#define sv_catpvn(dsv, sstr, slen) sv_catpvn_flags(dsv, sstr, slen, SV_GMAGIC)
+#define sv_2pv(sv, lp) sv_2pv_flags(sv, lp, SV_GMAGIC)
+#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)
+
 
 /*
 =for apidoc Am|SV*|newRV_inc|SV* sv
@@ -1136,6 +1132,8 @@ incremented.
 /* the following macros update any magic values this sv is associated with */
 
 /*
+=head1 Magical Functions
+
 =for apidoc Am|void|SvGETMAGIC|SV* sv
 Invokes C<mg_get> on an SV if it has 'get' magic.  This macro evaluates its
 argument more than once.
@@ -1158,15 +1156,33 @@ Like C<SvSetSV>, but does any set magic required afterwards.
 =for apidoc Am|void|SvSetMagicSV_nosteal|SV* dsv|SV* ssv
 Like C<SvSetMagicSV>, but does any set magic required afterwards.
 
+=for apidoc Am|void|SvSHARE|SV* sv
+Arranges for sv to be shared between threads if a suitable module
+has been loaded.
+
+=for apidoc Am|void|SvLOCK|SV* sv
+Arranges for a mutual exclusion lock to be obtained on sv if a suitable module
+has been loaded.
+
+=for apidoc Am|void|SvUNLOCK|SV* sv
+Releases a mutual exclusion lock on sv if a suitable module
+has been loaded.
+
+=head1 SV Manipulation Functions
+
 =for apidoc Am|char *|SvGROW|SV* sv|STRLEN len
 Expands the character buffer in the SV so that it has room for the
 indicated number of bytes (remember to reserve space for an extra trailing
-NUL character).  Calls C<sv_grow> to perform the expansion if necessary. 
+NUL character).  Calls C<sv_grow> to perform the expansion if necessary.
 Returns a pointer to the character buffer.
 
 =cut
 */
 
+#define SvSHARE(sv) CALL_FPTR(PL_sharehook)(aTHX_ sv)
+#define SvLOCK(sv) CALL_FPTR(PL_lockhook)(aTHX_ sv)
+#define SvUNLOCK(sv) CALL_FPTR(PL_unlockhook)(aTHX_ sv)
+
 #define SvGETMAGIC(x) STMT_START { if (SvGMAGICAL(x)) mg_get(x); } STMT_END
 #define SvSETMAGIC(x) STMT_START { if (SvSMAGICAL(x)) mg_set(x); } STMT_END
 
@@ -1198,7 +1214,7 @@ Returns a pointer to the character buffer.
 #define SvSetMagicSV_nosteal(dst,src) \
                SvSetSV_nosteal_and(dst,src,SvSETMAGIC(dst))
 
-#ifdef DEBUGGING
+#if !defined(SKIP_DEBUGGING)
 #define SvPEEK(sv) sv_peek(sv)
 #else
 #define SvPEEK(sv) ""
@@ -1217,7 +1233,8 @@ Returns a pointer to the character buffer.
 #define CLONEf_KEEP_PTR_TABLE 2
 #define CLONEf_CLONE_HOST 4
 
-typedef struct {
+struct clone_params {
   AV* stashes;
   UV  flags;
-} clone_params;
+  PerlInterpreter *proto_perl;
+};