This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Documentation added.
[perl5.git] / sv.h
diff --git a/sv.h b/sv.h
index 39c1c29..6f95c46 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -1,6 +1,6 @@
 /*    sv.h
  *
 /*    sv.h
  *
- *    Copyright (c) 1991-2000, 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.
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
 #endif
 
 /*
 #endif
 
 /*
+=head1 SV Flags
+
 =for apidoc AmU||svtype
 =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
 in the C<svtype> enum.  Test these flags with the C<SvTYPE> macro.
 
 =for apidoc AmU||SVt_PV
@@ -61,7 +63,7 @@ typedef enum {
 
 /* Using C's structural equivalence to help emulate C++ inheritance here... */
 
 
 /* Using C's structural equivalence to help emulate C++ inheritance here... */
 
-struct STRUCT_SV {
+struct STRUCT_SV {             /* struct sv { */
     void*      sv_any;         /* pointer to something */
     U32                sv_refcnt;      /* how many references to us */
     U32                sv_flags;       /* what we are */
     void*      sv_any;         /* pointer to something */
     U32                sv_refcnt;      /* how many references to us */
     U32                sv_flags;       /* what we are */
@@ -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.
 
 =for apidoc Am|U32|SvREFCNT|SV* sv
 Returns the value of the object's reference count.
 
@@ -121,7 +125,7 @@ perform the upgrade if necessary.  See C<svtype>.
 #define SvFLAGS(sv)    (sv)->sv_flags
 #define SvREFCNT(sv)   (sv)->sv_refcnt
 
 #define SvFLAGS(sv)    (sv)->sv_flags
 #define SvREFCNT(sv)   (sv)->sv_refcnt
 
-#ifdef USE_THREADS
+#ifdef USE_5005THREADS
 
 #  if defined(VMS)
 #    define ATOMIC_INC(count) __ATOMIC_INCREMENT_LONG(&count)
 
 #  if defined(VMS)
 #    define ATOMIC_INC(count) __ATOMIC_INCREMENT_LONG(&count)
@@ -146,7 +150,7 @@ perform the upgrade if necessary.  See C<svtype>.
 #else
 #  define ATOMIC_INC(count) (++count)
 #  define ATOMIC_DEC_AND_TEST(res, count) (res = (--count == 0))
 #else
 #  define ATOMIC_INC(count) (++count)
 #  define ATOMIC_DEC_AND_TEST(res, count) (res = (--count == 0))
-#endif /* USE_THREADS */
+#endif /* USE_5005THREADS */
 
 #ifdef __GNUC__
 #  define SvREFCNT_inc(sv)             \
 
 #ifdef __GNUC__
 #  define SvREFCNT_inc(sv)             \
@@ -157,7 +161,7 @@ perform the upgrade if necessary.  See C<svtype>.
        nsv;                            \
     })
 #else
        nsv;                            \
     })
 #else
-#  if defined(CRIPPLED_CC) || defined(USE_THREADS)
+#  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)
 #    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
 
 #  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)
 
 #define SVTYPEMASK     0xff
 #define SvTYPE(sv)     ((sv)->sv_flags & SVTYPEMASK)
@@ -193,7 +197,8 @@ perform the upgrade if necessary.  See C<svtype>.
 
 #define SVf_FAKE       0x00100000      /* glob or lexical is just a copy */
 #define SVf_OOK                0x00200000      /* has valid offset value */
 
 #define SVf_FAKE       0x00100000      /* glob or lexical is just a copy */
 #define SVf_OOK                0x00200000      /* has valid offset value */
-#define SVf_BREAK      0x00400000      /* refcnt is artificially low */
+#define SVf_BREAK      0x00400000      /* refcnt is artificially low - used
+                                        * by SV's in final arena  cleanup */
 #define SVf_READONLY   0x00800000      /* may not be modified */
 
 
 #define SVf_READONLY   0x00800000      /* may not be modified */
 
 
@@ -204,7 +209,7 @@ perform the upgrade if necessary.  See C<svtype>.
 
 #define SVf_UTF8        0x20000000      /* SvPVX is UTF-8 encoded */
 
 
 #define SVf_UTF8        0x20000000      /* SvPVX is UTF-8 encoded */
 
-#define SVf_THINKFIRST (SVf_READONLY|SVf_ROK|SVf_FAKE|SVf_UTF8)
+#define SVf_THINKFIRST (SVf_READONLY|SVf_ROK|SVf_FAKE)
 
 #define SVf_OK         (SVf_IOK|SVf_NOK|SVf_POK|SVf_ROK| \
                         SVp_IOK|SVp_NOK|SVp_POK)
 
 #define SVf_OK         (SVf_IOK|SVf_NOK|SVf_POK|SVf_ROK| \
                         SVp_IOK|SVp_NOK|SVp_POK)
@@ -217,6 +222,7 @@ perform the upgrade if necessary.  See C<svtype>.
 
 /* SVpad_OUR may be set on SVt_PV{NV,MG,GV} types */
 #define SVpad_OUR      0x80000000      /* pad name is "our" instead of "my" */
 
 /* SVpad_OUR may be set on SVt_PV{NV,MG,GV} types */
 #define SVpad_OUR      0x80000000      /* pad name is "our" instead of "my" */
+#define SVpad_TYPED    0x40000000      /* Typed Lexical */
 
 #define SVf_IVisUV     0x80000000      /* use XPVUV instead of XPVIV */
 
 
 #define SVf_IVisUV     0x80000000      /* use XPVUV instead of XPVIV */
 
@@ -229,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_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 */
 
 
 #define SVprv_WEAKREF   0x80000000      /* Weak reference */
 
@@ -336,20 +343,20 @@ struct xpvfm {
     HV *       xcv_stash;
     OP *       xcv_start;
     OP *       xcv_root;
     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;
     long       xcv_depth;      /* >= 2 indicates recursive call */
     AV *       xcv_padlist;
     CV *       xcv_outside;
     ANY                xcv_xsubany;
     GV *       xcv_gv;
     char *     xcv_file;
     long       xcv_depth;      /* >= 2 indicates recursive call */
     AV *       xcv_padlist;
     CV *       xcv_outside;
-#ifdef USE_THREADS
+#ifdef USE_5005THREADS
     perl_mutex *xcv_mutexp;    /* protects xcv_owner */
     struct perl_thread *xcv_owner;     /* current owner thread */
     perl_mutex *xcv_mutexp;    /* protects xcv_owner */
     struct perl_thread *xcv_owner;     /* current owner thread */
-#endif /* USE_THREADS */
+#endif /* USE_5005THREADS */
     cv_flags_t xcv_flags;
 
     cv_flags_t xcv_flags;
 
-    I32                xfm_lines;
+    IV         xfm_lines;
 };
 
 struct xpvio {
 };
 
 struct xpvio {
@@ -376,10 +383,10 @@ struct xpvio {
        DIR *   xiou_dirp;      /* for opendir, readdir, etc */
        void *  xiou_any;       /* for alignment */
     } xio_dirpu;
        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;   /* $~ */
     char *     xio_top_name;   /* $^ */
     GV *       xio_top_gv;     /* $^ */
     char *     xio_fmt_name;   /* $~ */
@@ -448,8 +455,11 @@ Tells and SV that it is an unsigned integer and disables all other OK bits.
 =for apidoc Am|void|SvIOK_UV|SV* sv
 Returns a boolean indicating whether the SV contains an unsigned integer.
 
 =for apidoc Am|void|SvIOK_UV|SV* sv
 Returns a boolean indicating whether the SV contains an unsigned integer.
 
+=for apidoc Am|void|SvUOK|SV* sv
+Returns a boolean indicating whether the SV contains an unsigned integer.
+
 =for apidoc Am|void|SvIOK_notUV|SV* sv
 =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.
 
 =for apidoc Am|bool|SvNOK|SV* sv
 Returns a boolean indicating whether the SV contains a double.
@@ -475,6 +485,7 @@ Unsets the PV status of an SV.
 
 =for apidoc Am|void|SvPOK_only|SV* sv
 Tells an SV that it is a string and disables all other OK bits.
 
 =for apidoc Am|void|SvPOK_only|SV* 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|SvOOK|SV* sv
 Returns a boolean indicating whether the SvIVX is a valid offset value for
 
 =for apidoc Am|bool|SvOOK|SV* sv
 Returns a boolean indicating whether the SvIVX is a valid offset value for
@@ -495,19 +506,19 @@ Unsets the RV status of an SV.
 Dereferences an RV to return the SV.
 
 =for apidoc Am|IV|SvIVX|SV* sv
 Dereferences an RV to return the SV.
 
 =for apidoc Am|IV|SvIVX|SV* sv
-Returns the integer which is stored in the SV, assuming SvIOK is
-true.
+Returns the raw value in the SV's IV slot, without checks or conversions.
+Only use when you are sure SvIOK is true. See also C<SvIV()>.
 
 =for apidoc Am|UV|SvUVX|SV* sv
 
 =for apidoc Am|UV|SvUVX|SV* sv
-Returns the unsigned integer which is stored in the SV, assuming SvIOK is
-true.
+Returns the raw value in the SV's UV slot, without checks or conversions.
+Only use when you are sure SvIOK is true. See also C<SvUV()>.
 
 =for apidoc Am|NV|SvNVX|SV* sv
 
 =for apidoc Am|NV|SvNVX|SV* sv
-Returns the double which is stored in the SV, assuming SvNOK is
-true.
+Returns the raw value in the SV's NV slot, without checks or conversions.
+Only use when you are sure SvNOK is true. See also C<SvNV()>.
 
 =for apidoc Am|char*|SvPVX|SV* sv
 
 =for apidoc Am|char*|SvPVX|SV* sv
-Returns a pointer to the string in the SV.  The SV must contain a
+Returns a pointer to the physical string in the SV.  The SV must contain a
 string.
 
 =for apidoc Am|STRLEN|SvCUR|SV* sv
 string.
 
 =for apidoc Am|STRLEN|SvCUR|SV* sv
@@ -562,6 +573,7 @@ Set the length of the string which is in the SV.  See C<SvCUR>.
 
 #define SvIOK_UV(sv)           ((SvFLAGS(sv) & (SVf_IOK|SVf_IVisUV))   \
                                 == (SVf_IOK|SVf_IVisUV))
 
 #define SvIOK_UV(sv)           ((SvFLAGS(sv) & (SVf_IOK|SVf_IVisUV))   \
                                 == (SVf_IOK|SVf_IVisUV))
