Skip to content

Commit bda5e7d

Browse files
authored
Merge pull request #10276 from lucioleKi/isabell/erts/is-integer-3/OTP-19809
erts: Add guard BIF `erlang:is_integer/3`
2 parents c52d31d + 64b2fde commit bda5e7d

25 files changed

+438
-24
lines changed

erts/emulator/beam/bif.tab

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,3 +834,8 @@ bif erl_debugger:peek_xreg/3
834834
#
835835
bif erts_debug:unaligned_bitstring/2
836836
bif re:import/1
837+
838+
#
839+
# New in 29.
840+
#
841+
ubif erlang:is_integer/3

erts/emulator/beam/emu/ops.tab

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,8 @@ bif1 Fail=f Bif S1 Dst => i_bif1 S1 Fail Bif Dst
10011001
bif2 p Bif S1 S2 Dst => i_bif2_body S2 S1 Bif Dst
10021002
bif2 Fail=f Bif S1 S2 Dst => i_bif2 S2 S1 Fail Bif Dst
10031003

1004+
bif3 p Bif S1 S2 S3 Dst => i_bif3_body S3 S2 S1 Bif Dst
1005+
10041006
i_get_hash c W d
10051007
i_get s d
10061008

erts/emulator/beam/erl_bif_guard.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,20 @@ BIF_RETTYPE size_1(BIF_ALIST_1)
334334
BIF_ERROR(BIF_P, BADARG);
335335
}
336336

337+
BIF_RETTYPE is_integer_3(BIF_ALIST_3)
338+
{
339+
if(is_not_integer(BIF_ARG_2) ||
340+
is_not_integer(BIF_ARG_3)) {
341+
BIF_ERROR(BIF_P, BADARG);
342+
}
343+
if(is_not_integer(BIF_ARG_1)) {
344+
BIF_RET(am_false);
345+
}
346+
347+
BIF_RET((CMP_LE(BIF_ARG_2, BIF_ARG_1) && CMP_LE(BIF_ARG_1, BIF_ARG_3)) ?
348+
am_true : am_false);
349+
}
350+
337351
/**********************************************************************/
338352
/* returns the bitsize of a bitstring */
339353

erts/emulator/beam/erl_db_util.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,12 @@ static DMCGuardBif guard_tab[] =
588588
1,
589589
DBIF_ALL
590590
},
591+
{
592+
am_is_integer,
593+
&is_integer_3,
594+
3,
595+
DBIF_ALL
596+
},
591597
{
592598
am_is_list,
593599
&is_list_1,

erts/emulator/beam/jit/arm/ops.tab

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,7 @@ bif2 _Fail Bif S1 S2 Dst | never_fails(Bif) => nofail_bif2 S1 S2 Bif Dst
814814

815815
bif1 Fail Bif S1 Dst => i_bif1 S1 Fail Bif Dst
816816
bif2 Fail Bif S1 S2 Dst => i_bif2 S1 S2 Fail Bif Dst
817+
bif3 Fail Bif S1 S2 S3 Dst => i_bif3 S1 S2 S3 Fail Bif Dst
817818

818819
nofail_bif2 S1=d S2 Bif Dst | is_eq_exact_bif(Bif) => bif_is_eq_exact S1 S2 Dst
819820
nofail_bif2 S1=d S2 Bif Dst | is_ne_exact_bif(Bif) => bif_is_ne_exact S1 S2 Dst

erts/emulator/beam/jit/x86/ops.tab

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,7 @@ bif2 _Fail Bif S1 S2 Dst | never_fails(Bif) => nofail_bif2 S1 S2 Bif Dst
745745

746746
bif1 Fail Bif S1 Dst => i_bif1 S1 Fail Bif Dst
747747
bif2 Fail Bif S1 S2 Dst => i_bif2 S1 S2 Fail Bif Dst
748+
bif3 Fail Bif S1 S2 S3 Dst => i_bif3 S1 S2 S3 Fail Bif Dst
748749

749750
nofail_bif2 S1=d S2 Bif Dst | is_eq_exact_bif(Bif) => bif_is_eq_exact S1 S2 Dst
750751
nofail_bif2 S1=d S2 Bif Dst | is_ne_exact_bif(Bif) => bif_is_ne_exact S1 S2 Dst

erts/emulator/test/bif_SUITE.erl

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
-include_lib("common_test/include/ct.hrl").
2626
-include_lib("kernel/include/file.hrl").
27+
-include_lib("stdlib/include/assert.hrl").
2728

2829
-export([all/0, suite/0, init_per_testcase/2, end_per_testcase/2]).
2930

@@ -46,7 +47,7 @@
4647
test_length/1,
4748
fixed_apply_badarg/1,
4849
external_fun_apply3/1,
49-
node_1/1,doctests/1]).
50+
node_1/1,doctests/1,is_integer_3_test/1]).
5051

