summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--av.h4
-rw-r--r--cv.h4
-rw-r--r--hv.h4
-rw-r--r--pad.c32
-rw-r--r--pad.h57
-rw-r--r--sv.h36
6 files changed, 119 insertions, 18 deletions
diff --git a/av.h b/av.h
index d91b6f0086..02a0afa2d4 100644
--- a/av.h
+++ b/av.h
@@ -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 */
diff --git a/cv.h b/cv.h
index 2673bcce26..cf71d15ffc 100644
--- a/cv.h
+++ b/cv.h
@@ -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 */
diff --git a/hv.h b/hv.h
index bd157f8b11..dee534d9ff 100644
--- a/hv.h
+++ b/hv.h
@@ -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 */
diff --git a/pad.c b/pad.c
index ba45bcf0ca..2cfdc85f93 100644
--- a/pad.c
+++ b/pad.c
@@ -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
diff --git a/pad.h b/pad.h
index d057211914..bf91d0cc6b 100644
--- a/pad.h
+++ b/pad.h
@@ -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 */
diff --git a/sv.h b/sv.h
index e0b3be5418..7614a6a1c9 100644
--- a/sv.h
+++ b/sv.h
@@ -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 */