#if defined(PERL_IN_HV_C) || defined(PERL_IN_XS_APITEST)
#define HE_SVSLOT SVt_NULL
#endif
+#ifdef PERL_IN_SV_C
+# define SVt_FIRST SVt_NULL /* the type of SV that new_SV() in sv.c returns */
+#endif
#define PERL_ARENA_ROOTS_SIZE (SVt_LAST)
U32 sv_refcnt; /* how many references to us */ \
U32 sv_flags /* what we are */
+#if NVSIZE <= IVSIZE
+# define _NV_BODYLESS_UNION NV svu_nv;
+#else
+# define _NV_BODYLESS_UNION
+#endif
+
#define _SV_HEAD_UNION \
union { \
char* svu_pv; /* pointer to malloced string */ \
IV svu_iv; \
UV svu_uv; \
+ _NV_BODYLESS_UNION \
SV* svu_rv; /* pointer to another SV */ \
struct regexp* svu_rx; \
SV** svu_array; \
GvIMPORTED_CV_on() if it needs to be
expanded to a real GV */
#define SVpad_NAMELIST SVp_SCREAM /* AV is a padnamelist */
-#define SVf_IsCOW 0x00010000 /* copy on write (shared hash key if
- SvLEN == 0) */
-#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 SVf_PROTECT 0x00010000 /* very read-only */
+#define SVs_PADTMP 0x00020000 /* in use as tmp */
#define SVpad_TYPED 0x00020000 /* pad name is a Typed Lexical */
-#define SVs_PADMY 0x00040000 /* in use a "my" variable */
+#define SVs_PADSTALE 0x00040000 /* lexical has gone out of scope;
+ only used when !PADTMP */
#define SVpad_OUR 0x00040000 /* pad name is "our" instead of "my" */
-#define SVs_TEMP 0x00080000 /* string is stealable? */
+#define SVs_TEMP 0x00080000 /* mortal (implies string is stealable) */
#define SVs_OBJECT 0x00100000 /* is "blessed" */
+#define SVpad_LVALUE 0x00100000 /* pad name is used as lvalue */
#define SVs_GMG 0x00200000 /* has magical get method */
#define SVs_SMG 0x00400000 /* has magical set method */
#define SVs_RMG 0x00800000 /* has random magical methods */
[CvEVAL(cv), CvSPECIAL(cv)]
3: On a pad name SV, that slot in the
frame AV is a REFCNT'ed reference
- to a lexical from "outside". */
+ to a lexical from "outside".
+ 4: HV: informally reserved by DAPM
+ for vtables */
#define SVf_OOK 0x02000000 /* has valid offset value. For a PVHV this
means that a hv_aux struct is present
after the main array */
-#define SVf_THINKFIRST (SVf_READONLY|SVf_ROK|SVf_FAKE|SVs_RMG|SVf_IsCOW)
+#define SVf_THINKFIRST (SVf_READONLY|SVf_PROTECT|SVf_ROK|SVf_FAKE \
+ |SVs_RMG|SVf_IsCOW)
#define SVf_OK (SVf_IOK|SVf_NOK|SVf_POK|SVf_ROK| \
SVp_IOK|SVp_NOK|SVp_POK|SVpgv_GP)
#define PRIVSHIFT 4 /* (SVp_?OK >> PRIVSHIFT) == SVf_?OK */
+/* Note that SVf_AMAGIC is now only set on stashes. */
#define SVf_AMAGIC 0x10000000 /* has magical overloaded methods */
+#define SVf_IsCOW 0x10000000 /* copy on write (shared hash key if
+ SvLEN == 0) */
-/* Ensure this value does not clash with the GV_ADD* flags in gv.h: */
+/* Ensure this value does not clash with the GV_ADD* flags in gv.h, or the
+ CV_CKPROTO_* flags in op.c, or the padadd_* flags in pad.h: */
#define SVf_UTF8 0x20000000 /* SvPV is UTF-8 encoded
This is also set on RVs whose overloaded
stringification is UTF-8. This might
only happen as a side effect of SvPV() */
-
-
-/* Some private flags. */
+/* PVHV */
+#define SVphv_SHAREKEYS 0x20000000 /* PVHV keys live on shared string table */
/* PVAV could probably use 0x2000000 without conflict. I assume that PVFM can
be UTF-8 encoded, and PVCVs could well have UTF-8 prototypes. PVIOs haven't
been restructured, so sometimes get used as string buffers. */
-/* PVHV */
-#define SVphv_SHAREKEYS 0x20000000 /* PVHV keys live on shared string table */
+
+/* Some private flags. */
+
/* PVNV, PVMG only, and only used in pads. Should be safe to test on any scalar
SV, as the core is careful to avoid setting both.
struct xpvinvlist {
_XPV_HEAD;
- IV prev_index;
- STRLEN iterator;
- bool is_offset; /* */
+ IV prev_index; /* caches result of previous invlist_search() */
+ STRLEN iterator; /* Stores where we are in iterating */
+ bool is_offset; /* The data structure for all inversion lists
+ begins with an element for code point U+0000.
+ If this bool is set, the actual list contains
+ that 0; otherwise, the list actually begins
+ with the following element. Thus to invert
+ the list, merely toggle this flag */
};
/* This structure works in 3 ways - regular scalar, GV with GP, or fast
HEK * xcv_hek; \
} xcv_gv_u; \
char * xcv_file; \
- PADLIST * xcv_padlist; \
+ union { \
+ PADLIST * xcv_padlist; \
+ void * xcv_hscxt; \
+ } xcv_padlist_u; \
CV * xcv_outside; \
U32 xcv_outside_seq; /* the COP sequence (at the point of our \
* compilation) in the lexically enclosing \
=for apidoc Am|char*|SvEND|SV* 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).
+C<NUL> character (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
Set the value of the NV pointer in sv to val. See C<SvIV_set>.
=for apidoc Am|void|SvPV_set|SV* sv|char* val
-Set the value of the PV pointer in sv to val. See also C<SvIV_set>.
+Set the value of the PV pointer in C<sv> to the C<NUL>-terminated string
+C<val>. See also C<SvIV_set>.
Beware that the existing pointer may be involved in copy-on-write or other
mischief, so do C<SvOOK_off(sv)> and use C<sv_force_normal> or
#define SvTHINKFIRST(sv) (SvFLAGS(sv) & SVf_THINKFIRST)
-#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 SVs_PADMY 0
+#define SvPADMY(sv) !(SvFLAGS(sv) & SVs_PADTMP)
+#ifndef PERL_CORE
+# define SvPADMY_on(sv) SvPADTMP_off(sv)
+#endif
-#define SvPADTMP(sv) ((SvFLAGS(sv) & (SVs_PADMY|SVs_PADTMP)) == SVs_PADTMP)
-#define SvPADSTALE(sv) ((SvFLAGS(sv) & (SVs_PADMY|SVs_PADSTALE)) \
- == (SVs_PADMY|SVs_PADSTALE))
+#define SvPADTMP(sv) (SvFLAGS(sv) & (SVs_PADTMP))
+#define SvPADSTALE(sv) (SvFLAGS(sv) & (SVs_PADSTALE))
-#define SvPADTMP_on(sv) S_SvPADTMP_on(MUTABLE_SV(sv))
-#define SvPADTMP_off(sv) S_SvPADTMP_off(MUTABLE_SV(sv))
+#define SvPADTMP_on(sv) (SvFLAGS(sv) |= SVs_PADTMP)
+#define SvPADTMP_off(sv) (SvFLAGS(sv) &= ~SVs_PADTMP)
#define SvPADSTALE_on(sv) S_SvPADSTALE_on(MUTABLE_SV(sv))
#define SvPADSTALE_off(sv) S_SvPADSTALE_off(MUTABLE_SV(sv))
#define SvOBJECT_on(sv) (SvFLAGS(sv) |= SVs_OBJECT)
#define SvOBJECT_off(sv) (SvFLAGS(sv) &= ~SVs_OBJECT)
-#define SvREADONLY(sv) (SvFLAGS(sv) & SVf_READONLY)
-#define SvREADONLY_on(sv) (SvFLAGS(sv) |= SVf_READONLY)
-#define SvREADONLY_off(sv) (SvFLAGS(sv) &= ~SVf_READONLY)
+#define SvREADONLY(sv) (SvFLAGS(sv) & (SVf_READONLY|SVf_PROTECT))
+#ifdef PERL_CORE
+# define SvREADONLY_on(sv) (SvFLAGS(sv) |= (SVf_READONLY|SVf_PROTECT))
+# define SvREADONLY_off(sv) (SvFLAGS(sv) &=~(SVf_READONLY|SVf_PROTECT))
+#else
+# define SvREADONLY_on(sv) (SvFLAGS(sv) |= SVf_READONLY)
+# define SvREADONLY_off(sv) (SvFLAGS(sv) &= ~SVf_READONLY)
+#endif
#define SvSCREAM(sv) ((SvFLAGS(sv) & (SVp_SCREAM|SVp_POK)) == (SVp_SCREAM|SVp_POK))
#define SvSCREAM_on(sv) (SvFLAGS(sv) |= SVp_SCREAM)
#define SvTAIL_on(sv) (SvFLAGS(sv) |= SVpbm_TAIL)
#define SvTAIL_off(sv) (SvFLAGS(sv) &= ~SVpbm_TAIL)
+#define SvPAD_NAME(sv) ((SvFLAGS(sv) & SVpad_NAME) == SVpad_NAME)
#define SvPAD_TYPED(sv) \
((SvFLAGS(sv) & (SVpad_NAME|SVpad_TYPED)) == (SVpad_NAME|SVpad_TYPED))
assert(SvTYPE(sv) >= SVt_PV); \
if (SvLEN(sv)) { \
assert(!SvROK(sv)); \
- if(SvOOK(sv)) { \
+ if(UNLIKELY(SvOOK(sv))) { \
STRLEN zok; \
SvOOK_offset(sv, zok); \
SvPV_set(sv, SvPVX_mutable(sv) - zok); \
#else
# define SvTAINTED(sv) (SvMAGICAL(sv) && sv_tainted(sv))
#endif
-#define SvTAINTED_on(sv) STMT_START{ if(TAINTING_get){sv_taint(sv);} }STMT_END
-#define SvTAINTED_off(sv) STMT_START{ if(TAINTING_get){sv_untaint(sv);} }STMT_END
+#define SvTAINTED_on(sv) STMT_START{ if(UNLIKELY(TAINTING_get)){sv_taint(sv);} }STMT_END
+#define SvTAINTED_off(sv) STMT_START{ if(UNLIKELY(TAINTING_get)){sv_untaint(sv);} }STMT_END
#define SvTAINT(sv) \
STMT_START { \
- if (TAINTING_get) { \
- if (TAINT_get) \
+ if (UNLIKELY(TAINTING_get)) { \
+ if (UNLIKELY(TAINT_get)) \
SvTAINTED_on(sv); \
} \
} STMT_END
=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. 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.
+stringified version becoming C<SvPOK>. Handles 'get' magic. The
+C<len> variable will be set to the length of the string (this is a macro, so
+don't use C<&len>). See also C<SvPVx> for a version which guarantees to
+evaluate sv only once.
Note that there is no guarantee that the return value of C<SvPV()> is
equal to C<SvPVX(sv)>, or that C<SvPVX(sv)> contains valid data, or that
#define SvPV_flags_const(sv, lp, flags) \
(SvPOK_nog(sv) \
? ((lp = SvCUR(sv)), SvPVX_const(sv)) : \
- (const char*) sv_2pv_flags(sv, &lp, flags|SV_CONST_RETURN))
+ (const char*) sv_2pv_flags(sv, &lp, (flags|SV_CONST_RETURN)))
#define SvPV_flags_const_nolen(sv, flags) \
(SvPOK_nog(sv) \
? SvPVX_const(sv) : \
- (const char*) sv_2pv_flags(sv, 0, flags|SV_CONST_RETURN))
+ (const char*) sv_2pv_flags(sv, 0, (flags|SV_CONST_RETURN)))
#define SvPV_flags_mutable(sv, lp, flags) \
(SvPOK_nog(sv) \
? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) : \
- sv_2pv_flags(sv, &lp, flags|SV_MUTABLE_RETURN))
+ sv_2pv_flags(sv, &lp, (flags|SV_MUTABLE_RETURN)))
#define SvPV_force(sv, lp) SvPV_force_flags(sv, lp, SV_GMAGIC)
#define SvPV_force_nolen(sv) SvPV_force_flags_nolen(sv, SV_GMAGIC)
#define SvPVutf8x_force(sv, lp) sv_pvutf8n_force(sv, &lp)
#define SvPVbytex_force(sv, lp) sv_pvbyten_force(sv, &lp)
-#define SvTRUE(sv) ((sv) && (SvGMAGICAL(sv) ? sv_2bool(sv) : SvTRUE_common(sv, sv_2bool_nomg(sv))))
-#define SvTRUE_nomg(sv) ((sv) && ( SvTRUE_common(sv, sv_2bool_nomg(sv))))
-#define SvTRUE_NN(sv) (SvGMAGICAL(sv) ? sv_2bool(sv) : SvTRUE_common(sv, sv_2bool_nomg(sv)))
+#define SvTRUE(sv) (LIKELY(sv) && (UNLIKELY(SvGMAGICAL(sv)) ? sv_2bool(sv) : SvTRUE_common(sv, sv_2bool_nomg(sv))))
+#define SvTRUE_nomg(sv) (LIKELY(sv) && ( SvTRUE_common(sv, sv_2bool_nomg(sv))))
+#define SvTRUE_NN(sv) (UNLIKELY(SvGMAGICAL(sv)) ? sv_2bool(sv) : SvTRUE_common(sv, sv_2bool_nomg(sv)))
#define SvTRUE_nomg_NN(sv) ( SvTRUE_common(sv, sv_2bool_nomg(sv)))
#define SvTRUE_common(sv,fallback) ( \
!SvOK(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
+#define SV_CATBYTES 16384
+#define SV_CATUTF8 32768
/* 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.
on-write. */
# define CAN_COW_MASK (SVs_OBJECT|SVs_GMG|SVs_SMG|SVs_RMG|SVf_IOK|SVf_NOK| \
SVf_POK|SVf_ROK|SVp_IOK|SVp_NOK|SVp_POK|SVf_FAKE| \
- SVf_OOK|SVf_BREAK|SVf_READONLY)
+ SVf_OOK|SVf_BREAK|SVf_READONLY|SVf_PROTECT)
#else
# define SvRELEASE_IVX(sv) 0
/* This little game brought to you by the need to shut this warning up:
/* Note: To allow 256 COW "copies", a refcnt of 0 means 1. */
# define CowREFCNT(sv) (*(U8 *)(SvPVX(sv)+SvLEN(sv)-1))
# define SV_COW_REFCNT_MAX ((1 << sizeof(U8)*8) - 1)
-# ifndef SV_COW_THRESHOLD
-# define SV_COW_THRESHOLD 0 /* min string length for cow */
-# endif
-# ifndef SV_COWBUF_THRESHOLD
-# define SV_COWBUF_THRESHOLD 1250 /* min string length for cow */
-# endif /* over existing buffer */
# define CAN_COW_MASK (SVf_POK|SVf_ROK|SVp_POK|SVf_FAKE| \
- SVf_OOK|SVf_BREAK|SVf_READONLY)
+ SVf_OOK|SVf_BREAK|SVf_READONLY|SVf_PROTECT)
# endif
#endif /* PERL_OLD_COPY_ON_WRITE */
(littlelen), SV_GMAGIC)
#define sv_mortalcopy(sv) \
Perl_sv_mortalcopy_flags(aTHX_ sv, SV_GMAGIC|SV_DO_COW_SVSETSV)
+#define sv_cathek(sv,hek) \
+ STMT_START { \
+ HEK * const bmxk = hek; \
+ sv_catpvn_flags(sv, HEK_KEY(bmxk), HEK_LEN(bmxk), \
+ HEK_UTF8(bmxk) ? SV_CATUTF8 : SV_CATBYTES); \
+ } STMT_END
/* Should be named SvCatPVN_utf8_upgrade? */
#define sv_catpvn_nomg_utf8_upgrade(dsv, sstr, slen, nsv) \
=for apidoc Am|void|SvSetSV|SV* dsv|SV* ssv
Calls C<sv_setsv> if dsv is not the same as ssv. May evaluate arguments
-more than once.
+more than once. Does not handle 'set' magic on the destination SV.
=for apidoc Am|void|SvSetSV_nosteal|SV* dsv|SV* ssv
Calls a non-destructive version of C<sv_setsv> if dsv is not the same as
=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.
+C<NUL> character). Calls C<sv_grow> to perform the expansion if necessary.
Returns a pointer to the character
buffer. SV must be of type >= SVt_PV. One
alternative is to call C<sv_grow> if you are not sure of the type of SV.
#define SvUNLOCK(sv) PL_unlockhook(aTHX_ sv)
#define SvDESTROYABLE(sv) PL_destroyhook(aTHX_ sv)
-#define SvGETMAGIC(x) ((void)(SvGMAGICAL(x) && mg_get(x)))
-#define SvSETMAGIC(x) STMT_START { if (SvSMAGICAL(x)) mg_set(x); } STMT_END
+#define SvGETMAGIC(x) ((void)(UNLIKELY(SvGMAGICAL(x)) && mg_get(x)))
+#define SvSETMAGIC(x) STMT_START { if (UNLIKELY(SvSMAGICAL(x))) mg_set(x); } STMT_END
#define SvSetSV_and(dst,src,finally) \
STMT_START { \
- if ((dst) != (src)) { \
+ if (LIKELY((dst) != (src))) { \
sv_setsv(dst, src); \
finally; \
} \
} STMT_END
#define SvSetSV_nosteal_and(dst,src,finally) \
STMT_START { \
- if ((dst) != (src)) { \
+ if (LIKELY((dst) != (src))) { \
sv_setsv_flags(dst, src, SV_GMAGIC | SV_NOSTEAL | SV_DO_COW_SVSETSV); \
finally; \
} \
/*
=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
+Creates a new SV and copies a string (which may contain C<NUL> (C<\0>)
+characters) into it. If utf8 is true, calls
C<SvUTF8_on> on the new SV. Implemented as a wrapper around C<newSVpvn_flags>.
=cut