From 256391d4f9b7425fd96b5b9f344b212751bdfda2 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Thu, 30 Jun 2011 14:33:28 +0200 Subject: Added enif_get_reverse_list to nif API --- erts/doc/src/erl_nif.xml | 7 +++++++ erts/emulator/beam/erl_nif.c | 24 ++++++++++++++++++++++++ erts/emulator/beam/erl_nif.h | 2 +- erts/emulator/beam/erl_nif_api_funcs.h | 2 ++ erts/emulator/test/nif_SUITE.erl | 12 ++++++++++-- erts/emulator/test/nif_SUITE_data/nif_SUITE.c | 11 ++++++++++- 6 files changed, 54 insertions(+), 4 deletions(-) (limited to 'erts') diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml index cdce4ec0b8..6b9a405647 100644 --- a/erts/doc/src/erl_nif.xml +++ b/erts/doc/src/erl_nif.xml @@ -604,6 +604,13 @@ typedef enum {

Set *len to the length of list term and return true, or return false if term is not a list.

+ intenif_get_reverse_list(ErlNifEnv* env, ERL_NIF_TERM term, ERL_NIF_TERM *list) + Get the reverse list of the list term. +

Set *list to the reverse list of the list term and return true, + or return false if term is not a list. This function should only be used on + short lists as a copy will be created of the list which will not be released until after the + nif returns.

+
intenif_get_long(ErlNifEnv* env, ERL_NIF_TERM term, long int* ip) Read an long integer term.

Set *ip to the long integer value of term and diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index 68421b4387..d1afeb4f03 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -1007,6 +1007,30 @@ void enif_system_info(ErlNifSysInfo *sip, size_t si_size) driver_system_info(sip, si_size); } +int enif_get_reverse_list(ErlNifEnv* env, ERL_NIF_TERM term, ERL_NIF_TERM *list) { + Eterm *listptr, *ret, *hp; + + if (is_nil(term)) { + *list = term; + return 1; + } + + ret = alloc_heap(env, 2); + *ret = NIL; + + while (is_not_nil(term)) { + if (is_not_list(term)) { + return 0; + } + hp = alloc_heap(env, 2); + listptr = list_val(term); + *ret = CONS(hp, CAR(listptr), *ret); + term = CDR(listptr); + } + *list = *ret; + return 1; +} + ErlNifMutex* enif_mutex_create(char *name) { return erl_drv_mutex_create(name); } void enif_mutex_destroy(ErlNifMutex *mtx) { erl_drv_mutex_destroy(mtx); } diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h index d028567faf..bb557e39e9 100644 --- a/erts/emulator/beam/erl_nif.h +++ b/erts/emulator/beam/erl_nif.h @@ -34,7 +34,7 @@ ** 2.2: R14B03 enif_is_exception */ #define ERL_NIF_MAJOR_VERSION 2 -#define ERL_NIF_MINOR_VERSION 2 +#define ERL_NIF_MINOR_VERSION 3 #include diff --git a/erts/emulator/beam/erl_nif_api_funcs.h b/erts/emulator/beam/erl_nif_api_funcs.h index c991b61abe..465d52227d 100644 --- a/erts/emulator/beam/erl_nif_api_funcs.h +++ b/erts/emulator/beam/erl_nif_api_funcs.h @@ -136,6 +136,7 @@ ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_int64,(ErlNifEnv*, ErlNifSInt64)); ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_uint64,(ErlNifEnv*, ErlNifUInt64)); #endif ERL_NIF_API_FUNC_DECL(int,enif_is_exception,(ErlNifEnv*, ERL_NIF_TERM term)); +ERL_NIF_API_FUNC_DECL(int,enif_get_reverse_list,(ErlNifEnv*, ERL_NIF_TERM term, ERL_NIF_TERM *list)); /* ** Add new entries here to keep compatibility on Windows!!! @@ -256,6 +257,7 @@ ERL_NIF_API_FUNC_DECL(int,enif_is_exception,(ErlNifEnv*, ERL_NIF_TERM term)); #endif # define enif_is_exception ERL_NIF_API_FUNC_MACRO(enif_is_exception) +# define enif_get_reverse_list ERL_NIF_API_FUNC_MACRO(enif_get_reverse_list) /* ** Add new entries here diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl index 91d695d979..813ed65f4b 100644 --- a/erts/emulator/test/nif_SUITE.erl +++ b/erts/emulator/test/nif_SUITE.erl @@ -35,7 +35,7 @@ resource_takeover/1, threading/1, send/1, send2/1, send3/1, send_threaded/1, neg/1, is_checks/1, - get_length/1, make_atom/1, make_string/1]). + get_length/1, make_atom/1, make_string/1, reverse_list_test/1]). -export([many_args_100/100]). @@ -60,7 +60,7 @@ all() -> iolist_as_binary, resource, resource_binary, resource_takeover, threading, send, send2, send3, send_threaded, neg, is_checks, get_length, make_atom, - make_string]. + make_string,reverse_list_test]. groups() -> []. @@ -1164,6 +1164,13 @@ make_string(Config) when is_list(Config) -> AStringWithAccents = [$E,$r,$l,$a,$n,$g,$ ,16#e4,$r,$ ,$e,$t,$t,$ ,$g,$e,$n,$e,$r,$e,$l,$l,$t,$ ,$p,$r,$o,$g,$r,$a,$m,$s,$p,$r,16#e5,$k], ?line Strings = {A0String,A0String,A0String,A0String0, AStringWithAccents}. +reverse_list_test(Config) -> + ?line ensure_lib_loaded(Config, 1), + List = lists:seq(1,100), + RevList = lists:reverse(List), + ?line RevList = reverse_list(List), + badarg = reverse_list(foo). + tmpmem() -> case erlang:system_info({allocator,temp_alloc}) of false -> undefined; @@ -1269,6 +1276,7 @@ send_blob_thread(_,_,_) -> ?nif_stub. join_send_thread(_) -> ?nif_stub. copy_blob(_) -> ?nif_stub. send_term(_,_) -> ?nif_stub. +reverse_list(_) -> ?nif_stub. nif_stub_error(Line) -> exit({nif_not_loaded,module,?MODULE,line,Line}). diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c index 0bb93daa33..87b4d4c4ed 100644 --- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c +++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c @@ -1373,6 +1373,14 @@ static ERL_NIF_TERM send_term(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[ return enif_make_int(env, ret); } +static ERL_NIF_TERM reverse_list(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { + ERL_NIF_TERM rev_list; + + if(!enif_get_reverse_list(env, argv[0], &rev_list)) + return enif_make_atom(env, "badarg"); + return rev_list; +} + static ErlNifFunc nif_funcs[] = { {"lib_version", 0, lib_version}, @@ -1417,7 +1425,8 @@ static ErlNifFunc nif_funcs[] = {"send_blob_thread", 3, send_blob_thread}, {"join_send_thread", 1, join_send_thread}, {"copy_blob", 1, copy_blob}, - {"send_term", 2, send_term} + {"send_term", 2, send_term}, + {"reverse_list",1, reverse_list} }; ERL_NIF_INIT(nif_SUITE,nif_funcs,load,reload,upgrade,unload) -- cgit v1.2.3 From 6f9e2029f780ed6fb2deef1dd7f78b84b090b488 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Thu, 30 Jun 2011 17:57:37 +0200 Subject: Remove extra allocated heap fragment --- erts/emulator/beam/erl_nif.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'erts') diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index d1afeb4f03..0f0790f8bb 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -1008,15 +1008,14 @@ void enif_system_info(ErlNifSysInfo *sip, size_t si_size) } int enif_get_reverse_list(ErlNifEnv* env, ERL_NIF_TERM term, ERL_NIF_TERM *list) { - Eterm *listptr, *ret, *hp; + Eterm *listptr, ret = NIL, *hp; if (is_nil(term)) { *list = term; return 1; } - ret = alloc_heap(env, 2); - *ret = NIL; + ret = NIL; while (is_not_nil(term)) { if (is_not_list(term)) { @@ -1024,10 +1023,10 @@ int enif_get_reverse_list(ErlNifEnv* env, ERL_NIF_TERM term, ERL_NIF_TERM *list) } hp = alloc_heap(env, 2); listptr = list_val(term); - *ret = CONS(hp, CAR(listptr), *ret); + ret = CONS(hp, CAR(listptr), ret); term = CDR(listptr); } - *list = *ret; + *list = ret; return 1; } -- cgit v1.2.3 From 406460b546ae014d335b4b5f6b011ce3fbf26e5c Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Fri, 1 Jul 2011 10:21:03 +0200 Subject: Rename enif_get_reverse_list to enif_make_reverse_list --- erts/doc/src/erl_nif.xml | 14 +++++++------- erts/emulator/beam/erl_nif.c | 2 +- erts/emulator/beam/erl_nif_api_funcs.h | 4 ++-- erts/emulator/test/nif_SUITE.erl | 2 +- erts/emulator/test/nif_SUITE_data/nif_SUITE.c | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) (limited to 'erts') diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml index 6b9a405647..382e446dce 100644 --- a/erts/doc/src/erl_nif.xml +++ b/erts/doc/src/erl_nif.xml @@ -604,13 +604,6 @@ typedef enum {

