aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib/src
diff options
context:
space:
mode:
authorJohn Högberg <[email protected]>2018-02-26 16:27:39 +0100
committerJohn Högberg <[email protected]>2018-02-26 17:47:07 +0100
commit2627297ad239697c7df297b8fde35f9827fa962f (patch)
tree524ecae6919dfd8316a0066eba7f0d466513ba40 /lib/stdlib/src
parent7914843737e490c49b0918b67a093e68415b3beb (diff)
downloadotp-2627297ad239697c7df297b8fde35f9827fa962f.tar.gz
otp-2627297ad239697c7df297b8fde35f9827fa962f.tar.bz2
otp-2627297ad239697c7df297b8fde35f9827fa962f.zip
Replace binary:bin_to_list CIF implementation with binary_to_list
binary:bin_to_list had a poor implementation that resulted in excessive garbage collection. binary_to_list is almost identical and has a generally better implementation, so I've replaced binary:bin_to_list's CIF with a thin wrapper around binary_to_list. Granted, binary_to_list has a deprecated indexing scheme, but we're unlikely to ever remote it entirely and it's somewhat easy to move it to the 'binary' module later on.
Diffstat (limited to 'lib/stdlib/src')
-rw-r--r--lib/stdlib/src/binary.erl28
1 files changed, 22 insertions, 6 deletions
diff --git a/lib/stdlib/src/binary.erl b/lib/stdlib/src/binary.erl
index 6a64133b45..7d0e42489e 100644
--- a/lib/stdlib/src/binary.erl
+++ b/lib/stdlib/src/binary.erl
@@ -47,23 +47,39 @@ at(_, _) ->
-spec bin_to_list(Subject) -> [byte()] when
Subject :: binary().
-bin_to_list(_) ->
- erlang:nif_error(undef).
+bin_to_list(Subject) ->
+ binary_to_list(Subject).
-spec bin_to_list(Subject, PosLen) -> [byte()] when
Subject :: binary(),
PosLen :: part().
-bin_to_list(_, _) ->
- erlang:nif_error(undef).
+bin_to_list(Subject, {Pos, Len}) ->
+ bin_to_list(Subject, Pos, Len);
+bin_to_list(_Subject, _BadArg) ->
+ erlang:error(badarg).
-spec bin_to_list(Subject, Pos, Len) -> [byte()] when
Subject :: binary(),
Pos :: non_neg_integer(),
Len :: integer().
-bin_to_list(_, _, _) ->
- erlang:nif_error(undef).
+bin_to_list(Subject, Pos, Len) when not is_binary(Subject);
+ not is_integer(Pos);
+ not is_integer(Len) ->
+ %% binary_to_list/3 allows bitstrings as long as the slice fits, and we
+ %% want to badarg when Pos/Len aren't integers instead of raising badarith
+ %% when adjusting args for binary_to_list/3.
+ erlang:error(badarg);
+bin_to_list(Subject, Pos, 0) when Pos >= 0, Pos =< byte_size(Subject) ->
+ %% binary_to_list/3 doesn't handle this case.
+ [];
+bin_to_list(_Subject, _Pos, 0) ->
+ erlang:error(badarg);
+bin_to_list(Subject, Pos, Len) when Len < 0 ->
+ bin_to_list(Subject, Pos + Len, -Len);
+bin_to_list(Subject, Pos, Len) when Len > 0 ->
+ binary_to_list(Subject, Pos + 1, Pos + Len).
-spec compile_pattern(Pattern) -> cp() when
Pattern :: binary() | [binary()].