+#define SvUOK(sv)              SvIOK_UV(sv)
 #define SvIOK_notUV(sv)                ((SvFLAGS(sv) & (SVf_IOK|SVf_IVisUV))   \
                                 == SVf_IOK)
 
 #define SvIOK_notUV(sv)                ((SvFLAGS(sv) & (SVf_IOK|SVf_IVisUV))   \
                                 == SVf_IOK)
 
@@ -580,15 +592,16 @@ Set the length of the string which is in the SV.  See C<SvCUR>.
 Returns a boolean indicating whether the SV contains UTF-8 encoded data.
 
 =for apidoc Am|void|SvUTF8_on|SV *sv
 Returns a boolean indicating whether the SV contains UTF-8 encoded data.
 
 =for apidoc Am|void|SvUTF8_on|SV *sv
-Tells an SV that it is a string and encoded in UTF8.  Do not use frivolously.
+Turn on the UTF8 status of an SV (the data is not changed, just the flag).
+Do not use frivolously.
 
 =for apidoc Am|void|SvUTF8_off|SV *sv
 Unsets the UTF8 status of an SV.
 
 =for apidoc Am|void|SvPOK_only_UTF8|SV* sv
 
 =for apidoc Am|void|SvUTF8_off|SV *sv
 Unsets the UTF8 status of an SV.
 
 =for apidoc Am|void|SvPOK_only_UTF8|SV* sv
-Tells an SV that it is a UTF8 string (do not use frivolously)
-and disables all other OK bits.
-  
+Tells an SV that it is a string and disables all other OK bits,
+and leaves the UTF8 status as it was.
+
 =cut
  */
 
 =cut
  */
 
@@ -638,7 +651,7 @@ and disables all other OK bits.
 #define SvAMAGIC_on(sv)                (SvFLAGS(sv) |= SVf_AMAGIC)
 #define SvAMAGIC_off(sv)       (SvFLAGS(sv) &= ~SVf_AMAGIC)
 
 #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) \
 
 /*
 #define Gv_AMG(stash) \
@@ -695,6 +708,14 @@ and disables all other OK bits.
 #define SvVALID_on(sv)         (SvFLAGS(sv) |= SVpbm_VALID)
 #define SvVALID_off(sv)                (SvFLAGS(sv) &= ~SVpbm_VALID)
 
 #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)
 
 #define SvRV(sv) ((XRV*)  SvANY(sv))->xrv_rv
 #define SvRVx(sv) SvRV(sv)
 
@@ -714,6 +735,12 @@ and disables all other OK bits.
 #define SvMAGIC(sv)    ((XPVMG*)  SvANY(sv))->xmg_magic
 #define SvSTASH(sv)    ((XPVMG*)  SvANY(sv))->xmg_stash
 
 #define SvMAGIC(sv)    ((XPVMG*)  SvANY(sv))->xmg_magic
 #define SvSTASH(sv)    ((XPVMG*)  SvANY(sv))->xmg_stash
 
+/* Ask a scalar nicely to try to become an IV, if possible.
+   Not guaranteed to stay returning void */
+/* Macro won't actually call sv_2iv if already IOK */
+#define SvIV_please(sv) \
+       STMT_START {if (!SvIOKp(sv) && (SvNOK(sv) || SvPOK(sv))) \
+               (void) SvIV(sv); } STMT_END
 #define SvIV_set(sv, val) \
        STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \
                (((XPVIV*)  SvANY(sv))->xiv_iv = val); } STMT_END
 #define SvIV_set(sv, val) \
        STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \
                (((XPVIV*)  SvANY(sv))->xiv_iv = val); } STMT_END
