File 2268-Teach-erlang-is_builtin-3-that-erlang-apply-3-is-bui.patch of Package erlang

From 93f5844185a459cbf9efc3843919c463a2eef0fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Thu, 8 Oct 2015 13:04:40 +0200
Subject: [PATCH] Teach erlang:is_builtin/3 that erlang:apply/3 is built-in

erlang:is_builtin(erlang, apply, 3) returns 'false'. That seems to be
an oversight in the implementation of erlang:is_builtin/3 rather than
a conscious design decision. Part of apply/3 is implemented in C (as a
special instruction), and part of it in Erlang (only used if apply/3
is used recursively). That makes apply/3 special compared to all other
BIFs.

From the viewpoint of the user, apply/3 is a built-in function,
since it cannot possibly be implemented in pure Erlang.

Noticed-by: Stavros Aronis
---
 erts/emulator/beam/beam_emu.c    |  9 +++++++++
 erts/emulator/test/bif_SUITE.erl | 21 +++++++++++++++++++--
 lib/tools/test/xref_SUITE.erl    | 28 +++++++++++++---------------
 3 files changed, 41 insertions(+), 17 deletions(-)

diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index a42ce1c9f1..faf496a030 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -6752,6 +6752,15 @@ 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;
+    }
+
     e.code[0] = Mod;
     e.code[1] = Name;
     e.code[2] = arity;
diff --git a/erts/emulator/test/bif_SUITE.erl b/erts/emulator/test/bif_SUITE.erl
index d6a771e7b9..ebc4db53c4 100644
--- a/erts/emulator/test/bif_SUITE.erl
+++ b/erts/emulator/test/bif_SUITE.erl
@@ -32,7 +32,8 @@
 	 specs/1,improper_bif_stubs/1,auto_imports/1,
 	 t_list_to_existing_atom/1,os_env/1,otp_7526/1,
 	 binary_to_atom/1,binary_to_existing_atom/1,
-	 atom_to_binary/1,min_max/1, erlang_halt/1]).
+	 atom_to_binary/1,min_max/1, erlang_halt/1,
+	 is_builtin/1]).
 
 suite() -> [{ct_hooks,[ts_install_cth]}].
 
@@ -42,7 +43,7 @@ all() ->
      t_list_to_existing_atom, os_env, otp_7526,
      display,
      atom_to_binary, binary_to_atom, binary_to_existing_atom,
-     min_max, erlang_halt].
+     min_max, erlang_halt, is_builtin].
 
 groups() -> 
     [].
@@ -716,6 +717,22 @@ wait_until_stable_size(File,PrevSz) ->
             wait_until_stable_size(File,NewSz)
     end.
 
