summaryrefslogtreecommitdiff
path: root/sv.h
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2021-07-02 19:03:28 +0000
committerNicholas Clark <nick@ccl4.org>2022-02-19 19:46:37 +0000
commitcff76435bba3c0cf32c22b33ad9f14672094c90b (patch)
tree66612dff5e781624a30ad4d7d76411f635ffc776 /sv.h
parentbb5bc97fde9ef2f16cffdfb44d7f42a03311ab2f (diff)
downloadperl-cff76435bba3c0cf32c22b33ad9f14672094c90b.tar.gz
Update SvPV() etc to avoid calling sv_2pv_flags() for cached IV strings.
This "teaches" them the new SV flags combination implemented by the previous commit.
Diffstat (limited to 'sv.h')
-rw-r--r--sv.h25
1 files changed, 18 insertions, 7 deletions
diff --git a/sv.h b/sv.h
index b426354d85..fa1a975644 100644
--- a/sv.h
+++ b/sv.h
@@ -1859,19 +1859,30 @@ scalar.
#define SvPV_const(sv, len) SvPV_flags_const(sv, len, SV_GMAGIC)
#define SvPV_mutable(sv, len) SvPV_flags_mutable(sv, len, SV_GMAGIC)
+/* This test is "is there a cached PV that we can use directly?"
+ * We can if
+ * a) SVf_POK is true and there's definitely no get magic on the scalar
+ * b) SVp_POK is true, there's no get magic, and we know that the cached PV
+ * came from an IV conversion.
+ * For the latter case, we don't set SVf_POK so that we can distinguish whether
+ * the value originated as a string or as an integer, before we cached the
+ * second representation. */
+#define SvPOK_or_cached_IV(sv) \
+ (((SvFLAGS(sv) & (SVf_POK|SVs_GMG)) == SVf_POK) || ((SvFLAGS(sv) & (SVf_IOK|SVp_POK|SVs_GMG)) == (SVf_IOK|SVp_POK)))
+
#define SvPV_flags(sv, len, flags) \
- (SvPOK_nog(sv) \
+ (SvPOK_or_cached_IV(sv) \
? ((len = SvCUR(sv)), SvPVX(sv)) : sv_2pv_flags(sv, &len, flags))
#define SvPV_flags_const(sv, len, flags) \
- (SvPOK_nog(sv) \
+ (SvPOK_or_cached_IV(sv) \
? ((len = SvCUR(sv)), SvPVX_const(sv)) : \
(const char*) sv_2pv_flags(sv, &len, (flags|SV_CONST_RETURN)))
#define SvPV_flags_const_nolen(sv, flags) \
- (SvPOK_nog(sv) \
+ (SvPOK_or_cached_IV(sv) \
? SvPVX_const(sv) : \
(const char*) sv_2pv_flags(sv, 0, (flags|SV_CONST_RETURN)))
#define SvPV_flags_mutable(sv, len, flags) \
- (SvPOK_nog(sv) \
+ (SvPOK_or_cached_IV(sv) \
? ((len = SvCUR(sv)), SvPVX_mutable(sv)) : \
sv_2pv_flags(sv, &len, (flags|SV_MUTABLE_RETURN)))
@@ -1896,16 +1907,16 @@ scalar.
: sv_pvn_force_flags(sv, &len, flags|SV_MUTABLE_RETURN))
#define SvPV_nolen(sv) \
- (SvPOK_nog(sv) \
+ (SvPOK_or_cached_IV(sv) \
? SvPVX(sv) : sv_2pv_flags(sv, 0, SV_GMAGIC))
/* "_nomg" in these defines means no mg_get() */
#define SvPV_nomg_nolen(sv) \
- (SvPOK_nog(sv) \
+ (SvPOK_or_cached_IV(sv) \
? SvPVX(sv) : sv_2pv_flags(sv, 0, 0))
#define SvPV_nolen_const(sv) \
- (SvPOK_nog(sv) \
+ (SvPOK_or_cached_IV(sv) \
? SvPVX_const(sv) : sv_2pv_flags(sv, 0, SV_GMAGIC|SV_CONST_RETURN))
#define SvPV_nomg(sv, len) SvPV_flags(sv, len, 0)