@@ -808,147 +835,168 @@ Taints an SV if tainting is enabled
 
 /*
 =for apidoc Am|char*|SvPV_force|SV* sv|STRLEN len
 
 /*
 =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 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
 
 =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.
+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
 
 =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
 
 =for apidoc Am|IV|SvIV|SV* sv
-Coerces the given SV to an integer and returns it.
+Coerces the given SV to an integer and returns it. See  C<SvIVx> for a
+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 efficient C<SvIV> otherwise.
 
 =for apidoc Am|NV|SvNV|SV* sv
 
 =for apidoc Am|NV|SvNV|SV* sv
-Coerce the given SV to a double and return it.
+Coerce the given SV to a double and return it. See  C<SvNVx> for a version
+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 efficient C<SvNV> otherwise.
 
 =for apidoc Am|UV|SvUV|SV* sv
 
 =for apidoc Am|UV|SvUV|SV* sv
-Coerces the given SV to an unsigned integer and returns it.
+Coerces the given SV to an unsigned integer and returns it.  See C<SvUVx>
+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 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|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.
 
-=cut
-*/
+=for apidoc Am|char*|SvPVutf8_force|SV* sv|STRLEN len
+Like C<SvPV_force>, but converts sv to utf8 first if necessary.
 
 
-#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)
+=for apidoc Am|char*|SvPVutf8|SV* sv|STRLEN len
+Like C<SvPV>, but converts sv to utf8 first if necessary.
 
 
-#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)
+=for apidoc Am|char*|SvPVutf8_nolen|SV* sv
+Like C<SvPV_nolen>, but converts sv to utf8 first if necessary.
 
 
-#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)
+=for apidoc Am|char*|SvPVbyte_force|SV* sv|STRLEN len
+Like C<SvPV_force>, but converts sv to byte representation first if necessary.
 
 
-#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)
+=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
+Like C<SvPV_nolen>, but converts sv to byte representation first if necessary.
 
 
-#define SvIVx(sv) sv_iv(sv)
-#define SvUVx(sv) sv_uv(sv)
-#define SvNVx(sv) sv_nv(sv)
+=for apidoc Am|char*|SvPVutf8x_force|SV* sv|STRLEN len
+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.
 
 
-#define SvTRUEx(sv) sv_true(sv)
+=for apidoc Am|char*|SvPVutf8x|SV* sv|STRLEN len
+Like C<SvPV>, but converts sv to utf8 first if necessary.
+Guarantees to evaluate sv only once; use the more efficient C<SvPVutf8>
+otherwise.
 
 
-#define SvIV(sv) SvIVx(sv)
-#define SvNV(sv) SvNVx(sv)
-#define SvUV(sv) SvUVx(sv)
-#define SvTRUE(sv) SvTRUEx(sv)
+=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 evaluate sv only once; use the more efficient C<SvPVbyte_force>
+otherwise.
 
 
-#ifndef CRIPPLED_CC
-/* redefine some things to more efficient inlined versions */
+=for apidoc Am|char*|SvPVbytex|SV* sv|STRLEN len
+Like C<SvPV>, but converts sv to byte representation first if necessary.
+Guarantees to evaluate sv only once; use the more efficient C<SvPVbyte>
+otherwise.
+
+
+=cut
+*/
 
 /* Let us hope that bitmaps for UV and IV are the same */
 
 /* Let us hope that bitmaps for UV and IV are the same */
-#undef SvIV
 #define SvIV(sv) (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv))
 #define SvIV(sv) (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv))
-
-#undef SvUV
 #define SvUV(sv) (SvIOK(sv) ? SvUVX(sv) : sv_2uv(sv))
 #define SvUV(sv) (SvIOK(sv) ? SvUVX(sv) : sv_2uv(sv))
-
-#undef SvNV
 #define SvNV(sv) (SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv))
 
 #define SvNV(sv) (SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv))
 
-#undef SvPV
-#define SvPV(sv, lp) \
+/* ----*/
+
+#define SvPV(sv, lp) SvPV_flags(sv, lp, SV_GMAGIC)
+
+#define SvPV_flags(sv, lp, flags) \
     ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
     ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv(sv, &lp))
