aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStanislav Mayorov <[email protected]>2018-12-13 11:39:16 +0700
committerJohn Högberg <[email protected]>2019-01-10 09:40:27 +0100
commit46c7a85d70ee6d060a393ca4b22b06eef6fbb324 (patch)
tree38212f3401c5c5c9d839ca65f906112b1cc51ca6
parenta56bc7180c639f1f08355f22e22cf539db16982c (diff)
downloadotp-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.c33
-rw-r--r--erts/emulator/beam/bif.tab7
-rw-r--r--erts/emulator/beam/binary.c33
-rw-r--r--erts/preloaded/ebin/erlang.beambin103384 -> 101872 bytes
-rw-r--r--erts/preloaded/src/erlang.erl55
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
index 498d437616..0f0c2faa95 100644
--- a/erts/preloaded/ebin/erlang.beam
+++ b/erts/preloaded/ebin/erlang.beam
Binary files differ
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,