X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=sv.h;h=6b4a125d39c9e3e3a938cbec50e215a4ed91eae1;hb=c4f23d77f4b3486a36335c4460cbfd4e81e37892;hp=36fa72d74997b91454c95245fcbf29a8bbe1e55f;hpb=5f05dabc4054964aa3b10f44f8468547f051cdf8;p=p5sagit%2Fp5-mst-13.2.git diff --git a/sv.h b/sv.h index 36fa72d..6b4a125 100644 --- a/sv.h +++ b/sv.h @@ -1,6 +1,6 @@ /* sv.h * - * Copyright (c) 1991-1994, Larry Wall + * Copyright (c) 1991-1997, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -70,17 +70,53 @@ struct io { #define SvANY(sv) (sv)->sv_any #define SvFLAGS(sv) (sv)->sv_flags - #define SvREFCNT(sv) (sv)->sv_refcnt -#ifdef CRIPPLED_CC -#define SvREFCNT_inc(sv) sv_newref((SV*)sv) -#define SvREFCNT_dec(sv) sv_free((SV*)sv) + +#ifdef USE_THREADS + +# ifndef EMULATE_ATOMIC_REFCOUNTS +# include "atomic.h" +# endif + +# ifdef EMULATE_ATOMIC_REFCOUNTS +# define ATOMIC_INC(count) STMT_START { \ + MUTEX_LOCK(&svref_mutex); \ + ++count; \ + MUTEX_UNLOCK(&svref_mutex); \ + } STMT_END +# define ATOMIC_DEC_AND_TEST(res,count) STMT_START { \ + MUTEX_LOCK(&svref_mutex); \ + res = (--count == 0); \ + MUTEX_UNLOCK(&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 */ #else -#define SvREFCNT_inc(sv) ((Sv = (SV*)(sv)), \ - (Sv && ++SvREFCNT(Sv)), (SV*)Sv) -#define SvREFCNT_dec(sv) sv_free((SV*)sv) +# define ATOMIC_INC(count) (++count) +# define ATOMIC_DEC_AND_TEST(res, count) (res = (--count == 0)) +#endif /* USE_THREADS */ + +#ifdef __GNUC__ +# define SvREFCNT_inc(sv) \ + ({ \ + SV *nsv = (SV*)(sv); \ + if (nsv) \ + ATOMIC_INC(SvREFCNT(nsv)); \ + nsv; \ + }) +#else +# if defined(CRIPPLED_CC) || defined(USE_THREADS) +# define SvREFCNT_inc(sv) sv_newref((SV*)sv) +# else +# define SvREFCNT_inc(sv) \ + ((Sv=(SV*)(sv)), (Sv && ATOMIC_INC(SvREFCNT(Sv))), (SV*)Sv) +# endif #endif +#define SvREFCNT_dec(sv) sv_free((SV*)sv) + #define SVTYPEMASK 0xff #define SvTYPE(sv) ((sv)->sv_flags & SVTYPEMASK) @@ -131,11 +167,6 @@ struct io { #define SVphv_SHAREKEYS 0x20000000 /* keys live on shared string table */ #define SVphv_LAZYDEL 0x40000000 /* entry in xhv_eiter must be deleted */ -#ifdef OVERLOAD -#define SVpgv_AM 0x40000000 -/* #define SVpgv_badAM 0x20000000 */ -#endif /* OVERLOAD */ - struct xrv { SV * xrv_rv; /* pointer to another SV */ }; @@ -168,6 +199,7 @@ struct xpvnv { double xnv_nv; /* numeric value, if any */ }; +/* These structure must match the beginning of struct xpvhv in hv.h. */ struct xpvmg { char * xpv_pv; /* pointer to malloced string */ STRLEN xpv_cur; /* length of xpv_pv as a C string */ @@ -223,6 +255,10 @@ struct xpvbm { U8 xbm_rare; /* rarest character in string */ }; +/* This structure much match XPVCV */ + +typedef U16 cv_flags_t; + struct xpvfm { char * xpv_pv; /* pointer to malloced string */ STRLEN xpv_cur; /* length of xpv_pv as a C string */ @@ -242,6 +278,12 @@ struct xpvfm { long xcv_depth; /* >= 2 indicates recursive call */ AV * xcv_padlist; CV * xcv_outside; +#ifdef USE_THREADS + perl_mutex *xcv_mutexp; /* protects xcv_owner */ + struct perl_thread *xcv_owner; /* current owner thread */ +#endif /* USE_THREADS */ + cv_flags_t xcv_flags; + I32 xfm_lines; }; @@ -482,26 +524,31 @@ struct xpvio { #define SvTAINTED_on(sv) STMT_START{ if(tainting){sv_taint(sv);} }STMT_END #define SvTAINTED_off(sv) STMT_START{ if(tainting){sv_untaint(sv);} }STMT_END -#define SvTAINT(sv) STMT_START{ if(tainted){SvTAINTED_on(sv);} }STMT_END +#define SvTAINT(sv) \ + STMT_START { \ + if (tainting) { \ + dTHR; \ + if (tainted) \ + SvTAINTED_on(sv); \ + } \ + } STMT_END -#ifdef CRIPPLED_CC - -IV SvIV _((SV* sv)); -UV SvUV _((SV* sv)); -double SvNV _((SV* sv)); #define SvPV_force(sv, lp) sv_pvn_force(sv, &lp) #define SvPV(sv, lp) sv_pvn(sv, &lp) -char *sv_pvn _((SV *, STRLEN *)); -I32 SvTRUE _((SV *)); - -#define SvIVx(sv) SvIV(sv) -#define SvUVx(sv) SvUV(sv) -#define SvNVx(sv) SvNV(sv) +#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 SvPVx_force(sv, lp) sv_pvn_force(sv, &lp) -#define SvTRUEx(sv) SvTRUE(sv) +#define SvTRUEx(sv) sv_true(sv) -#else /* !CRIPPLED_CC */ +#define SvIV(sv) SvIVx(sv) +#define SvNV(sv) SvNVx(sv) +#define SvUV(sv) SvIVx(sv) +#define SvTRUE(sv) SvTRUEx(sv) + +#ifndef CRIPPLED_CC +/* redefine some things to more efficient inlined versions */ #undef SvIV #define SvIV(sv) (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) @@ -521,8 +568,51 @@ I32 SvTRUE _((SV *)); ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \ ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvn_force(sv, &lp)) -#undef SvTRUE -#define SvTRUE(sv) ( \ +#ifdef __GNUC__ +# undef SvIVx +# undef SvUVx +# undef SvNVx +# undef SvPVx +# undef SvTRUE +# undef SvTRUEx +# define SvIVx(sv) ({SV *nsv = (SV*)(sv); SvIV(nsv); }) +# define SvUVx(sv) ({SV *nsv = (SV*)(sv); SvUV(nsv); }) +# define SvNVx(sv) ({SV *nsv = (SV*)(sv); SvNV(nsv); }) +# define SvPVx(sv, lp) ({SV *nsv = (sv); SvPV(nsv, lp); }) +# define SvTRUE(sv) ( \ + !sv \ + ? 0 \ + : SvPOK(sv) \ + ? (({XPV *nxpv = (XPV*)SvANY(sv); \ + nxpv && \ + (*nxpv->xpv_pv > '0' || \ + nxpv->xpv_cur > 1 || \ + (nxpv->xpv_cur && *nxpv->xpv_pv != '0')); }) \ + ? 1 \ + : 0) \ + : \ + SvIOK(sv) \ + ? SvIVX(sv) != 0 \ + : SvNOK(sv) \ + ? SvNVX(sv) != 0.0 \ + : sv_2bool(sv) ) +# define SvTRUEx(sv) ({SV *nsv = (sv); SvTRUE(nsv); }) +#else /* __GNUC__ */ +#ifndef USE_THREADS +/* These inlined macros use globals, which will require a thread + * declaration in user code, so we avoid them under threads */ + +# undef SvIVx +# undef SvUVx +# undef SvNVx +# undef SvPVx +# undef SvTRUE +# undef SvTRUEx +# define SvIVx(sv) ((Sv = (sv)), SvIV(Sv)) +# define SvUVx(sv) ((Sv = (sv)), SvUV(Sv)) +# define SvNVx(sv) ((Sv = (sv)), SvNV(Sv)) +# define SvPVx(sv, lp) ((Sv = (sv)), SvPV(Sv, lp)) +# define SvTRUE(sv) ( \ !sv \ ? 0 \ : SvPOK(sv) \ @@ -538,32 +628,62 @@ I32 SvTRUE _((SV *)); : SvNOK(sv) \ ? SvNVX(sv) != 0.0 \ : sv_2bool(sv) ) - -#define SvIVx(sv) ((Sv = (sv)), SvIV(Sv)) -#define SvUVx(sv) ((Sv = (sv)), SvUV(Sv)) -#define SvNVx(sv) ((Sv = (sv)), SvNV(Sv)) -#define SvPVx(sv, lp) ((Sv = (sv)), SvPV(Sv, lp)) -#define SvTRUEx(sv) ((Sv = (sv)), SvTRUE(Sv)) - -#endif /* CRIPPLED_CC */ +# define SvTRUEx(sv) ((Sv = (sv)), SvTRUE(Sv)) +#endif /* !USE_THREADS */ +#endif /* !__GNU__ */ +#endif /* !CRIPPLED_CC */ #define newRV_inc(sv) newRV(sv) -#ifdef CRIPPLED_CC -SV *newRV_noinc _((SV *)); +#ifdef __GNUC__ +# undef newRV_noinc +# define newRV_noinc(sv) ({SV *nsv=newRV((sv)); --SvREFCNT(SvRV(nsv)); nsv;}) #else -#define newRV_noinc(sv) ((Sv = newRV(sv)), --SvREFCNT(SvRV(Sv)), Sv) -#endif - -/* the following macro updates any magic values this sv is associated with */ - -#define SvSETMAGIC(x) if (SvSMAGICAL(x)) mg_set(x) - -#define SvSetSV(dst,src) if (dst != src) sv_setsv(dst,src) +# if defined(CRIPPLED_CC) || defined(USE_THREADS) +# else +# undef newRV_noinc +# define newRV_noinc(sv) ((Sv = newRV(sv)), --SvREFCNT(SvRV(Sv)), Sv) +# endif +#endif /* __GNUC__ */ + +/* the following macros update any magic values this sv is associated with */ + +#define SvGETMAGIC(x) STMT_START { if (SvGMAGICAL(x)) mg_get(x); } STMT_END +#define SvSETMAGIC(x) STMT_START { if (SvSMAGICAL(x)) mg_set(x); } STMT_END + +#define SvSetSV_and(dst,src,finally) \ + STMT_START { \ + if ((dst) != (src)) { \ + sv_setsv(dst, src); \ + finally; \ + } \ + } STMT_END +#define SvSetSV_nosteal_and(dst,src,finally) \ + STMT_START { \ + if ((dst) != (src)) { \ + U32 tMpF = SvFLAGS(src) & SVs_TEMP; \ + SvTEMP_off(src); \ + sv_setsv(dst, src); \ + SvFLAGS(src) |= tMpF; \ + 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)) #define SvPEEK(sv) sv_peek(sv) #define SvIMMORTAL(sv) ((sv)==&sv_undef || (sv)==&sv_yes || (sv)==&sv_no) +#define boolSV(b) ((b) ? &sv_yes : &sv_no) + #define isGV(sv) (SvTYPE(sv) == SVt_PVGV) #ifndef DOSISH