+     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv_flags(sv, &lp, flags))
+
+#define SvPV_force(sv, lp) SvPV_force_flags(sv, lp, SV_GMAGIC)
 
 
+#define SvPV_force_nomg(sv, lp) SvPV_force_flags(sv, lp, 0)
 
 
-#undef SvPV_force
-#define SvPV_force(sv, lp) \
+#define SvPV_force_flags(sv, lp, flags) \
     ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \
     ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvn_force(sv, &lp))
+    ? ((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))
 
 #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))
+#define SvPV_nomg(sv, lp) SvPV_flags(sv, lp, 0)
 
 
-#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 SvPVutf8
 #define SvPVutf8(sv, lp) \
     ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK|SVf_UTF8) \
      ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvutf8(sv, &lp))
 
 #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 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))
 
 #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))
 
 #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))
 
 #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 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__
 #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); })
 #  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); })
@@ -972,26 +1020,31 @@ false, defined or undefined.  Does not handle 'get' magic.
                ? SvNVX(sv) != 0.0                              \
                : sv_2bool(sv) )
 #  define SvTRUEx(sv) ({SV *nsv = (sv); SvTRUE(nsv); })
                ? SvNVX(sv) != 0.0                              \
                : sv_2bool(sv) )
 #  define SvTRUEx(sv) ({SV *nsv = (sv); SvTRUE(nsv); })
+
 #else /* __GNUC__ */
 #else /* __GNUC__ */
-#ifndef USE_THREADS
+
+#  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 */
 
 /* 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)                                             \
     !sv                                                                \
     ? 0                                                                \
     :    SvPOK(sv)                                             \
@@ -1006,10 +1059,34 @@ false, defined or undefined.  Does not handle 'get' magic.
            :   SvNOK(sv)                                       \
                ? SvNVX(sv) != 0.0                              \
                : sv_2bool(sv) )
            :   SvNOK(sv)                                       \
                ? SvNVX(sv) != 0.0                              \
                : sv_2bool(sv) )
-#  define SvTRUEx(sv) ((PL_Sv = (sv)), SvTRUE(PL_Sv))
-#endif /* !USE_THREADS */
-#endif /* !__GNU__ */
-#endif /* !CRIPPLED_CC */
+#    define SvTRUEx(sv) ((PL_Sv = (sv)), SvTRUE(PL_Sv))
+#  endif /* USE_5005THREADS */
+#endif /* __GNU__ */
+
+
+/* flag values for sv_*_flags functions */
+#define SV_IMMEDIATE_UNREF     1
+#define SV_GMAGIC              2
+
+/* 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
 
 /*
 =for apidoc Am|SV*|newRV_inc|SV* sv
@@ -1025,6 +1102,8 @@ incremented.
 /* the following macros update any magic values this sv is associated with */
 
 /*
 /* 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.
 =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.
@@ -1041,15 +1120,39 @@ more than once.
 Calls a non-destructive version of C<sv_setsv> if dsv is not the same as
 ssv. May evaluate arguments more than once.
 
 Calls a non-destructive version of C<sv_setsv> if dsv is not the same as
 ssv. May evaluate arguments more than once.
 
-=for apidoc Am|void|SvGROW|SV* sv|STRLEN len
+=for apidoc Am|void|SvSetMagicSV|SV* dsb|SV* ssv
+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
 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
 */
 
 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
 
 #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
 
@@ -1081,7 +1184,7 @@ Returns a pointer to the character buffer.
 #define SvSetMagicSV_nosteal(dst,src) \
                SvSetSV_nosteal_and(dst,src,SvSETMAGIC(dst))
 
 #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) ""
 #define SvPEEK(sv) sv_peek(sv)
 #else
 #define SvPEEK(sv) ""
@@ -1096,4 +1199,11 @@ Returns a pointer to the character buffer.
 #define SvGROW(sv,len) (SvLEN(sv) < (len) ? sv_grow(sv,len) : SvPVX(sv))
 #define Sv_Grow sv_grow
 
 #define SvGROW(sv,len) (SvLEN(sv) < (len) ? sv_grow(sv,len) : SvPVX(sv))
 #define Sv_Grow sv_grow
 
-#define SV_IMMEDIATE_UNREF     1
+#define CLONEf_COPY_STACKS 1
+#define CLONEf_KEEP_PTR_TABLE 2
+#define CLONEf_CLONE_HOST 4
+
+struct clone_params {
+  AV* stashes;
+  UV  flags;
+};