diff options
author | John Högberg <[email protected]> | 2018-03-23 08:19:12 +0100 |
---|---|---|
committer | John Högberg <[email protected]> | 2018-03-23 08:19:12 +0100 |
commit | bf7206f13aae8d55e4d54320a179e11ad8f90765 (patch) | |
tree | de212a221a5bb2bfeb04261ee5322d4f9f310f03 /erts/emulator/beam | |
parent | 7c2672e614883d8f0eac7559a59d0373ec92af69 (diff) | |
parent | 187564ffccee4a3b5727bdab3df2458f3b5ced72 (diff) | |
download | otp-bf7206f13aae8d55e4d54320a179e11ad8f90765.tar.gz otp-bf7206f13aae8d55e4d54320a179e11ad8f90765.tar.bz2 otp-bf7206f13aae8d55e4d54320a179e11ad8f90765.zip |
Merge branch 'john/erts/nif-map-from-array/OTP-14954'
* john/erts/nif-map-from-array/OTP-14954:
Add enif_make_map_from_arrays
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r-- | erts/emulator/beam/erl_map.c | 4 | ||||
-rw-r--r-- | erts/emulator/beam/erl_nif.c | 38 | ||||
-rw-r--r-- | erts/emulator/beam/erl_nif.h | 2 | ||||
-rw-r--r-- | erts/emulator/beam/erl_nif_api_funcs.h | 3 |
4 files changed, 45 insertions, 2 deletions
diff --git a/erts/emulator/beam/erl_map.c b/erts/emulator/beam/erl_map.c index 8047a9567f..4ec6960997 100644 --- a/erts/emulator/beam/erl_map.c +++ b/erts/emulator/beam/erl_map.c @@ -490,7 +490,9 @@ Eterm erts_map_from_ks_and_vs(ErtsHeapFactory *factory, Eterm *ks0, Eterm *vs0, sys_memcpy(ks, ks0, n * sizeof(Eterm)); sys_memcpy(vs, vs0, n * sizeof(Eterm)); - erts_validate_and_sort_flatmap(mp); + if (!erts_validate_and_sort_flatmap(mp)) { + return THE_NON_VALUE; + } return make_flatmap(mp); } else { diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index 1d337d9792..f883b3f1e3 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -2934,6 +2934,44 @@ ERL_NIF_TERM enif_make_new_map(ErlNifEnv* env) return make_flatmap(mp); } +int enif_make_map_from_arrays(ErlNifEnv *env, + ERL_NIF_TERM keys[], + ERL_NIF_TERM values[], + size_t cnt, + ERL_NIF_TERM *map_out) +{ + ErtsHeapFactory factory; + int succeeded; + +#ifdef ERTS_NIF_ASSERT_IN_ENV + size_t index = 0; + + while (index < cnt) { + ASSERT_IN_ENV(env, keys[index], index, "key"); + ASSERT_IN_ENV(env, values[index], index, "value"); + index++; + } +#endif + + flush_env(env); + + erts_factory_proc_prealloc_init(&factory, env->proc, + cnt * 2 + MAP_HEADER_FLATMAP_SZ + 1); + + (*map_out) = erts_map_from_ks_and_vs(&factory, keys, values, cnt); + succeeded = (*map_out) != THE_NON_VALUE; + + if (!succeeded) { + erts_factory_undo(&factory); + } + + erts_factory_close(&factory); + + cache_env(env); + + return succeeded; +} + int enif_make_map_put(ErlNifEnv* env, Eterm map_in, Eterm key, diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h index e051ecb26e..1906da732b 100644 --- a/erts/emulator/beam/erl_nif.h +++ b/erts/emulator/beam/erl_nif.h @@ -53,7 +53,7 @@ ** 2.12: 20.0 add enif_select, enif_open_resource_type_x ** 2.13: 20.1 add enif_ioq ** 2.14: 21.0 add enif_ioq_peek_head, enif_(mutex|cond|rwlock|thread)_name -** enif_vfprintf, enif_vsnprintf +** enif_vfprintf, enif_vsnprintf, enif_make_map_from_arrays */ #define ERL_NIF_MAJOR_VERSION 2 #define ERL_NIF_MINOR_VERSION 14 diff --git a/erts/emulator/beam/erl_nif_api_funcs.h b/erts/emulator/beam/erl_nif_api_funcs.h index 744f7c9f69..61f8fcf6ed 100644 --- a/erts/emulator/beam/erl_nif_api_funcs.h +++ b/erts/emulator/beam/erl_nif_api_funcs.h @@ -208,6 +208,8 @@ ERL_NIF_API_FUNC_DECL(char*,enif_thread_name,(ErlNifTid)); ERL_NIF_API_FUNC_DECL(int,enif_vfprintf,(FILE*, const char *fmt, va_list)); ERL_NIF_API_FUNC_DECL(int,enif_vsnprintf,(char*, size_t, const char *fmt, va_list)); +ERL_NIF_API_FUNC_DECL(int,enif_make_map_from_arrays,(ErlNifEnv *env, ERL_NIF_TERM keys[], ERL_NIF_TERM values[], size_t cnt, ERL_NIF_TERM *map_out)); + /* ** ADD NEW ENTRIES HERE (before this comment) !!! */ @@ -389,6 +391,7 @@ ERL_NIF_API_FUNC_DECL(int,enif_vsnprintf,(char*, size_t, const char *fmt, va_lis # define enif_thread_name ERL_NIF_API_FUNC_MACRO(enif_thread_name) # define enif_vfprintf ERL_NIF_API_FUNC_MACRO(enif_vfprintf) # define enif_vsnprintf ERL_NIF_API_FUNC_MACRO(enif_vsnprintf) +# define enif_make_map_from_arrays ERL_NIF_API_FUNC_MACRO(enif_make_map_from_arrays) /* ** ADD NEW ENTRIES HERE (before this comment) |