diff options
author | Sverker Eriksson <[email protected]> | 2009-12-09 11:04:51 +0000 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2009-12-09 11:04:51 +0000 |
commit | f7c1ea4ff481a8dd7bd8c79ae540342fd8213434 (patch) | |
tree | 1db7ad6096eadfbca1d1c60330ab4392be6db690 /erts/emulator/beam | |
parent | 8fbc15b2502bb6d8c808f4d0c8077c39a1f828e8 (diff) | |
download | otp-f7c1ea4ff481a8dd7bd8c79ae540342fd8213434.tar.gz otp-f7c1ea4ff481a8dd7bd8c79ae540342fd8213434.tar.bz2 otp-f7c1ea4ff481a8dd7bd8c79ae540342fd8213434.zip |
OTP-8304 Incompatible changes in the experimental NIF feature. Changed 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.
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r-- | erts/emulator/beam/beam_emu.c | 95 | ||||
-rw-r--r-- | erts/emulator/beam/break.c | 2 | ||||
-rw-r--r-- | erts/emulator/beam/erl_nif.c | 148 | ||||
-rw-r--r-- | erts/emulator/beam/erl_nif.h | 16 | ||||
-rw-r--r-- | erts/emulator/beam/erl_nif_api_funcs.h | 24 | ||||
-rw-r--r-- | erts/emulator/beam/global.h | 3 |
6 files changed, 204 insertions, 84 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index dcaa43b51c..4ebb8853be 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -974,10 +974,6 @@ static int hibernate(Process* c_p, Eterm module, Eterm function, static Eterm* call_fun(Process* p, int arity, Eterm* reg, Eterm args); static Eterm* apply_fun(Process* p, Eterm fun, Eterm args, Eterm* reg); static Eterm new_fun(Process* p, Eterm* reg, ErlFunEntry* fe, int num_free); -static BIF_RETTYPE nif_dispatcher_0(Process* p, Uint* I); -static BIF_RETTYPE nif_dispatcher_1(Process* p, Eterm arg1, Uint* I); -static BIF_RETTYPE nif_dispatcher_2(Process* p, Eterm arg1, Eterm arg2, Uint* I); -static BIF_RETTYPE nif_dispatcher_3(Process* p, Eterm arg1, Eterm arg2, Eterm arg3, Uint* I); #if defined(_OSE_) || defined(VXWORKS) static int init_done; @@ -2949,11 +2945,38 @@ void process_main(void) OpCase(call_nif): { - static void* const dispatchers[4] = { - nif_dispatcher_0, nif_dispatcher_1, nif_dispatcher_2, nif_dispatcher_3 - }; - BifFunction vbf = dispatchers[I[-1]]; - goto apply_bif_or_nif; + /* + * call_nif is always first instruction in function: + * + * I[-3]: Module + * I[-2]: Function + * I[-1]: Arity + * I[0]: &&call_nif + * I[1]: Function pointer to NIF function + * I[2]: priv_data pointer + */ + BifFunction vbf; + + c_p->current = I-3; /* current and vbf set to please handle_error */ + SWAPOUT; + c_p->fcalls = FCALLS - 1; + PROCESS_MAIN_CHK_LOCKS(c_p); + tmp_arg2 = I[-1]; + ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p); + + ASSERT(!ERTS_PROC_IS_EXITING(c_p)); + { + typedef Eterm NifF(struct enif_environment_t*, int argc, Eterm argv[]); + NifF* fp = vbf = (NifF*) I[1]; + struct enif_environment_t env; + erts_pre_nif(&env, c_p, (void*)I[2]); + reg[0] = r(0); + tmp_arg1 = (*fp)(&env, tmp_arg2, reg); + erts_post_nif(&env); + } + ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(tmp_arg1)); + PROCESS_MAIN_CHK_LOCKS(c_p); + goto apply_bif_or_nif_epilogue; OpCase(apply_bif): /* @@ -2966,17 +2989,15 @@ void process_main(void) * code[3]: &&apply_bif * code[4]: Function pointer to BIF function */ - vbf = (BifFunction) Arg(0); - apply_bif_or_nif: c_p->current = I-3; /* In case we apply process_info/1,2 or load_nif/1 */ c_p->i = I; /* In case we apply check_process_code/2. */ c_p->arity = 0; /* To allow garbage collection on ourselves * (check_process_code/2). */ - SWAPOUT; c_p->fcalls = FCALLS - 1; + vbf = (BifFunction) Arg(0); PROCESS_MAIN_CHK_LOCKS(c_p); tmp_arg2 = I[-1]; ASSERT(tmp_arg2 <= 3); @@ -3019,6 +3040,7 @@ void process_main(void) break; } } +apply_bif_or_nif_epilogue: ERTS_SMP_REQ_PROC_MAIN_LOCK(c_p); ERTS_HOLE_CHECK(c_p); if (c_p->mbuf) { @@ -5245,6 +5267,7 @@ save_stacktrace(Process* c_p, Eterm* pc, Eterm* reg, BifFunction bf, * The Bif does not really exist (no BIF entry). It is a * TRAP and traps are called through apply_bif, which also * sets c_p->current (luckily). + * OR it is a NIF called by call_nif where current is also set. */ ASSERT(c_p->current); s->current = c_p->current; @@ -6148,51 +6171,3 @@ erts_current_reductions(Process *current, Process *p) } } -static BIF_RETTYPE nif_dispatcher_0(Process* p, Uint* I) -{ - typedef Eterm NifF(struct enif_environment_t*); - NifF* fp = (NifF*) I[1]; - struct enif_environment_t env; - Eterm ret; - erts_pre_nif(&env, p, (void*)I[2]); - ret = (*fp)(&env); - erts_post_nif(&env); - return ret; -} - -static BIF_RETTYPE nif_dispatcher_1(Process* p, Eterm arg1, Uint* I) -{ - typedef Eterm NifF(struct enif_environment_t*, Eterm); - NifF* fp = (NifF*) I[1]; - struct enif_environment_t env; - Eterm ret; - erts_pre_nif(&env, p, (void*)I[2]); - ret = (*fp)(&env, arg1); - erts_post_nif(&env); - return ret; -} - -static BIF_RETTYPE nif_dispatcher_2(Process* p, Eterm arg1, Eterm arg2, Uint* I) -{ - typedef Eterm NifF(struct enif_environment_t*, Eterm, Eterm); - NifF* fp = (NifF*) I[1]; - struct enif_environment_t env; - Eterm ret; - erts_pre_nif(&env, p, (void*)I[2]); - ret = (*fp)(&env, arg1, arg2); - erts_post_nif(&env); - return ret; -} - -static BIF_RETTYPE nif_dispatcher_3(Process* p, Eterm arg1, Eterm arg2, Eterm arg3, Uint* I) -{ - typedef Eterm NifF(struct enif_environment_t*, Eterm, Eterm, Eterm); - NifF* fp = (NifF*) I[1]; - struct enif_environment_t env; - Eterm ret; - erts_pre_nif(&env, p, (void*)I[2]); - ret = (*fp)(&env, arg1, arg2, arg3); - erts_post_nif(&env); - return ret; -} - diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c index 5ea47e16f5..cc69977b79 100644 --- a/erts/emulator/beam/break.c +++ b/erts/emulator/beam/break.c @@ -703,6 +703,8 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args) erts_fdprintf(fd, "System version: "); erts_print_system_version(fd, NULL, NULL); erts_fdprintf(fd, "%s\n", "Compiled: " ERLANG_COMPILE_DATE); + erts_fdprintf(fd, "Taints: "); + erts_print_nif_taints(fd, NULL); erts_fdprintf(fd, "Atoms: %d\n", atom_table_size()); info(fd, NULL); /* General system info */ if (process_tab != NULL) /* XXX true at init */ diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index fa4454a3f3..b09f92d342 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -35,13 +35,6 @@ #include <limits.h> -/* -static ERTS_INLINE Eterm* alloc_heap(ErlNifEnv* env, unsigned need) -{ - return HAlloc(env->proc, need); -} -*/ - #define MIN_HEAP_FRAG_SZ 200 static Eterm* alloc_heap_heavy(ErlNifEnv* env, unsigned need); @@ -116,12 +109,21 @@ void enif_free(ErlNifEnv* env, void* ptr) erts_free(ERTS_ALC_T_NIF, ptr); } +int enif_is_atom(ErlNifEnv* env, ERL_NIF_TERM term) +{ + return is_atom(term); +} int enif_is_binary(ErlNifEnv* env, ERL_NIF_TERM term) { return is_binary(term) && (binary_bitsize(term) % 8 == 0); } - + +int enif_is_ref(ErlNifEnv* env, ERL_NIF_TERM term) +{ + return is_ref(term); +} + int enif_inspect_binary(ErlNifEnv* env, Eterm bin_term, ErlNifBinary* bin) { @@ -157,6 +159,25 @@ int enif_alloc_binary(ErlNifEnv* env, unsigned size, ErlNifBinary* bin) return 1; } +int enif_realloc_binary(ErlNifEnv* env, ErlNifBinary* bin, unsigned size) +{ + Binary* oldbin; + Binary* newbin; + ASSERT(bin->ref_bin != NULL); + + oldbin = (Binary*) bin->ref_bin; + newbin = (Binary *) erts_bin_realloc_fnf(oldbin, size); + if (!newbin) { + return 0; + } + newbin->orig_size = size; + bin->ref_bin = newbin; + bin->data = (unsigned char*) newbin->orig_bytes; + bin->size = size; + return 1; +} + + void enif_release_binary(ErlNifEnv* env, ErlNifBinary* bin) { if (bin->ref_bin == NULL) { @@ -177,6 +198,28 @@ void enif_release_binary(ErlNifEnv* env, ErlNifBinary* bin) #endif } +int enif_is_identical(ErlNifEnv* env, Eterm lhs, Eterm rhs) +{ + return EQ(lhs,rhs); +} + +int enif_compare(ErlNifEnv* env, Eterm lhs, Eterm rhs) +{ + return cmp(lhs,rhs); +} + +int enif_get_tuple(ErlNifEnv* env, Eterm tpl, int* arity, Eterm** array) +{ + Eterm* ptr; + if (is_not_tuple(tpl)) { + return 0; + } + ptr = tuple_val(tpl); + *arity = arityval(*ptr); + *array = ptr+1; + return 1; +} + Eterm enif_make_binary(ErlNifEnv* env, ErlNifBinary* bin) { if (bin->ref_bin == NULL) { @@ -203,7 +246,7 @@ Eterm enif_make_binary(ErlNifEnv* env, ErlNifBinary* bin) } } -ERL_NIF_TERM enif_make_badarg(ErlNifEnv* env) +Eterm enif_make_badarg(ErlNifEnv* env) { BIF_ERROR(env->proc, BADARG); } @@ -212,7 +255,7 @@ ERL_NIF_TERM enif_make_badarg(ErlNifEnv* env) int enif_get_int(ErlNifEnv* env, Eterm term, int* ip) { #if SIZEOF_INT == SIZEOF_VOID_P - return term_to_Sint(term, ip); + return term_to_Sint(term, (Sint*)ip); #elif SIZEOF_LONG == SIZEOF_VOID_P Sint i; if (!term_to_Sint(term, &i) || i < INT_MIN || i > INT_MAX) { @@ -234,6 +277,17 @@ int enif_get_ulong(ErlNifEnv* env, Eterm term, unsigned long* ip) #endif } +int enif_get_double(ErlNifEnv* env, Eterm term, double* dp) +{ + FloatDef f; + if (is_not_float(term)) { + return 0; + } + GET_DOUBLE(term, f); + *dp = f.fd; + return 1; +} + int enif_get_list_cell(ErlNifEnv* env, Eterm term, Eterm* head, Eterm* tail) { Eterm* val; @@ -267,12 +321,24 @@ ERL_NIF_TERM enif_make_ulong(ErlNifEnv* env, unsigned long i) } +ERL_NIF_TERM enif_make_double(ErlNifEnv* env, double d) +{ + Eterm* hp = alloc_heap(env,FLOAT_SIZE_OBJECT); + FloatDef f; + f.fd = d; + PUT_DOUBLE(f, hp); + return make_float(hp); +} ERL_NIF_TERM enif_make_atom(ErlNifEnv* env, const char* name) { return am_atom_put(name, sys_strlen(name)); } +int enif_make_existing_atom(ErlNifEnv* env, const char* name, ERL_NIF_TERM* atom) +{ + return erts_atom_get(name, sys_strlen(name), atom); +} ERL_NIF_TERM enif_make_tuple(ErlNifEnv* env, unsigned cnt, ...) { @@ -320,13 +386,43 @@ ERL_NIF_TERM enif_make_list(ErlNifEnv* env, unsigned cnt, ...) ERL_NIF_TERM enif_make_string(ErlNifEnv* env, const char* string) { - Sint n = strlen(string); + Sint n = sys_strlen(string); Eterm* hp = alloc_heap(env,n*2); return erts_bld_string_n(&hp,NULL,string,n); } +ERL_NIF_TERM enif_make_ref(ErlNifEnv* env) +{ + Eterm* hp = alloc_heap(env, REF_THING_SIZE); + return erts_make_ref_in_buffer(hp); +} + +#if 0 /* To be continued... */ +typedef struct enif_handle_type_t +{ + struct enif_handle_type_t* next; + struct enif_handle_type_t* prev; + const char* name; + void (*dtor)(void* obj); + erts_smp_atomic_t ref_cnt; /* num of handles of this type */ +}ErlNifHandleType; + +ErlNifHandleType* +enif_create_handle_type(ErlNifEnv* env, const char* type_name, + void (*dtor)(void *)) +{ + +} + +ERL_NIF_TERM enif_make_handle(ErlNifEnv* env, ErlNifHandleType* htype, void* obj) +{ +} +int enif_get_handle(ErlNifEnv* env, ERL_NIF_TERM term, void** objp) +{ +} +#endif /*************************************************************************** ** load_nif/2 ** @@ -361,7 +457,7 @@ static void refresh_cached_nif_data(Eterm* mod_code, ErlNifFunc* func = &mod_nif->entry->funcs[i]; Uint* code_ptr; - erts_atom_get(func->name, strlen(func->name), &f_atom); + erts_atom_get(func->name, sys_strlen(func->name), &f_atom); code_ptr = *get_func_pp(mod_code, f_atom, func->arity); code_ptr[5+2] = (Uint) mod_nif->data; } @@ -411,6 +507,18 @@ Eterm erts_nif_taints(Process* p) return list; } +void erts_print_nif_taints(int to, void* to_arg) +{ + struct tainted_module_t* t; + const char* delim = ""; + for (t=first_tainted_module ; t!=NULL; t=t->next) { + const Atom* atom = atom_tab(atom_val(t->module_atom)); + erts_print(to,to_arg,"%s%.*s", delim, atom->len, atom->name); + delim = ","; + } + erts_print(to,to_arg,"\n"); +} + static Eterm load_nif_error(Process* p, const char* atom, const char* format, ...) { @@ -428,7 +536,8 @@ static Eterm load_nif_error(Process* p, const char* atom, const char* format, .. for (;;) { Eterm txt = erts_bld_string_n(hpp, &sz, dsbufp->str, dsbufp->str_len); - ret = erts_bld_tuple(hpp, szp, 3, am_error, mkatom(atom), txt); + ret = erts_bld_tuple(hpp, szp, 2, am_error, + erts_bld_tuple(hpp, szp, 2, mkatom(atom), txt)); if (hpp != NULL) { break; } @@ -489,8 +598,13 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2) "module '%T' not allowed", mod_atom); } else if ((err=erts_sys_ddll_open2(lib_name, &handle, &errdesc)) != ERL_DE_NO_ERROR) { - ret = load_nif_error(BIF_P, "load_failed", "Failed to load NIF library" - " %s: '%s'", lib_name, errdesc.str); + const char slogan[] = "Failed to load NIF library"; + if (strstr(errdesc.str, lib_name) != NULL) { + ret = load_nif_error(BIF_P, "load_failed", "%s: '%s'", slogan, errdesc.str); + } + else { + ret = load_nif_error(BIF_P, "load_failed", "%s %s: '%s'", slogan, lib_name, errdesc.str); + } } else if (erts_sys_ddll_load_nif_init(handle, &init_func, &errdesc) != ERL_DE_NO_ERROR) { ret = load_nif_error(BIF_P, bad_lib, "Failed to find library init" @@ -521,7 +635,7 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2) 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, strlen(f->name), &f_atom) + 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) { ret = load_nif_error(BIF_P,bad_lib,"Function not found %T:%s/%u", mod_atom, f->name, f->arity); @@ -612,7 +726,7 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2) for (i=0; i < entry->num_of_funcs; i++) { Uint* code_ptr; - erts_atom_get(entry->funcs[i].name, strlen(entry->funcs[i].name), &f_atom); + erts_atom_get(entry->funcs[i].name, sys_strlen(entry->funcs[i].name), &f_atom); code_ptr = *get_func_pp(mod->code, f_atom, entry->funcs[i].arity); if (code_ptr[1] == 0) { diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h index 8650b7ce47..e5e6d65c0e 100644 --- a/erts/emulator/beam/erl_nif.h +++ b/erts/emulator/beam/erl_nif.h @@ -20,23 +20,27 @@ /* Include file for writers of Native Implemented Functions. */ -#define ERL_NIF_MAJOR_VERSION 0 -#define ERL_NIF_MINOR_VERSION 1 +/* Version history: +** 0.1: R13B03 +** 1.0: R13B04 +*/ +#define ERL_NIF_MAJOR_VERSION 1 +#define ERL_NIF_MINOR_VERSION 0 #include <stdlib.h> typedef unsigned long ERL_NIF_TERM; +struct enif_environment_t; +typedef struct enif_environment_t ErlNifEnv; + typedef struct { const char* name; unsigned arity; - void* fptr; //ERL_NIF_TERM (*fptr)(void*, ...); + ERL_NIF_TERM (*fptr)(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); }ErlNifFunc; -struct enif_environment_t; -typedef struct enif_environment_t ErlNifEnv; - typedef struct enif_entry_t { int major; diff --git a/erts/emulator/beam/erl_nif_api_funcs.h b/erts/emulator/beam/erl_nif_api_funcs.h index 400c1822cc..7556806ce4 100644 --- a/erts/emulator/beam/erl_nif_api_funcs.h +++ b/erts/emulator/beam/erl_nif_api_funcs.h @@ -25,44 +25,68 @@ ERL_NIF_API_FUNC_DECL(void*,enif_get_data,(ErlNifEnv*)); ERL_NIF_API_FUNC_DECL(void*,enif_alloc,(ErlNifEnv*, size_t size)); ERL_NIF_API_FUNC_DECL(void,enif_free,(ErlNifEnv*, void* ptr)); +ERL_NIF_API_FUNC_DECL(int,enif_is_atom,(ErlNifEnv*, ERL_NIF_TERM term)); ERL_NIF_API_FUNC_DECL(int,enif_is_binary,(ErlNifEnv*, ERL_NIF_TERM term)); +ERL_NIF_API_FUNC_DECL(int,enif_is_ref,(ErlNifEnv*, ERL_NIF_TERM term)); ERL_NIF_API_FUNC_DECL(int,enif_inspect_binary,(ErlNifEnv*, ERL_NIF_TERM bin_term, ErlNifBinary* bin)); ERL_NIF_API_FUNC_DECL(int,enif_alloc_binary,(ErlNifEnv*, unsigned size, ErlNifBinary* bin)); +ERL_NIF_API_FUNC_DECL(int,enif_realloc_binary,(ErlNifEnv*, ErlNifBinary* bin, unsigned size)); ERL_NIF_API_FUNC_DECL(void,enif_release_binary,(ErlNifEnv*, ErlNifBinary* bin)); ERL_NIF_API_FUNC_DECL(int,enif_get_int,(ErlNifEnv*, ERL_NIF_TERM term, int* ip)); ERL_NIF_API_FUNC_DECL(int,enif_get_ulong,(ErlNifEnv*, ERL_NIF_TERM term, unsigned long* ip)); +ERL_NIF_API_FUNC_DECL(int,enif_get_double,(ErlNifEnv*, ERL_NIF_TERM term, double* dp)); ERL_NIF_API_FUNC_DECL(int,enif_get_list_cell,(ErlNifEnv* env, ERL_NIF_TERM term, ERL_NIF_TERM* head, ERL_NIF_TERM* tail)); +ERL_NIF_API_FUNC_DECL(int,enif_get_tuple,(ErlNifEnv* env, ERL_NIF_TERM tpl, int* arity, ERL_NIF_TERM** array)); +ERL_NIF_API_FUNC_DECL(int,enif_is_identical,(ErlNifEnv* env, ERL_NIF_TERM lhs, ERL_NIF_TERM rhs)); +ERL_NIF_API_FUNC_DECL(int,enif_compare,(ErlNifEnv* env, ERL_NIF_TERM lhs, ERL_NIF_TERM rhs)); ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_binary,(ErlNifEnv* env, ErlNifBinary* bin)); ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_badarg,(ErlNifEnv* env)); ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_int,(ErlNifEnv* env, int i)); ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_ulong,(ErlNifEnv* env, unsigned long i)); +ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_double,(ErlNifEnv* env, double d)); ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_atom,(ErlNifEnv* env, const char* name)); +ERL_NIF_API_FUNC_DECL(int,enif_make_existing_atom,(ErlNifEnv* env, const char* name, ERL_NIF_TERM* atom)); ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_tuple,(ErlNifEnv* env, unsigned cnt, ...)); ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_list,(ErlNifEnv* env, unsigned cnt, ...)); ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_list_cell,(ErlNifEnv* env, ERL_NIF_TERM car, ERL_NIF_TERM cdr)); ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_string,(ErlNifEnv* env, const char* string)); +ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_ref,(ErlNifEnv* env)); +/* +** Add last to keep compatibility on Windows!!! +*/ #endif #ifdef ERL_NIF_API_FUNC_MACRO # define enif_get_data ERL_NIF_API_FUNC_MACRO(enif_get_data) # define enif_alloc ERL_NIF_API_FUNC_MACRO(enif_alloc) # define enif_free ERL_NIF_API_FUNC_MACRO(enif_free) +# define enif_is_atom ERL_NIF_API_FUNC_MACRO(enif_is_atom) # define enif_is_binary ERL_NIF_API_FUNC_MACRO(enif_is_binary) +# define enif_is_ref ERL_NIF_API_FUNC_MACRO(enif_is_ref) # define enif_inspect_binary ERL_NIF_API_FUNC_MACRO(enif_inspect_binary) # define enif_alloc_binary ERL_NIF_API_FUNC_MACRO(enif_alloc_binary) +# define enif_realloc_binary ERL_NIF_API_FUNC_MACRO(enif_realloc_binary) # define enif_release_binary ERL_NIF_API_FUNC_MACRO(enif_release_binary) # define enif_get_int ERL_NIF_API_FUNC_MACRO(enif_get_int) # define enif_get_ulong ERL_NIF_API_FUNC_MACRO(enif_get_ulong) +# define enif_get_double ERL_NIF_API_FUNC_MACRO(enif_get_double) +# define enif_get_tuple ERL_NIF_API_FUNC_MACRO(enif_get_tuple) # define enif_get_list_cell ERL_NIF_API_FUNC_MACRO(enif_get_list_cell) +# define enif_is_identical ERL_NIF_API_FUNC_MACRO(enif_is_identical) +# define enif_compare ERL_NIF_API_FUNC_MACRO(enif_compare) # define enif_make_binary ERL_NIF_API_FUNC_MACRO(enif_make_binary) # define enif_make_badarg ERL_NIF_API_FUNC_MACRO(enif_make_badarg) # define enif_make_int ERL_NIF_API_FUNC_MACRO(enif_make_int) # define enif_make_ulong ERL_NIF_API_FUNC_MACRO(enif_make_ulong) +# define enif_make_double ERL_NIF_API_FUNC_MACRO(enif_make_double) # define enif_make_atom ERL_NIF_API_FUNC_MACRO(enif_make_atom) +# define enif_make_existing_atom ERL_NIF_API_FUNC_MACRO(enif_make_existing_atom) # define enif_make_tuple ERL_NIF_API_FUNC_MACRO(enif_make_tuple) # define enif_make_list ERL_NIF_API_FUNC_MACRO(enif_make_list) # define enif_make_list_cell ERL_NIF_API_FUNC_MACRO(enif_make_list_cell) # define enif_make_string ERL_NIF_API_FUNC_MACRO(enif_make_string) +# define enif_make_ref ERL_NIF_API_FUNC_MACRO(enif_make_ref) + #endif diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 1b64e23174..62a788cbff 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -86,7 +86,8 @@ struct enif_environment_t /* ErlNifEnv */ }; extern void erts_pre_nif(struct enif_environment_t*, Process*, void* nif_data); extern void erts_post_nif(struct enif_environment_t* env); -extern Eterm erts_nif_taints(Process* p); +extern Eterm erts_nif_taints(Process* p); +extern void erts_print_nif_taints(int to, void* to_arg); /* * Port Specific Data. |