Skip to content

Commit ef8c420

Browse files
committed
sv_numeq etc: don't do numify overloading with SV_SKIP_OVERLOAD
1 parent b638a90 commit ef8c420

File tree

6 files changed

+42
-18
lines changed

6 files changed

+42
-18
lines changed

embed.fnc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3410,7 +3410,7 @@ ARdp |SV * |sv_newmortal
34103410
Cdp |SV * |sv_newref |NULLOK SV * const sv
34113411
Adp |void |sv_nosharing |NULLOK SV *sv
34123412
: Used in pp.c, pp_hot.c, sv.c
3413-
dpx |SV * |sv_2num |NN SV * const sv
3413+
dmp |SV * |sv_2num |NN SV * const sv
34143414
Admp |I32 |sv_numcmp |NULLOK SV *sv1 \
34153415
|NULLOK SV *sv2
34163416
Adp |I32 |sv_numcmp_flags|NULLOK SV *sv1 \
@@ -3421,6 +3421,8 @@ Admp |bool |sv_numeq |NULLOK SV *sv1 \
34213421
Adp |bool |sv_numeq_flags |NULLOK SV *sv1 \
34223422
|NULLOK SV *sv2 \
34233423
|const U32 flags
3424+
dpx |SV * |sv_2num_flags |NN SV * const sv \
3425+
|int flags
34243426
Admp |bool |sv_numge |NULLOK SV *sv1 \
34253427
|NULLOK SV *sv2
34263428
Adp |bool |sv_numge_flags |NULLOK SV *sv1 \

embed.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@
281281
# undef case_98_SBOX32
282282
# undef case_99_SBOX32
283283
# undef case_9_SBOX32
284+
# undef sv_2num
284285
# if !defined(PERL_EXT)
285286
# undef invlist_intersection_
286287
# undef invlist_subtract_
@@ -1383,7 +1384,7 @@
13831384
# define subsignature_append_slurpy(a,b) Perl_subsignature_append_slurpy(aTHX_ a,b)
13841385
# define subsignature_finish() Perl_subsignature_finish(aTHX)
13851386
# define subsignature_start() Perl_subsignature_start(aTHX)
1386-
# define sv_2num(a) Perl_sv_2num(aTHX_ a)
1387+
# define sv_2num_flags(a,b) Perl_sv_2num_flags(aTHX_ a,b)
13871388
# define sv_clean_all() Perl_sv_clean_all(aTHX)
13881389
# define sv_clean_objs() Perl_sv_clean_objs(aTHX)
13891390
# define sv_del_backref(a,b) Perl_sv_del_backref(aTHX_ a,b)
@@ -2047,6 +2048,11 @@
20472048
# define quadmath_format_needed Perl_quadmath_format_needed
20482049
# define quadmath_format_valid Perl_quadmath_format_valid
20492050
# endif
2051+
# if defined(USE_THREADS)
2052+
# define Perl_sv_2num(mTHX,a) sv_2num(a)
2053+
# else
2054+
# define Perl_sv_2num sv_2num
2055+
# endif
20502056
# if defined(WIN32)
20512057
# define get_win32_message_utf8ness(a) Perl_get_win32_message_utf8ness(aTHX_ a)
20522058
# else

ext/XS-APItest/t/sv_numeq.t

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!perl
22

3-
use Test::More tests => 22;
3+
use Test::More tests => 23;
44
use XS::APItest;
55
use Config;
66

@@ -44,7 +44,8 @@ ok sv_numeq_flags($1, 10, SV_GMAGIC), 'sv_numeq_flags with SV_GMAGIC does';
4444
ok sv_numeq(10, $obj), 'AlwaysTen is 10 on the right';
4545
ok !sv_numeq(11, $obj), 'AlwaysTen is not 11 on the right';
4646

47-
ok !sv_numeq_flags($obj, 10, SV_SKIP_OVERLOAD), 'AlwaysTen is not 10 with SV_SKIP_OVERLOAD'
47+
ok !sv_numeq_flags($obj, 10, SV_SKIP_OVERLOAD), 'AlwaysTen is not 10 with SV_SKIP_OVERLOAD';
48+
ok !sv_numeq_flags($obj, 123456, SV_SKIP_OVERLOAD), 'AlwaysTen is not its overloaded numeric value with SV_SKIP_OVERLOAD';
4849
}
4950

5051
# +0 overloading with large numbers and using fallback

proto.h

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sv.c

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2763,23 +2763,30 @@ Perl_sv_2nv_flags(pTHX_ SV *const sv, const I32 flags)
27632763
}
27642764

