diff options
author | Stanislav Mayorov <[email protected]> | 2018-12-13 11:39:16 +0700 |
---|---|---|
committer | John Högberg <[email protected]> | 2019-01-10 09:40:27 +0100 |
commit | 46c7a85d70ee6d060a393ca4b22b06eef6fbb324 (patch) | |
tree | 38212f3401c5c5c9d839ca65f906112b1cc51ca6 | |
parent | a56bc7180c639f1f08355f22e22cf539db16982c (diff) | |
download | otp-46c7a85d70ee6d060a393ca4b22b06eef6fbb324.tar.gz otp-46c7a85d70ee6d060a393ca4b22b06eef6fbb324.tar.bz2 otp-46c7a85d70ee6d060a393ca4b22b06eef6fbb324.zip |
Implement integer_to_list/2 and integer_to_binary/2 as CIFs
This makes them roughly as fast as integer_to_list/1 and
integer_to_binary/1.
-rw-r--r-- | erts/emulator/beam/bif.c | 33 | ||||
-rw-r--r-- | erts/emulator/beam/bif.tab | 7 | ||||
-rw-r--r-- | erts/emulator/beam/binary.c | 33 | ||||
-rw-r--r-- | erts/preloaded/ebin/erlang.beam | bin | 103384 -> 101872 bytes | |||
-rw-r--r-- | erts/preloaded/src/erlang.erl | 55 |
5 files changed, 78 insertions, 50 deletions
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index 45b75a4e31..f1fac7f8d0 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -2883,6 +2883,39 @@ BIF_RETTYPE integer_to_list_1(BIF_ALIST_1) return res; } +BIF_RETTYPE integer_to_list_2(BIF_ALIST_2) +{ + Eterm res; + int base; + + if (is_not_integer(BIF_ARG_1) || is_not_integer(BIF_ARG_2)) { + BIF_ERROR(BIF_P, BADARG); + } + + base = unsigned_val(BIF_ARG_2); + if (base < 2 || base > 36) { + BIF_ERROR(BIF_P, BADARG); + } + + res = integer_to_list(BIF_P, BIF_ARG_1, base); + + if (is_non_value(res)) { + Eterm args[2]; + args[0] = BIF_ARG_1; + args[1] = BIF_ARG_2; + return erts_schedule_bif(BIF_P, + args, + BIF_I, + integer_to_list_2, + ERTS_SCHED_DIRTY_CPU, + am_erlang, + am_integer_to_list, + 2); + } + + return res; +} + /**********************************************************************/ /* diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab index 0e218811d8..c96278b10c 100644 --- a/erts/emulator/beam/bif.tab +++ b/erts/emulator/beam/bif.tab @@ -731,3 +731,10 @@ bif erts_internal:counters_info/1 # bif erts_internal:spawn_system_process/3 + +# +# New in 21.3 +# + +bif erlang:integer_to_list/2 +bif erlang:integer_to_binary/2 diff --git a/erts/emulator/beam/binary.c b/erts/emulator/beam/binary.c index 982bf087b0..5f090e89d7 100644 --- a/erts/emulator/beam/binary.c +++ b/erts/emulator/beam/binary.c @@ -387,6 +387,39 @@ BIF_RETTYPE integer_to_binary_1(BIF_ALIST_1) return res; } +BIF_RETTYPE integer_to_binary_2(BIF_ALIST_2) +{ + Eterm res; + int base; + + if (is_not_integer(BIF_ARG_1) || is_not_integer(BIF_ARG_2)) { + BIF_ERROR(BIF_P, BADARG); + } + + base = unsigned_val(BIF_ARG_2); + if (base < 2 || base > 36) { + BIF_ERROR(BIF_P, BADARG); + } + + res = integer_to_binary(BIF_P, BIF_ARG_1, base); + + if (is_non_value(res)) { + Eterm args[2]; + args[0] = BIF_ARG_1; + args[1] = BIF_ARG_2; + return erts_schedule_bif(BIF_P, + args, + BIF_I, + integer_to_binary_2, + ERTS_SCHED_DIRTY_CPU, + am_erlang, + am_integer_to_binary, + 2); + } + + return res; +} + #define ERTS_B2L_BYTES_PER_REDUCTION 256 typedef struct { diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam Binary files differindex 498d437616..0f0c2faa95 100644 --- a/erts/preloaded/ebin/erlang.beam +++ b/erts/preloaded/ebin/erlang.beam diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl index f37a3fc5db..c20082a545 100644 --- a/erts/preloaded/src/erlang.erl +++ b/erts/preloaded/src/erlang.erl @@ -3395,60 +3395,15 @@ get_cookie() -> -spec integer_to_list(Integer, Base) -> string() when Integer :: integer(), Base :: 2..36. -integer_to_list(I, 10) -> - erlang:integer_to_list(I); -integer_to_list(I, Base) - when erlang:is_integer(I), erlang:is_integer(Base), - Base >= 2, Base =< 1+$Z-$A+10 -> - if I < 0 -> - [$-|integer_to_list(-I, Base, [])]; - true -> - integer_to_list(I, Base, []) - end; -integer_to_list(I, Base) -> - erlang:error(badarg, [I, Base]). - -integer_to_list(I0, Base, R0) -> - D = I0 rem Base, - I1 = I0 div Base, - R1 = if D >= 10 -> - [D-10+$A|R0]; - true -> - [D+$0|R0] - end, - if I1 =:= 0 -> - R1; - true -> - integer_to_list(I1, Base, R1) - end. +integer_to_list(_I, _Base) -> + erlang:nif_error(undefined). -spec integer_to_binary(Integer, Base) -> binary() when Integer :: integer(), Base :: 2..36. -integer_to_binary(I, 10) -> - erlang:integer_to_binary(I); -integer_to_binary(I, Base) - when erlang:is_integer(I), erlang:is_integer(Base), - Base >= 2, Base =< 1+$Z-$A+10 -> - if I < 0 -> - <<$-,(integer_to_binary(-I, Base, <<>>))/binary>>; - true -> - integer_to_binary(I, Base, <<>>) - end; -integer_to_binary(I, Base) -> - erlang:error(badarg, [I, Base]). - -integer_to_binary(I0, Base, R0) -> - D = I0 rem Base, - I1 = I0 div Base, - R1 = if - D >= 10 -> <<(D-10+$A),R0/binary>>; - true -> <<(D+$0),R0/binary>> - end, - if - I1 =:= 0 -> R1; - true -> integer_to_binary(I1, Base, R1) - end. +integer_to_binary(_I, _Base) -> + erlang:nif_error(undefined). + -record(cpu, {node = -1, processor = -1, |