Mercurial > repo
diff perl-5.22.2/sv.h @ 8045:a16537d2fe07
<xfix> tar xf perl-5.22.2.tar.gz # Ah, whatever, I\'m doing it anyway
author | HackBot |
---|---|
date | Sat, 14 May 2016 14:54:38 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/perl-5.22.2/sv.h Sat May 14 14:54:38 2016 +0000 @@ -0,0 +1,2275 @@ +/* sv.h + * + * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + * 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by Larry Wall and others + * + * You may distribute under the terms of either the GNU General Public + * License or the Artistic License, as specified in the README file. + * + */ + +#ifdef sv_flags +#undef sv_flags /* Convex has this in <signal.h> for sigvec() */ +#endif + +/* +=head1 SV Flags + +=for apidoc AmU||svtype +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. + +The types are: + + SVt_NULL + SVt_IV + SVt_NV + SVt_RV + SVt_PV + SVt_PVIV + SVt_PVNV + SVt_PVMG + SVt_INVLIST + SVt_REGEXP + SVt_PVGV + SVt_PVLV + SVt_PVAV + SVt_PVHV + SVt_PVCV + SVt_PVFM + SVt_PVIO + +These are most easily explained from the bottom up. + +SVt_PVIO is for I/O objects, SVt_PVFM for formats, SVt_PVCV for +subroutines, SVt_PVHV for hashes and SVt_PVAV for arrays. + +All the others are scalar types, that is, things that can be bound to a +C<$> variable. For these, the internal types are mostly orthogonal to +types in the Perl language. + +Hence, checking C<< SvTYPE(sv) < SVt_PVAV >> is the best way to see whether +something is a scalar. + +SVt_PVGV represents a typeglob. If !SvFAKE(sv), then it is a real, +incoercible typeglob. If SvFAKE(sv), then it is a scalar to which a +typeglob has been assigned. Assigning to it again will stop it from being +a typeglob. SVt_PVLV represents a scalar that delegates to another scalar +behind the scenes. It is used, e.g., for the return value of C<substr> and +for tied hash and array elements. It can hold any scalar value, including +a typeglob. SVt_REGEXP is for regular +expressions. SVt_INVLIST is for Perl +core internal use only. + +SVt_PVMG represents a "normal" scalar (not a typeglob, regular expression, +or delegate). Since most scalars do not need all the internal fields of a +PVMG, we save memory by allocating smaller structs when possible. All the +other types are just simpler forms of SVt_PVMG, with fewer internal fields. + SVt_NULL can only hold undef. SVt_IV can hold undef, an integer, or a +reference. (SVt_RV is an alias for SVt_IV, which exists for backward +compatibility.) SVt_NV can hold any of those or a double. SVt_PV can only +hold undef or a string. SVt_PVIV is a superset of SVt_PV and SVt_IV. +SVt_PVNV is similar. SVt_PVMG can hold anything SVt_PVNV can hold, but it +can, but does not have to, be blessed or magical. + +=for apidoc AmU||SVt_NULL +Type flag for scalars. See L</svtype>. + +=for apidoc AmU||SVt_IV +Type flag for scalars. See L</svtype>. + +=for apidoc AmU||SVt_NV +Type flag for scalars. See L</svtype>. + +=for apidoc AmU||SVt_PV +Type flag for scalars. See L</svtype>. + +=for apidoc AmU||SVt_PVIV +Type flag for scalars. See L</svtype>. + +=for apidoc AmU||SVt_PVNV +Type flag for scalars. See L</svtype>. + +=for apidoc AmU||SVt_PVMG +Type flag for scalars. See L</svtype>. + +=for apidoc AmU||SVt_INVLIST +Type flag for scalars. See L</svtype>. + +=for apidoc AmU||SVt_REGEXP +Type flag for regular expressions. See L</svtype>. + +=for apidoc AmU||SVt_PVGV +Type flag for typeglobs. See L</svtype>. + +=for apidoc AmU||SVt_PVLV +Type flag for scalars. See L</svtype>. + +=for apidoc AmU||SVt_PVAV +Type flag for arrays. See L</svtype>. + +=for apidoc AmU||SVt_PVHV +Type flag for hashes. See L</svtype>. + +=for apidoc AmU||SVt_PVCV +Type flag for subroutines. See L</svtype>. + +=for apidoc AmU||SVt_PVFM +Type flag for formats. See L</svtype>. + +=for apidoc AmU||SVt_PVIO +Type flag for I/O objects. See L</svtype>. + +=cut + + These are ordered so that the simpler types have a lower value; SvUPGRADE + doesn't allow you to upgrade from a higher numbered type to a lower numbered + one; also there is code that assumes that anything that has as a PV component + has a type numbered >= SVt_PV. +*/ + + +typedef enum { + SVt_NULL, /* 0 */ + /* BIND was here, before INVLIST replaced it. */ + SVt_IV, /* 1 */ + SVt_NV, /* 2 */ + /* RV was here, before it was merged with IV. */ + SVt_PV, /* 3 */ + SVt_INVLIST, /* 4, implemented as a PV */ + 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 */ + SVt_PVAV, /* 11 */ + SVt_PVHV, /* 12 */ + SVt_PVCV, /* 13 */ + SVt_PVFM, /* 14 */ + SVt_PVIO, /* 15 */ + SVt_LAST /* keep last in enum. used to size arrays */ +} svtype; + +/* *** any alterations to the SV types above need to be reflected in + * SVt_MASK and the various PL_valid_types_* tables. As of this writing those + * tables are in perl.h. There are also two affected names tables in dump.c, + * one in B.xs, and 'bodies_by_type[]' in sv.c */ + +#define SVt_MASK 0xf /* smallest bitmask that covers all types */ + +#ifndef PERL_CORE +/* Although Fast Boyer Moore tables are now being stored in PVGVs, for most + purposes external 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 + so never reaches the clause at the end that uses sv_type_details->body_size + to determine whether to call safefree(). Hence body_size can be set + non-zero to record the size of HEs, without fear of bogus frees. */ +#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) + +/* typedefs to eliminate some typing */ +typedef struct he HE; +typedef struct hek HEK; + +/* Using C's structural equivalence to help emulate C++ inheritance here... */ + +/* start with 2 sv-head building blocks */ +#define _SV_HEAD(ptrtype) \ + ptrtype sv_any; /* pointer to body */ \ + 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; \ + HE** svu_hash; \ + GP* svu_gp; \ + PerlIO *svu_fp; \ + } sv_u + + +struct STRUCT_SV { /* struct sv { */ + _SV_HEAD(void*); + _SV_HEAD_UNION; +#ifdef DEBUG_LEAKING_SCALARS + PERL_BITFIELD32 sv_debug_optype:9; /* the type of OP that allocated us */ + PERL_BITFIELD32 sv_debug_inpad:1; /* was allocated in a pad for an OP */ + PERL_BITFIELD32 sv_debug_line:16; /* the line where we were allocated */ + UV sv_debug_serial; /* serial number of sv allocation */ + char * sv_debug_file; /* the file where we were allocated */ + SV * sv_debug_parent; /* what we were cloned from (ithreads)*/ +#endif +}; + +struct gv { + _SV_HEAD(XPVGV*); /* pointer to xpvgv body */ + _SV_HEAD_UNION; +}; + +struct cv { + _SV_HEAD(XPVCV*); /* pointer to xpvcv body */ + _SV_HEAD_UNION; +}; + +struct av { + _SV_HEAD(XPVAV*); /* pointer to xpvav body */ + _SV_HEAD_UNION; +}; + +struct hv { + _SV_HEAD(XPVHV*); /* pointer to xpvhv body */ + _SV_HEAD_UNION; +}; + +struct io { + _SV_HEAD(XPVIO*); /* pointer to xpvio body */ + _SV_HEAD_UNION; +}; + +struct p5rx { + _SV_HEAD(struct regexp*); /* pointer to regexp body */ + _SV_HEAD_UNION; +}; + +#undef _SV_HEAD +#undef _SV_HEAD_UNION /* ensure no pollution */ + +/* +=head1 SV Manipulation Functions + +=for apidoc Am|U32|SvREFCNT|SV* sv +Returns the value of the object's reference count. + +=for apidoc Am|SV*|SvREFCNT_inc|SV* sv +Increments the reference count of the given SV, returning the SV. + +All of the following SvREFCNT_inc* macros are optimized versions of +SvREFCNT_inc, and can be replaced with SvREFCNT_inc. + +=for apidoc Am|SV*|SvREFCNT_inc_NN|SV* sv +Same as SvREFCNT_inc, but can only be used if you know I<sv> +is not NULL. Since we don't have to check the NULLness, it's faster +and smaller. + +=for apidoc Am|void|SvREFCNT_inc_void|SV* sv +Same as SvREFCNT_inc, but can only be used if you don't need the +return value. The macro doesn't need to return a meaningful value. + +=for apidoc Am|void|SvREFCNT_inc_void_NN|SV* sv +Same as SvREFCNT_inc, but can only be used if you don't need the return +value, and you know that I<sv> is not NULL. The macro doesn't need +to return a meaningful value, or check for NULLness, so it's smaller +and faster. + +=for apidoc Am|SV*|SvREFCNT_inc_simple|SV* sv +Same as SvREFCNT_inc, but can only be used with expressions without side +effects. Since we don't have to store a temporary value, it's faster. + +=for apidoc Am|SV*|SvREFCNT_inc_simple_NN|SV* sv +Same as SvREFCNT_inc_simple, but can only be used if you know I<sv> +is not NULL. Since we don't have to check the NULLness, it's faster +and smaller. + +=for apidoc Am|void|SvREFCNT_inc_simple_void|SV* sv +Same as SvREFCNT_inc_simple, but can only be used if you don't need the +return value. The macro doesn't need to return a meaningful value. + +=for apidoc Am|void|SvREFCNT_inc_simple_void_NN|SV* sv +Same as SvREFCNT_inc, but can only be used if you don't need the return +value, and you know that I<sv> is not NULL. The macro doesn't need +to return a meaningful value, or check for NULLness, so it's smaller +and faster. + +=for apidoc Am|void|SvREFCNT_dec|SV* sv +Decrements the reference count of the given SV. I<sv> may be NULL. + +=for apidoc Am|void|SvREFCNT_dec_NN|SV* sv +Same as SvREFCNT_dec, but can only be used if you know I<sv> +is not NULL. Since we don't have to check the NULLness, it's faster +and smaller. + +=for apidoc Am|svtype|SvTYPE|SV* sv +Returns the type of the SV. See C<svtype>. + +=for apidoc Am|void|SvUPGRADE|SV* sv|svtype type +Used to upgrade an SV to a more complex form. Uses C<sv_upgrade> to +perform the upgrade if necessary. See C<svtype>. + +=cut +*/ + +#define SvANY(sv) (sv)->sv_any +#define SvFLAGS(sv) (sv)->sv_flags +#define SvREFCNT(sv) (sv)->sv_refcnt + +#define SvREFCNT_inc(sv) S_SvREFCNT_inc(MUTABLE_SV(sv)) +#define SvREFCNT_inc_simple(sv) SvREFCNT_inc(sv) +#define SvREFCNT_inc_NN(sv) S_SvREFCNT_inc_NN(MUTABLE_SV(sv)) +#define SvREFCNT_inc_void(sv) S_SvREFCNT_inc_void(MUTABLE_SV(sv)) + +/* These guys don't need the curly blocks */ +#define SvREFCNT_inc_simple_void(sv) STMT_START { if (sv) SvREFCNT(sv)++; } STMT_END +#define SvREFCNT_inc_simple_NN(sv) (++(SvREFCNT(sv)),MUTABLE_SV(sv)) +#define SvREFCNT_inc_void_NN(sv) (void)(++SvREFCNT(MUTABLE_SV(sv))) +#define SvREFCNT_inc_simple_void_NN(sv) (void)(++SvREFCNT(MUTABLE_SV(sv))) + +#define SvREFCNT_dec(sv) S_SvREFCNT_dec(aTHX_ MUTABLE_SV(sv)) +#define SvREFCNT_dec_NN(sv) S_SvREFCNT_dec_NN(aTHX_ MUTABLE_SV(sv)) + +#define SVTYPEMASK 0xff +#define SvTYPE(sv) ((svtype)((sv)->sv_flags & SVTYPEMASK)) + +/* Sadly there are some parts of the core that have pointers to already-freed + SV heads, and rely on being able to tell that they are now free. So mark + them all by using a consistent macro. */ +#define SvIS_FREED(sv) UNLIKELY(((sv)->sv_flags == SVTYPEMASK)) + +/* this is defined in this peculiar way to avoid compiler warnings. + * See the <20121213131428.GD1842@iabyn.com> thread in p5p */ +#define SvUPGRADE(sv, mt) \ + ((void)(SvTYPE(sv) >= (mt) || (sv_upgrade(sv, mt),1))) + +#define SVf_IOK 0x00000100 /* has valid public integer value */ +#define SVf_NOK 0x00000200 /* has valid public numeric value */ +#define SVf_POK 0x00000400 /* has valid public pointer value */ +#define SVf_ROK 0x00000800 /* has a valid reference pointer */ + +#define SVp_IOK 0x00001000 /* has valid non-public integer value */ +#define SVp_NOK 0x00002000 /* has valid non-public numeric value */ +#define SVp_POK 0x00004000 /* has valid non-public pointer value */ +#define SVp_SCREAM 0x00008000 /* method name is DOES */ +#define SVphv_CLONEABLE SVp_SCREAM /* PVHV (stashes) clone its objects */ +#define SVpgv_GP SVp_SCREAM /* GV has a valid GP */ +#define SVprv_PCS_IMPORTED SVp_SCREAM /* RV is a proxy for a constant + subroutine in another package. Set the + GvIMPORTED_CV_on() if it needs to be + expanded to a real GV */ +#define SVf_PROTECT 0x00010000 /* very read-only */ +#define SVs_PADTMP 0x00020000 /* in use as tmp */ +#define SVs_PADSTALE 0x00040000 /* lexical has gone out of scope; + only used when !PADTMP */ +#define SVs_TEMP 0x00080000 /* mortal (implies string is stealable) */ +#define SVs_OBJECT 0x00100000 /* is "blessed" */ +#define SVs_GMG 0x00200000 /* has magical get method */ +#define SVs_SMG 0x00400000 /* has magical set method */ +#define SVs_RMG 0x00800000 /* has random magical methods */ + +#define SVf_FAKE 0x01000000 /* 0: glob is just a copy + 1: SV head arena wasn't malloc()ed + 2: For PVCV, whether CvUNIQUE(cv) + refers to an eval or once only + [CvEVAL(cv), CvSPECIAL(cv)] + 3: 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_BREAK 0x04000000 /* refcnt is artificially low - used by + SVs in final arena cleanup. + Set in S_regtry on PL_reg_curpm, so that + perl_destruct will skip it. */ +#define SVf_READONLY 0x08000000 /* may not be modified */ + + + + +#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, 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() */ +/* 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. */ + + +/* Some private flags. */ + + +/* The SVp_SCREAM|SVpbm_VALID (0x40008000) combination is up for grabs. + Formerly it was used for pad names, but now it is available. The core + is careful to avoid setting both flags. + + SVf_POK, SVp_POK also set: + 0x00004400 Normal + 0x0000C400 method name for DOES (SvSCREAM) + 0x40004400 FBM compiled (SvVALID) + 0x4000C400 *** Formerly used for pad names *** + + 0x00008000 GV with GP + 0x00008800 RV with PCS imported +*/ +/* PVAV */ +#define SVpav_REAL 0x40000000 /* free old entries */ +/* PVHV */ +#define SVphv_LAZYDEL 0x40000000 /* entry in xhv_eiter must be deleted */ +/* This is only set true on a PVGV when it's playing "PVBM", but is tested for + on any regular scalar (anything <= PVLV) */ +#define SVpbm_VALID 0x40000000 +/* Only used in toke.c on an SV stored in PL_lex_repl */ +#define SVrepl_EVAL 0x40000000 /* Replacement part of s///e */ + +/* IV, PVIV, PVNV, PVMG, PVGV and (I assume) PVLV */ +#define SVf_IVisUV 0x80000000 /* use XPVUV instead of XPVIV */ +/* PVAV */ +#define SVpav_REIFY 0x80000000 /* can become real */ +/* PVHV */ +#define SVphv_HASKFLAGS 0x80000000 /* keys have flag byte after hash */ +/* PVGV when SVpbm_VALID is true */ +#define SVpbm_TAIL 0x80000000 +/* RV upwards. However, SVf_ROK and SVp_IOK are exclusive */ +#define SVprv_WEAKREF 0x80000000 /* Weak reference */ +/* pad name vars only */ + +#define _XPV_HEAD \ + HV* xmg_stash; /* class package */ \ + union _xmgu xmg_u; \ + STRLEN xpv_cur; /* length of svu_pv as a C string */ \ + union { \ + STRLEN xpvlenu_len; /* allocated size */ \ + char * xpvlenu_pv; /* regexp string */ \ + } xpv_len_u + +#define xpv_len xpv_len_u.xpvlenu_len + +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 */ +}; + +union _xivu { + IV xivu_iv; /* integer value */ + UV xivu_uv; + HEK * xivu_namehek; /* xpvlv, xpvgv: GvNAME */ +}; + +union _xmgu { + MAGIC* xmg_magic; /* linked list of magicalness */ + STRLEN xmg_hash_index; /* used while freeing hash entries */ +}; + +struct xpv { + _XPV_HEAD; +}; + +struct xpviv { + _XPV_HEAD; + union _xivu xiv_u; +}; + +#define xiv_iv xiv_u.xivu_iv + +struct xpvuv { + _XPV_HEAD; + union _xivu xuv_u; +}; + +#define xuv_uv xuv_u.xivu_uv + +struct xpvnv { + _XPV_HEAD; + union _xivu xiv_u; + union _xnvu xnv_u; +}; + +/* This structure must match the beginning of struct xpvhv in hv.h. */ +struct xpvmg { + _XPV_HEAD; + union _xivu xiv_u; + union _xnvu xnv_u; +}; + +struct xpvlv { + _XPV_HEAD; + union _xivu xiv_u; + union _xnvu xnv_u; + union { + STRLEN xlvu_targoff; + SSize_t xlvu_stargoff; + } xlv_targoff_u; + STRLEN xlv_targlen; + SV* xlv_targ; + char xlv_type; /* k=keys .=pos x=substr v=vec /=join/re + * y=alem/helem/iter t=tie T=tied HE */ + char xlv_flags; /* 1 = negative offset 2 = negative len */ +}; + +#define xlv_targoff xlv_targoff_u.xlvu_targoff + +struct xpvinvlist { + _XPV_HEAD; + 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 + Boyer-Moore. */ +struct xpvgv { + _XPV_HEAD; + union _xivu xiv_u; + union _xnvu xnv_u; +}; + +typedef U32 cv_flags_t; + +#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; \ + union { \ + GV * xcv_gv; \ + HEK * xcv_hek; \ + } xcv_gv_u; \ + char * xcv_file; \ + 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 \ + * sub */ \ + cv_flags_t xcv_flags; \ + I32 xcv_depth /* >= 2 indicates recursive call */ + +/* This structure must match XPVCV in cv.h */ + +struct xpvfm { + _XPV_HEAD; + _XPVCV_COMMON; +}; + + +struct xpvio { + _XPV_HEAD; + union _xivu xiv_u; + /* ifp and ofp are normally the same, but sockets need separate streams */ + PerlIO * xio_ofp; + /* Cray addresses everything by word boundaries (64 bits) and + * code and data pointers cannot be mixed (which is exactly what + * Perl_filter_add() tries to do with the dirp), hence the + * following union trick (as suggested by Gurusamy Sarathy). + * For further information see Geir Johansen's problem report + * titled [ID 20000612.002] Perl problem on Cray system + * The any pointer (known as IoANY()) will also be a good place + * to hang any IO disciplines to. + */ + union { + DIR * xiou_dirp; /* for opendir, readdir, etc */ + void * xiou_any; /* for alignment */ + } xio_dirpu; + /* IV xio_lines is now in IVX $. */ + IV xio_page; /* $% */ + IV xio_page_len; /* $= */ + IV xio_lines_left; /* $- */ + char * xio_top_name; /* $^ */ + GV * xio_top_gv; /* $^ */ + char * xio_fmt_name; /* $~ */ + GV * xio_fmt_gv; /* $~ */ + char * xio_bottom_name;/* $^B */ + GV * xio_bottom_gv; /* $^B */ + char xio_type; + U8 xio_flags; +}; + +#define xio_dirp xio_dirpu.xiou_dirp +#define xio_any xio_dirpu.xiou_any + +#define IOf_ARGV 1 /* this fp iterates over ARGV */ +#define IOf_START 2 /* check for null ARGV and substitute '-' */ +#define IOf_FLUSH 4 /* this fp wants a flush after write op */ +#define IOf_DIDTOP 8 /* just did top of form */ +#define IOf_UNTAINT 16 /* consider this fp (and its data) "safe" */ +#define IOf_NOLINE 32 /* slurped a pseudo-line from empty file */ +#define IOf_FAKE_DIRP 64 /* xio_dirp is fake (source filters kludge) + Also, when this is set, SvPVX() is valid */ + +/* The following macros define implementation-independent predicates on SVs. */ + +/* +=for apidoc Am|U32|SvNIOK|SV* sv +Returns a U32 value indicating whether the SV contains a number, integer or +double. + +=for apidoc Am|U32|SvNIOKp|SV* sv +Returns a U32 value indicating whether the SV contains a number, integer or +double. Checks the B<private> setting. Use C<SvNIOK> instead. + +=for apidoc Am|void|SvNIOK_off|SV* sv +Unsets the NV/IV status of an SV. + +=for apidoc Am|U32|SvOK|SV* sv +Returns a U32 value indicating whether the value is defined. This is +only meaningful for scalars. + +=for apidoc Am|U32|SvIOKp|SV* sv +Returns a U32 value indicating whether the SV contains an integer. Checks +the B<private> setting. Use C<SvIOK> instead. + +=for apidoc Am|U32|SvNOKp|SV* sv +Returns a U32 value indicating whether the SV contains a double. Checks the +B<private> setting. Use C<SvNOK> instead. + +=for apidoc Am|U32|SvPOKp|SV* sv +Returns a U32 value indicating whether the SV contains a character string. +Checks the B<private> setting. Use C<SvPOK> instead. + +=for apidoc Am|U32|SvIOK|SV* sv +Returns a U32 value indicating whether the SV contains an integer. + +=for apidoc Am|void|SvIOK_on|SV* sv +Tells an SV that it is an integer. + +=for apidoc Am|void|SvIOK_off|SV* sv +Unsets the IV status of an SV. + +=for apidoc Am|void|SvIOK_only|SV* sv +Tells an SV that it is an integer and disables all other OK bits. + +=for apidoc Am|void|SvIOK_only_UV|SV* sv +Tells an SV that it is an unsigned integer and disables all other OK bits. + +=for apidoc Am|bool|SvIOK_UV|SV* sv +Returns a boolean indicating whether the SV contains an integer that must be +interpreted as unsigned. A non-negative integer whose value is within the +range of both an IV and a UV may be be flagged as either SvUOK or SVIOK. + +=for apidoc Am|bool|SvUOK|SV* sv +Returns a boolean indicating whether the SV contains an integer that must be +interpreted as unsigned. A non-negative integer whose value is within the +range of both an IV and a UV may be be flagged as either SvUOK or SVIOK. + +=for apidoc Am|bool|SvIOK_notUV|SV* sv +Returns a boolean indicating whether the SV contains a signed integer. + +=for apidoc Am|U32|SvNOK|SV* sv +Returns a U32 value indicating whether the SV contains a double. + +=for apidoc Am|void|SvNOK_on|SV* sv +Tells an SV that it is a double. + +=for apidoc Am|void|SvNOK_off|SV* sv +Unsets the NV status of an SV. + +=for apidoc Am|void|SvNOK_only|SV* sv +Tells an SV that it is a double and disables all other OK bits. + +=for apidoc Am|U32|SvPOK|SV* sv +Returns a U32 value indicating whether the SV contains a character +string. + +=for apidoc Am|void|SvPOK_on|SV* sv +Tells an SV that it is a string. + +=for apidoc Am|void|SvPOK_off|SV* sv +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. +Will also turn off the UTF-8 status. + +=for apidoc Am|bool|SvVOK|SV* sv +Returns a boolean indicating whether the SV contains a v-string. + +=for apidoc Am|U32|SvOOK|SV* sv +Returns a U32 indicating whether the pointer to the string buffer is offset. +This hack is used internally to speed up removal of characters from the +beginning of a SvPV. When SvOOK is true, then the start of the +allocated string buffer is actually C<SvOOK_offset()> bytes before SvPVX. +This offset used to be stored in SvIVX, but is now stored within the spare +part of the buffer. + +=for apidoc Am|U32|SvROK|SV* sv +Tests if the SV is an RV. + +=for apidoc Am|void|SvROK_on|SV* sv +Tells an SV that it is an RV. + +=for apidoc Am|void|SvROK_off|SV* sv +Unsets the RV status of an SV. + +=for apidoc Am|SV*|SvRV|SV* sv +Dereferences an RV to return the SV. + +=for apidoc Am|IV|SvIVX|SV* sv +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 +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 +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 +Returns a pointer to the physical string in the SV. The SV must contain a +string. Prior to 5.9.3 it is not safe +to execute this macro unless the SV's +type >= SVt_PV. + +This is also used to store the name of an autoloaded subroutine in an XS +AUTOLOAD routine. See L<perlguts/Autoloading with XSUBs>. + +=for apidoc Am|STRLEN|SvCUR|SV* sv +Returns the length of the string which is in the SV. See C<SvLEN>. + +=for apidoc Am|STRLEN|SvLEN|SV* sv +Returns the size of the string buffer in the SV, not including any part +attributable to C<SvOOK>. See C<SvCUR>. + +=for apidoc Am|char*|SvEND|SV* sv +Returns a pointer to the spot just after the last character in +the string which is in the SV, where there is usually a trailing +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 +unallocated memory. + +=for apidoc Am|HV*|SvSTASH|SV* sv +Returns the stash of the SV. + +=for apidoc Am|void|SvIV_set|SV* sv|IV val +Set the value of the IV pointer in sv to val. It is possible to perform +the same function of this macro with an lvalue assignment to C<SvIVX>. +With future Perls, however, it will be more efficient to use +C<SvIV_set> instead of the lvalue assignment to C<SvIVX>. + +=for apidoc Am|void|SvNV_set|SV* sv|NV val +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 +This is probably not what you want to use, you probably wanted +L</sv_usepvn_flags> or L</sv_setpvn> or L</sv_setpvs>. + +Set the value of the PV pointer in C<sv> to the Perl allocated +C<NUL>-terminated string C<val>. See also C<SvIV_set>. + +Remember to free the previous PV buffer. There are many things to check. +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 +C<SvPV_force> (or check the SvIsCOW flag) first to make sure this +modification is safe. Then finally, if it is not a COW, call C<SvPV_free> to +free the previous PV buffer. + +=for apidoc Am|void|SvUV_set|SV* sv|UV val +Set the value of the UV pointer in sv to val. See C<SvIV_set>. + +=for apidoc Am|void|SvRV_set|SV* sv|SV* val +Set the value of the RV pointer in sv to val. See C<SvIV_set>. + +=for apidoc Am|void|SvMAGIC_set|SV* sv|MAGIC* val +Set the value of the MAGIC pointer in sv to val. See C<SvIV_set>. + +=for apidoc Am|void|SvSTASH_set|SV* sv|HV* val +Set the value of the STASH pointer in sv to val. See C<SvIV_set>. + +=for apidoc Am|void|SvCUR_set|SV* sv|STRLEN len +Set the current length of the string which is in the SV. See C<SvCUR> +and C<SvIV_set>. + +=for apidoc Am|void|SvLEN_set|SV* sv|STRLEN len +Set the size of the string buffer for the SV. See C</SvLEN>. + +=cut +*/ + +#define SvNIOK(sv) (SvFLAGS(sv) & (SVf_IOK|SVf_NOK)) +#define SvNIOKp(sv) (SvFLAGS(sv) & (SVp_IOK|SVp_NOK)) +#define SvNIOK_off(sv) (SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK| \ + SVp_IOK|SVp_NOK|SVf_IVisUV)) + +#define assert_not_ROK(sv) assert_(!SvROK(sv) || !SvRV(sv)) +#define assert_not_glob(sv) assert_(!isGV_with_GP(sv)) + +#define SvOK(sv) (SvFLAGS(sv) & SVf_OK || isREGEXP(sv)) +#define SvOK_off(sv) (assert_not_ROK(sv) assert_not_glob(sv) \ + SvFLAGS(sv) &= ~(SVf_OK| \ + SVf_IVisUV|SVf_UTF8), \ + SvOOK_off(sv)) +#define SvOK_off_exc_UV(sv) (assert_not_ROK(sv) \ + SvFLAGS(sv) &= ~(SVf_OK| \ + SVf_UTF8), \ + SvOOK_off(sv)) + +#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) \ + SvFLAGS(sv) |= SVp_IOK) +#define SvNOKp(sv) (SvFLAGS(sv) & SVp_NOK) +#define SvNOKp_on(sv) (assert_not_glob(sv) SvFLAGS(sv) |= SVp_NOK) +#define SvPOKp(sv) (SvFLAGS(sv) & SVp_POK) +#define SvPOKp_on(sv) (assert_not_ROK(sv) assert_not_glob(sv) \ + SvFLAGS(sv) |= SVp_POK) + +#define SvIOK(sv) (SvFLAGS(sv) & SVf_IOK) +#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), \ + SvFLAGS(sv) |= (SVf_IOK|SVp_IOK)) +#define SvIOK_only_UV(sv) (assert_not_glob(sv) SvOK_off_exc_UV(sv), \ + SvFLAGS(sv) |= (SVf_IOK|SVp_IOK)) + +#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 SvIsUV(sv) (SvFLAGS(sv) & SVf_IVisUV) +#define SvIsUV_on(sv) (SvFLAGS(sv) |= SVf_IVisUV) +#define SvIsUV_off(sv) (SvFLAGS(sv) &= ~SVf_IVisUV) + +#define SvNOK(sv) (SvFLAGS(sv) & SVf_NOK) +#define SvNOK_on(sv) (assert_not_glob(sv) \ + SvFLAGS(sv) |= (SVf_NOK|SVp_NOK)) +#define SvNOK_off(sv) (SvFLAGS(sv) &= ~(SVf_NOK|SVp_NOK)) +#define SvNOK_only(sv) (SvOK_off(sv), \ + SvFLAGS(sv) |= (SVf_NOK|SVp_NOK)) + +/* +=for apidoc Am|U32|SvUTF8|SV* sv +Returns a U32 value indicating the UTF-8 status of an SV. If things are set-up +properly, this indicates whether or not the SV contains UTF-8 encoded data. +You should use this I<after> a call to SvPV() or one of its variants, in +case any call to string overloading updates the internal flag. + +If you want to take into account the L<bytes> pragma, use C<L</DO_UTF8>> +instead. + +=for apidoc Am|void|SvUTF8_on|SV *sv +Turn on the UTF-8 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 UTF-8 status of an SV (the data is not changed, just the flag). +Do not use frivolously. + +=for apidoc Am|void|SvPOK_only_UTF8|SV* sv +Tells an SV that it is a string and disables all other OK bits, +and leaves the UTF-8 status as it was. + +=cut + */ + +/* Ensure the return value of this macro does not clash with the GV_ADD* flags +in gv.h: */ +#define SvUTF8(sv) (SvFLAGS(sv) & SVf_UTF8) +#define SvUTF8_on(sv) (SvFLAGS(sv) |= (SVf_UTF8)) +#define SvUTF8_off(sv) (SvFLAGS(sv) &= ~(SVf_UTF8)) + +#define SvPOK(sv) (SvFLAGS(sv) & SVf_POK) +#define SvPOK_on(sv) (assert_not_ROK(sv) assert_not_glob(sv) \ + SvFLAGS(sv) |= (SVf_POK|SVp_POK)) +#define SvPOK_off(sv) (SvFLAGS(sv) &= ~(SVf_POK|SVp_POK)) +#define SvPOK_only(sv) (assert_not_ROK(sv) assert_not_glob(sv) \ + SvFLAGS(sv) &= ~(SVf_OK| \ + SVf_IVisUV|SVf_UTF8), \ + SvFLAGS(sv) |= (SVf_POK|SVp_POK)) +#define SvPOK_only_UTF8(sv) (assert_not_ROK(sv) assert_not_glob(sv) \ + SvFLAGS(sv) &= ~(SVf_OK| \ + SVf_IVisUV), \ + SvFLAGS(sv) |= (SVf_POK|SVp_POK)) + +#define SvVOK(sv) (SvMAGICAL(sv) \ + && mg_find(sv,PERL_MAGIC_vstring)) +/* returns the vstring magic, if any */ +#define SvVSTRING_mg(sv) (SvMAGICAL(sv) \ + ? mg_find(sv,PERL_MAGIC_vstring) : NULL) + +#define SvOOK(sv) (SvFLAGS(sv) & SVf_OOK) +#define SvOOK_on(sv) (SvFLAGS(sv) |= SVf_OOK) +#define SvOOK_off(sv) ((void)(SvOOK(sv) && sv_backoff(sv))) + +#define SvFAKE(sv) (SvFLAGS(sv) & SVf_FAKE) +#define SvFAKE_on(sv) (SvFLAGS(sv) |= SVf_FAKE) +#define SvFAKE_off(sv) (SvFLAGS(sv) &= ~SVf_FAKE) + +#define SvROK(sv) (SvFLAGS(sv) & SVf_ROK) +#define SvROK_on(sv) (SvFLAGS(sv) |= SVf_ROK) +#define SvROK_off(sv) (SvFLAGS(sv) &= ~(SVf_ROK)) + +#define SvMAGICAL(sv) (SvFLAGS(sv) & (SVs_GMG|SVs_SMG|SVs_RMG)) +#define SvMAGICAL_on(sv) (SvFLAGS(sv) |= (SVs_GMG|SVs_SMG|SVs_RMG)) +#define SvMAGICAL_off(sv) (SvFLAGS(sv) &= ~(SVs_GMG|SVs_SMG|SVs_RMG)) + +#define SvGMAGICAL(sv) (SvFLAGS(sv) & SVs_GMG) +#define SvGMAGICAL_on(sv) (SvFLAGS(sv) |= SVs_GMG) +#define SvGMAGICAL_off(sv) (SvFLAGS(sv) &= ~SVs_GMG) + +#define SvSMAGICAL(sv) (SvFLAGS(sv) & SVs_SMG) +#define SvSMAGICAL_on(sv) (SvFLAGS(sv) |= SVs_SMG) +#define SvSMAGICAL_off(sv) (SvFLAGS(sv) &= ~SVs_SMG) + +#define SvRMAGICAL(sv) (SvFLAGS(sv) & SVs_RMG) +#define SvRMAGICAL_on(sv) (SvFLAGS(sv) |= SVs_RMG) +#define SvRMAGICAL_off(sv) (SvFLAGS(sv) &= ~SVs_RMG) + +#define SvAMAGIC(sv) (SvROK(sv) && SvOBJECT(SvRV(sv)) && \ + HvAMAGIC(SvSTASH(SvRV(sv)))) + +/* To be used on the stashes themselves: */ +#define HvAMAGIC(hv) (SvFLAGS(hv) & SVf_AMAGIC) +#define HvAMAGIC_on(hv) (SvFLAGS(hv) |= SVf_AMAGIC) +#define HvAMAGIC_off(hv) (SvFLAGS(hv) &=~ SVf_AMAGIC) + + +/* "nog" means "doesn't have get magic" */ +#define SvPOK_nog(sv) ((SvFLAGS(sv) & (SVf_POK|SVs_GMG)) == SVf_POK) +#define SvIOK_nog(sv) ((SvFLAGS(sv) & (SVf_IOK|SVs_GMG)) == SVf_IOK) +#define SvUOK_nog(sv) ((SvFLAGS(sv) & (SVf_IOK|SVf_IVisUV|SVs_GMG)) == (SVf_IOK|SVf_IVisUV)) +#define SvNOK_nog(sv) ((SvFLAGS(sv) & (SVf_NOK|SVs_GMG)) == SVf_NOK) +#define SvNIOK_nog(sv) (SvNIOK(sv) && !(SvFLAGS(sv) & SVs_GMG)) + +#define SvPOK_nogthink(sv) ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST|SVs_GMG)) == SVf_POK) +#define SvIOK_nogthink(sv) ((SvFLAGS(sv) & (SVf_IOK|SVf_THINKFIRST|SVs_GMG)) == SVf_IOK) +#define SvUOK_nogthink(sv) ((SvFLAGS(sv) & (SVf_IOK|SVf_IVisUV|SVf_THINKFIRST|SVs_GMG)) == (SVf_IOK|SVf_IVisUV)) +#define SvNOK_nogthink(sv) ((SvFLAGS(sv) & (SVf_NOK|SVf_THINKFIRST|SVs_GMG)) == SVf_NOK) +#define SvNIOK_nogthink(sv) (SvNIOK(sv) && !(SvFLAGS(sv) & (SVf_THINKFIRST|SVs_GMG))) + +#define SvPOK_utf8_nog(sv) ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVs_GMG)) == (SVf_POK|SVf_UTF8)) +#define SvPOK_utf8_nogthink(sv) ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVf_THINKFIRST|SVs_GMG)) == (SVf_POK|SVf_UTF8)) + +#define SvPOK_byte_nog(sv) ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVs_GMG)) == SVf_POK) +#define SvPOK_byte_nogthink(sv) ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVf_THINKFIRST|SVs_GMG)) == SVf_POK) + +#define SvPOK_pure_nogthink(sv) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_IOK|SVf_NOK|SVf_ROK|SVpgv_GP|SVf_THINKFIRST|SVs_GMG)) == SVf_POK) +#define SvPOK_utf8_pure_nogthink(sv) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVf_IOK|SVf_NOK|SVf_ROK|SVpgv_GP|SVf_THINKFIRST|SVs_GMG)) == (SVf_POK|SVf_UTF8)) +#define SvPOK_byte_pure_nogthink(sv) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVf_IOK|SVf_NOK|SVf_ROK|SVpgv_GP|SVf_THINKFIRST|SVs_GMG)) == SVf_POK) + +/* +=for apidoc Am|U32|SvGAMAGIC|SV* sv + +Returns true if the SV has get magic or +overloading. If either is true then +the scalar is active data, and has the potential to return a new value every +time it is accessed. Hence you must be careful to +only read it once per user logical operation and work +with that returned value. If neither is true then +the scalar's value cannot change unless written to. + +=cut +*/ + +#define SvGAMAGIC(sv) (SvGMAGICAL(sv) || SvAMAGIC(sv)) + +#define Gv_AMG(stash) \ + (HvNAME(stash) && Gv_AMupdate(stash,FALSE) \ + ? 1 \ + : (HvAMAGIC_off(stash), 0)) + +#define SvWEAKREF(sv) ((SvFLAGS(sv) & (SVf_ROK|SVprv_WEAKREF)) \ + == (SVf_ROK|SVprv_WEAKREF)) +#define SvWEAKREF_on(sv) (SvFLAGS(sv) |= (SVf_ROK|SVprv_WEAKREF)) +#define SvWEAKREF_off(sv) (SvFLAGS(sv) &= ~(SVf_ROK|SVprv_WEAKREF)) + +#define SvPCS_IMPORTED(sv) ((SvFLAGS(sv) & (SVf_ROK|SVprv_PCS_IMPORTED)) \ + == (SVf_ROK|SVprv_PCS_IMPORTED)) +#define SvPCS_IMPORTED_on(sv) (SvFLAGS(sv) |= (SVf_ROK|SVprv_PCS_IMPORTED)) +#define SvPCS_IMPORTED_off(sv) (SvFLAGS(sv) &= ~(SVf_ROK|SVprv_PCS_IMPORTED)) + +/* +=for apidoc m|U32|SvTHINKFIRST|SV *sv + +A quick flag check to see whether an sv should be passed to sv_force_normal +to be "downgraded" before SvIVX or SvPVX can be modified directly. + +For example, if your scalar is a reference and you want to modify the SvIVX +slot, you can't just do SvROK_off, as that will leak the referent. + +This is used internally by various sv-modifying functions, such as +sv_setsv, sv_setiv and sv_pvn_force. + +One case that this does not handle is a gv without SvFAKE set. After + + if (SvTHINKFIRST(gv)) sv_force_normal(gv); + +it will still be a gv. + +SvTHINKFIRST sometimes produces false positives. In those cases +sv_force_normal does nothing. + +=cut +*/ + +#define SvTHINKFIRST(sv) (SvFLAGS(sv) & SVf_THINKFIRST) + +#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_PADTMP)) +#define SvPADSTALE(sv) (SvFLAGS(sv) & (SVs_PADSTALE)) + +#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 SvTEMP(sv) (SvFLAGS(sv) & SVs_TEMP) +#define SvTEMP_on(sv) (SvFLAGS(sv) |= SVs_TEMP) +#define SvTEMP_off(sv) (SvFLAGS(sv) &= ~SVs_TEMP) + +#define SvOBJECT(sv) (SvFLAGS(sv) & SVs_OBJECT) +#define SvOBJECT_on(sv) (SvFLAGS(sv) |= SVs_OBJECT) +#define SvOBJECT_off(sv) (SvFLAGS(sv) &= ~SVs_OBJECT) + +#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 SvSCREAM_off(sv) (SvFLAGS(sv) &= ~SVp_SCREAM) + +#ifndef PERL_CORE +# define SvCOMPILED(sv) 0 +# define SvCOMPILED_on(sv) +# define SvCOMPILED_off(sv) +#endif + +#define SvEVALED(sv) (SvFLAGS(sv) & SVrepl_EVAL) +#define SvEVALED_on(sv) (SvFLAGS(sv) |= SVrepl_EVAL) +#define SvEVALED_off(sv) (SvFLAGS(sv) &= ~SVrepl_EVAL) + +#if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) +# define SvVALID(sv) ({ const SV *const _svvalid = (const SV*)(sv); \ + if (SvFLAGS(_svvalid) & SVpbm_VALID && !SvSCREAM(_svvalid)) \ + assert(!isGV_with_GP(_svvalid)); \ + (SvFLAGS(_svvalid) & SVpbm_VALID); \ + }) +# define SvVALID_on(sv) ({ SV *const _svvalid = MUTABLE_SV(sv); \ + assert(!isGV_with_GP(_svvalid)); \ + assert(!SvSCREAM(_svvalid)); \ + (SvFLAGS(_svvalid) |= SVpbm_VALID); \ + }) +# define SvVALID_off(sv) ({ SV *const _svvalid = MUTABLE_SV(sv); \ + assert(!isGV_with_GP(_svvalid)); \ + assert(!SvSCREAM(_svvalid)); \ + (SvFLAGS(_svvalid) &= ~SVpbm_VALID); \ + }) + +# define SvTAIL(sv) ({ const SV *const _svtail = (const SV *)(sv); \ + assert(SvTYPE(_svtail) != SVt_PVAV); \ + assert(SvTYPE(_svtail) != SVt_PVHV); \ + assert(!SvSCREAM(_svtail)); \ + (SvFLAGS(sv) & (SVpbm_TAIL|SVpbm_VALID)) \ + == (SVpbm_TAIL|SVpbm_VALID); \ + }) +#else +# define SvVALID(sv) ((SvFLAGS(sv) & SVpbm_VALID) && !SvSCREAM(sv)) +# define SvVALID_on(sv) (SvFLAGS(sv) |= SVpbm_VALID) +# define SvVALID_off(sv) (SvFLAGS(sv) &= ~SVpbm_VALID) +# define SvTAIL(sv) ((SvFLAGS(sv) & (SVpbm_TAIL|SVpbm_VALID)) \ + == (SVpbm_TAIL|SVpbm_VALID)) + +#endif +#define SvTAIL_on(sv) (SvFLAGS(sv) |= SVpbm_TAIL) +#define SvTAIL_off(sv) (SvFLAGS(sv) &= ~SVpbm_TAIL) + +#define SvRVx(sv) SvRV(sv) + +#ifdef PERL_DEBUG_COW +/* Need -0.0 for SvNVX to preserve IEEE FP "negative zero" because + +0.0 + -0.0 => +0.0 but -0.0 + -0.0 => -0.0 */ +# define SvIVX(sv) (0 + ((XPVIV*) SvANY(sv))->xiv_iv) +# define SvUVX(sv) (0 + ((XPVUV*) SvANY(sv))->xuv_uv) +# define SvNVX(sv) (-0.0 + ((XPVNV*) SvANY(sv))->xnv_u.xnv_nv) +# define SvRV(sv) (0 + (sv)->sv_u.svu_rv) +# define SvRV_const(sv) (0 + (sv)->sv_u.svu_rv) +/* Don't test the core XS code yet. */ +# if defined (PERL_CORE) && PERL_DEBUG_COW > 1 +# define SvPVX(sv) (0 + (assert_(!SvREADONLY(sv)) (sv)->sv_u.svu_pv)) +# else +# define SvPVX(sv) SvPVX_mutable(sv) +# endif +# define SvCUR(sv) (0 + ((XPV*) SvANY(sv))->xpv_cur) +# define SvLEN(sv) (0 + ((XPV*) SvANY(sv))->xpv_len) +# define SvEND(sv) ((sv)->sv_u.svu_pv + ((XPV*)SvANY(sv))->xpv_cur) + +# define SvMAGIC(sv) (0 + *(assert_(SvTYPE(sv) >= SVt_PVMG) &((XPVMG*) SvANY(sv))->xmg_u.xmg_magic)) +# define SvSTASH(sv) (0 + *(assert_(SvTYPE(sv) >= SVt_PVMG) &((XPVMG*) SvANY(sv))->xmg_stash)) +#else +# define SvLEN(sv) ((XPV*) SvANY(sv))->xpv_len +# define SvEND(sv) ((sv)->sv_u.svu_pv + ((XPV*)SvANY(sv))->xpv_cur) + +# if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) +/* These get expanded inside other macros that already use a variable _sv */ +# define SvPVX(sv) \ + (*({ SV *const _svpvx = MUTABLE_SV(sv); \ + assert(PL_valid_types_PVX[SvTYPE(_svpvx) & SVt_MASK]); \ + assert(!isGV_with_GP(_svpvx)); \ + assert(!(SvTYPE(_svpvx) == SVt_PVIO \ + && !(IoFLAGS(_svpvx) & IOf_FAKE_DIRP))); \ + &((_svpvx)->sv_u.svu_pv); \ + })) +# define SvCUR(sv) \ + (*({ const SV *const _svcur = (const SV *)(sv); \ + assert(PL_valid_types_PVX[SvTYPE(_svcur) & SVt_MASK] \ + || SvTYPE(_svcur) == SVt_REGEXP); \ + assert(!isGV_with_GP(_svcur)); \ + assert(!(SvTYPE(_svcur) == SVt_PVIO \ + && !(IoFLAGS(_svcur) & IOf_FAKE_DIRP))); \ + &(((XPV*) MUTABLE_PTR(SvANY(_svcur)))->xpv_cur); \ + })) +# define SvIVX(sv) \ + (*({ const SV *const _svivx = (const SV *)(sv); \ + assert(PL_valid_types_IVX[SvTYPE(_svivx) & SVt_MASK]); \ + assert(!isGV_with_GP(_svivx)); \ + &(((XPVIV*) MUTABLE_PTR(SvANY(_svivx)))->xiv_iv); \ + })) +# define SvUVX(sv) \ + (*({ const SV *const _svuvx = (const SV *)(sv); \ + assert(PL_valid_types_IVX[SvTYPE(_svuvx) & SVt_MASK]); \ + assert(!isGV_with_GP(_svuvx)); \ + &(((XPVUV*) MUTABLE_PTR(SvANY(_svuvx)))->xuv_uv); \ + })) +# define SvNVX(sv) \ + (*({ const SV *const _svnvx = (const SV *)(sv); \ + assert(PL_valid_types_NVX[SvTYPE(_svnvx) & SVt_MASK]); \ + assert(!isGV_with_GP(_svnvx)); \ + &(((XPVNV*) MUTABLE_PTR(SvANY(_svnvx)))->xnv_u.xnv_nv); \ + })) +# define SvRV(sv) \ + (*({ SV *const _svrv = MUTABLE_SV(sv); \ + assert(PL_valid_types_RV[SvTYPE(_svrv) & SVt_MASK]); \ + assert(!isGV_with_GP(_svrv)); \ + assert(!(SvTYPE(_svrv) == SVt_PVIO \ + && !(IoFLAGS(_svrv) & IOf_FAKE_DIRP))); \ + &((_svrv)->sv_u.svu_rv); \ + })) +# define SvRV_const(sv) \ + ({ const SV *const _svrv = (const SV *)(sv); \ + assert(PL_valid_types_RV[SvTYPE(_svrv) & SVt_MASK]); \ + assert(!isGV_with_GP(_svrv)); \ + assert(!(SvTYPE(_svrv) == SVt_PVIO \ + && !(IoFLAGS(_svrv) & IOf_FAKE_DIRP))); \ + (_svrv)->sv_u.svu_rv; \ + }) +# define SvMAGIC(sv) \ + (*({ const SV *const _svmagic = (const SV *)(sv); \ + assert(SvTYPE(_svmagic) >= SVt_PVMG); \ + &(((XPVMG*) MUTABLE_PTR(SvANY(_svmagic)))->xmg_u.xmg_magic); \ + })) +# define SvSTASH(sv) \ + (*({ const SV *const _svstash = (const SV *)(sv); \ + assert(SvTYPE(_svstash) >= SVt_PVMG); \ + &(((XPVMG*) MUTABLE_PTR(SvANY(_svstash)))->xmg_stash); \ + })) +# else +# define SvPVX(sv) ((sv)->sv_u.svu_pv) +# define SvCUR(sv) ((XPV*) SvANY(sv))->xpv_cur +# define SvIVX(sv) ((XPVIV*) SvANY(sv))->xiv_iv +# define SvUVX(sv) ((XPVUV*) SvANY(sv))->xuv_uv +# define SvNVX(sv) ((XPVNV*) SvANY(sv))->xnv_u.xnv_nv +# define SvRV(sv) ((sv)->sv_u.svu_rv) +# define SvRV_const(sv) (0 + (sv)->sv_u.svu_rv) +# define SvMAGIC(sv) ((XPVMG*) SvANY(sv))->xmg_u.xmg_magic +# define SvSTASH(sv) ((XPVMG*) SvANY(sv))->xmg_stash +# endif +#endif + +#ifndef PERL_POISON +/* Given that these two are new, there can't be any existing code using them + * as LVALUEs */ +# define SvPVX_mutable(sv) (0 + (sv)->sv_u.svu_pv) +# define SvPVX_const(sv) ((const char*)(0 + (sv)->sv_u.svu_pv)) +#else +/* Except for the poison code, which uses & to scribble over the pointer after + free() is called. */ +# define SvPVX_mutable(sv) ((sv)->sv_u.svu_pv) +# define SvPVX_const(sv) ((const char*)((sv)->sv_u.svu_pv)) +#endif + +#define SvIVXx(sv) SvIVX(sv) +#define SvUVXx(sv) SvUVX(sv) +#define SvNVXx(sv) SvNVX(sv) +#define SvPVXx(sv) SvPVX(sv) +#define SvLENx(sv) SvLEN(sv) +#define SvENDx(sv) ((PL_Sv = (sv)), SvEND(PL_Sv)) + + +/* 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) && (SvFLAGS(sv) & (SVf_NOK|SVf_POK))) \ + (void) SvIV(sv); } STMT_END +#define SvIV_please_nomg(sv) \ + (!(SvFLAGS(sv) & (SVf_IOK|SVp_IOK)) && (SvFLAGS(sv) & (SVf_NOK|SVf_POK)) \ + ? (sv_2iv_flags(sv, 0), SvIOK(sv)) \ + : SvIOK(sv)) +#define SvIV_set(sv, val) \ + STMT_START { \ + assert(PL_valid_types_IV_set[SvTYPE(sv) & SVt_MASK]); \ + assert(!isGV_with_GP(sv)); \ + (((XPVIV*) SvANY(sv))->xiv_iv = (val)); } STMT_END +#define SvNV_set(sv, val) \ + STMT_START { \ + assert(PL_valid_types_NV_set[SvTYPE(sv) & SVt_MASK]); \ + assert(!isGV_with_GP(sv)); \ + (((XPVNV*)SvANY(sv))->xnv_u.xnv_nv = (val)); } STMT_END +#define SvPV_set(sv, val) \ + STMT_START { \ + assert(PL_valid_types_PVX[SvTYPE(sv) & SVt_MASK]); \ + assert(!isGV_with_GP(sv)); \ + assert(!(SvTYPE(sv) == SVt_PVIO \ + && !(IoFLAGS(sv) & IOf_FAKE_DIRP))); \ + ((sv)->sv_u.svu_pv = (val)); } STMT_END +#define SvUV_set(sv, val) \ + STMT_START { \ + assert(PL_valid_types_IV_set[SvTYPE(sv) & SVt_MASK]); \ + assert(!isGV_with_GP(sv)); \ + (((XPVUV*)SvANY(sv))->xuv_uv = (val)); } STMT_END +#define SvRV_set(sv, val) \ + STMT_START { \ + assert(PL_valid_types_RV[SvTYPE(sv) & SVt_MASK]); \ + assert(!isGV_with_GP(sv)); \ + assert(!(SvTYPE(sv) == SVt_PVIO \ + && !(IoFLAGS(sv) & IOf_FAKE_DIRP))); \ + ((sv)->sv_u.svu_rv = (val)); } STMT_END +#define SvMAGIC_set(sv, val) \ + STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \ + (((XPVMG*)SvANY(sv))->xmg_u.xmg_magic = (val)); } STMT_END +#define SvSTASH_set(sv, val) \ + STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \ + (((XPVMG*) SvANY(sv))->xmg_stash = (val)); } STMT_END +#define SvCUR_set(sv, val) \ + STMT_START { \ + assert(PL_valid_types_PVX[SvTYPE(sv) & SVt_MASK] \ + || SvTYPE(sv) == SVt_REGEXP); \ + assert(!isGV_with_GP(sv)); \ + assert(!(SvTYPE(sv) == SVt_PVIO \ + && !(IoFLAGS(sv) & IOf_FAKE_DIRP))); \ + (((XPV*) SvANY(sv))->xpv_cur = (val)); } STMT_END +#define SvLEN_set(sv, val) \ + STMT_START { \ + assert(PL_valid_types_PVX[SvTYPE(sv) & SVt_MASK]); \ + assert(!isGV_with_GP(sv)); \ + assert(!(SvTYPE(sv) == SVt_PVIO \ + && !(IoFLAGS(sv) & IOf_FAKE_DIRP))); \ + (((XPV*) SvANY(sv))->xpv_len = (val)); } STMT_END +#define SvEND_set(sv, val) \ + STMT_START { assert(SvTYPE(sv) >= SVt_PV); \ + SvCUR_set(sv, (val) - SvPVX(sv)); } STMT_END + +#define SvPV_renew(sv,n) \ + STMT_START { SvLEN_set(sv, n); \ + SvPV_set((sv), (MEM_WRAP_CHECK_(n,char) \ + (char*)saferealloc((Malloc_t)SvPVX(sv), \ + (MEM_SIZE)((n))))); \ + } STMT_END + +#define SvPV_shrink_to_cur(sv) STMT_START { \ + const STRLEN _lEnGtH = SvCUR(sv) + 1; \ + SvPV_renew(sv, _lEnGtH); \ + } STMT_END + +#define SvPV_free(sv) \ + STMT_START { \ + assert(SvTYPE(sv) >= SVt_PV); \ + if (SvLEN(sv)) { \ + assert(!SvROK(sv)); \ + if(UNLIKELY(SvOOK(sv))) { \ + STRLEN zok; \ + SvOOK_offset(sv, zok); \ + SvPV_set(sv, SvPVX_mutable(sv) - zok); \ + 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 + +#ifndef PERL_CORE +# define BmFLAGS(sv) (SvTAIL(sv) ? FBMcf_TAIL : 0) +#endif + +#if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) +# define BmUSEFUL(sv) \ + (*({ SV *const _bmuseful = MUTABLE_SV(sv); \ + assert(SvTYPE(_bmuseful) >= SVt_PVIV); \ + assert(SvVALID(_bmuseful)); \ + assert(!SvIOK(_bmuseful)); \ + &(((XPVIV*) SvANY(_bmuseful))->xiv_u.xivu_iv); \ + })) +#else +# define BmUSEFUL(sv) ((XPVIV*) SvANY(sv))->xiv_u.xivu_iv + +#endif + +#ifndef PERL_CORE +# define BmRARE(sv) 0 +# define BmPREVIOUS(sv) 0 +#endif + +#define FmLINES(sv) ((XPVIV*) SvANY(sv))->xiv_iv + +#define LvTYPE(sv) ((XPVLV*) SvANY(sv))->xlv_type +#define LvTARG(sv) ((XPVLV*) SvANY(sv))->xlv_targ +#define LvTARGOFF(sv) ((XPVLV*) SvANY(sv))->xlv_targoff +#define LvSTARGOFF(sv) ((XPVLV*) SvANY(sv))->xlv_targoff_u.xlvu_stargoff +#define LvTARGLEN(sv) ((XPVLV*) SvANY(sv))->xlv_targlen +#define LvFLAGS(sv) ((XPVLV*) SvANY(sv))->xlv_flags + +#define IoIFP(sv) (sv)->sv_u.svu_fp +#define IoOFP(sv) ((XPVIO*) SvANY(sv))->xio_ofp +#define IoDIRP(sv) ((XPVIO*) SvANY(sv))->xio_dirp +#define IoANY(sv) ((XPVIO*) SvANY(sv))->xio_any +#define IoLINES(sv) ((XPVIO*) SvANY(sv))->xiv_u.xivu_iv +#define IoPAGE(sv) ((XPVIO*) SvANY(sv))->xio_page +#define IoPAGE_LEN(sv) ((XPVIO*) SvANY(sv))->xio_page_len +#define IoLINES_LEFT(sv)((XPVIO*) SvANY(sv))->xio_lines_left +#define IoTOP_NAME(sv) ((XPVIO*) SvANY(sv))->xio_top_name +#define IoTOP_GV(sv) ((XPVIO*) SvANY(sv))->xio_top_gv +#define IoFMT_NAME(sv) ((XPVIO*) SvANY(sv))->xio_fmt_name +#define IoFMT_GV(sv) ((XPVIO*) SvANY(sv))->xio_fmt_gv +#define IoBOTTOM_NAME(sv)((XPVIO*) SvANY(sv))->xio_bottom_name +#define IoBOTTOM_GV(sv) ((XPVIO*) SvANY(sv))->xio_bottom_gv +#define IoTYPE(sv) ((XPVIO*) SvANY(sv))->xio_type +#define IoFLAGS(sv) ((XPVIO*) SvANY(sv))->xio_flags + +/* IoTYPE(sv) is a single character telling the type of I/O connection. */ +#define IoTYPE_RDONLY '<' +#define IoTYPE_WRONLY '>' +#define IoTYPE_RDWR '+' +#define IoTYPE_APPEND 'a' +#define IoTYPE_PIPE '|' +#define IoTYPE_STD '-' /* stdin or stdout */ +#define IoTYPE_SOCKET 's' +#define IoTYPE_CLOSED ' ' +#define IoTYPE_IMPLICIT 'I' /* stdin or stdout or stderr */ +#define IoTYPE_NUMERIC '#' /* fdopen */ + +/* +=for apidoc Am|bool|SvTAINTED|SV* sv +Checks to see if an SV is tainted. Returns TRUE if it is, FALSE if +not. + +=for apidoc Am|void|SvTAINTED_on|SV* sv +Marks an SV as tainted if tainting is enabled. + +=for apidoc Am|void|SvTAINTED_off|SV* sv +Untaints an SV. Be I<very> careful with this routine, as it short-circuits +some of Perl's fundamental security features. XS module authors should not +use this function unless they fully understand all the implications of +unconditionally untainting the value. Untainting should be done in the +standard perl fashion, via a carefully crafted regexp, rather than directly +untainting variables. + +=for apidoc Am|void|SvTAINT|SV* sv +Taints an SV if tainting is enabled, and if some input to the current +expression is tainted--usually a variable, but possibly also implicit +inputs such as locale settings. C<SvTAINT> propagates that taintedness to +the outputs of an expression in a pessimistic fashion; i.e., without paying +attention to precisely which outputs are influenced by which inputs. + +=cut +*/ + +#define sv_taint(sv) sv_magic((sv), NULL, PERL_MAGIC_taint, NULL, 0) + +#ifdef NO_TAINT_SUPPORT +# define SvTAINTED(sv) 0 +#else +# define SvTAINTED(sv) (SvMAGICAL(sv) && sv_tainted(sv)) +#endif +#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 (UNLIKELY(TAINTING_get)) { \ + if (UNLIKELY(TAINT_get)) \ + SvTAINTED_on(sv); \ + } \ + } STMT_END + +/* +=for apidoc Am|char*|SvPV_force|SV* sv|STRLEN len +Like C<SvPV> but will force the SV into containing a string (C<SvPOK>), and +only a string (C<SvPOK_only>), by hook or by crook. You need force if you are +going to update the C<SvPVX> directly. Processes get magic. + +Note that coercing an arbitrary scalar into a plain PV will potentially +strip useful data from it. For example if the SV was C<SvROK>, then the +referent will have its reference count decremented, and the SV itself may +be converted to an C<SvPOK> scalar with a string buffer containing a value +such as C<"ARRAY(0x1234)">. + +=for apidoc Am|char*|SvPV_force_nomg|SV* sv|STRLEN len +Like C<SvPV_force>, but doesn't process get 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. The SV may cache the +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 +successive calls to C<SvPV(sv)> will return the same pointer value each +time. This is due to the way that things like overloading and +Copy-On-Write are handled. In these cases, the return value may point to +a temporary buffer or similar. If you absolutely need the SvPVX field to +be valid (for example, if you intend to write to it), then see +L</SvPV_force>. + +=for apidoc Am|char*|SvPVx|SV* sv|STRLEN len +A version of C<SvPV> which guarantees to evaluate C<sv> only once. +Only use this if C<sv> is an expression with side effects, otherwise use the +more efficient C<SvPV>. + +=for apidoc Am|char*|SvPV_nomg|SV* sv|STRLEN len +Like C<SvPV> but doesn't process magic. + +=for apidoc Am|char*|SvPV_nolen|SV* sv +Like C<SvPV> but doesn't set a length variable. + +=for apidoc Am|char*|SvPV_nomg_nolen|SV* sv +Like C<SvPV_nolen> but doesn't process magic. + +=for apidoc Am|IV|SvIV|SV* sv +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|SvIV_nomg|SV* sv +Like C<SvIV> but doesn't process magic. + +=for apidoc Am|IV|SvIVx|SV* sv +Coerces the given SV to an integer and returns it. +Guarantees to evaluate C<sv> only once. Only use +this if C<sv> is an expression with side effects, +otherwise use the more efficient C<SvIV>. + +=for apidoc Am|NV|SvNV|SV* sv +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|SvNV_nomg|SV* sv +Like C<SvNV> but doesn't process magic. + +=for apidoc Am|NV|SvNVx|SV* sv +Coerces the given SV to a double and returns it. +Guarantees to evaluate C<sv> only once. Only use +this if C<sv> is an expression with side effects, +otherwise use the more efficient C<SvNV>. + +=for apidoc Am|UV|SvUV|SV* sv +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|SvUV_nomg|SV* sv +Like C<SvUV> but doesn't process magic. + +=for apidoc Am|UV|SvUVx|SV* sv +Coerces the given SV to an unsigned integer and +returns it. Guarantees to evaluate C<sv> only once. Only +use this if C<sv> is an expression with side effects, +otherwise use the more efficient C<SvUV>. + +=for apidoc Am|bool|SvTRUE|SV* sv +Returns a boolean indicating whether Perl would evaluate the SV as true or +false. See SvOK() for a defined/undefined test. Handles 'get' magic +unless the scalar is already SvPOK, SvIOK or SvNOK (the public, not the +private flags). + +=for apidoc Am|bool|SvTRUE_nomg|SV* sv +Returns a boolean indicating whether Perl would evaluate the SV as true or +false. See SvOK() for a defined/undefined test. Does not handle 'get' magic. + +=for apidoc Am|char*|SvPVutf8_force|SV* sv|STRLEN len +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 utf8 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. + +=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. + +=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. + +=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. + +=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. + +=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. + +=for apidoc Am|U32|SvIsCOW|SV* sv +Returns a U32 value indicating whether the SV is Copy-On-Write (either shared +hash key scalars, or full Copy On Write scalars if 5.9.0 is configured for +COW). + +=for apidoc Am|bool|SvIsCOW_shared_hash|SV* sv +Returns a boolean indicating whether the SV is Copy-On-Write shared hash key +scalar. + +=for apidoc Am|void|sv_catpvn_nomg|SV* sv|const char* ptr|STRLEN len +Like C<sv_catpvn> but doesn't process magic. + +=for apidoc Am|void|sv_catpv_nomg|SV* sv|const char* ptr +Like C<sv_catpv> but doesn't process magic. + +=for apidoc Am|void|sv_setsv_nomg|SV* dsv|SV* ssv +Like C<sv_setsv> but doesn't process magic. + +=for apidoc Am|void|sv_catsv_nomg|SV* dsv|SV* ssv +Like C<sv_catsv> but doesn't process magic. + +=for apidoc Amdb|STRLEN|sv_utf8_upgrade_nomg|NN SV *sv + +Like sv_utf8_upgrade, but doesn't do magic on C<sv>. + +=cut +*/ + +/* Let us hope that bitmaps for UV and IV are the same */ +#define SvIV(sv) (SvIOK_nog(sv) ? SvIVX(sv) : sv_2iv(sv)) +#define SvUV(sv) (SvUOK_nog(sv) ? SvUVX(sv) : sv_2uv(sv)) +#define SvNV(sv) (SvNOK_nog(sv) ? SvNVX(sv) : sv_2nv(sv)) + +#define SvIV_nomg(sv) (SvIOK(sv) ? SvIVX(sv) : sv_2iv_flags(sv, 0)) +#define SvUV_nomg(sv) (SvIOK(sv) ? SvUVX(sv) : sv_2uv_flags(sv, 0)) +#define SvNV_nomg(sv) (SvNOK(sv) ? SvNVX(sv) : sv_2nv_flags(sv, 0)) + +/* ----*/ + +#define SvPV(sv, lp) SvPV_flags(sv, lp, SV_GMAGIC) +#define SvPV_const(sv, lp) SvPV_flags_const(sv, lp, SV_GMAGIC) +#define SvPV_mutable(sv, lp) SvPV_flags_mutable(sv, lp, SV_GMAGIC) + +#define SvPV_flags(sv, lp, flags) \ + (SvPOK_nog(sv) \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv_flags(sv, &lp, flags)) +#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))) +#define SvPV_flags_const_nolen(sv, flags) \ + (SvPOK_nog(sv) \ + ? SvPVX_const(sv) : \ + (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))) + +#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 SvPV_force_mutable(sv, lp) SvPV_force_flags_mutable(sv, lp, SV_GMAGIC) + +#define SvPV_force_nomg(sv, lp) SvPV_force_flags(sv, lp, 0) +#define SvPV_force_nomg_nolen(sv) SvPV_force_flags_nolen(sv, 0) + +#define SvPV_force_flags(sv, lp, flags) \ + (SvPOK_pure_nogthink(sv) \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvn_force_flags(sv, &lp, flags)) + +#define SvPV_force_flags_nolen(sv, flags) \ + (SvPOK_pure_nogthink(sv) \ + ? SvPVX(sv) : sv_pvn_force_flags(sv, 0, flags)) + +#define SvPV_force_flags_mutable(sv, lp, flags) \ + (SvPOK_pure_nogthink(sv) \ + ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) \ + : sv_pvn_force_flags(sv, &lp, flags|SV_MUTABLE_RETURN)) + +#define SvPV_nolen(sv) \ + (SvPOK_nog(sv) \ + ? SvPVX(sv) : sv_2pv_flags(sv, 0, SV_GMAGIC)) + +/* "_nomg" in these defines means no mg_get() */ +#define SvPV_nomg_nolen(sv) \ + (SvPOK_nog(sv) \ + ? SvPVX(sv) : sv_2pv_flags(sv, 0, 0)) + +#define SvPV_nolen_const(sv) \ + (SvPOK_nog(sv) \ + ? SvPVX_const(sv) : sv_2pv_flags(sv, 0, SV_GMAGIC|SV_CONST_RETURN)) + +#define SvPV_nomg(sv, lp) SvPV_flags(sv, lp, 0) +#define SvPV_nomg_const(sv, lp) SvPV_flags_const(sv, lp, 0) +#define SvPV_nomg_const_nolen(sv) SvPV_flags_const_nolen(sv, 0) + +/* ----*/ + +#define SvPVutf8(sv, lp) \ + (SvPOK_utf8_nog(sv) \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvutf8(sv, &lp)) + +#define SvPVutf8_force(sv, lp) \ + (SvPOK_utf8_pure_nogthink(sv) \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvutf8n_force(sv, &lp)) + +#define SvPVutf8_nolen(sv) \ + (SvPOK_utf8_nog(sv) \ + ? SvPVX(sv) : sv_2pvutf8(sv, 0)) + +/* ----*/ + +#define SvPVbyte(sv, lp) \ + (SvPOK_byte_nog(sv) \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvbyte(sv, &lp)) + +#define SvPVbyte_force(sv, lp) \ + (SvPOK_byte_pure_nogthink(sv) \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvbyten_force(sv, &lp)) + +#define SvPVbyte_nolen(sv) \ + (SvPOK_byte_nog(sv) \ + ? SvPVX(sv) : sv_2pvbyte(sv, 0)) + + +/* 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) + +#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) \ + ? 0 \ + : SvPOK(sv) \ + ? SvPVXtrue(sv) \ + : (SvFLAGS(sv) & (SVf_IOK|SVf_NOK)) \ + ? ( (SvIOK(sv) && SvIVX(sv) != 0) \ + || (SvNOK(sv) && SvNVX(sv) != 0.0)) \ + : (fallback)) + +#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) + +# define SvIVx(sv) ({SV *_sv = MUTABLE_SV(sv); SvIV(_sv); }) +# define SvUVx(sv) ({SV *_sv = MUTABLE_SV(sv); SvUV(_sv); }) +# define SvNVx(sv) ({SV *_sv = MUTABLE_SV(sv); SvNV(_sv); }) +# define SvPVx(sv, lp) ({SV *_sv = (sv); SvPV(_sv, lp); }) +# define SvPVx_const(sv, lp) ({SV *_sv = (sv); SvPV_const(_sv, lp); }) +# define SvPVx_nolen(sv) ({SV *_sv = (sv); SvPV_nolen(_sv); }) +# define SvPVx_nolen_const(sv) ({SV *_sv = (sv); SvPV_nolen_const(_sv); }) +# define SvPVutf8x(sv, lp) ({SV *_sv = (sv); SvPVutf8(_sv, lp); }) +# define SvPVbytex(sv, lp) ({SV *_sv = (sv); SvPVbyte(_sv, lp); }) +# define SvPVbytex_nolen(sv) ({SV *_sv = (sv); SvPVbyte_nolen(_sv); }) +# define SvTRUEx(sv) ({SV *_sv = (sv); SvTRUE(_sv); }) +# define SvTRUEx_nomg(sv) ({SV *_sv = (sv); SvTRUE_nomg(_sv); }) + +#else /* __GNUC__ */ + +/* These inlined macros use globals, which will require a thread + * declaration in user code, so we avoid them under threads */ + +# 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 SvPVx_const(sv, lp) ((PL_Sv = (sv)), SvPV_const(PL_Sv, lp)) +# define SvPVx_nolen(sv) ((PL_Sv = (sv)), SvPV_nolen(PL_Sv)) +# define SvPVx_nolen_const(sv) ((PL_Sv = (sv)), SvPV_nolen_const(PL_Sv)) +# define SvPVutf8x(sv, lp) ((PL_Sv = (sv)), SvPVutf8(PL_Sv, lp)) +# define SvPVbytex(sv, lp) ((PL_Sv = (sv)), SvPVbyte(PL_Sv, lp)) +# define SvPVbytex_nolen(sv) ((PL_Sv = (sv)), SvPVbyte_nolen(PL_Sv)) +# define SvTRUEx(sv) ((PL_Sv = (sv)), SvTRUE(PL_Sv)) +# define SvTRUEx_nomg(sv) ((PL_Sv = (sv)), SvTRUE_nomg(PL_Sv)) +#endif /* __GNU__ */ + +#define SvPVXtrue(sv) ( \ + ((XPV*)SvANY((sv))) \ + && ( \ + ((XPV*)SvANY((sv)))->xpv_cur > 1 \ + || ( \ + ((XPV*)SvANY((sv)))->xpv_cur \ + && *(sv)->sv_u.svu_pv != '0' \ + ) \ + ) \ +) + +#define SvIsCOW(sv) (SvFLAGS(sv) & SVf_IsCOW) +#define SvIsCOW_on(sv) (SvFLAGS(sv) |= SVf_IsCOW) +#define SvIsCOW_off(sv) (SvFLAGS(sv) &= ~SVf_IsCOW) +#define SvIsCOW_shared_hash(sv) (SvIsCOW(sv) && SvLEN(sv) == 0) + +#define SvSHARED_HEK_FROM_PV(pvx) \ + ((struct hek*)(pvx - STRUCT_OFFSET(struct hek, hek_key))) +#define SvSHARED_HASH(sv) (0 + SvSHARED_HEK_FROM_PV(SvPVX_const(sv))->hek_hash) + +/* flag values for sv_*_flags functions */ +#define SV_IMMEDIATE_UNREF 1 +#define SV_GMAGIC 2 +#define SV_COW_DROP_PV 4 +#define SV_UTF8_NO_ENCODING 8 +#define SV_NOSTEAL 16 +#define SV_CONST_RETURN 32 +#define SV_MUTABLE_RETURN 64 +#define SV_SMAGIC 128 +#define SV_HAS_TRAILING_NUL 256 +#define SV_COW_SHARED_HASH_KEYS 512 +/* This one is only enabled for PERL_OLD_COPY_ON_WRITE */ +#define SV_COW_OTHER_PVS 1024 +/* Make sv_2pv_flags return NULL if something is undefined. */ +#define SV_UNDEF_RETURNS_NULL 2048 +/* Tell sv_utf8_upgrade() to not check to see if an upgrade is really needed. + * This is used when the caller has already determined it is, and avoids + * redundant work */ +#define SV_FORCE_UTF8_UPGRADE 4096 +/* 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 +#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. + */ +#ifdef PERL_CORE +# ifndef SV_DO_COW_SVSETSV +# define SV_DO_COW_SVSETSV SV_COW_SHARED_HASH_KEYS|SV_COW_OTHER_PVS +# endif +#endif + +#ifndef SV_DO_COW_SVSETSV +# define SV_DO_COW_SVSETSV 0 +#endif + + +#define sv_unref(sv) sv_unref_flags(sv, 0) +#define sv_force_normal(sv) sv_force_normal_flags(sv, 0) +#define sv_usepvn(sv, p, l) sv_usepvn_flags(sv, p, l, 0) +#define sv_usepvn_mg(sv, p, l) sv_usepvn_flags(sv, p, l, SV_SMAGIC) + +/* 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_OLD_COPY_ON_WRITE +#define SvRELEASE_IVX(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), +# define SvCANCOW(sv) \ + (SvIsCOW(sv) || (SvFLAGS(sv) & CAN_COW_MASK) == CAN_COW_FLAGS) +/* This is a pessimistic view. Scalar must be purely a read-write PV to copy- + 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_PROTECT) +#else +# 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) /**/ +# ifdef PERL_NEW_COPY_ON_WRITE +# define SvCANCOW(sv) \ + (SvIsCOW(sv) \ + ? SvLEN(sv) ? CowREFCNT(sv) != SV_COW_REFCNT_MAX : 1 \ + : (SvFLAGS(sv) & CAN_COW_MASK) == CAN_COW_FLAGS \ + && SvCUR(sv)+1 < SvLEN(sv)) + /* 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) +# define CAN_COW_MASK (SVf_POK|SVf_ROK|SVp_POK|SVf_FAKE| \ + SVf_OOK|SVf_BREAK|SVf_READONLY|SVf_PROTECT) +# endif +#endif /* PERL_OLD_COPY_ON_WRITE */ + +#define CAN_COW_FLAGS (SVp_POK|SVf_POK) + +#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_flags(sv, flags) sv_utf8_upgrade_flags_grow(sv, flags, 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_catpv_nomg(dsv, sstr) sv_catpv_flags(dsv, sstr, 0) +#define sv_setsv(dsv, ssv) \ + sv_setsv_flags(dsv, ssv, SV_GMAGIC|SV_DO_COW_SVSETSV) +#define sv_setsv_nomg(dsv, ssv) sv_setsv_flags(dsv, ssv, SV_DO_COW_SVSETSV) +#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_catsv_mg(dsv, ssv) sv_catsv_flags(dsv, ssv, SV_GMAGIC|SV_SMAGIC) +#define sv_catpvn(dsv, sstr, slen) sv_catpvn_flags(dsv, sstr, slen, SV_GMAGIC) +#define sv_catpvn_mg(sv, sstr, slen) sv_catpvn_flags(sv, sstr, slen, SV_GMAGIC|SV_SMAGIC); +#define sv_copypv(dsv, ssv) sv_copypv_flags(dsv, ssv, SV_GMAGIC) +#define sv_copypv_nomg(dsv, ssv) sv_copypv_flags(dsv, ssv, 0) +#define sv_2pv(sv, lp) sv_2pv_flags(sv, lp, SV_GMAGIC) +#define sv_2pv_nolen(sv) sv_2pv(sv, 0) +#define sv_2pvbyte_nolen(sv) sv_2pvbyte(sv, 0) +#define sv_2pvutf8_nolen(sv) sv_2pvutf8(sv, 0) +#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) +#define sv_2iv(sv) sv_2iv_flags(sv, SV_GMAGIC) +#define sv_2uv(sv) sv_2uv_flags(sv, SV_GMAGIC) +#define sv_2nv(sv) sv_2nv_flags(sv, SV_GMAGIC) +#define sv_eq(sv1, sv2) sv_eq_flags(sv1, sv2, SV_GMAGIC) +#define sv_cmp(sv1, sv2) sv_cmp_flags(sv1, sv2, SV_GMAGIC) +#define sv_cmp_locale(sv1, sv2) sv_cmp_locale_flags(sv1, sv2, SV_GMAGIC) +#define sv_collxfrm(sv, nxp) sv_cmp_flags(sv, nxp, SV_GMAGIC) +#define sv_2bool(sv) sv_2bool_flags(sv, SV_GMAGIC) +#define sv_2bool_nomg(sv) sv_2bool_flags(sv, 0) +#define sv_insert(bigstr, offset, len, little, littlelen) \ + Perl_sv_insert_flags(aTHX_ (bigstr),(offset), (len), (little), \ + (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) \ + STMT_START { \ + if (!(nsv)) \ + nsv = newSVpvn_flags(sstr, slen, SVs_TEMP); \ + else \ + sv_setpvn(nsv, sstr, slen); \ + SvUTF8_off(nsv); \ + sv_utf8_upgrade(nsv); \ + sv_catsv_nomg(dsv, nsv); \ + } STMT_END +#define sv_catpvn_nomg_maybeutf8(dsv, sstr, slen, is_utf8) \ + sv_catpvn_flags(dsv, sstr, slen, (is_utf8)?SV_CATUTF8:SV_CATBYTES) + +#if defined(PERL_CORE) || defined(PERL_EXT) +# define sv_or_pv_len_utf8(sv, pv, bytelen) \ + (SvGAMAGIC(sv) \ + ? utf8_length((U8 *)(pv), (U8 *)(pv)+(bytelen)) \ + : sv_len_utf8(sv)) +#endif + +/* +=for apidoc Am|SV*|newRV_inc|SV* sv + +Creates an RV wrapper for an SV. The reference count for the original SV is +incremented. + +=cut +*/ + +#define newRV_inc(sv) newRV(sv) + +/* 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. For example, this +will call C<FETCH> on a tied variable. This macro evaluates its +argument more than once. + +=for apidoc Am|void|SvSETMAGIC|SV* sv +Invokes C<mg_set> on an SV if it has 'set' magic. This is necessary +after modifying a scalar, in case it is a magical variable like C<$|> +or a tied variable (it calls C<STORE>). This macro evaluates its +argument more than once. + +=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. 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 +ssv. May evaluate arguments more than once. + +=for apidoc Am|void|SvSetMagicSV|SV* dsv|SV* ssv +Like C<SvSetSV>, but does any set magic required afterwards. + +=for apidoc Am|void|SvSetMagicSV_nosteal|SV* dsv|SV* ssv +Like C<SvSetSV_nosteal>, 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 +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. + +=cut +*/ + +#define SvSHARE(sv) PL_sharehook(aTHX_ sv) +#define SvLOCK(sv) PL_lockhook(aTHX_ sv) +#define SvUNLOCK(sv) PL_unlockhook(aTHX_ sv) +#define SvDESTROYABLE(sv) PL_destroyhook(aTHX_ sv) + +#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 (LIKELY((dst) != (src))) { \ + sv_setsv(dst, src); \ + finally; \ + } \ + } STMT_END +#define SvSetSV_nosteal_and(dst,src,finally) \ + STMT_START { \ + if (LIKELY((dst) != (src))) { \ + sv_setsv_flags(dst, src, SV_GMAGIC | SV_NOSTEAL | SV_DO_COW_SVSETSV); \ + finally; \ + } \ + } STMT_END + +#define SvSetSV(dst,src) \ + SvSetSV_and(dst,src,/*nothing*/;) +#define SvSetSV_nosteal(dst,src) \ + SvSetSV_nosteal_and(dst,src,/*nothing*/;) + +#define SvSetMagicSV(dst,src) \ + SvSetSV_and(dst,src,SvSETMAGIC(dst)) +#define SvSetMagicSV_nosteal(dst,src) \ + SvSetSV_nosteal_and(dst,src,SvSETMAGIC(dst)) + + +#if !defined(SKIP_DEBUGGING) +#define SvPEEK(sv) sv_peek(sv) +#else +#define SvPEEK(sv) "" +#endif + +#define SvIMMORTAL(sv) (SvREADONLY(sv) && ((sv)==&PL_sv_undef || (sv)==&PL_sv_yes || (sv)==&PL_sv_no || (sv)==&PL_sv_placeholder)) + +#ifdef DEBUGGING + /* exercise the immortal resurrection code in sv_free2() */ +# define SvREFCNT_IMMORTAL 1000 +#else +# define SvREFCNT_IMMORTAL ((~(U32)0)/2) +#endif + +/* +=for apidoc Am|SV *|boolSV|bool b + +Returns a true SV if C<b> is a true value, or a false SV if C<b> is 0. + +See also C<PL_sv_yes> and C<PL_sv_no>. + +=cut +*/ + +#define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no) + +#define isGV(sv) (SvTYPE(sv) == SVt_PVGV) +/* If I give every macro argument a different name, then there won't be bugs + where nested macros get confused. Been there, done that. */ +#define isGV_with_GP(pwadak) \ + (((SvFLAGS(pwadak) & (SVp_POK|SVpgv_GP)) == SVpgv_GP) \ + && (SvTYPE(pwadak) == SVt_PVGV || SvTYPE(pwadak) == SVt_PVLV)) +#define isGV_with_GP_on(sv) STMT_START { \ + assert (SvTYPE(sv) == SVt_PVGV || SvTYPE(sv) == SVt_PVLV); \ + assert (!SvPOKp(sv)); \ + assert (!SvIOKp(sv)); \ + (SvFLAGS(sv) |= SVpgv_GP); \ + } STMT_END +#define isGV_with_GP_off(sv) STMT_START { \ + assert (SvTYPE(sv) == SVt_PVGV || SvTYPE(sv) == SVt_PVLV); \ + assert (!SvPOKp(sv)); \ + assert (!SvIOKp(sv)); \ + (SvFLAGS(sv) &= ~SVpgv_GP); \ + } STMT_END +#define isREGEXP(sv) \ + (SvTYPE(sv) == SVt_REGEXP \ + || (SvFLAGS(sv) & (SVTYPEMASK|SVp_POK|SVpgv_GP|SVf_FAKE)) \ + == (SVt_PVLV|SVf_FAKE)) + + +#ifdef PERL_ANY_COW +# define SvGROW(sv,len) \ + (SvIsCOW(sv) || SvLEN(sv) < (len) ? sv_grow(sv,len) : SvPVX(sv)) +#else +# define SvGROW(sv,len) (SvLEN(sv) < (len) ? sv_grow(sv,len) : SvPVX(sv)) +#endif +#define SvGROW_mutable(sv,len) \ + (SvLEN(sv) < (len) ? sv_grow(sv,len) : SvPVX_mutable(sv)) +#define Sv_Grow sv_grow + +#define CLONEf_COPY_STACKS 1 +#define CLONEf_KEEP_PTR_TABLE 2 +#define CLONEf_CLONE_HOST 4 +#define CLONEf_JOIN_IN 8 + +struct clone_params { + AV* stashes; + UV flags; + PerlInterpreter *proto_perl; + PerlInterpreter *new_perl; + AV *unreferenced; +}; + +/* +=for apidoc Am|SV*|newSVpvn_utf8|NULLOK const char* s|STRLEN len|U32 utf8 + +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 +*/ + +#define newSVpvn_utf8(s, len, u) newSVpvn_flags((s), (len), (u) ? SVf_UTF8 : 0) + +/* +=for apidoc Amx|SV*|newSVpadname|PADNAME *pn + +Creates a new SV containing the pad name. + +=cut +*/ + +#define newSVpadname(pn) newSVpvn_utf8(PadnamePV(pn), PadnameLEN(pn), TRUE) + +/* +=for apidoc Am|void|SvOOK_offset|NN SV*sv|STRLEN len + +Reads into I<len> the offset from SvPVX back to the true start of the +allocated buffer, which will be non-zero if C<sv_chop> has been used to +efficiently remove characters from start of the buffer. Implemented as a +macro, which takes the address of I<len>, which must be of type C<STRLEN>. +Evaluates I<sv> more than once. Sets I<len> to 0 if C<SvOOK(sv)> is false. + +=cut +*/ + +#ifdef DEBUGGING +/* Does the bot know something I don't? +10:28 <@Nicholas> metabatman +10:28 <+meta> Nicholas: crash +*/ +# define SvOOK_offset(sv, offset) STMT_START { \ + assert(sizeof(offset) == sizeof(STRLEN)); \ + if (SvOOK(sv)) { \ + const U8 *_crash = (U8*)SvPVX_const(sv); \ + (offset) = *--_crash; \ + if (!(offset)) { \ + _crash -= sizeof(STRLEN); \ + Copy(_crash, (U8 *)&(offset), sizeof(STRLEN), U8); \ + } \ + { \ + /* Validate the preceding buffer's sentinels to \ + verify that no-one is using it. */ \ + const U8 *const _bonk = (U8*)SvPVX_const(sv) - (offset);\ + while (_crash > _bonk) { \ + --_crash; \ + assert (*_crash == (U8)PTR2UV(_crash)); \ + } \ + } \ + } else { \ + (offset) = 0; \ + } \ + } STMT_END +#else + /* This is the same code, but avoids using any temporary variables: */ +# define SvOOK_offset(sv, offset) STMT_START { \ + assert(sizeof(offset) == sizeof(STRLEN)); \ + if (SvOOK(sv)) { \ + (offset) = ((U8*)SvPVX_const(sv))[-1]; \ + if (!(offset)) { \ + Copy(SvPVX_const(sv) - 1 - sizeof(STRLEN), \ + (U8*)&(offset), sizeof(STRLEN), U8); \ + } \ + } else { \ + (offset) = 0; \ + } \ + } STMT_END +#endif + +#define newIO() MUTABLE_IO(newSV_type(SVt_PVIO)) + +#define SV_CONST(name) \ + PL_sv_consts[SV_CONST_##name] \ + ? PL_sv_consts[SV_CONST_##name] \ + : (PL_sv_consts[SV_CONST_##name] = newSVpv_share(#name, 0)) + +#define SV_CONST_TIESCALAR 0 +#define SV_CONST_TIEARRAY 1 +#define SV_CONST_TIEHASH 2 +#define SV_CONST_TIEHANDLE 3 + +#define SV_CONST_FETCH 4 +#define SV_CONST_FETCHSIZE 5 +#define SV_CONST_STORE 6 +#define SV_CONST_STORESIZE 7 +#define SV_CONST_EXISTS 8 + +#define SV_CONST_PUSH 9 +#define SV_CONST_POP 10 +#define SV_CONST_SHIFT 11 +#define SV_CONST_UNSHIFT 12 +#define SV_CONST_SPLICE 13 +#define SV_CONST_EXTEND 14 + +#define SV_CONST_FIRSTKEY 15 +#define SV_CONST_NEXTKEY 16 +#define SV_CONST_SCALAR 17 + +#define SV_CONST_OPEN 18 +#define SV_CONST_WRITE 19 +#define SV_CONST_PRINT 20 +#define SV_CONST_PRINTF 21 +#define SV_CONST_READ 22 +#define SV_CONST_READLINE 23 +#define SV_CONST_GETC 24 +#define SV_CONST_SEEK 25 +#define SV_CONST_TELL 26 +#define SV_CONST_EOF 27 +#define SV_CONST_BINMODE 28 +#define SV_CONST_FILENO 29 +#define SV_CONST_CLOSE 30 + +#define SV_CONST_DELETE 31 +#define SV_CONST_CLEAR 32 +#define SV_CONST_UNTIE 33 +#define SV_CONST_DESTROY 34 + +#define SV_CONSTS_COUNT 35 + +/* + * ex: set ts=8 sts=4 sw=4 et: + */