From b07e9f5652106a4b07335b51763192421b1671c8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Tue, 22 Nov 2011 15:34:24 +0100
Subject: beam_load.c: apply/2 does not need a special case

It is wrongly assumed in the BEAM loader that apply/2 is a BIF
and must be treated specially. Also make it clearer in ops.tab
that apply/3 is a BIF, but apply/2 is not.
---
 erts/emulator/beam/beam_load.c | 25 ++++---------------------
 erts/emulator/beam/ops.tab     | 12 ++++++++----
 2 files changed, 12 insertions(+), 25 deletions(-)

(limited to 'erts/emulator')

diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index dd788df6e4..a510632220 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -1315,15 +1315,6 @@ load_import_table(LoaderState* stp)
 static int
 read_export_table(LoaderState* stp)
 {
-    static struct {
-	Eterm mod;
-	Eterm func;
-	int arity;
-    } allow_redef[] = {
-	/* The BIFs that are allowed to be redefined by Erlang code */
-	{am_erlang,am_apply,2},
-	{am_erlang,am_apply,3},
-    };
     int i;
 
     GetInt(stp, 4, stp->num_exps);
@@ -1361,21 +1352,13 @@ read_export_table(LoaderState* stp)
 	stp->export[i].address = stp->code + value;
 
 	/*
-	 * Check that we are not redefining a BIF (except the ones allowed to
-	 * redefine).
+	 * Check that we are not redefining a BIF (except erlang:apply/3).
 	 */
 	if ((e = erts_find_export_entry(stp->module, func, arity)) != NULL) {
 	    if (e->code[3] == (BeamInstr) em_apply_bif) {
-		int j;
-
-		for (j = 0; j < sizeof(allow_redef)/sizeof(allow_redef[0]); j++) {
-		    if (stp->module == allow_redef[j].mod &&
-			func == allow_redef[j].func &&
-			arity == allow_redef[j].arity) {
-			break;
-		    }
-		}
-		if (j == sizeof(allow_redef)/sizeof(allow_redef[0])) {
+		if (stp->module != am_erlang ||
+		    func != am_apply ||
+		    arity != 3) {
 		    LoadError2(stp, "exported function %T/%d redefines BIF",
 			       func, arity);
 		}
diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab
index fc53a88a3a..f051f6aa5b 100644
--- a/erts/emulator/beam/ops.tab
+++ b/erts/emulator/beam/ops.tab
@@ -829,16 +829,20 @@ call_ext_only Ar=u==2 Bif=u$bif:erlang:load_nif/2 => allocate u Ar | i_call_ext
 
 
 #
-# The apply/2 and apply/3 BIFs are instructions.
+# apply/2 is an instruction, not a BIF.
 #
 
 call_ext u==2 u$func:erlang:apply/2 => i_apply_fun
 call_ext_last u==2 u$func:erlang:apply/2 D => i_apply_fun_last D
 call_ext_only u==2 u$func:erlang:apply/2 => i_apply_fun_only
 
-call_ext u==3 u$func:erlang:apply/3 => i_apply
-call_ext_last u==3 u$func:erlang:apply/3 D => i_apply_last D
-call_ext_only u==3 u$func:erlang:apply/3 => i_apply_only
+#
+# The apply/3 BIF is an instruction.
+#
+
+call_ext u==3 u$bif:erlang:apply/3 => i_apply
+call_ext_last u==3 u$bif:erlang:apply/3 D => i_apply_last D
+call_ext_only u==3 u$bif:erlang:apply/3 => i_apply_only
 
 #
 # The exit/1 and throw/1 BIFs never execute the instruction following them;
-- 
cgit v1.2.3