In earlier versions (older than erts-7.0, OTP 18) the return value
from enif_make_badarg had to be returned from the NIF. This
requirement is now lifted as the return value from the NIF is ignored
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index 6fa8164787..0a05bdcf8b 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -747,6 +747,11 @@ Eterm enif_make_badarg(ErlNifEnv* env)
BIF_ERROR(env->proc, BADARG);
}
+int enif_has_pending_exception(ErlNifEnv* env)
+{
+ return env->exception_thrown;
+}
+
int enif_get_atom(ErlNifEnv* env, Eterm atom, char* buf, unsigned len,
ErlNifCharEncoding encoding)
{
diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h
index 849024453c..006547e1d0 100644
--- a/erts/emulator/beam/erl_nif.h
+++ b/erts/emulator/beam/erl_nif.h
@@ -46,9 +46,10 @@
** remove enif_schedule_dirty_nif, enif_schedule_dirty_nif_finalizer, enif_dirty_nif_finalizer
** add ErlNifEntry options
** add ErlNifFunc flags
+** 2.8: 18.0 add enif_has_pending_exception
*/
#define ERL_NIF_MAJOR_VERSION 2
-#define ERL_NIF_MINOR_VERSION 7
+#define ERL_NIF_MINOR_VERSION 8
/*
* The emulator will refuse to load a nif-lib with a major version
diff --git a/erts/emulator/beam/erl_nif_api_funcs.h b/erts/emulator/beam/erl_nif_api_funcs.h
index 630cefae93..bdcbb32c46 100644
--- a/erts/emulator/beam/erl_nif_api_funcs.h
+++ b/erts/emulator/beam/erl_nif_api_funcs.h
@@ -156,6 +156,7 @@ ERL_NIF_API_FUNC_DECL(int, enif_map_iterator_next, (ErlNifEnv *env, ErlNifMapIte
ERL_NIF_API_FUNC_DECL(int, enif_map_iterator_prev, (ErlNifEnv *env, ErlNifMapIterator *iter));
ERL_NIF_API_FUNC_DECL(int, enif_map_iterator_get_pair, (ErlNifEnv *env, ErlNifMapIterator *iter, ERL_NIF_TERM *key, ERL_NIF_TERM *value));
ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_schedule_nif,(ErlNifEnv*,const char*,int,ERL_NIF_TERM (*)(ErlNifEnv*,int,const ERL_NIF_TERM[]),int,const ERL_NIF_TERM[]));
+ERL_NIF_API_FUNC_DECL(int, enif_has_pending_exception, (ErlNifEnv *env));
/*
** ADD NEW ENTRIES HERE (before this comment) !!!
@@ -305,6 +306,7 @@ ERL_NIF_API_FUNC_DECL(int,enif_is_on_dirty_scheduler,(ErlNifEnv*));
# define enif_map_iterator_prev ERL_NIF_API_FUNC_MACRO(enif_map_iterator_prev)
# define enif_map_iterator_get_pair ERL_NIF_API_FUNC_MACRO(enif_map_iterator_get_pair)
# define enif_schedule_nif ERL_NIF_API_FUNC_MACRO(enif_schedule_nif)
+# define enif_has_pending_exception ERL_NIF_API_FUNC_MACRO(enif_has_pending_exception)
/*
** ADD NEW ENTRIES HERE (before this comment)
diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
index b30c484a6c..87f0e72d9f 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
@@ -892,6 +892,7 @@ static ERL_NIF_TERM check_is_exception(ErlNifEnv* env, int argc, const ERL_NIF_T
ERL_NIF_TERM badarg = enif_make_badarg(env);
if (enif_is_exception(env, error_atom)) return error_atom;
if (!enif_is_exception(env, badarg)) return error_atom;
+ if (!enif_has_pending_exception(env)) return error_atom;
return badarg;
}
@@ -1692,6 +1693,7 @@ static ERL_NIF_TERM call_nif_nan_or_inf(ErlNifEnv* env, int argc, const ERL_NIF_
}
res = enif_make_double(env, val);
assert(enif_is_exception(env, res));
+ assert(enif_has_pending_exception(env));
if (strcmp(arg, "tuple") == 0) {
return enif_make_tuple2(env, argv[0], res);
} else {
--
cgit v1.2.3
From 308b03e8afa14e03973330942e7aacf0cc925bf2 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Tue, 14 Apr 2015 15:43:40 +0200
Subject: erts: Remove old docs about experimental NIF versions.
---
erts/doc/src/erl_nif.xml | 28 ----------------------------
1 file changed, 28 deletions(-)
(limited to 'erts')
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
index 5c912e0fe3..4bad8b253c 100644
--- a/erts/doc/src/erl_nif.xml
+++ b/erts/doc/src/erl_nif.xml
@@ -66,34 +66,6 @@
- The NIF concept is officially supported from R14B. NIF source code
- written for earlier experimental versions might need adaption to run on R14B
- or later versions:
-
- - No incompatible changes between R14B and R14A.
- - Incompatible changes between R14A and R13B04:
-
- - Environment argument removed for enif_alloc,
- enif_realloc, enif_free, enif_alloc_binary,
- enif_realloc_binary, enif_release_binary,
- enif_alloc_resource, enif_release_resource,
- enif_is_identical and enif_compare.
- - Character encoding argument added to enif_get_atom
- and enif_make_existing_atom.
- - Module argument added to enif_open_resource_type
- while changing name spaces of resource types from global to module local.
-
-
- - Incompatible changes between R13B04 and R13B03:
-
- - The function prototypes of the NIFs have changed to expect argc and argv
- arguments. The arity of a NIF is by that no longer limited to 3.
- - enif_get_data renamed as enif_priv_data.
- - enif_make_string got a third argument for character encoding.
-
-
-
-
A minimal example of a NIF library can look like this:
--
cgit v1.2.3
From dd9ad8da73e15e89c8ab27efdd47a8bda8019957 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Wed, 15 Apr 2015 17:30:00 +0200
Subject: erts: Reject non-finite float terms in erl_drv_output_term
---
erts/emulator/beam/io.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index 012a7d1a4b..07dc0db3b9 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -5581,7 +5581,9 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len)
mess = make_float(hp);
f.fd = *((double *) ptr[0]);
- PUT_DOUBLE(f, hp);
+ if (!erts_isfinite(f.fd))
+ ERTS_DDT_FAIL;
+ PUT_DOUBLE(f, hp);
hp += FLOAT_SIZE_OBJECT;
ptr++;
break;
--
cgit v1.2.3