diff options
author | John Högberg <[email protected]> | 2019-03-06 15:28:30 +0100 |
---|---|---|
committer | John Högberg <[email protected]> | 2019-03-07 09:31:16 +0100 |
commit | f951b3fcc69c195ce04ae1022fa53272cb74f71b (patch) | |
tree | 781e576d1acc8882eca11c789e0eaedb47387f52 /erts/emulator/beam/erl_nif.c | |
parent | 31bff2cdb13a6e2032b7f067d037da0520752fc0 (diff) | |
download | otp-f951b3fcc69c195ce04ae1022fa53272cb74f71b.tar.gz otp-f951b3fcc69c195ce04ae1022fa53272cb74f71b.tar.bz2 otp-f951b3fcc69c195ce04ae1022fa53272cb74f71b.zip |
erts: Add enif_term_type
This helps avoid long sequences of enif_is_xxx in code that
serializes terms (such as JSON encoders) by letting the user
switch on the type.
Diffstat (limited to 'erts/emulator/beam/erl_nif.c')
-rw-r--r-- | erts/emulator/beam/erl_nif.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index 349d9bf13a..dd9210a888 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -1158,6 +1158,47 @@ int enif_is_number(ErlNifEnv* env, ERL_NIF_TERM term) return is_number(term); } +ErlNifTermType enif_term_type(ErlNifEnv* env, ERL_NIF_TERM term) { + (void)env; + + switch (tag_val_def(term)) { + case ATOM_DEF: + return ERL_NIF_TERM_TYPE_ATOM; + case BINARY_DEF: + return ERL_NIF_TERM_TYPE_BITSTRING; + case FLOAT_DEF: + return ERL_NIF_TERM_TYPE_FLOAT; + case EXPORT_DEF: + case FUN_DEF: + return ERL_NIF_TERM_TYPE_FUN; + case BIG_DEF: + case SMALL_DEF: + return ERL_NIF_TERM_TYPE_INTEGER; + case LIST_DEF: + case NIL_DEF: + return ERL_NIF_TERM_TYPE_LIST; + case MAP_DEF: + return ERL_NIF_TERM_TYPE_MAP; + case EXTERNAL_PID_DEF: + case PID_DEF: + return ERL_NIF_TERM_TYPE_PID; + case EXTERNAL_PORT_DEF: + case PORT_DEF: + return ERL_NIF_TERM_TYPE_PORT; + case EXTERNAL_REF_DEF: + case REF_DEF: + return ERL_NIF_TERM_TYPE_REFERENCE; + case TUPLE_DEF: + return ERL_NIF_TERM_TYPE_TUPLE; + default: + /* tag_val_def() aborts on its own when passed complete garbage, but + * it's possible that the user has given us garbage that just happens + * to match something that tag_val_def() accepts but we don't, like + * binary match contexts. */ + ERTS_INTERNAL_ERROR("Invalid term passed to enif_term_type"); + } +} + static void aligned_binary_dtor(struct enif_tmp_obj_t* obj) { erts_free_aligned_binary_bytes_extra((byte*)obj, obj->allocator); |