5152
suite() ->
5253
[{ct_hooks,[ts_install_cth]},
@@ -64,7 +65,7 @@ all() ->
6465
is_process_alive, is_process_alive_signal_from,
6566
process_info_blast, os_env_case_sensitivity,
6667
verify_middle_queue_save, test_length,fixed_apply_badarg,
67-
external_fun_apply3, node_1, doctests].
68+
external_fun_apply3, node_1, doctests, is_integer_3_test].
6869

6970
init_per_testcase(guard_bifs_in_erl_bif_types, Config) when is_list(Config) ->
7071
skip_missing_erl_bif_types(Config);
@@ -1780,6 +1781,72 @@ node_error(E0) ->
17801781
doctests(_Config) ->
17811782
shell_docs:test(erlang, []).
17821783

1784+
is_integer_3_test(_Config) ->
1785+
_ = [is_between_ten(X) || X <- lists:seq(-2, 12)],
1786+
1787+
false = is_between_ten(0),
1788+
true = is_between_ten(1),
1789+
true = is_between_ten(10),
1790+
false = is_between_ten(11),
1791+
1792+
false = is_between_ten(a),
1793+
false = is_between_ten(5.0),
1794+
false = is_between_ten(-7.0),
1795+
false = is_between_ten([1]),
1796+
1797+
_ = [begin
1798+
is_between_negative(X),
1799+
false = is_between_negative(-X)
1800+
end || X <- lists:seq(-100, -70)],
1801+
1802+
_ = [is_between_mixed(X) || X <- lists:seq(-10, 10)],
1803+
1804+
_ = [begin
1805+
is_between_bignum(X),
1806+
false = is_between_bignum(-X),
1807+
false = is_between_bignum(X - (1 bsl 64))
1808+
end || X <- lists:seq((1 bsl 64) - 3, (1 bsl 64) + 10)],
1809+
1810+
is_between_badarg(2, 1.5, 10.0),
1811+
is_between_badarg(2, 10.0, 1.5),
1812+
is_between_badarg(2, 1.5, 10),
1813+
is_between_badarg(2, 1, 10.0),
1814+
is_between_badarg(2, lower, upper),
1815+
1816+
ok.
1817+
1818+
-define(IS_BETWEEN_TEST(Name, LB, UB),
1819+
Name(X0) ->
1820+
F = id(is_integer),
1821+
Lower0 = LB,
1822+
Upper0 = UB,
1823+
Lower = id(Lower0),
1824+
Upper = id(Upper0),
1825+
1826+
X1 = id(X0),
1827+
Result = is_integer(X1, Lower0, Upper0),
1828+
Result = is_integer(X1, Lower, Upper),
1829+
Result = apply(erlang, F, id([X1, Lower, Upper])),
1830+
Result = erlang:F(X1, Lower, Upper),
1831+
1832+
false = is_integer(id(X1), Upper, Lower),
1833+
1834+
X = id(X1),
1835+
Result = is_integer(X) andalso Lower =< X andalso X =< Upper,
1836+
Result).
1837+
1838+
?IS_BETWEEN_TEST(is_between_ten, 1, 10).
1839+
?IS_BETWEEN_TEST(is_between_negative, -89, -77).
1840+
?IS_BETWEEN_TEST(is_between_mixed, -7, 7).
1841+
?IS_BETWEEN_TEST(is_between_bignum, 1 bsl 64, (1 bsl 64) + 7).
1842+
1843+
is_between_badarg(X, A, B) ->
1844+
F = id(is_integer),
1845+
1846+
?assertError(badarg, is_integer(id(X), id(A), id(B))),
1847+
?assertError(badarg, erlang:F(X, A, B)),
1848+
?assertError(badarg, apply(erlang, F, id([X, A, B]))).
1849+
17831850
%% helpers
17841851

17851852
wait_until(Fun) ->

erts/emulator/test/exception_SUITE.erl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,7 @@ error_info(_Config) ->
940940
{is_builtin, [1, 2, a]},
941941
{is_function, [abc, bad_arity]},
942942
{is_function, [abc, -1]},
943+
{is_integer, [5, a, b]},
943944
{is_map_key, [key, not_map]},
944945
{is_process_alive, [abc]},
945946
{is_record, [not_tuple,42]},

erts/preloaded/ebin/erlang.beam

40 Bytes
Binary file not shown.

erts/preloaded/ebin/init.beam

12 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)