=for apidoc Am|SV*|SvREFCNT_inc|SV* sv
Increments the reference count of the given SV.
+All of the following SvREFCNT_inc* macros are optimized versions of
+SvREFCNT_inc, and can be replaced with SvREFCNT_inc.
+
+=for apidoc Am|SV*|SvREFCNT_inc_NN|SV* sv
+Same as SvREFCNT_inc, but can only be used if you know I<sv>
+is not NULL. Since we don't have to check the NULLness, it's faster
+and smaller.
+
+=for apidoc Am|SV*|SvREFCNT_inc_void|SV* sv
+Same as SvREFCNT_inc, but can only be used if you don't need the
+return value. The macro doesn't need to return a meaningful value.
+
+=for apidoc Am|SV*|SvREFCNT_inc_void_NN|SV* sv
+Same as SvREFCNT_inc, but can only be used if you don't need the return
+value, and you know that I<sv> is not NULL. The macro doesn't need
+to return a meaningful value, or check for NULLness, so it's smaller
+and faster.
+
+=for apidoc Am|SV*|SvREFCNT_inc_simple|SV* sv
+Same as SvREFCNT_inc, but can only be used with simple variables, not
+expressions or pointer dereferences. Since we don't have to store a
+temporary value, it's faster.
+
+=for apidoc Am|SV*|SvREFCNT_inc_simple_NN|SV* sv
+Same as SvREFCNT_inc_simple, but can only be used if you know I<sv>
+is not NULL. Since we don't have to check the NULLness, it's faster
+and smaller.
+
+=for apidoc Am|SV*|SvREFCNT_inc_simple_void|SV* sv
+Same as SvREFCNT_inc_simple, but can only be used if you don't need the
+return value. The macro doesn't need to return a meaningful value.
+
+=for apidoc Am|SV*|SvREFCNT_inc|SV* sv
+Increments the reference count of the given SV.
+
=for apidoc Am|void|SvREFCNT_dec|SV* sv
Decrements the reference count of the given SV.
(SvREFCNT(_sv))++; \
_sv; \
})
+# define SvREFCNT_inc_simple(sv) \
+ ({ \
+ if (sv) \
+ (SvREFCNT(sv))++; \
+ (SV *)(sv); \
+ })
+# define SvREFCNT_inc_NN(sv) \
+ ({ \
+ SV * const _sv = (SV*)(sv); \
+ SvREFCNT(_sv)++; \
+ _sv; \
+ })
+# define SvREFCNT_inc_void(sv) \
+ ({ \
+ SV * const _sv = (SV*)(sv); \
+ if (_sv) \
+ (void)(SvREFCNT(_sv)++); \
+ })
#else
# define SvREFCNT_inc(sv) \
- ((PL_Sv=(SV*)(sv)) ? ((++(SvREFCNT(PL_Sv))),(PL_Sv)) : NULL)
+ ((PL_Sv=(SV*)(sv)) ? (++(SvREFCNT(PL_Sv)),PL_Sv) : NULL)
+# define SvREFCNT_inc_simple(sv) \
+ ((sv) ? (SvREFCNT(sv)++,(SV*)(sv)) : NULL)
+# define SvREFCNT_inc_NN(sv) \
+ (PL_Sv=(SV*)(sv),++(SvREFCNT(PL_Sv)),PL_Sv)
+# define SvREFCNT_inc_void(sv) \
+ (void)((PL_Sv=(SV*)(sv)) ? ++(SvREFCNT(PL_Sv)) : 0)
#endif
+/* These guys don't need the curly blocks */
+#define SvREFCNT_inc_simple_void(sv) if (sv) (SvREFCNT(sv)++);
+#define SvREFCNT_inc_simple_NN(sv) (++(SvREFCNT(sv)),(SV*)(sv))
+#define SvREFCNT_inc_void_NN(sv) (void)(++SvREFCNT((SV*)(sv)))
+#define SvREFCNT_inc_simple_void_NN(sv) (void)(++SvREFCNT((SV*)(sv)))
+
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && !defined(PERL_GCC_PEDANTIC)
# define SvREFCNT_dec(sv) \
({ \
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".
- */
+ 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
/* Some private flags. */
/* PVHV */
-#define SVphv_REHASH 0x10000000 /* PVHV is recalculating hash values */
-/* PVHV */
#define SVphv_SHAREKEYS 0x20000000 /* PVHV
keys live on shared string table */
/* PVNV, PVMG, PVGV, presumably only inside pads */
UV xivu_uv;
void * xivu_p1;
I32 xivu_i32;
+ HEK * xivu_namehek;
} xiv_u;
};
UV xivu_uv;
void * xivu_p1;
I32 xivu_i32;
+ HEK * xivu_namehek;
} xiv_u;
} xpviv_allocated;
#endif
IV xuvu_iv;
UV xuvu_uv; /* unsigned value or pv offset */
void * xuvu_p1;
+ HEK * xivu_namehek;
} xuv_u;
};
UV xivu_uv;
void * xivu_p1;
I32 xivu_i32;
+ HEK * xivu_namehek;
} xiv_u;
};
UV xivu_uv;
void * xivu_p1;
I32 xivu_i32;
+ HEK * xivu_namehek;
} xiv_u;
union {
MAGIC* xmg_magic; /* linked list of magicalness */
UV xivu_uv;
void * xivu_p1;
I32 xivu_i32;
+ HEK * xivu_namehek; /* GvNAME */
} xiv_u;
union {
MAGIC* xmg_magic; /* linked list of magicalness */
} xmg_u;
HV* xmg_stash; /* class package */
- /* a full glob fits into this */
- char* xgv_name;
- STRLEN xgv_namelen;
- U8 xgv_flags;
-
STRLEN xlv_targoff;
STRLEN xlv_targlen;
SV* xlv_targ;
NV xnv_nv;
HV * xgv_stash; /* The stash of this GV */
} xnv_u;
- STRLEN xpv_cur; /* length of svu_pv as a C string */
- STRLEN xpv_len; /* allocated size */
+ STRLEN xpv_cur; /* xgv_flags */
+ STRLEN xpv_len; /* 0 */
union {
- IV xivu_iv; /* integer value or pv offset */
+ 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 */
} xmg_u;
HV* xmg_stash; /* class package */
- char* xgv_name;
- STRLEN xgv_namelen;
- U8 xgv_flags;
};
struct xpvbm {
UV xivu_uv;
void * xivu_p1;
I32 xivu_i32;
+ HEK * xivu_namehek;
} xiv_u;
union {
MAGIC* xmg_magic; /* linked list of magicalness */
UV xivu_uv;
void * xivu_p1;
I32 xivu_i32;
+ HEK * xivu_namehek;
} xiv_u;
union {
MAGIC* xmg_magic; /* linked list of magicalness */
UV xivu_uv;
void * xivu_p1;
I32 xivu_i32;
+ HEK * xivu_namehek;
} xiv_u;
union {
MAGIC* xmg_magic; /* linked list of magicalness */
UV xivu_uv;
void * xivu_p1;
I32 xivu_i32;
+ HEK * xivu_namehek;
} xiv_u;
union {
MAGIC* xmg_magic; /* linked list of magicalness */
#define SvOK(sv) (SvFLAGS(sv) & SVf_OK)
#define SvOK_off(sv) (assert_not_ROK(sv) assert_not_glob(sv) \
- SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \
+ SvFLAGS(sv) &= ~(SVf_OK| \
SVf_IVisUV|SVf_UTF8), \
SvOOK_off(sv))
#define SvOK_off_exc_UV(sv) (assert_not_ROK(sv) \
- SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \
+ SvFLAGS(sv) &= ~(SVf_OK| \
SVf_UTF8), \
SvOOK_off(sv))
SvFLAGS(sv) |= (SVf_POK|SVp_POK))
#define SvPOK_off(sv) (SvFLAGS(sv) &= ~(SVf_POK|SVp_POK))
#define SvPOK_only(sv) (assert_not_ROK(sv) assert_not_glob(sv) \
- SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \
+ SvFLAGS(sv) &= ~(SVf_OK| \
SVf_IVisUV|SVf_UTF8), \
SvFLAGS(sv) |= (SVf_POK|SVp_POK))
#define SvPOK_only_UTF8(sv) (assert_not_ROK(sv) assert_not_glob(sv) \
- SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \
+ SvFLAGS(sv) &= ~(SVf_OK| \
SVf_IVisUV), \
SvFLAGS(sv) |= (SVf_POK|SVp_POK))
#define SvROK(sv) (SvFLAGS(sv) & SVf_ROK)
#define SvROK_on(sv) (SvFLAGS(sv) |= SVf_ROK)
-#define SvROK_off(sv) (SvFLAGS(sv) &= ~(SVf_ROK|SVf_AMAGIC))
+#define SvROK_off(sv) (SvFLAGS(sv) &= ~(SVf_ROK))
#define SvMAGICAL(sv) (SvFLAGS(sv) & (SVs_GMG|SVs_SMG|SVs_RMG))
#define SvMAGICAL_on(sv) (SvFLAGS(sv) |= (SVs_GMG|SVs_SMG|SVs_RMG))
#define SvRMAGICAL_on(sv) (SvFLAGS(sv) |= SVs_RMG)
#define SvRMAGICAL_off(sv) (SvFLAGS(sv) &= ~SVs_RMG)
-#define SvAMAGIC(sv) (SvFLAGS(sv) & SVf_AMAGIC)
-#define SvAMAGIC_on(sv) (SvFLAGS(sv) |= SVf_AMAGIC)
-#define SvAMAGIC_off(sv) (SvFLAGS(sv) &= ~SVf_AMAGIC)
+#define SvAMAGIC(sv) (SvROK(sv) && (SvFLAGS(SvRV(sv)) & SVf_AMAGIC))
+#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
+# define SvAMAGIC_on(sv) ({ SV * const kloink = sv; \
+ assert(SvROK(kloink)); \
+ SvFLAGS(SvRV(kloink)) |= SVf_AMAGIC; \
+ })
+# define SvAMAGIC_off(sv) ({ SV * const kloink = sv; \
+ if(SvROK(kloink)) \
+ SvFLAGS(SvRV(kloink)) &= ~SVf_AMAGIC;\
+ })
+#else
+# define SvAMAGIC_on(sv) (SvFLAGS(SvRV(sv)) |= SVf_AMAGIC)
+# define SvAMAGIC_off(sv) \
+ (SvROK(sv) && (SvFLAGS(SvRV(sv)) &= ~SVf_AMAGIC))
+#endif
-#define SvGAMAGIC(sv) (SvFLAGS(sv) & (SVs_GMG|SVf_AMAGIC))
+#define SvGAMAGIC(sv) (SvGMAGICAL(sv) || SvAMAGIC(sv))
-/*
-#define Gv_AMG(stash) \
- (HV_AMAGICmb(stash) && \
- ((!HV_AMAGICbad(stash) && HV_AMAGIC(stash)) || Gv_AMupdate(stash)))
-*/
#define Gv_AMG(stash) (PL_amagic_generation && Gv_AMupdate(stash))
#define SvWEAKREF(sv) ((SvFLAGS(sv) & (SVf_ROK|SVprv_WEAKREF)) \
# define SvSTASH(sv) (0 + ((XPVMG*) SvANY(sv))->xmg_stash)
# endif
#else
-# define SvCUR(sv) ((XPV*) SvANY(sv))->xpv_cur
# define SvLEN(sv) ((XPV*) SvANY(sv))->xpv_len
# define SvEND(sv) ((sv)->sv_u.svu_pv + ((XPV*)SvANY(sv))->xpv_cur)
assert(!isGV_with_GP(_svi)); \
&((_svi)->sv_u.svu_pv); \
}))
+# define SvCUR(sv) \
+ (*({ SV *const _svi = (SV *) sv; \
+ assert(SvTYPE(_svi) >= SVt_PV); \
+ assert(SvTYPE(_svi) != SVt_PVAV); \
+ assert(SvTYPE(_svi) != SVt_PVHV); \
+ assert(!isGV_with_GP(_svi)); \
+ &(((XPV*) SvANY(_svi))->xpv_cur); \
+ }))
# define SvIVX(sv) \
(*({ SV *const _svi = (SV *) sv; \
assert(SvTYPE(_svi) == SVt_IV || SvTYPE(_svi) >= SVt_PVIV); \
&(((XPVMG*) SvANY(_svi))->xmg_stash); \
}))
# else
-# define SvPVX(sv) ((sv)->sv_u.svu_pv)
+# define SvPVX(sv) ((sv)->sv_u.svu_pv)
+# define SvCUR(sv) ((XPV*) SvANY(sv))->xpv_cur
# define SvIVX(sv) ((XPVIV*) SvANY(sv))->xiv_iv
# define SvUVX(sv) ((XPVUV*) SvANY(sv))->xuv_uv
# define SvNVX(sv) ((XPVNV*) SvANY(sv))->xnv_u.xnv_nv
(void) SvIV(sv); } STMT_END
#define SvIV_set(sv, val) \
STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \
+ assert(!isGV_with_GP(sv)); \
(((XPVIV*) SvANY(sv))->xiv_iv = (val)); } STMT_END
#define SvNV_set(sv, val) \
STMT_START { assert(SvTYPE(sv) == SVt_NV || SvTYPE(sv) >= SVt_PVNV); \
assert(SvTYPE(sv) != SVt_PVAV); assert(SvTYPE(sv) != SVt_PVHV); \
+ assert(!isGV_with_GP(sv)); \
(((XPVNV*)SvANY(sv))->xnv_u.xnv_nv = (val)); } STMT_END
#define SvPV_set(sv, val) \
STMT_START { assert(SvTYPE(sv) >= SVt_PV); \
+ assert(!isGV_with_GP(sv)); \
((sv)->sv_u.svu_pv = (val)); } STMT_END
#define SvUV_set(sv, val) \
STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \
+ assert(!isGV_with_GP(sv)); \
(((XPVUV*)SvANY(sv))->xuv_uv = (val)); } STMT_END
#define SvRV_set(sv, val) \
STMT_START { assert(SvTYPE(sv) >= SVt_RV); \
+ assert(!isGV_with_GP(sv)); \
((sv)->sv_u.svu_rv = (val)); } STMT_END
#define SvMAGIC_set(sv, val) \
STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \
(((XPVMG*) SvANY(sv))->xmg_stash = (val)); } STMT_END
#define SvCUR_set(sv, val) \
STMT_START { assert(SvTYPE(sv) >= SVt_PV); \
+ assert(!isGV_with_GP(sv)); \
(((XPV*) SvANY(sv))->xpv_cur = (val)); } STMT_END
#define SvLEN_set(sv, val) \
STMT_START { assert(SvTYPE(sv) >= SVt_PV); \
#define SV_CONST_RETURN 32
#define SV_MUTABLE_RETURN 64
#define SV_SMAGIC 128
+#define SV_HAS_TRAILING_NUL 256
#define sv_unref(sv) sv_unref_flags(sv, 0)
#define sv_force_normal(sv) sv_force_normal_flags(sv, 0)
+#define sv_usepvn(sv, p, l) sv_usepvn_flags(sv, p, l, 0)
+#define sv_usepvn_mg(sv, p, l) sv_usepvn_flags(sv, p, l, SV_SMAGIC)
/* 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
#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)
+ SVf_OOK|SVf_BREAK|SVf_READONLY)
#define CAN_COW_FLAGS (SVp_POK|SVf_POK)
#define SV_CHECK_THINKFIRST(sv) if (SvTHINKFIRST(sv)) \