diff options
author | Nicholas Clark <nick@ccl4.org> | 2006-12-28 21:21:22 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2006-12-28 21:21:22 +0000 |
commit | 3441fb63c8a89050ee7151eb55228fe165595be1 (patch) | |
tree | 63644fc6c0ff184296ab16c31e79fc4eed1d9718 | |
parent | 809abb02185a4df0f7a1a043727bae7a5c08a798 (diff) | |
download | perl-3441fb63c8a89050ee7151eb55228fe165595be1.tar.gz |
Move the low/high cop sequences from NVX/IVX to a two U32 structure
in the xnv union. This frees up IVX for the PL_generation code, which
in turn will allow SvCUR to return to its real purpose.
p4raw-id: //depot/perl@29630
-rw-r--r-- | av.h | 4 | ||||
-rw-r--r-- | cv.h | 4 | ||||
-rw-r--r-- | hv.h | 4 | ||||
-rw-r--r-- | pad.c | 32 | ||||
-rw-r--r-- | pad.h | 57 | ||||
-rw-r--r-- | sv.h | 36 |
6 files changed, 119 insertions, 18 deletions
@@ -12,6 +12,10 @@ struct xpvav { 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 */ } xnv_u; SSize_t xav_fill; /* Index of last element present */ SSize_t xav_max; /* max index for which array has space */ @@ -14,6 +14,10 @@ struct xpvcv { 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 */ } xnv_u; STRLEN xpv_cur; /* length of xp_pv as a C string */ STRLEN xpv_len; /* allocated size */ @@ -52,6 +52,10 @@ struct xpvhv { 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 */ } xnv_u; STRLEN xhv_fill; /* how full xhv_array currently is */ STRLEN xhv_max; /* subscript of last element of xhv_array */ @@ -72,19 +72,19 @@ but only by their index allocated at compile time (which is usually in PL_op->op_targ), wasting a name SV for them doesn't make sense. The SVs in the names AV have their PV being the name of the variable. -NV+1..IV inclusive is a range of cop_seq numbers for which the name is -valid. For typed lexicals name SV is SVt_PVMG and SvSTASH points at the -type. For C<our> lexicals, the type is also SVt_PVMG, with the OURSTASH slot -pointing at the stash of the associated global (so that duplicate C<our> -declarations in the same package can be detected). SvCUR is sometimes -hijacked to store the generation number during compilation. +xlow+1..xhigh inclusive in the NV union is a range of cop_seq numbers for +which the name is valid. For typed lexicals name SV is SVt_PVMG and SvSTASH +points at the type. For C<our> lexicals, the type is also SVt_PVMG, with the +OURSTASH slot pointing at the stash of the associated global (so that +duplicate C<our> declarations in the same package can be detected). SvCUR is +sometimes hijacked to store the generation number during compilation. If SvFAKE is set on the name SV, then that slot in the frame AV is a REFCNT'ed reference to a lexical from "outside". In this case, -the name SV does not use NVX and IVX to store a cop_seq range, since it is -in scope throughout. Instead IVX stores some flags containing info about +the name SV does not use xlow and xhigh to store a cop_seq range, since it is +in scope throughout. Instead xhigh stores some flags containing info about the real lexical (is it declared in an anon, and is it capable of being -instantiated multiple times?), and for fake ANONs, NVX contains the index +instantiated multiple times?), and for fake ANONs, xlow contains the index within the parent's pad where the lexical's value is stored, to make cloning quicker. @@ -111,11 +111,15 @@ to be generated in evals, such as #include "perl.h" #include "keywords.h" -#define COP_SEQ_RANGE_LOW_set(sv,val) SvNV_set(sv, (NV)val) -#define COP_SEQ_RANGE_HIGH_set(sv,val) SvUV_set(sv, val) +#define COP_SEQ_RANGE_LOW_set(sv,val) \ + STMT_START { ((XPVNV*)SvANY(sv))->xnv_u.xpad_cop_seq.xlow = (val); } STMT_END +#define COP_SEQ_RANGE_HIGH_set(sv,val) \ + STMT_START { ((XPVNV*)SvANY(sv))->xnv_u.xpad_cop_seq.xhigh = (val); } STMT_END -#define PARENT_PAD_INDEX_set(sv,val) SvNV_set(sv, (NV)val) -#define PARENT_FAKELEX_FLAGS_set(sv,val) SvUV_set(sv, val) +#define PARENT_PAD_INDEX_set(sv,val) \ + STMT_START { ((XPVNV*)SvANY(sv))->xnv_u.xpad_cop_seq.xlow = (val); } STMT_END +#define PARENT_FAKELEX_FLAGS_set(sv,val) \ + STMT_START { ((XPVNV*)SvANY(sv))->xnv_u.xpad_cop_seq.xhigh = (val); } STMT_END #define PAD_MAX IV_MAX @@ -659,7 +663,7 @@ associated with the IVX field of a fake namesv. Note that pad_findlex() is recursive; it recurses up the chain of CVs, then comes back down, adding fake entries as it goes. It has to be this way -because fake namesvs in anon protoypes have to store in NVX the index into +because fake namesvs in anon protoypes have to store in xlow the index into the parent pad. =cut @@ -33,12 +33,61 @@ typedef U64TYPE PADOFFSET; /* B.xs needs these for the benefit of B::Deparse */ /* Low range end is exclusive (valid from the cop seq after this one) */ -#define COP_SEQ_RANGE_LOW(sv) U_32(SvNVX(sv)) /* High range end is inclusive (valid up to this cop seq) */ -#define COP_SEQ_RANGE_HIGH(sv) U_32(SvUVX(sv)) -#define PARENT_PAD_INDEX(sv) U_32(SvNVX(sv)) -#define PARENT_FAKELEX_FLAGS(sv) U_32(SvUVX(sv)) +#if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) +# define COP_SEQ_RANGE_LOW(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.xpad_cop_seq.xlow; \ + })) +# define COP_SEQ_RANGE_HIGH(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.xpad_cop_seq.xhigh; \ + })) +# define PARENT_PAD_INDEX(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.xpad_cop_seq.xlow; \ + })) +# define PARENT_FAKELEX_FLAGS(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.xpad_cop_seq.xhigh; \ + })) +#else +# define COP_SEQ_RANGE_LOW(sv) \ + (0 + (((XPVNV*) SvANY(sv))->xnv_u.xpad_cop_seq.xlow)) +# define COP_SEQ_RANGE_HIGH(sv) \ + (0 + (((XPVNV*) SvANY(sv))->xnv_u.xpad_cop_seq.xhigh)) + + +# define PARENT_PAD_INDEX(sv) \ + (0 + (((XPVNV*) SvANY(sv))->xnv_u.xpad_cop_seq.xlow)) +# define PARENT_FAKELEX_FLAGS(sv) \ + (0 + (((XPVNV*) SvANY(sv))->xnv_u.xpad_cop_seq.xhigh)) +#endif /* flags for the pad_new() function */ @@ -389,6 +389,10 @@ 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 */ } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ @@ -407,6 +411,10 @@ 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 */ } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ @@ -441,6 +449,10 @@ 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 */ } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ @@ -458,6 +470,10 @@ 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 */ } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ @@ -475,6 +491,10 @@ 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 */ } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ @@ -496,6 +516,10 @@ 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 */ } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ @@ -525,6 +549,10 @@ 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 */ } xnv_u; STRLEN xpv_cur; /* xgv_flags */ STRLEN xpv_len; /* 0 */ @@ -551,6 +579,10 @@ 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 */ } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ @@ -627,6 +659,10 @@ 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 */ } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ |