X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/36c662f48c9a23ec4251c3cf747c3f42c63a6fd9..8dc00b2f10de49b4d2d4be48279a996698c3f04a:/sv.h diff --git a/sv.h b/sv.h index c80c2aa..65e6ec4 100644 --- a/sv.h +++ b/sv.h @@ -117,10 +117,10 @@ struct STRUCT_SV { /* struct sv { */ _SV_HEAD(void*); _SV_HEAD_UNION; #ifdef DEBUG_LEAKING_SCALARS - unsigned sv_debug_optype:9; /* the type of OP that allocated us */ - unsigned sv_debug_inpad:1; /* was allocated in a pad for an OP */ - unsigned sv_debug_cloned:1; /* was cloned for an ithread */ - unsigned sv_debug_line:16; /* the line where we were allocated */ + 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_cloned:1; /* was cloned for an ithread */ + PERL_BITFIELD32 sv_debug_line:16; /* the line where we were allocated */ char * sv_debug_file; /* the file where we were allocated */ #endif }; @@ -221,7 +221,7 @@ perform the upgrade if necessary. See C. #define SvFLAGS(sv) (sv)->sv_flags #define SvREFCNT(sv) (sv)->sv_refcnt -#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && !defined(PERL_GCC_PEDANTIC) +#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) # define SvREFCNT_inc(sv) \ ({ \ SV * const _sv = (SV*)(sv); \ @@ -264,7 +264,7 @@ perform the upgrade if necessary. See C. #define SvREFCNT_inc_void_NN(sv) (void)(++SvREFCNT((SV*)(sv))) #define SvREFCNT_inc_simple_void_NN(sv) (void)(++SvREFCNT((SV*)(sv))) -#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && !defined(PERL_GCC_PEDANTIC) +#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) # define SvREFCNT_dec(sv) \ ({ \ SV * const _sv = (SV*)(sv); \ @@ -328,12 +328,10 @@ perform the upgrade if necessary. See C. 3: For PVCV, whether CvUNIQUE(cv) refers to an eval or once only [CvEVAL(cv), CvSPECIAL(cv)] - 4: Whether the regexp pointer is in - fact an offset [SvREPADTMP(sv)] - 5: On a pad name SV, that slot in the + 4: On a pad name SV, that slot in the frame AV is a REFCNT'ed reference to a lexical from "outside". */ -#define SVphv_REHASH SVf_FAKE /* 6: On a PVHV, hash values are being +#define SVphv_REHASH SVf_FAKE /* 5: On a PVHV, hash values are being recalculated */ #define SVf_OOK 0x02000000 /* has valid offset value. For a PVHV this means that a hv_aux struct is present @@ -534,38 +532,48 @@ typedef struct { IV xfm_lines; } xpvfm_allocated; +#define _XPVIO_TAIL \ + PerlIO * xio_ifp; /* ifp and ofp are normally the same */ \ + PerlIO * xio_ofp; /* but sockets need separate streams */ \ + /* 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; /* $. */ \ + 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 + + struct xpvio { _XPV_HEAD; _XPVMG_HEAD; - - PerlIO * xio_ifp; /* ifp and ofp are normally the same */ - PerlIO * xio_ofp; /* but sockets need separate streams */ - /* 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; /* $. */ - 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; + _XPVIO_TAIL; }; + +typedef struct { + _XPV_ALLOCATED_HEAD; + _XPVMG_HEAD; + _XPVIO_TAIL; +} xpvio_allocated; + #define xio_dirp xio_dirpu.xiou_dirp #define xio_any xio_dirpu.xiou_any @@ -958,23 +966,23 @@ the scalar's value cannot change unless written to. #define SvEVALED_off(sv) (SvFLAGS(sv) &= ~SVrepl_EVAL) #if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) -# define SvVALID(sv) ({ SV *const thwacke = (SV *) (sv); \ - if (SvFLAGS(thwacke) & SVpbm_VALID) \ - assert(!isGV_with_GP(thwacke)); \ - (SvFLAGS(thwacke) & SVpbm_VALID); \ +# define SvVALID(sv) ({ SV *const _svvalid = (SV *) (sv); \ + if (SvFLAGS(_svvalid) & SVpbm_VALID) \ + assert(!isGV_with_GP(_svvalid)); \ + (SvFLAGS(_svvalid) & SVpbm_VALID); \ }) -# define SvVALID_on(sv) ({ SV *const thwacke = (SV *) (sv); \ - assert(!isGV_with_GP(thwacke)); \ - (SvFLAGS(thwacke) |= SVpbm_VALID); \ +# define SvVALID_on(sv) ({ SV *const _svvalid = (SV *) (sv); \ + assert(!isGV_with_GP(_svvalid)); \ + (SvFLAGS(_svvalid) |= SVpbm_VALID); \ }) -# define SvVALID_off(sv) ({ SV *const thwacke = (SV *) (sv); \ - assert(!isGV_with_GP(thwacke)); \ - (SvFLAGS(thwacke) &= ~SVpbm_VALID); \ +# define SvVALID_off(sv) ({ SV *const _svvalid = (SV *) (sv); \ + assert(!isGV_with_GP(_svvalid)); \ + (SvFLAGS(_svvalid) &= ~SVpbm_VALID); \ }) -# define SvTAIL(sv) ({ SV *const _svi = (SV *) (sv); \ - assert(SvTYPE(_svi) != SVt_PVAV); \ - assert(SvTYPE(_svi) != SVt_PVHV); \ +# define SvTAIL(sv) ({ SV *const _svtail = (SV *) (sv); \ + assert(SvTYPE(_svtail) != SVt_PVAV); \ + assert(SvTYPE(_svtail) != SVt_PVHV); \ (SvFLAGS(sv) & (SVpbm_TAIL|SVpbm_VALID)) \ == (SVpbm_TAIL|SVpbm_VALID); \ }) @@ -990,14 +998,6 @@ the scalar's value cannot change unless written to. #define SvTAIL_off(sv) (SvFLAGS(sv) &= ~SVpbm_TAIL) -#ifdef USE_ITHREADS -/* The following uses the FAKE flag to show that a regex pointer is infact - its own offset in the regexpad for ithreads */ -#define SvREPADTMP(sv) (SvFLAGS(sv) & SVf_FAKE) -#define SvREPADTMP_on(sv) (SvFLAGS(sv) |= SVf_FAKE) -#define SvREPADTMP_off(sv) (SvFLAGS(sv) &= ~SVf_FAKE) -#endif - #define SvPAD_TYPED(sv) \ ((SvFLAGS(sv) & (SVpad_NAME|SVpad_TYPED)) == (SVpad_NAME|SVpad_TYPED)) @@ -1009,19 +1009,19 @@ the scalar's value cannot change unless written to. #if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) # define SvPAD_TYPED_on(sv) ({ \ - SV *const whap = (SV *) (sv); \ - assert(SvTYPE(whap) == SVt_PVMG); \ - (SvFLAGS(whap) |= SVpad_NAME|SVpad_TYPED); \ + SV *const _svpad = (SV *) (sv); \ + assert(SvTYPE(_svpad) == SVt_PVMG); \ + (SvFLAGS(_svpad) |= SVpad_NAME|SVpad_TYPED); \ }) #define SvPAD_OUR_on(sv) ({ \ - SV *const whap = (SV *) (sv); \ - assert(SvTYPE(whap) == SVt_PVMG); \ - (SvFLAGS(whap) |= SVpad_NAME|SVpad_OUR); \ + SV *const _svpad = (SV *) (sv); \ + assert(SvTYPE(_svpad) == SVt_PVMG); \ + (SvFLAGS(_svpad) |= SVpad_NAME|SVpad_OUR); \ }) #define SvPAD_STATE_on(sv) ({ \ - SV *const whap = (SV *) (sv); \ - assert(SvTYPE(whap) == SVt_PVNV || SvTYPE(whap) == SVt_PVMG); \ - (SvFLAGS(whap) |= SVpad_NAME|SVpad_STATE); \ + SV *const _svpad = (SV *) (sv); \ + assert(SvTYPE(_svpad) == SVt_PVNV || SvTYPE(_svpad) == SVt_PVMG); \ + (SvFLAGS(_svpad) |= SVpad_NAME|SVpad_STATE); \ }) #else # define SvPAD_TYPED_on(sv) (SvFLAGS(sv) |= SVpad_NAME|SVpad_TYPED) @@ -1073,70 +1073,71 @@ the scalar's value cannot change unless written to. # 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 _svi = (SV *) (sv); \ - assert(SvTYPE(_svi) >= SVt_PV); \ - assert(SvTYPE(_svi) != SVt_PVAV); \ - assert(SvTYPE(_svi) != SVt_PVHV); \ - assert(!isGV_with_GP(_svi)); \ - &((_svi)->sv_u.svu_pv); \ + (*({ SV *const _svpvx = (SV *) (sv); \ + assert(SvTYPE(_svpvx) >= SVt_PV); \ + assert(SvTYPE(_svpvx) != SVt_PVAV); \ + assert(SvTYPE(_svpvx) != SVt_PVHV); \ + assert(!isGV_with_GP(_svpvx)); \ + &((_svpvx)->sv_u.svu_pv); \ })) # define SvCUR(sv) \ - (*({ SV *const _svi = (SV *) (sv); \ - assert(SvTYPE(_svi) >= SVt_PV); \ - assert(SvTYPE(_svi) != SVt_PVAV); \ - assert(SvTYPE(_svi) != SVt_PVHV); \ - assert(!isGV_with_GP(_svi)); \ - &(((XPV*) SvANY(_svi))->xpv_cur); \ + (*({ SV *const _svcur = (SV *) (sv); \ + assert(SvTYPE(_svcur) >= SVt_PV); \ + assert(SvTYPE(_svcur) != SVt_PVAV); \ + assert(SvTYPE(_svcur) != SVt_PVHV); \ + assert(!isGV_with_GP(_svcur)); \ + &(((XPV*) SvANY(_svcur))->xpv_cur); \ })) # define SvIVX(sv) \ - (*({ SV *const _svi = (SV *) (sv); \ - assert(SvTYPE(_svi) == SVt_IV || SvTYPE(_svi) >= SVt_PVIV); \ - assert(SvTYPE(_svi) != SVt_PVAV); \ - assert(SvTYPE(_svi) != SVt_PVHV); \ - assert(SvTYPE(_svi) != SVt_PVCV); \ - assert(!isGV_with_GP(_svi)); \ - &(((XPVIV*) SvANY(_svi))->xiv_iv); \ + (*({ SV *const _svivx = (SV *) (sv); \ + assert(SvTYPE(_svivx) == SVt_IV || SvTYPE(_svivx) >= SVt_PVIV); \ + assert(SvTYPE(_svivx) != SVt_PVAV); \ + assert(SvTYPE(_svivx) != SVt_PVHV); \ + assert(SvTYPE(_svivx) != SVt_PVCV); \ + assert(!isGV_with_GP(_svivx)); \ + &(((XPVIV*) SvANY(_svivx))->xiv_iv); \ })) # define SvUVX(sv) \ - (*({ SV *const _svi = (SV *) (sv); \ - assert(SvTYPE(_svi) == SVt_IV || SvTYPE(_svi) >= SVt_PVIV); \ - assert(SvTYPE(_svi) != SVt_PVAV); \ - assert(SvTYPE(_svi) != SVt_PVHV); \ - assert(SvTYPE(_svi) != SVt_PVCV); \ - assert(!isGV_with_GP(_svi)); \ - &(((XPVUV*) SvANY(_svi))->xuv_uv); \ + (*({ SV *const _svuvx = (SV *) (sv); \ + assert(SvTYPE(_svuvx) == SVt_IV || SvTYPE(_svuvx) >= SVt_PVIV); \ + assert(SvTYPE(_svuvx) != SVt_PVAV); \ + assert(SvTYPE(_svuvx) != SVt_PVHV); \ + assert(SvTYPE(_svuvx) != SVt_PVCV); \ + assert(!isGV_with_GP(_svuvx)); \ + &(((XPVUV*) SvANY(_svuvx))->xuv_uv); \ })) # define SvNVX(sv) \ - (*({ SV *const _svi = (SV *) (sv); \ - assert(SvTYPE(_svi) == SVt_NV || SvTYPE(_svi) >= SVt_PVNV); \ - assert(SvTYPE(_svi) != SVt_PVAV); \ - assert(SvTYPE(_svi) != SVt_PVHV); \ - assert(SvTYPE(_svi) != SVt_PVCV); \ - assert(SvTYPE(_svi) != SVt_PVFM); \ - assert(!isGV_with_GP(_svi)); \ - &(((XPVNV*) SvANY(_svi))->xnv_u.xnv_nv); \ + (*({ SV *const _svnvx = (SV *) (sv); \ + assert(SvTYPE(_svnvx) == SVt_NV || SvTYPE(_svnvx) >= SVt_PVNV); \ + assert(SvTYPE(_svnvx) != SVt_PVAV); \ + assert(SvTYPE(_svnvx) != SVt_PVHV); \ + assert(SvTYPE(_svnvx) != SVt_PVCV); \ + assert(SvTYPE(_svnvx) != SVt_PVFM); \ + assert(SvTYPE(_svnvx) != SVt_PVIO); \ + assert(!isGV_with_GP(_svnvx)); \ + &(((XPVNV*) SvANY(_svnvx))->xnv_u.xnv_nv); \ })) # define SvRV(sv) \ - (*({ SV *const _svi = (SV *) (sv); \ - assert(SvTYPE(_svi) >= SVt_PV || SvTYPE(_svi) == SVt_IV); \ - assert(SvTYPE(_svi) != SVt_PVAV); \ - assert(SvTYPE(_svi) != SVt_PVHV); \ - assert(SvTYPE(_svi) != SVt_PVCV); \ - assert(SvTYPE(_svi) != SVt_PVFM); \ - assert(!isGV_with_GP(_svi)); \ - &((_svi)->sv_u.svu_rv); \ + (*({ SV *const _svrv = (SV *) (sv); \ + assert(SvTYPE(_svrv) >= SVt_PV || SvTYPE(_svrv) == SVt_IV); \ + assert(SvTYPE(_svrv) != SVt_PVAV); \ + assert(SvTYPE(_svrv) != SVt_PVHV); \ + assert(SvTYPE(_svrv) != SVt_PVCV); \ + assert(SvTYPE(_svrv) != SVt_PVFM); \ + assert(!isGV_with_GP(_svrv)); \ + &((_svrv)->sv_u.svu_rv); \ })) # define SvMAGIC(sv) \ - (*({ SV *const _svi = (SV *) (sv); \ - assert(SvTYPE(_svi) >= SVt_PVMG); \ - if(SvTYPE(_svi) == SVt_PVMG) \ - assert(!SvPAD_OUR(_svi)); \ - &(((XPVMG*) SvANY(_svi))->xmg_u.xmg_magic); \ + (*({ SV *const _svmagic = (SV *) (sv); \ + assert(SvTYPE(_svmagic) >= SVt_PVMG); \ + if(SvTYPE(_svmagic) == SVt_PVMG) \ + assert(!SvPAD_OUR(_svmagic)); \ + &(((XPVMG*) SvANY(_svmagic))->xmg_u.xmg_magic); \ })) # define SvSTASH(sv) \ - (*({ SV *const _svi = (SV *) (sv); \ - assert(SvTYPE(_svi) >= SVt_PVMG); \ - &(((XPVMG*) SvANY(_svi))->xmg_stash); \ + (*({ SV *const _svstash = (SV *) (sv); \ + assert(SvTYPE(_svstash) >= SVt_PVMG); \ + &(((XPVMG*) SvANY(_svstash))->xmg_stash); \ })) # else # define SvPVX(sv) ((sv)->sv_u.svu_pv) @@ -1187,6 +1188,7 @@ the scalar's value cannot change unless written to. STMT_START { assert(SvTYPE(sv) == SVt_NV || SvTYPE(sv) >= SVt_PVNV); \ assert(SvTYPE(sv) != SVt_PVAV); assert(SvTYPE(sv) != SVt_PVHV); \ assert(SvTYPE(sv) != SVt_PVCV); assert(SvTYPE(sv) != SVt_PVFM); \ + assert(SvTYPE(sv) != SVt_PVIO); \ assert(!isGV_with_GP(sv)); \ (((XPVNV*)SvANY(sv))->xnv_u.xnv_nv = (val)); } STMT_END #define SvPV_set(sv, val) \ @@ -1230,7 +1232,7 @@ the scalar's value cannot change unless written to. (((XPV*) SvANY(sv))->xpv_len = (val)); } STMT_END #define SvEND_set(sv, val) \ STMT_START { assert(SvTYPE(sv) >= SVt_PV); \ - (SvCUR(sv) = (val) - SvPVX(sv)); } STMT_END + SvCUR_set(sv, (val) - SvPVX(sv)); } STMT_END #define SvPV_renew(sv,n) \ STMT_START { SvLEN_set(sv, n); \ @@ -1281,29 +1283,29 @@ the scalar's value cannot change unless written to. */ #if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) # define BmFLAGS(sv) \ - (*({ SV *const uggh = (SV *) (sv); \ - assert(SvTYPE(uggh) == SVt_PVGV); \ - assert(SvVALID(uggh)); \ - &(((XPVGV*) SvANY(uggh))->xnv_u.xbm_s.xbm_flags); \ + (*({ SV *const _bmflags = (SV *) (sv); \ + assert(SvTYPE(_bmflags) == SVt_PVGV); \ + assert(SvVALID(_bmflags)); \ + &(((XPVGV*) SvANY(_bmflags))->xnv_u.xbm_s.xbm_flags); \ })) # define BmRARE(sv) \ - (*({ SV *const uggh = (SV *) (sv); \ - assert(SvTYPE(uggh) == SVt_PVGV); \ - assert(SvVALID(uggh)); \ - &(((XPVGV*) SvANY(uggh))->xnv_u.xbm_s.xbm_rare); \ + (*({ SV *const _bmrare = (SV *) (sv); \ + assert(SvTYPE(_bmrare) == SVt_PVGV); \ + assert(SvVALID(_bmrare)); \ + &(((XPVGV*) SvANY(_bmrare))->xnv_u.xbm_s.xbm_rare); \ })) # define BmUSEFUL(sv) \ - (*({ SV *const uggh = (SV *) (sv); \ - assert(SvTYPE(uggh) == SVt_PVGV); \ - assert(SvVALID(uggh)); \ - assert(!SvIOK(uggh)); \ - &(((XPVGV*) SvANY(uggh))->xiv_u.xivu_i32); \ + (*({ SV *const _bmuseful = (SV *) (sv); \ + assert(SvTYPE(_bmuseful) == SVt_PVGV); \ + assert(SvVALID(_bmuseful)); \ + assert(!SvIOK(_bmuseful)); \ + &(((XPVGV*) SvANY(_bmuseful))->xiv_u.xivu_i32); \ })) # define BmPREVIOUS(sv) \ - (*({ SV *const uggh = (SV *) (sv); \ - assert(SvTYPE(uggh) == SVt_PVGV); \ - assert(SvVALID(uggh)); \ - &(((XPVGV*) SvANY(uggh))->xnv_u.xbm_s.xbm_previous); \ + (*({ SV *const _bmprevious = (SV *) (sv); \ + assert(SvTYPE(_bmprevious) == SVt_PVGV); \ + assert(SvVALID(_bmprevious)); \ + &(((XPVGV*) SvANY(_bmprevious))->xnv_u.xbm_s.xbm_previous); \ })) #else # define BmFLAGS(sv) ((XPVGV*) SvANY(sv))->xnv_u.xbm_s.xbm_flags @@ -1695,6 +1697,8 @@ Like C but doesn't process magic. #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 /* 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. @@ -1774,6 +1778,9 @@ mg.c:1024: warning: left-hand operand of comma expression has no effect #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_insert(bigstr, offset, len, little, littlelen) \ + Perl_sv_insert_flags(aTHX_ (bigstr),(offset), (len), (little), \ + (littlelen), SV_GMAGIC) /* Should be named SvCatPVN_utf8_upgrade? */ #define sv_catpvn_utf8_upgrade(dsv, sstr, slen, nsv) \