From 7ff117e24a97ce98ac13671ea140c45a67400b5d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?=
Date: Fri, 21 May 2010 16:00:21 +0200
Subject: Add erlang:nif_error/1,2
A stub function that is supposed to be replaced by a NIF usually
calls erlang:error/1 to cause an exception if the NIF library
is not loaded. For example:
foo() ->
erlang:error(nif_not_loaded).
The problem is that although erlang:error/1 will normally never be
called, Dialyzer will think that any call to the function will fail
and thus generate false warnings. Adding a spec for the function
will not help because Dialyzer will not believe the spec.
Add erlang:nif_error/1,2 that work exactly like erlang:error/1,2.
Define the return types for both BIFs to be t_any().
erlang:nif_error is used like this:
-spec foo() -> binary().
foo() ->
erlang:nif_error(nif_not_loaded).
(The -spec is optional but highly recommended, since Dialyzer
otherwise has no chance to figure out the types.)
---
erts/doc/src/erlang.xml | 31 +++++++++++++++++++++++++++++++
erts/emulator/beam/bif.c | 28 ++++++++++++++++++++++++++++
erts/emulator/beam/bif.tab | 3 +++
3 files changed, 62 insertions(+)
(limited to 'erts')
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index e683f161f1..7ff52c5b50 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -2643,6 +2643,37 @@ os_prompt%
option list is malformed.
+
+ erlang:nif_error(Reason)
+ Stop execution with a given reason
+
+ Reason = term()
+
+
+ Works exactly like
+ erlang:error/1,
+ but Dialyzer thinks that this BIF will return an arbitrary term.
+ When used in a stub function for a NIF to generate an
+ exception when the NIF library is not loaded, Dialyzer
+ will not generate false warnings.
+
+
+
+ erlang:nif_error(Reason, Args)
+ Stop execution with a given reason
+
+ Reason = term()
+ Args = [term()]
+
+
+ Works exactly like
+ erlang:error/2,
+ but Dialyzer thinks that this BIF will return an arbitrary term.
+ When used in a stub function for a NIF to generate an
+ exception when the NIF library is not loaded, Dialyzer
+ will not generate false warnings.
+
+
node() -> Node
Name of the local node
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 85bf584337..7a69dc6eff 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -1131,6 +1131,34 @@ BIF_RETTYPE error_2(Process* p, Eterm value, Eterm args)
BIF_ERROR(p, EXC_ERROR_2);
}
+/**********************************************************************/
+/*
+ * This is like exactly like error/1. The only difference is
+ * that Dialyzer thinks that it it will return an arbitrary term.
+ * It is useful in stub functions for NIFs.
+ */
+
+BIF_RETTYPE nif_error_1(Process* p, Eterm term)
+{
+ p->fvalue = term;
+ BIF_ERROR(p, EXC_ERROR);
+}
+
+/**********************************************************************/
+/*
+ * This is like exactly like error/2. The only difference is
+ * that Dialyzer thinks that it it will return an arbitrary term.
+ * It is useful in stub functions for NIFs.
+ */
+
+BIF_RETTYPE nif_error_2(Process* p, Eterm value, Eterm args)
+{
+ Eterm* hp = HAlloc(p, 3);
+
+ p->fvalue = TUPLE2(hp, value, args);
+ BIF_ERROR(p, EXC_ERROR_2);
+}
+
/**********************************************************************/
/* this is like throw/1 except that we set freason to EXC_EXIT */
diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab
index 9feb302a3d..e4713567de 100644
--- a/erts/emulator/beam/bif.tab
+++ b/erts/emulator/beam/bif.tab
@@ -793,6 +793,9 @@ bif binary:encode_unsigned/2
bif binary:decode_unsigned/1
bif binary:decode_unsigned/2
+bif erlang:nif_error/1
+bif erlang:nif_error/2
+
#
# Obsolete
#
--
cgit v1.2.3