Permalink
Browse files

OTP-8304 Incompatible changes in the experimental NIF feature. Change…

…d the

          NIF function prototypes in order to allow more than 3 function
          arguments. Also an incompatible change in the return value of
          erlang:load_nif/2. Added support for references, floats and term
          comparison in NIFs. Read more in the documentation of erl_nif and
          erlang:load_nif/2.
  • Loading branch information...
1 parent dd983db commit e2ecf7de626ecc2c60f9c8738c20820d21403d77 @sverker sverker committed with Erlang/OTP Dec 9, 2009
Showing with 34 additions and 9 deletions.
  1. +2 −6 erts/emulator/beam/erl_nif.c
  2. +16 −2 erts/emulator/test/nif_SUITE.erl
  3. +16 −1 erts/emulator/test/nif_SUITE_data/nif_SUITE.c
@@ -631,12 +631,8 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
for (i=0; i < entry->num_of_funcs && ret==am_ok; i++) {
Uint** code_pp;
ErlNifFunc* f = &entry->funcs[i];
- if (f->arity > 3) {
- ret = load_nif_error(BIF_P,bad_lib,"Function arity too high for NIF %s/%u",
- f->name, f->arity);
- }
- else if (!erts_atom_get(f->name, sys_strlen(f->name), &f_atom)
- || (code_pp = get_func_pp(mod->code, f_atom, f->arity))==NULL) {
+ if (!erts_atom_get(f->name, sys_strlen(f->name), &f_atom)
+ || (code_pp = get_func_pp(mod->code, f_atom, f->arity))==NULL) {
ret = load_nif_error(BIF_P,bad_lib,"Function not found %T:%s/%u",
mod_atom, f->name, f->arity);
}
@@ -24,12 +24,13 @@
-include("test_server.hrl").
-export([all/1, fin_per_testcase/2, basic/1, reload/1, upgrade/1, heap_frag/1,
- types/1, neg/1]).
+ types/1, many_args/1, neg/1]).
+-export([many_args_100/100]).
-define(nif_stub,nif_stub_error(?LINE)).
all(suite) ->
- [basic, reload, upgrade, heap_frag, types, neg].
+ [basic, reload, upgrade, heap_frag, types, many_args, neg].
fin_per_testcase(_Func, _Config) ->
P1 = code:purge(nif_mod),
@@ -222,6 +223,18 @@ eq_cmp_do(A,B) ->
end,
ok.
+
+many_args(doc) -> ["Test NIF with many arguments"];
+many_args(suite) -> [];
+many_args(Config) when is_list(Config) ->
+ ?line ensure_lib_loaded(Config ,1),
+ ?line ok = apply(?MODULE,many_args_100,lists:seq(1,100)),
+ ?line ok = many_args_100(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100),
+ ok.
+
+
+
+
neg(doc) -> ["Negative testing of load_nif"];
neg(suite) -> [];
neg(Config) when is_list(Config) ->
@@ -271,6 +284,7 @@ type_test() -> ?nif_stub.
tuple_2_list(_) -> ?nif_stub.
is_identical(_,_) -> ?nif_stub.
compare(_,_) -> ?nif_stub.
+many_args_100(_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_) -> ?nif_stub.
nif_stub_error(Line) ->
exit({nif_not_loaded,module,?MODULE,line,Line}).
@@ -289,6 +289,20 @@ static ERL_NIF_TERM compare(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
return enif_make_int(env, enif_compare(env,argv[0],argv[1]));
}
+static ERL_NIF_TERM many_args_100(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ int i, k;
+ if (argc == 100) {
+ for (i=1; i<=100; i++) {
+ if (!enif_get_int(env,argv[i-1],&k) || k!=i) {
+ goto badarg;
+ }
+ }
+ return enif_make_atom(env,"ok");
+ }
+badarg:
+ return enif_make_badarg(env);
+}
static ErlNifFunc nif_funcs[] =
{
@@ -300,7 +314,8 @@ static ErlNifFunc nif_funcs[] =
{"type_test", 0, type_test},
{"tuple_2_list", 1, tuple_2_list},
{"is_identical",2,is_identical},
- {"compare",2,compare}
+ {"compare",2,compare},
+ {"many_args_100", 100, many_args_100}
};
ERL_NIF_INIT(nif_SUITE,nif_funcs,load,reload,upgrade,unload)

0 comments on commit e2ecf7d

Please sign in to comment.