27652765
/*
2766-
=for apidoc sv_2num
2766+
=for apidoc sv_2num_flags
2767+
=for apidoc_item sv_2num
2768+
X<SV_SKIP_OVERLOAD>
27672769

27682770
Return an SV with the numeric value of the source SV, doing any necessary
27692771
reference or overload conversion. The caller is expected to have handled
27702772
get-magic already.
27712773

2774+
For sv_2num_flags() you can set C<SV_SKIP_OVERLOAD> in flags to avoid
2775+
any numeric context overloading.
2776+
27722777
=cut
27732778
*/
27742779

27752780
SV *
2776-
Perl_sv_2num(pTHX_ SV *const sv)
2781+
Perl_sv_2num_flags(pTHX_ SV *const sv, int flags)
27772782
{
2778-
PERL_ARGS_ASSERT_SV_2NUM;
2783+
PERL_ARGS_ASSERT_SV_2NUM_FLAGS;
2784+
2785+
assert((flags & ~SV_SKIP_OVERLOAD) == 0);
27792786

27802787
if (!SvROK(sv))
27812788
return sv;
2782-
if (SvAMAGIC(sv)) {
2789+
if (SvAMAGIC(sv) && !(flags & SV_SKIP_OVERLOAD)) {
27832790
SV * const tmpsv = AMG_CALLunary(sv, numer_amg);
27842791
TAINT_IF(tmpsv && SvTAINTED(tmpsv));
27852792
if (tmpsv && (!SvROK(tmpsv) || (SvRV(tmpsv) != SvRV(sv))))
@@ -8727,16 +8734,20 @@ S_sv_numcmp_common(pTHX_ SV **sv1, SV **sv2, const U32 flags,
87278734
if(!*sv2)
87288735
*sv2 = &PL_sv_undef;
87298736

8730-
if(!(flags & SV_SKIP_OVERLOAD) &&
8731-
(SvAMAGIC(*sv1) || SvAMAGIC(*sv2))) {
8732-
if ((*result = amagic_call(*sv1, *sv2, method, AMGf_force_scalar)))
8733-
return true;
8737+
if (SvAMAGIC(*sv1) || SvAMAGIC(*sv2)) {
8738+
if (!(flags & SV_SKIP_OVERLOAD)) {
8739+
if ((*result = amagic_call(*sv1, *sv2, method, AMGf_force_scalar)))
8740+
return true;
8741+
}
87348742

8735-
/* normally handled by try_amagic_bin */
8743+
/* Normally handled by try_amagic_bin
8744+
This will do the normal RV to UV conversion
8745+
with SV_SKIP_OVERLOAD.
8746+
*/
87368747
if (SvROK(*sv1))
8737-
*sv1 = sv_2num(*sv1);
8748+
*sv1 = sv_2num_flags(*sv1, flags & SV_SKIP_OVERLOAD);
87388749
if (SvROK(*sv2))
8739-
*sv2 = sv_2num(*sv2);
8750+
*sv2 = sv_2num_flags(*sv2, flags & SV_SKIP_OVERLOAD);
87408751
}
87418752

87428753
return false;
@@ -8826,7 +8837,6 @@ otherwise 'get' magic is ignored.
88268837
=item C<SV_SKIP_OVERLOAD>
88278838

88288839
Skip any operator overloading implemented for this type and operator.
8829-
Be aware that numeric, C<+0>, overloading will still be applied, unless in the scope of C<no overloading;>.
88308840

88318841
=back
88328842

sv.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2311,6 +2311,7 @@ Usually accessed via the C<SvPVutf8_nolen> macro.
23112311
23122312
=cut
23132313
*/
2314+
#define sv_2num(sv) sv_2num_flags(sv, 0)
23142315
#define sv_2pvutf8_nolen(sv) sv_2pvutf8(sv, 0)
23152316
#define sv_2pv_nomg(sv, lp) sv_2pv_flags(sv, lp, 0)
23162317
#define sv_pvn_force(sv, lp) sv_pvn_force_flags(sv, lp, SV_GMAGIC)
@@ -2366,6 +2367,10 @@ Usually accessed via the C<SvPVutf8_nolen> macro.
23662367
#define sv_catpvn_nomg_maybeutf8(dsv, sstr, len, is_utf8) \
23672368
sv_catpvn_flags(dsv, sstr, len, (is_utf8)?SV_CATUTF8:SV_CATBYTES)
23682369

2370+
#if defined(PERL_CORE)
2371+
#define sv_2num(sv) sv_2num_flags(sv, 0)
2372+
#endif
2373+
23692374
#if defined(PERL_CORE) || defined(PERL_EXT)
23702375
# define sv_or_pv_len_utf8(sv, pv, bytelen) \
23712376
(SvGAMAGIC(sv) \

0 commit comments

Comments
 (0)