Set *len to the length of list term and return true, or return false if term is not a list.

- intenif_get_reverse_list(ErlNifEnv* env, ERL_NIF_TERM term, ERL_NIF_TERM *list) - Get the reverse list of the list term. -

Set *list to the reverse list of the list term and return true, - or return false if term is not a list. This function should only be used on - short lists as a copy will be created of the list which will not be released until after the - nif returns.

-
intenif_get_long(ErlNifEnv* env, ERL_NIF_TERM term, long int* ip) Read an long integer term.

Set *ip to the long integer value of term and @@ -829,6 +822,13 @@ typedef enum {

Create an ordinary list containing the elements of array arr of length cnt. An empty list is returned if cnt is 0.

+ intenif_make_reverse_list(ErlNifEnv* env, ERL_NIF_TERM term, ERL_NIF_TERM *list) + Create the reverse list of the list term. +

Set *list to the reverse list of the list term and return true, + or return false if term is not a list. This function should only be used on + short lists as a copy will be created of the list which will not be released until after the + nif returns.

+
ERL_NIF_TERMenif_make_long(ErlNifEnv* env, long int i) Create an integer term from a long int

Create an integer term from a long int.

diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index 0f0790f8bb..aa6a024b35 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -1007,7 +1007,7 @@ void enif_system_info(ErlNifSysInfo *sip, size_t si_size) driver_system_info(sip, si_size); } -int enif_get_reverse_list(ErlNifEnv* env, ERL_NIF_TERM term, ERL_NIF_TERM *list) { +int enif_make_reverse_list(ErlNifEnv* env, ERL_NIF_TERM term, ERL_NIF_TERM *list) { Eterm *listptr, ret = NIL, *hp; if (is_nil(term)) { diff --git a/erts/emulator/beam/erl_nif_api_funcs.h b/erts/emulator/beam/erl_nif_api_funcs.h index 465d52227d..4af9f61000 100644 --- a/erts/emulator/beam/erl_nif_api_funcs.h +++ b/erts/emulator/beam/erl_nif_api_funcs.h @@ -136,7 +136,7 @@ ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_int64,(ErlNifEnv*, ErlNifSInt64)); ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_uint64,(ErlNifEnv*, ErlNifUInt64)); #endif ERL_NIF_API_FUNC_DECL(int,enif_is_exception,(ErlNifEnv*, ERL_NIF_TERM term)); -ERL_NIF_API_FUNC_DECL(int,enif_get_reverse_list,(ErlNifEnv*, ERL_NIF_TERM term, ERL_NIF_TERM *list)); +ERL_NIF_API_FUNC_DECL(int,enif_make_reverse_list,(ErlNifEnv*, ERL_NIF_TERM term, ERL_NIF_TERM *list)); /* ** Add new entries here to keep compatibility on Windows!!! @@ -257,7 +257,7 @@ ERL_NIF_API_FUNC_DECL(int,enif_get_reverse_list,(ErlNifEnv*, ERL_NIF_TERM term, #endif # define enif_is_exception ERL_NIF_API_FUNC_MACRO(enif_is_exception) -# define enif_get_reverse_list ERL_NIF_API_FUNC_MACRO(enif_get_reverse_list) +# define enif_make_reverse_list ERL_NIF_API_FUNC_MACRO(enif_make_reverse_list) /* ** Add new entries here diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl index 813ed65f4b..3bc4ad610f 100644 --- a/erts/emulator/test/nif_SUITE.erl +++ b/erts/emulator/test/nif_SUITE.erl @@ -1169,7 +1169,7 @@ reverse_list_test(Config) -> List = lists:seq(1,100), RevList = lists:reverse(List), ?line RevList = reverse_list(List), - badarg = reverse_list(foo). + ?line badarg = reverse_list(foo). tmpmem() -> case erlang:system_info({allocator,temp_alloc}) of diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c index 87b4d4c4ed..b9bacbb693 100644 --- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c +++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c @@ -1376,7 +1376,7 @@ static ERL_NIF_TERM send_term(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[ static ERL_NIF_TERM reverse_list(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ERL_NIF_TERM rev_list; - if(!enif_get_reverse_list(env, argv[0], &rev_list)) + if(!enif_make_reverse_list(env, argv[0], &rev_list)) return enif_make_atom(env, "badarg"); return rev_list; } -- cgit v1.2.3 From acc2de565374e9b2c22b803fe234608cb84424f4 Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Fri, 1 Jul 2011 10:24:45 +0200 Subject: Add version comment --- erts/emulator/beam/erl_nif.h | 1 + 1 file changed, 1 insertion(+) (limited to 'erts') diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h index bb557e39e9..fea527f954 100644 --- a/erts/emulator/beam/erl_nif.h +++ b/erts/emulator/beam/erl_nif.h @@ -32,6 +32,7 @@ ** 2.0: R14A ** 2.1: R14B02 "vm_variant" ** 2.2: R14B03 enif_is_exception +** 2.3: R15 enif_make_reverse_list */ #define ERL_NIF_MAJOR_VERSION 2 #define ERL_NIF_MINOR_VERSION 3 -- cgit v1.2.3