X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/dd36d13c89140c2d9d7954b9f1de583003154c13..16073f159843070bc8b173d94704d3759febc9f1:/sv.h diff --git a/sv.h b/sv.h index 7a13905..f63d058 100644 --- a/sv.h +++ b/sv.h @@ -1,6 +1,7 @@ /* sv.h * - * Copyright (c) 1991-2002, Larry Wall + * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + * 2000, 2001, 2002, 2003, 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. @@ -125,63 +126,42 @@ perform the upgrade if necessary. See C. #define SvFLAGS(sv) (sv)->sv_flags #define SvREFCNT(sv) (sv)->sv_refcnt -#ifdef USE_5005THREADS - -# if defined(VMS) -# define ATOMIC_INC(count) __ATOMIC_INCREMENT_LONG(&count) -# define ATOMIC_DEC_AND_TEST(res,count) res=(1==__ATOMIC_DECREMENT_LONG(&count)) - # else -# ifdef EMULATE_ATOMIC_REFCOUNTS - # define ATOMIC_INC(count) STMT_START { \ - MUTEX_LOCK(&PL_svref_mutex); \ - ++count; \ - MUTEX_UNLOCK(&PL_svref_mutex); \ - } STMT_END -# define ATOMIC_DEC_AND_TEST(res,count) STMT_START { \ - MUTEX_LOCK(&PL_svref_mutex); \ - res = (--count == 0); \ - MUTEX_UNLOCK(&PL_svref_mutex); \ - } STMT_END -# else -# define ATOMIC_INC(count) atomic_inc(&count) -# define ATOMIC_DEC_AND_TEST(res,count) (res = atomic_dec_and_test(&count)) -# endif /* EMULATE_ATOMIC_REFCOUNTS */ -# endif /* VMS */ -#else -# define ATOMIC_INC(count) (++count) -# define ATOMIC_DEC_AND_TEST(res, count) (res = (--count == 0)) -#endif /* USE_5005THREADS */ - -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && !defined(PERL_GCC_PEDANTIC) # define SvREFCNT_inc(sv) \ ({ \ SV *nsv = (SV*)(sv); \ if (nsv) \ - ATOMIC_INC(SvREFCNT(nsv)); \ + (SvREFCNT(nsv))++; \ nsv; \ }) #else -# ifdef USE_5005THREADS -# if defined(VMS) && defined(__ALPHA) -# define SvREFCNT_inc(sv) \ - (PL_Sv=(SV*)(sv), (PL_Sv && __ATOMIC_INCREMENT_LONG(&(SvREFCNT(PL_Sv)))), (SV *)PL_Sv) -# else -# define SvREFCNT_inc(sv) sv_newref((SV*)sv) -# endif -# else -# define SvREFCNT_inc(sv) \ - ((PL_Sv=(SV*)(sv)), (PL_Sv && ATOMIC_INC(SvREFCNT(PL_Sv))), (SV*)PL_Sv) -# endif +# define SvREFCNT_inc(sv) \ + ((PL_Sv=(SV*)(sv)), (PL_Sv && ++(SvREFCNT(PL_Sv))), (SV*)PL_Sv) #endif -#define SvREFCNT_dec(sv) sv_free((SV*)sv) +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && !defined(PERL_GCC_PEDANTIC) +# define SvREFCNT_dec(sv) \ + ({ \ + SV *nsv = (SV*)(sv); \ + if (nsv) { \ + if (SvREFCNT(nsv)) { \ + if (--(SvREFCNT(nsv)) == 0) \ + Perl_sv_free2(aTHX_ nsv); \ + } else { \ + sv_free(nsv); \ + } \ + } \ + }) +#else +#define SvREFCNT_dec(sv) sv_free((SV*)(sv)) +#endif #define SVTYPEMASK 0xff #define SvTYPE(sv) ((sv)->sv_flags & SVTYPEMASK) #define SvUPGRADE(sv, mt) (SvTYPE(sv) >= mt || sv_upgrade(sv, mt)) -#define SVs_PADBUSY 0x00000100 /* reserved for tmp or my already */ +#define SVs_PADSTALE 0x00000100 /* lexical has gone out of scope */ #define SVs_PADTMP 0x00000200 /* in use as tmp */ #define SVs_PADMY 0x00000400 /* in use a "my" variable */ #define SVs_TEMP 0x00000800 /* string is stealable? */ @@ -207,7 +187,7 @@ perform the upgrade if necessary. See C. #define SVp_POK 0x04000000 /* has valid non-public pointer value */ #define SVp_SCREAM 0x08000000 /* has been studied? */ -#define SVf_UTF8 0x20000000 /* SvPVX is UTF-8 encoded */ +#define SVf_UTF8 0x20000000 /* SvPV is UTF-8 encoded */ #define SVf_THINKFIRST (SVf_READONLY|SVf_ROK|SVf_FAKE) @@ -216,7 +196,7 @@ perform the upgrade if necessary. See C. #define SVf_AMAGIC 0x10000000 /* has magical overloaded methods */ -#define PRIVSHIFT 8 +#define PRIVSHIFT 8 /* (SVp_?OK >> PRIVSHIFT) == SVf_?OK */ /* Some private flags. */ @@ -294,7 +274,8 @@ struct xpvlv { STRLEN xlv_targoff; STRLEN xlv_targlen; SV* xlv_targ; - char xlv_type; + char xlv_type; /* k=keys .=pos x=substr v=vec /=join/re + * y=alem/helem/iter t=tie T=tied HE */ }; struct xpvgv { @@ -327,7 +308,7 @@ struct xpvbm { U8 xbm_rare; /* rarest character in string */ }; -/* This structure much match XPVCV in cv.h */ +/* This structure must match XPVCV in cv.h */ typedef U16 cv_flags_t; @@ -350,12 +331,10 @@ struct xpvfm { long xcv_depth; /* >= 2 indicates recursive call */ AV * xcv_padlist; CV * xcv_outside; -#ifdef USE_5005THREADS - perl_mutex *xcv_mutexp; /* protects xcv_owner */ - struct perl_thread *xcv_owner; /* current owner thread */ -#endif /* USE_5005THREADS */ cv_flags_t xcv_flags; - + U32 xcv_outside_seq; /* the COP sequence (at the point of our + * compilation) in the lexically enclosing + * sub */ IV xfm_lines; }; @@ -407,7 +386,6 @@ struct xpvio { #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) */ -#define IOf_DIR_UTF8 128 /* readdir tries to return utf8 */ /* The following macros define implementation-independent predicates on SVs. */ @@ -488,6 +466,9 @@ Unsets the PV status of an SV. Tells an SV that it is a string and disables all other OK bits. Will also turn off the UTF8 status. +=for apidoc Am|bool|SvVOK|SV* sv +Returns a boolean indicating whether the SV contains a v-string. + =for apidoc Am|bool|SvOOK|SV* sv Returns a boolean indicating whether the SvIVX is a valid offset value for the SvPVX. This hack is used internally to speed up removal of characters @@ -547,24 +528,34 @@ Set the length of the string which is in the SV. See C. #define SvNIOK_off(sv) (SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK| \ SVp_IOK|SVp_NOK|SVf_IVisUV)) +#ifdef __GNUC__ +#define assert_not_ROK(sv) ({assert(!SvROK(sv) || !SvRV(sv))}), +#else +#define assert_not_ROK(sv) +#endif + #define SvOK(sv) (SvFLAGS(sv) & SVf_OK) -#define SvOK_off(sv) (SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \ +#define SvOK_off(sv) (assert_not_ROK(sv) \ + SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \ SVf_IVisUV|SVf_UTF8), \ SvOOK_off(sv)) -#define SvOK_off_exc_UV(sv) (SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \ +#define SvOK_off_exc_UV(sv) (assert_not_ROK(sv) \ + SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \ 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) ((void)SvOOK_off(sv), SvFLAGS(sv) |= SVp_IOK) +#define SvIOKp_on(sv) (SvRELEASE_IVX(sv), \ + SvFLAGS(sv) |= SVp_IOK) #define SvNOKp(sv) (SvFLAGS(sv) & SVp_NOK) #define SvNOKp_on(sv) (SvFLAGS(sv) |= SVp_NOK) #define SvPOKp(sv) (SvFLAGS(sv) & SVp_POK) -#define SvPOKp_on(sv) (SvFLAGS(sv) |= SVp_POK) +#define SvPOKp_on(sv) (assert_not_ROK(sv) \ + SvFLAGS(sv) |= SVp_POK) #define SvIOK(sv) (SvFLAGS(sv) & SVf_IOK) -#define SvIOK_on(sv) ((void)SvOOK_off(sv), \ +#define SvIOK_on(sv) (SvRELEASE_IVX(sv), \ SvFLAGS(sv) |= (SVf_IOK|SVp_IOK)) #define SvIOK_off(sv) (SvFLAGS(sv) &= ~(SVf_IOK|SVp_IOK|SVf_IVisUV)) #define SvIOK_only(sv) ((void)SvOK_off(sv), \ @@ -611,15 +602,19 @@ and leaves the UTF8 status as it was. #define SvUTF8_off(sv) (SvFLAGS(sv) &= ~(SVf_UTF8)) #define SvPOK(sv) (SvFLAGS(sv) & SVf_POK) -#define SvPOK_on(sv) (SvFLAGS(sv) |= (SVf_POK|SVp_POK)) +#define SvPOK_on(sv) (assert_not_ROK(sv) \ + SvFLAGS(sv) |= (SVf_POK|SVp_POK)) #define SvPOK_off(sv) (SvFLAGS(sv) &= ~(SVf_POK|SVp_POK)) -#define SvPOK_only(sv) (SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \ +#define SvPOK_only(sv) (assert_not_ROK(sv) \ + SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \ SVf_IVisUV|SVf_UTF8), \ SvFLAGS(sv) |= (SVf_POK|SVp_POK)) -#define SvPOK_only_UTF8(sv) (SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \ +#define SvPOK_only_UTF8(sv) (assert_not_ROK(sv) \ + SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \ SVf_IVisUV), \ SvFLAGS(sv) |= (SVf_POK|SVp_POK)) +#define SvVOK(sv) (SvMAGICAL(sv) && mg_find(sv,'V')) #define SvOOK(sv) (SvFLAGS(sv) & SVf_OOK) #define SvOOK_on(sv) ((void)SvIOK_off(sv), SvFLAGS(sv) |= SVf_OOK) #define SvOOK_off(sv) (SvOOK(sv) && sv_backoff(sv)) @@ -668,14 +663,16 @@ and leaves the UTF8 status as it was. #define SvTHINKFIRST(sv) (SvFLAGS(sv) & SVf_THINKFIRST) -#define SvPADBUSY(sv) (SvFLAGS(sv) & SVs_PADBUSY) +#define SvPADSTALE(sv) (SvFLAGS(sv) & SVs_PADSTALE) +#define SvPADSTALE_on(sv) (SvFLAGS(sv) |= SVs_PADSTALE) +#define SvPADSTALE_off(sv) (SvFLAGS(sv) &= ~SVs_PADSTALE) #define SvPADTMP(sv) (SvFLAGS(sv) & SVs_PADTMP) -#define SvPADTMP_on(sv) (SvFLAGS(sv) |= SVs_PADTMP|SVs_PADBUSY) +#define SvPADTMP_on(sv) (SvFLAGS(sv) |= SVs_PADTMP) #define SvPADTMP_off(sv) (SvFLAGS(sv) &= ~SVs_PADTMP) #define SvPADMY(sv) (SvFLAGS(sv) & SVs_PADMY) -#define SvPADMY_on(sv) (SvFLAGS(sv) |= SVs_PADMY|SVs_PADBUSY) +#define SvPADMY_on(sv) (SvFLAGS(sv) |= SVs_PADMY) #define SvTEMP(sv) (SvFLAGS(sv) & SVs_TEMP) #define SvTEMP_on(sv) (SvFLAGS(sv) |= SVs_TEMP) @@ -925,6 +922,14 @@ Like C, but converts sv to byte representation first if necessary. Guarantees to evaluate sv only once; use the more efficient C otherwise. +=for apidoc Am|bool|SvIsCOW|SV* sv +Returns a boolean 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. =cut */ @@ -996,7 +1001,7 @@ otherwise. #define SvPVutf8x_force(sv, lp) sv_pvutf8n_force(sv, &lp) #define SvPVbytex_force(sv, lp) sv_pvbyten_force(sv, &lp) -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && !defined(PERL_GCC_PEDANTIC) # define SvIVx(sv) ({SV *nsv = (SV*)(sv); SvIV(nsv); }) # define SvUVx(sv) ({SV *nsv = (SV*)(sv); SvUV(nsv); }) @@ -1024,28 +1029,16 @@ otherwise. #else /* __GNUC__ */ -# ifdef USE_5005THREADS -# define SvIVx(sv) sv_iv(sv) -# define SvUVx(sv) sv_uv(sv) -# define SvNVx(sv) sv_nv(sv) -# define SvPVx(sv, lp) sv_pvn(sv, &lp) -# define SvPVutf8x(sv, lp) sv_pvutf8n(sv, &lp) -# define SvPVbytex(sv, lp) sv_pvbyten(sv, &lp) -# define SvTRUE(sv) SvTRUEx(sv) -# define SvTRUEx(sv) sv_true(sv) - -# else /* USE_5005THREADS */ - /* These inlined macros use globals, which will require a thread * declaration in user code, so we avoid them under threads */ -# define SvIVx(sv) ((PL_Sv = (sv)), SvIV(PL_Sv)) -# define SvUVx(sv) ((PL_Sv = (sv)), SvUV(PL_Sv)) -# define SvNVx(sv) ((PL_Sv = (sv)), SvNV(PL_Sv)) -# define SvPVx(sv, lp) ((PL_Sv = (sv)), SvPV(PL_Sv, lp)) -# define SvPVutf8x(sv, lp) ((PL_Sv = (sv)), SvPVutf8(PL_Sv, lp)) -# define SvPVbytex(sv, lp) ((PL_Sv = (sv)), SvPVbyte(PL_Sv, lp)) -# define SvTRUE(sv) ( \ +# define SvIVx(sv) ((PL_Sv = (sv)), SvIV(PL_Sv)) +# define SvUVx(sv) ((PL_Sv = (sv)), SvUV(PL_Sv)) +# define SvNVx(sv) ((PL_Sv = (sv)), SvNV(PL_Sv)) +# define SvPVx(sv, lp) ((PL_Sv = (sv)), SvPV(PL_Sv, lp)) +# define SvPVutf8x(sv, lp) ((PL_Sv = (sv)), SvPVutf8(PL_Sv, lp)) +# define SvPVbytex(sv, lp) ((PL_Sv = (sv)), SvPVbyte(PL_Sv, lp)) +# define SvTRUE(sv) ( \ !sv \ ? 0 \ : SvPOK(sv) \ @@ -1060,14 +1053,45 @@ otherwise. : SvNOK(sv) \ ? SvNVX(sv) != 0.0 \ : sv_2bool(sv) ) -# define SvTRUEx(sv) ((PL_Sv = (sv)), SvTRUE(PL_Sv)) -# endif /* USE_5005THREADS */ +# define SvTRUEx(sv) ((PL_Sv = (sv)), SvTRUE(PL_Sv)) #endif /* __GNU__ */ +#define SvIsCOW(sv) ((SvFLAGS(sv) & (SVf_FAKE | SVf_READONLY)) == \ + (SVf_FAKE | SVf_READONLY)) +#define SvIsCOW_shared_hash(sv) (SvIsCOW(sv) && SvLEN(sv) == 0) /* flag values for sv_*_flags functions */ #define SV_IMMEDIATE_UNREF 1 #define SV_GMAGIC 2 +#define SV_COW_DROP_PV 4 +#define SV_UTF8_NO_ENCODING 8 + +/* We are about to replace the SV's current value. So if it's copy on write + we need to normalise it. Use the SV_COW_DROP_PV flag hint to say that + the value is about to get thrown away, so drop the PV rather than go to + the effort of making a read-write copy only for it to get immediately + discarded. */ + +#define SV_CHECK_THINKFIRST_COW_DROP(sv) if (SvTHINKFIRST(sv)) \ + sv_force_normal_flags(sv, SV_COW_DROP_PV) + +#ifdef PERL_COPY_ON_WRITE +# define SvRELEASE_IVX(sv) ((void)((SvFLAGS(sv) & (SVf_OOK|SVf_READONLY|SVf_FAKE)) \ + && Perl_sv_release_IVX(aTHX_ sv))) +# define SvIsCOW_normal(sv) (SvIsCOW(sv) && SvLEN(sv)) + +#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_AMAGIC) +#define CAN_COW_FLAGS (SVp_POK|SVf_POK) + +#else +# define SvRELEASE_IVX(sv) ((void)SvOOK_off(sv)) +#endif /* PERL_COPY_ON_WRITE */ + +#define SV_CHECK_THINKFIRST(sv) if (SvTHINKFIRST(sv)) \ + sv_force_normal_flags(sv, 0) + /* all these 'functions' are now just macros */ @@ -1088,6 +1112,17 @@ otherwise. #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) +/* Should be named SvCatPVN_utf8_upgrade? */ +#define sv_catpvn_utf8_upgrade(dsv, sstr, slen, nsv) \ + STMT_START { \ + if (!(nsv)) \ + nsv = sv_2mortal(newSVpvn(sstr, slen)); \ + else \ + sv_setpvn(nsv, sstr, slen); \ + SvUTF8_off(nsv); \ + sv_utf8_upgrade(nsv); \ + sv_catsv(dsv, nsv); \ + } STMT_END /* =for apidoc Am|SV*|newRV_inc|SV* sv @@ -1185,6 +1220,7 @@ Returns a pointer to the character buffer. #define SvSetMagicSV_nosteal(dst,src) \ SvSetSV_nosteal_and(dst,src,SvSETMAGIC(dst)) + #if !defined(SKIP_DEBUGGING) #define SvPEEK(sv) sv_peek(sv) #else @@ -1203,8 +1239,10 @@ Returns a pointer to the character buffer. #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; };