aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2017-10-26 12:57:24 +0200
committerBjörn Gustavsson <[email protected]>2017-10-27 11:36:58 +0200
commit696f47b64c8ad5da71cbffd8fecf0f3bae1e7466 (patch)
treecf9e18961c4193c2305d20661c72cfab267dbe42 /erts/emulator
parent56455ce5b80087cd661ac3343f96c5a3df2f9f9c (diff)
downloadotp-696f47b64c8ad5da71cbffd8fecf0f3bae1e7466.tar.gz
otp-696f47b64c8ad5da71cbffd8fecf0f3bae1e7466.tar.bz2
otp-696f47b64c8ad5da71cbffd8fecf0f3bae1e7466.zip
Correct erlang:is_builtin/3 for apply/2 and yield/0
erlang:is_builtin(erlang, M, F) returns false for apply/2 and yield/0. The documentation for erlang:is_builtin/3 says that it returns true for BIFs that are implemented in C. apply/2 and yield/0 are implemented in C (as BEAM instructions), and therefore the correct return value is true. Also see a similar argument that was made for apply/3 in the past: http://erlang.org/pipermail/erlang-bugs/2015-October/005101.html https://bugs.erlang.org/browse/ERL-500
Diffstat (limited to 'erts/emulator')
-rw-r--r--erts/emulator/beam/beam_emu.c17
-rw-r--r--erts/emulator/test/bif_SUITE.erl18
2 files changed, 22 insertions, 13 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index aa94fbf536..60d0008d8f 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -3199,13 +3199,16 @@ erts_is_builtin(Eterm Mod, Eterm Name, int arity)
Export e;
Export* ep;
- if (Mod == am_erlang && Name == am_apply && arity == 3) {
- /*
- * Special case. apply/3 is built-in (implemented in C),
- * but implemented in a different way than all other
- * BIFs.
- */
- return 1;
+ if (Mod == am_erlang) {
+ /*
+ * Special case for built-in functions that are implemented
+ * as instructions as opposed to SNIFs.
+ */
+ if (Name == am_apply && (arity == 2 || arity == 3)) {
+ return 1;
+ } else if (Name == am_yield && arity == 0) {
+ return 1;
+ }
}
e.info.mfa.module = Mod;
diff --git a/erts/emulator/test/bif_SUITE.erl b/erts/emulator/test/bif_SUITE.erl
index 146c37b118..e1b42e5d85 100644
--- a/erts/emulator/test/bif_SUITE.erl
+++ b/erts/emulator/test/bif_SUITE.erl
@@ -781,14 +781,20 @@ is_builtin(_Config) ->
{F,A} <- M:module_info(exports)],
Exp = ordsets:from_list(Exp0),
- %% erlang:apply/3 is considered to be built-in, but is not
- %% implemented as other BIFs.
+ %% Built-ins implemented as special instructions.
+ Instructions = [{erlang,apply,2},{erlang,apply,3},{erlang,yield,0}],
- Builtins0 = [{erlang,apply,3}|erlang:system_info(snifs)],
+ Builtins0 = Instructions ++ erlang:system_info(snifs),
Builtins = ordsets:from_list(Builtins0),
- NotBuiltin = ordsets:subtract(Exp, Builtins),
- _ = [true = erlang:is_builtin(M, F, A) || {M,F,A} <- Builtins],
- _ = [false = erlang:is_builtin(M, F, A) || {M,F,A} <- NotBuiltin],
+
+ Fakes = [{M,F,42} || {M,F,_} <- Instructions],
+ All = ordsets:from_list(Fakes ++ Exp),
+ NotBuiltin = ordsets:subtract(All, Builtins),
+
+ _ = [{true,_} = {erlang:is_builtin(M, F, A),MFA} ||
+ {M,F,A}=MFA <- Builtins],
+ _ = [{false,_} = {erlang:is_builtin(M, F, A),MFA} ||
+ {M,F,A}=MFA <- NotBuiltin],
ok.