From f951b3fcc69c195ce04ae1022fa53272cb74f71b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20H=C3=B6gberg?= Date: Wed, 6 Mar 2019 15:28:30 +0100 Subject: 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. --- erts/emulator/beam/erl_nif.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'erts/emulator/beam/erl_nif.c') 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); -- cgit v1.2.3