+is_builtin(_Config) ->
+    Exp0 = [{M,F,A} || {M,_} <- code:all_loaded(),
+		       {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.
+
+    Builtins0 = [{erlang,apply,3}|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],
+
+    ok.
+
 
 %% Helpers
     
diff --git a/lib/tools/test/xref_SUITE.erl b/lib/tools/test/xref_SUITE.erl
index ad47b31443..71c8b1a277 100644
--- a/lib/tools/test/xref_SUITE.erl
+++ b/lib/tools/test/xref_SUITE.erl
@@ -1151,17 +1151,13 @@ read_expected(Version) ->
 	  {POS8+4,{FF,{a,b,1}}},
 	  {POS8+4,{FF,{erlang,apply,2}}},
 	  {POS8+5,{FF,{erlang,apply,2}}},
-	  {POS8+6,{FF,{erlang,apply,3}}},
 	  {POS8+6,{FF,{m,f,1}}},
-	  {POS8+7,{FF,{erlang,apply,3}}},
-	  {POS9+1,{FF,{erlang,apply,3}}},
 	  {POS9+1,{FF,{read,bi,0}}},
 	  {POS9+2,{FF,{a,b,1}}},
 	  {POS9+2,{FF,{erlang,apply,2}}},
 	  {POS9+3,{FF,{erlang,apply,2}}},
 	  {POS9+4,{FF,{erlang,apply,2}}},
 	  {POS9+4,{FF,{erlang,not_a_function,1}}},
-	  {POS9+5,{FF,{erlang,apply,3}}},
 	  {POS9+5,{FF,{mod,func,2}}},
 	  {POS9+6,{FF,{erlang,apply,1}}},
 	  {POS9+7,{FF,{erlang,apply,2}}},
@@ -1169,17 +1165,11 @@ read_expected(Version) ->
 	  {POS9+8,{FF,{q,f,1}}},
 	  {POS10+4,{FF,{erlang,apply,2}}},
 	  {POS10+5,{FF,{mod1,fun1,1}}},
-	  {POS11+1,{FF,{erlang,apply,3}}},
-	  {POS11+2,{FF,{erlang,apply,3}}},
-	  {POS11+3,{FF,{erlang,apply,3}}},
-	  {POS11+4,{FF,{erlang,apply,3}}},
 	  {POS11+6,{FF,{erlang,apply,2}}},
 	  {POS12+1,{FF,{erlang,apply,2}}},
 	  {POS12+4,{FF,{erlang,apply,2}}},
-	  {POS12+5,{FF,{erlang,apply,3}}},
 	  {POS12+5,{FF,{m3,f3,2}}},
 	  {POS12+7,{FF,{erlang,apply,2}}},
-	  {POS12+8,{FF,{erlang,apply,3}}},
 	  {POS13+1,{FF,{dm,df,1}}},
 	  {POS13+6,{{read,bi,0},{foo,module_info,0}}},
 	  {POS13+7,{{read,bi,0},{read,module_info,0}}},
@@ -1189,10 +1179,6 @@ read_expected(Version) ->
 
     OK = case Version of
 	     abstract_v1 ->
-		 [{POS8+3, {FF,{erlang,apply,3}}},
-		  {POS10+1, {FF,{erlang,apply,3}}},
-		  {POS10+6, {FF,{erlang,apply,3}}}]
-                 ++
                  [{0,{FF,{read,'$F_EXPR',178}}},
                   {0,{FF,{modul,'$F_EXPR',179}}}]
                  ++ O1;
@@ -1213,13 +1199,25 @@ read_expected(Version) ->
             {POS3+3,  {FF,{erlang,spawn_link,3}}},
             {POS3+4, {FF,{erlang,spawn_link,3}}},
             {POS6+4, {FF,{erlang,spawn,3}}},
+	    {POS8+6,{FF,{erlang,apply,3}}},
+	    {POS8+7,{FF,{erlang,apply,3}}},
+	    {POS9+1,{FF,{erlang,apply,3}}},
+	    {POS9+5,{FF,{erlang,apply,3}}},
+	    {POS11+1,{FF,{erlang,apply,3}}},
+	    {POS11+2,{FF,{erlang,apply,3}}},
+	    {POS11+3,{FF,{erlang,apply,3}}},
+	    {POS11+4,{FF,{erlang,apply,3}}},
+	    {POS12+5,{FF,{erlang,apply,3}}},
+	    {POS12+8,{FF,{erlang,apply,3}}},
             {POS13+5, {{read,bi,0},{erlang,length,1}}},
             {POS14+3, {{read,bi,0},{erlang,length,1}}}],
 
     %% Operators (OTP-8647):
     OKB = case Version of
               abstract_v1 ->
-                  [];
+		  [{POS8+3, {FF,{erlang,apply,3}}},
+		   {POS10+1, {FF,{erlang,apply,3}}},
+		   {POS10+6, {FF,{erlang,apply,3}}}];
               _ ->
                   [{POS13+16, {{read,bi,0},{erlang,'!',2}}},
                    {POS13+16, {{read,bi,0},{erlang,'-',1}}},
-- 
2.15.0

openSUSE Build Service is sponsored by