X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=sv.h;h=f7a7ba09350e6ce699a3afe31f9cec9f4501950e;hb=44a10c71f5d5adc63a15c1d8fb5e8b72de48836f;hp=379175a73252852ed9d4a2f7685439f38ecfc2fd;hpb=78d0cf80609ca6ef7050cc76fbcfe7807885b9ce;p=p5sagit%2Fp5-mst-13.2.git diff --git a/sv.h b/sv.h index 379175a..f7a7ba0 100644 --- a/sv.h +++ b/sv.h @@ -48,11 +48,12 @@ typedef enum { SVt_IV, /* 1 */ SVt_NV, /* 2 */ SVt_RV, /* 3 */ - SVt_PV, /* 4 */ - SVt_PVIV, /* 5 */ - SVt_PVNV, /* 6 */ - SVt_PVMG, /* 7 */ - SVt_PVBM, /* 8 */ + SVt_BIND, /* 4 */ + SVt_PV, /* 5 */ + SVt_PVIV, /* 6 */ + SVt_PVNV, /* 7 */ + SVt_PVMG, /* 8 */ + /* PVBM was here, before BIND replaced it. */ SVt_PVGV, /* 9 */ SVt_PVLV, /* 10 */ SVt_PVAV, /* 11 */ @@ -63,6 +64,13 @@ typedef enum { SVt_LAST /* keep last in enum. used to size arrays */ } svtype; +#ifndef PERL_CORE +/* Although Fast Boyer Moore tables are now being stored in PVGVs, for most + purposes eternal code wanting to consider PVBM probably needs to think of + PVMG instead. */ +# define SVt_PVBM SVt_PVMG +#endif + /* There is collusion here with sv_clear - sv_clear exits early for SVt_NULL and SVt_IV, so never reaches the clause at the end that uses sv_type_details->body_size to determine whether to call safefree(). Hence @@ -275,52 +283,56 @@ perform the upgrade if necessary. See C. #define SvUPGRADE(sv, mt) (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 /* has been studied? */ -#define SVphv_CLONEABLE 0x00008000 /* PVHV (stashes) clone its objects */ - -#define SVs_PADSTALE 0x00010000 /* lexical has gone out of scope */ -#define SVpad_STATE 0x00010000 /* pad name is a "state" var */ -#define SVs_PADTMP 0x00020000 /* in use as tmp */ -#define SVpad_TYPED 0x00020000 /* pad name is a Typed Lexical */ -#define SVs_PADMY 0x00040000 /* in use a "my" variable */ -#define SVpad_OUR 0x00040000 /* pad name is "our" instead of "my" */ -#define SVs_TEMP 0x00080000 /* 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 or lexical is just a copy - 1: SV head arena wasn't malloc()ed - 2: in conjunction with SVf_READONLY - marks a shared hash key scalar - (SvLEN == 0) or a copy on write - string (SvLEN != 0) [SvIsCOW(sv)] - 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 - 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 - recalculated */ -#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 SV's in final arena cleanup */ -#define SVf_READONLY 0x08000000 /* may not be modified */ +#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 /* has been studied? */ +#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 + CvIMPORTED_CV_ON() if it needs to be + expanded to a real GV */ + +#define SVs_PADSTALE 0x00010000 /* lexical has gone out of scope */ +#define SVpad_STATE 0x00010000 /* pad name is a "state" var */ +#define SVs_PADTMP 0x00020000 /* in use as tmp */ +#define SVpad_TYPED 0x00020000 /* pad name is a Typed Lexical */ +#define SVs_PADMY 0x00040000 /* in use a "my" variable */ +#define SVpad_OUR 0x00040000 /* pad name is "our" instead of "my" */ +#define SVs_TEMP 0x00080000 /* 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 or lexical is just a copy + 1: SV head arena wasn't malloc()ed + 2: in conjunction with SVf_READONLY + marks a shared hash key scalar + (SvLEN == 0) or a copy on write + string (SvLEN != 0) [SvIsCOW(sv)] + 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 + 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 + recalculated */ +#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 + SV's in final arena cleanup */ +#define SVf_READONLY 0x08000000 /* may not be modified */ @@ -328,51 +340,64 @@ perform the upgrade if necessary. See C. #define SVf_THINKFIRST (SVf_READONLY|SVf_ROK|SVf_FAKE) #define SVf_OK (SVf_IOK|SVf_NOK|SVf_POK|SVf_ROK| \ - SVp_IOK|SVp_NOK|SVp_POK|SVp_SCREAM) + SVp_IOK|SVp_NOK|SVp_POK|SVpgv_GP) #define PRIVSHIFT 4 /* (SVp_?OK >> PRIVSHIFT) == SVf_?OK */ -#define SVf_AMAGIC 0x10000000 /* has magical overloaded methods */ -#define SVf_UTF8 0x20000000 /* SvPV is UTF-8 encoded */ +#define SVf_AMAGIC 0x10000000 /* has magical overloaded methods */ +#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() */ + /* Ensure this value does not clash with the GV_ADD* flags in gv.h */ /* Some private flags. */ /* PVHV */ -#define SVphv_SHAREKEYS 0x20000000 /* PVHV - keys live on shared string table */ -/* PVNV, PVMG, PVGV, presumably only inside pads */ -#define SVpad_NAME 0x40000000 /* This SV is a name in the PAD, so - SVpad_TYPED, SVpad_OUR and - SVpad_STATE apply */ +#define SVphv_SHAREKEYS 0x20000000 /* PVHV keys live on shared string table */ +/* PVNV, PVMG, presumably only inside pads */ +#define SVpad_NAME 0x40000000 /* This SV is a name in the PAD, so + SVpad_TYPED, SVpad_OUR and SVpad_STATE + apply */ /* PVAV */ -#define SVpav_REAL 0x40000000 /* free old entries */ +#define SVpav_REAL 0x40000000 /* free old entries */ /* PVHV */ -#define SVphv_LAZYDEL 0x40000000 /* entry in xhv_eiter must be deleted */ -/* Not just PVBM - basically anything that can be a regular scalar */ +#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 /* ??? */ -#define SVrepl_EVAL 0x40000000 /* Replacement part of s///e */ +#define SVrepl_EVAL 0x40000000 /* Replacement part of s///e */ /* IV, PVIV, PVNV, PVMG, PVGV and (I assume) PVLV */ /* Presumably IVs aren't stored in pads */ -#define SVf_IVisUV 0x80000000 /* use XPVUV instead of XPVIV */ +#define SVf_IVisUV 0x80000000 /* use XPVUV instead of XPVIV */ /* PVAV */ -#define SVpav_REIFY 0x80000000 /* can become real */ +#define SVpav_REIFY 0x80000000 /* can become real */ /* PVHV */ -#define SVphv_HASKFLAGS 0x80000000 /* keys have flag byte after hash */ +#define SVphv_HASKFLAGS 0x80000000 /* keys have flag byte after hash */ /* PVFM */ -#define SVpfm_COMPILED 0x80000000 /* FORMLINE is compiled */ -/* PVBM */ +#define SVpfm_COMPILED 0x80000000 /* FORMLINE is compiled */ +/* 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 */ +#define SVprv_WEAKREF 0x80000000 /* Weak reference */ struct xpv { union { 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 */ + struct { + U32 xbm_previous; /* how many characters in string before rare? */ + U8 xbm_flags; + U8 xbm_rare; /* rarest character in string */ + } xbm_s; /* fields from PVBM */ } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ @@ -391,6 +416,15 @@ struct xpviv { union { 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 */ + struct { + U32 xbm_previous; /* how many characters in string before rare? */ + U8 xbm_flags; + U8 xbm_rare; /* rarest character in string */ + } xbm_s; /* fields from PVBM */ } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ @@ -425,6 +459,15 @@ struct xpvuv { union { 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 */ + struct { + U32 xbm_previous; /* how many characters in string before rare? */ + U8 xbm_flags; + U8 xbm_rare; /* rarest character in string */ + } xbm_s; /* fields from PVBM */ } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ @@ -442,6 +485,15 @@ struct xpvnv { union { 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 */ + struct { + U32 xbm_previous; /* how many characters in string before rare? */ + U8 xbm_flags; + U8 xbm_rare; /* rarest character in string */ + } xbm_s; /* fields from PVBM */ } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ @@ -459,6 +511,15 @@ struct xpvmg { union { 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 */ + struct { + U32 xbm_previous; /* how many characters in string before rare? */ + U8 xbm_flags; + U8 xbm_rare; /* rarest character in string */ + } xbm_s; /* fields from PVBM */ } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ @@ -480,6 +541,15 @@ struct xpvlv { union { 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 */ + struct { + U32 xbm_previous; /* how many characters in string before rare? */ + U8 xbm_flags; + U8 xbm_rare; /* rarest character in string */ + } xbm_s; /* fields from PVBM */ } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ @@ -503,10 +573,21 @@ struct xpvlv { * y=alem/helem/iter t=tie T=tied HE */ }; +/* This structure works in 3 ways - regular scalar, GV with GP, or fast + Boyer-Moore. */ struct xpvgv { union { NV xnv_nv; HV * xgv_stash; /* The stash of this GV */ + struct { + U32 xlow; + U32 xhigh; + } xpad_cop_seq; /* used by pad.c for cop_sequence */ + struct { + U32 xbm_previous; /* how many characters in string before rare? */ + U8 xbm_flags; + U8 xbm_rare; /* rarest character in string */ + } xbm_s; /* fields from PVBM */ } xnv_u; STRLEN xpv_cur; /* xgv_flags */ STRLEN xpv_len; /* 0 */ @@ -514,30 +595,8 @@ struct xpvgv { IV xivu_iv; UV xivu_uv; void * xivu_p1; - I32 xivu_i32; - HEK * xivu_namehek; /* GvNAME */ - } xiv_u; - union { - MAGIC* xmg_magic; /* linked list of magicalness */ - HV* xmg_ourstash; /* Stash for our (when SvPAD_OUR is true) */ - } xmg_u; - HV* xmg_stash; /* class package */ - -}; - -struct xpvbm { - union { - NV xnv_nv; /* numeric value, if any */ - HV * xgv_stash; - } xnv_u; - STRLEN xpv_cur; /* length of svu_pv as a C string */ - STRLEN xpv_len; /* allocated size */ - union { - IV xivu_iv; /* integer value or pv offset */ - UV xivu_uv; - void * xivu_p1; I32 xivu_i32; /* is this constant pattern being useful? */ - HEK * xivu_namehek; + HEK * xivu_namehek; /* GvNAME */ } xiv_u; union { MAGIC* xmg_magic; /* linked list of magicalness */ @@ -545,8 +604,6 @@ struct xpvbm { } xmg_u; HV* xmg_stash; /* class package */ - U16 xbm_previous; /* how many characters in string before rare? */ - U8 xbm_rare; /* rarest character in string */ }; /* This structure must match XPVCV in cv.h */ @@ -557,6 +614,15 @@ struct xpvfm { union { 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 */ + struct { + U32 xbm_previous; /* how many characters in string before rare? */ + U8 xbm_flags; + U8 xbm_rare; /* rarest character in string */ + } xbm_s; /* fields from PVBM */ } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ @@ -633,6 +699,15 @@ struct xpvio { union { 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 */ + struct { + U32 xbm_previous; /* how many characters in string before rare? */ + U8 xbm_flags; + U8 xbm_rare; /* rarest character in string */ + } xbm_s; /* fields from PVBM */ } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ @@ -916,6 +991,8 @@ Set the actual length of the string which is in the SV. See C. /* =for apidoc Am|bool|SvUTF8|SV* sv Returns a boolean indicating whether the SV contains UTF-8 encoded data. +Call this after SvPV() in case any call to string overloading updates the +internal flag. =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). @@ -1021,6 +1098,11 @@ the scalar's value cannot change unless written to. #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)) + #define SvTHINKFIRST(sv) (SvFLAGS(sv) & SVf_THINKFIRST) #define SvPADSTALE(sv) (SvFLAGS(sv) & SVs_PADSTALE) @@ -1059,6 +1141,20 @@ 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_on(sv) ({ SV *const thwacke = (SV *) (sv); \ + assert(!isGV_with_GP(thwacke)); \ + (SvFLAGS(thwacke) |= SVpbm_VALID); \ + }) +# define SvVALID_off(sv) ({ SV *const thwacke = (SV *) (sv); \ + assert(!isGV_with_GP(thwacke)); \ + (SvFLAGS(thwacke) &= ~SVpbm_VALID); \ + }) + # define SvTAIL(sv) ({ SV *const _svi = (SV *) (sv); \ assert(SvTYPE(_svi) != SVt_PVAV); \ assert(SvTYPE(_svi) != SVt_PVHV); \ @@ -1066,16 +1162,16 @@ the scalar's value cannot change unless written to. == (SVpbm_TAIL|SVpbm_VALID); \ }) #else +# define SvVALID(sv) (SvFLAGS(sv) & SVpbm_VALID) +# 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)); + == (SVpbm_TAIL|SVpbm_VALID)) #endif #define SvTAIL_on(sv) (SvFLAGS(sv) |= SVpbm_TAIL) #define SvTAIL_off(sv) (SvFLAGS(sv) &= ~SVpbm_TAIL) -#define SvVALID(sv) (SvFLAGS(sv) & SVpbm_VALID) -#define SvVALID_on(sv) (SvFLAGS(sv) |= SVpbm_VALID) -#define SvVALID_off(sv) (SvFLAGS(sv) &= ~SVpbm_VALID) #ifdef USE_ITHREADS /* The following uses the FAKE flag to show that a regex pointer is infact @@ -1087,15 +1183,34 @@ the scalar's value cannot change unless written to. #define SvPAD_TYPED(sv) \ ((SvFLAGS(sv) & (SVpad_NAME|SVpad_TYPED)) == (SVpad_NAME|SVpad_TYPED)) -#define SvPAD_TYPED_on(sv) (SvFLAGS(sv) |= SVpad_NAME|SVpad_TYPED) #define SvPAD_OUR(sv) \ ((SvFLAGS(sv) & (SVpad_NAME|SVpad_OUR)) == (SVpad_NAME|SVpad_OUR)) -#define SvPAD_OUR_on(sv) (SvFLAGS(sv) |= SVpad_NAME|SVpad_OUR) #define SvPAD_STATE(sv) \ ((SvFLAGS(sv) & (SVpad_NAME|SVpad_STATE)) == (SVpad_NAME|SVpad_STATE)) -#define SvPAD_STATE_on(sv) (SvFLAGS(sv) |= SVpad_NAME|SVpad_STATE) + +#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); \ + }) +#define SvPAD_OUR_on(sv) ({ \ + SV *const whap = (SV *) (sv); \ + assert(SvTYPE(whap) == SVt_PVMG); \ + (SvFLAGS(whap) |= 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); \ + }) +#else +# define SvPAD_TYPED_on(sv) (SvFLAGS(sv) |= SVpad_NAME|SVpad_TYPED) +# define SvPAD_OUR_on(sv) (SvFLAGS(sv) |= SVpad_NAME|SVpad_OUR) +# define SvPAD_STATE_on(sv) (SvFLAGS(sv) |= SVpad_NAME|SVpad_STATE) +#endif #define OURSTASH(sv) \ (SvPAD_OUR(sv) ? ((XPVMG*) SvANY(sv))->xmg_u.xmg_ourstash : NULL) @@ -1310,27 +1425,44 @@ the scalar's value cannot change unless written to. } \ } STMT_END + +#define PERL_FBM_TABLE_OFFSET 1 /* Number of bytes between EOS and table */ + +/* SvPOKp not SvPOK in the assertion because the string can be tainted! eg + perl -T -e '/$^X/' +*/ #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); \ + })) # define BmRARE(sv) \ - (*({ SV *const _svi = (SV *) (sv); \ - assert(SvTYPE(_svi) == SVt_PVBM); \ - &(((XPVBM*) SvANY(_svi))->xbm_rare); \ + (*({ SV *const uggh = (SV *) (sv); \ + assert(SvTYPE(uggh) == SVt_PVGV); \ + assert(SvVALID(uggh)); \ + &(((XPVGV*) SvANY(uggh))->xnv_u.xbm_s.xbm_rare); \ })) # define BmUSEFUL(sv) \ - (*({ SV *const _svi = (SV *) (sv); \ - assert(SvTYPE(_svi) == SVt_PVBM); \ - assert(!SvIOK(_svi)); \ - &(((XPVBM*) SvANY(_svi))->xiv_u.xivu_i32); \ + (*({ SV *const uggh = (SV *) (sv); \ + assert(SvTYPE(uggh) == SVt_PVGV); \ + assert(SvVALID(uggh)); \ + assert(!SvIOK(uggh)); \ + &(((XPVGV*) SvANY(uggh))->xiv_u.xivu_i32); \ })) # define BmPREVIOUS(sv) \ - (*({ SV *const _svi = (SV *) (sv); \ - assert(SvTYPE(_svi) == SVt_PVBM); \ - &(((XPVBM*) SvANY(_svi))->xbm_previous); \ + (*({ SV *const uggh = (SV *) (sv); \ + assert(SvTYPE(uggh) == SVt_PVGV); \ + assert(SvVALID(uggh)); \ + &(((XPVGV*) SvANY(uggh))->xnv_u.xbm_s.xbm_previous); \ })) #else -# define BmRARE(sv) ((XPVBM*) SvANY(sv))->xbm_rare -# define BmUSEFUL(sv) ((XPVBM*) SvANY(sv))->xiv_u.xivu_i32 -# define BmPREVIOUS(sv) ((XPVBM*) SvANY(sv))->xbm_previous +# define BmFLAGS(sv) ((XPVGV*) SvANY(sv))->xnv_u.xbm_s.xbm_flags +# define BmRARE(sv) ((XPVGV*) SvANY(sv))->xnv_u.xbm_s.xbm_rare +# define BmUSEFUL(sv) ((XPVGV*) SvANY(sv))->xiv_u.xivu_i32 +# define BmPREVIOUS(sv) ((XPVGV*) SvANY(sv))->xnv_u.xbm_s.xbm_previous + #endif #define FmLINES(sv) ((XPVFM*) SvANY(sv))->xfm_lines @@ -1903,8 +2035,21 @@ Returns a pointer to the character buffer. /* 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|SVp_SCREAM)) == SVp_SCREAM) \ + (((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 SvGROW(sv,len) (SvLEN(sv) < (len) ? sv_grow(sv,len) : SvPVX(sv)) #define SvGROW_mutable(sv,len) \