diff options
author | Nicholas Clark <nick@ccl4.org> | 2021-07-02 12:45:42 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2022-02-19 19:46:37 +0000 |
commit | bb5bc97fde9ef2f16cffdfb44d7f42a03311ab2f (patch) | |
tree | bb279aaf82ca65990a0c0edb8007a97fda158002 /sv.c | |
parent | 9cb26ed2ae572b61849be5ef0d9e2fc19c8e49a8 (diff) | |
download | perl-bb5bc97fde9ef2f16cffdfb44d7f42a03311ab2f.tar.gz |
Don't set SVf_POK in Perl_sv_2pv_flags() when caching the string for an IV.
This permits XS code (such as serialisers) to distinguish between values
that started as IVs but had a string representation cached, and values that
started as PVs but had an (exact) integer representation cached.
As implemented, the change in flags means that Perl_sv_2pv_flags() will be
entered each time the string for an IV is wanted. The next commit will fix
SvPV() and the other macros to avoid calling Perl_sv_2pv_flags() more than
once, restoring the previous behaviour.
Diffstat (limited to 'sv.c')
-rw-r--r-- | sv.c | 14 |
1 files changed, 13 insertions, 1 deletions
@@ -3309,7 +3309,19 @@ Perl_sv_2pv_flags(pTHX_ SV *const sv, STRLEN *const lp, const U32 flags) Move(ptr, s, len, char); s += len; *s = '\0'; - SvPOK_on(sv); + /* We used to call SvPOK_on(). Whilst this is fine for (most) Perl code, + it means that after this stringification is cached, there is no way + to distinguish between values originally assigned as $a = 42; and + $a = "42"; (or results of string operators vs numeric operators) + where the value has subsequently been used in the other sense + and had a value cached. + This (somewhat) hack means that we retain the cached stringification, + but the existing SvPV() macros end up entering this function (which + returns the cached value) instead of using it directly inline. + However, the result is that if a value is SVf_IOK|SVf_POK then it + originated as "42", whereas if it's SVf_IOK then it originated as 42. + (ignore SVp_IOK and SVp_POK) */ + SvPOKp_on(sv); } else if (SvNOK(sv)) { if (SvTYPE(sv) < SVt_PVNV) |