diff --git a/src/libAtomVM/erl_nif.h b/src/libAtomVM/erl_nif.h index 5b97197891..73ab4e9e2b 100644 --- a/src/libAtomVM/erl_nif.h +++ b/src/libAtomVM/erl_nif.h @@ -207,11 +207,14 @@ int enif_release_resource(void *resource); * usage confusion, users should rather call `term_from_resource` and should * not decrement the reference counter. * + * @deprecated This function aborts on out of memory. Use + * `memory_erl_nif_env_ensure_free` followed by `term_from_resource` instead. + * * @param env current environment * @param obj resource * @return a new term representing the resource */ -ERL_NIF_TERM enif_make_resource(ErlNifEnv *env, void *obj); +ERL_NIF_TERM enif_make_resource(ErlNifEnv *env, void *obj) __attribute__((deprecated("use memory_erl_nif_env_ensure_free + term_from_resource instead"))); /** * @brief create a binary term memory managed by a resource. @@ -225,13 +228,17 @@ ERL_NIF_TERM enif_make_resource(ErlNifEnv *env, void *obj); * resource. The resource destructor will only be called when all binaries * are garbage collected. * + * @deprecated This function aborts on out of memory. Use + * `memory_erl_nif_env_ensure_free` followed by `term_from_resource_binary` + * instead. + * * @param env current environment * @param obj resource * @param data binary data to encapsulate * @param size size of the data * @return a new binary term */ -ERL_NIF_TERM enif_make_resource_binary(ErlNifEnv *env, void *obj, const void *data, size_t size); +ERL_NIF_TERM enif_make_resource_binary(ErlNifEnv *env, void *obj, const void *data, size_t size) __attribute__((deprecated("use memory_erl_nif_env_ensure_free + term_from_resource_binary instead"))); /** * @brief Run a POSIX-like select on a given object (event) and send a message diff --git a/src/libAtomVM/jit_stream_flash.c b/src/libAtomVM/jit_stream_flash.c index 65b9c13423..d53245dca8 100644 --- a/src/libAtomVM/jit_stream_flash.c +++ b/src/libAtomVM/jit_stream_flash.c @@ -535,7 +535,11 @@ static term nif_jit_stream_flash_new(Context *ctx, int argc, term argv[]) RAISE_ERROR(BADARG_ATOM); } - term obj = enif_make_resource(erl_nif_env_from_context(ctx), js); + if (UNLIKELY(memory_ensure_free(ctx, TERM_BOXED_REFERENCE_RESOURCE_SIZE) != MEMORY_GC_OK)) { + enif_release_resource(js); + RAISE_ERROR(OUT_OF_MEMORY_ATOM); + } + term obj = term_from_resource(js, &ctx->heap); enif_release_resource(js); // decrement refcount after enif_alloc_resource return obj; } diff --git a/src/libAtomVM/otp_socket.c b/src/libAtomVM/otp_socket.c index 63e25919a8..46729dbb3d 100644 --- a/src/libAtomVM/otp_socket.c +++ b/src/libAtomVM/otp_socket.c @@ -641,7 +641,7 @@ static term nif_socket_open(Context *ctx, int argc, term argv[]) AVM_LOGW(TAG, "Failed to allocate memory: %s:%i.", __FILE__, __LINE__); RAISE_ERROR(OUT_OF_MEMORY_ATOM); } - term obj = enif_make_resource(erl_nif_env_from_context(ctx), rsrc_obj); + term obj = term_from_resource(rsrc_obj, &ctx->heap); enif_release_resource(rsrc_obj); // decrement refcount after enif_alloc_resource size_t requested_size = TUPLE_SIZE(2) + TUPLE_SIZE(2) + REF_SIZE; @@ -1814,7 +1814,10 @@ static term nif_socket_listen(Context *ctx, int argc, term argv[]) #if OTP_SOCKET_LWIP static term make_accepted_socket_term(Context *ctx, struct SocketResource *conn_rsrc_obj) { - term obj = enif_make_resource(erl_nif_env_from_context(ctx), conn_rsrc_obj); + if (UNLIKELY(memory_ensure_free(ctx, TERM_BOXED_REFERENCE_RESOURCE_SIZE + TUPLE_SIZE(2) + REF_SIZE) != MEMORY_GC_OK)) { + RAISE_ERROR(OUT_OF_MEMORY_ATOM); + } + term obj = term_from_resource(conn_rsrc_obj, &ctx->heap); enif_release_resource(conn_rsrc_obj); // decrement refcount after enif_allocate_resource in make_accepted_socket_resource term socket_term = term_alloc_tuple(2, &ctx->heap); @@ -1899,7 +1902,11 @@ static term nif_socket_accept(Context *ctx, int argc, term argv[]) #endif TRACE("nif_socket_accept: Created socket on accept fd=%i\n", rsrc_obj->fd); - term new_resource = enif_make_resource(erl_nif_env_from_context(ctx), conn_rsrc_obj); + if (UNLIKELY(memory_ensure_free(ctx, TERM_BOXED_REFERENCE_RESOURCE_SIZE) != MEMORY_GC_OK)) { + AVM_LOGW(TAG, "Failed to allocate memory: %s:%i.", __FILE__, __LINE__); + RAISE_ERROR(OUT_OF_MEMORY_ATOM); + } + term new_resource = term_from_resource(conn_rsrc_obj, &ctx->heap); enif_release_resource(conn_rsrc_obj); // decrement refcount after enif_alloc_resource size_t requested_size = TUPLE_SIZE(2) + TUPLE_SIZE(2) + REF_SIZE; diff --git a/src/libAtomVM/otp_ssl.c b/src/libAtomVM/otp_ssl.c index ee86b96657..d7ded0b6ff 100644 --- a/src/libAtomVM/otp_ssl.c +++ b/src/libAtomVM/otp_ssl.c @@ -235,7 +235,11 @@ static term nif_ssl_entropy_init(Context *ctx, int argc, term argv[]) AVM_LOGW(TAG, "Failed to allocate memory: %s:%i.\n", __FILE__, __LINE__); RAISE_ERROR(OUT_OF_MEMORY_ATOM); } - term obj = enif_make_resource(erl_nif_env_from_context(ctx), rsrc_obj); + if (UNLIKELY(memory_ensure_free(ctx, TERM_BOXED_REFERENCE_RESOURCE_SIZE) != MEMORY_GC_OK)) { + enif_release_resource(rsrc_obj); + RAISE_ERROR(OUT_OF_MEMORY_ATOM); + } + term obj = term_from_resource(rsrc_obj, &ctx->heap); enif_release_resource(rsrc_obj); // decrement refcount after enif_alloc_resource mbedtls_entropy_init(&rsrc_obj->context); @@ -258,7 +262,11 @@ static term nif_ssl_ctr_drbg_init(Context *ctx, int argc, term argv[]) AVM_LOGW(TAG, "Failed to allocate memory: %s:%i.\n", __FILE__, __LINE__); RAISE_ERROR(OUT_OF_MEMORY_ATOM); } - term obj = enif_make_resource(erl_nif_env_from_context(ctx), rsrc_obj); + if (UNLIKELY(memory_ensure_free(ctx, TERM_BOXED_REFERENCE_RESOURCE_SIZE) != MEMORY_GC_OK)) { + enif_release_resource(rsrc_obj); + RAISE_ERROR(OUT_OF_MEMORY_ATOM); + } + term obj = term_from_resource(rsrc_obj, &ctx->heap); enif_release_resource(rsrc_obj); // decrement refcount after enif_alloc_resource mbedtls_ctr_drbg_init(&rsrc_obj->context); @@ -310,7 +318,11 @@ static term nif_ssl_init(Context *ctx, int argc, term argv[]) AVM_LOGW(TAG, "Failed to allocate memory: %s:%i.\n", __FILE__, __LINE__); RAISE_ERROR(OUT_OF_MEMORY_ATOM); } - term obj = enif_make_resource(erl_nif_env_from_context(ctx), rsrc_obj); + if (UNLIKELY(memory_ensure_free(ctx, TERM_BOXED_REFERENCE_RESOURCE_SIZE) != MEMORY_GC_OK)) { + enif_release_resource(rsrc_obj); + RAISE_ERROR(OUT_OF_MEMORY_ATOM); + } + term obj = term_from_resource(rsrc_obj, &ctx->heap); enif_release_resource(rsrc_obj); // decrement refcount after enif_alloc_resource mbedtls_ssl_init(&rsrc_obj->context); @@ -363,7 +375,11 @@ static term nif_ssl_config_init(Context *ctx, int argc, term argv[]) AVM_LOGW(TAG, "Failed to allocate memory: %s:%i.\n", __FILE__, __LINE__); RAISE_ERROR(OUT_OF_MEMORY_ATOM); } - term obj = enif_make_resource(erl_nif_env_from_context(ctx), rsrc_obj); + if (UNLIKELY(memory_ensure_free(ctx, TERM_BOXED_REFERENCE_RESOURCE_SIZE) != MEMORY_GC_OK)) { + enif_release_resource(rsrc_obj); + RAISE_ERROR(OUT_OF_MEMORY_ATOM); + } + term obj = term_from_resource(rsrc_obj, &ctx->heap); enif_release_resource(rsrc_obj); // decrement refcount after enif_alloc_resource mbedtls_ssl_config_init(&rsrc_obj->config); diff --git a/src/libAtomVM/posix_nifs.c b/src/libAtomVM/posix_nifs.c index d82f8d2eb0..1666fddaa4 100644 --- a/src/libAtomVM/posix_nifs.c +++ b/src/libAtomVM/posix_nifs.c @@ -235,7 +235,11 @@ static term make_posix_fd_resource(Context *ctx, int fd) } fd_obj->fd = fd; fd_obj->selecting_process_id = INVALID_PROCESS_ID; - term obj = enif_make_resource(erl_nif_env_from_context(ctx), fd_obj); + if (UNLIKELY(memory_ensure_free(ctx, TERM_BOXED_REFERENCE_RESOURCE_SIZE) != MEMORY_GC_OK)) { + enif_release_resource(fd_obj); + RAISE_ERROR(OUT_OF_MEMORY_ATOM); + } + term obj = term_from_resource(fd_obj, &ctx->heap); enif_release_resource(fd_obj); // decrement refcount after enif_alloc_resource return obj; } @@ -847,7 +851,7 @@ static term nif_atomvm_posix_opendir(Context *ctx, int argc, term argv[]) != MEMORY_GC_OK)) { RAISE_ERROR(OUT_OF_MEMORY_ATOM); } - term obj = enif_make_resource(erl_nif_env_from_context(ctx), dir_obj); + term obj = term_from_resource(dir_obj, &ctx->heap); enif_release_resource(dir_obj); // decrement refcount after enif_alloc_resource result = term_alloc_tuple(2, &ctx->heap); term_put_tuple_element(result, 0, OK_ATOM); diff --git a/src/libAtomVM/resources.c b/src/libAtomVM/resources.c index 0a793a714b..8da525b02f 100644 --- a/src/libAtomVM/resources.c +++ b/src/libAtomVM/resources.c @@ -120,6 +120,9 @@ int enif_release_resource(void *resource) return true; } +// Suppress deprecation warning for the implementation +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" ERL_NIF_TERM enif_make_resource(ErlNifEnv *env, void *obj) { if (UNLIKELY(memory_erl_nif_env_ensure_free(env, TERM_BOXED_REFERENCE_RESOURCE_SIZE) != MEMORY_GC_OK)) { @@ -127,6 +130,7 @@ ERL_NIF_TERM enif_make_resource(ErlNifEnv *env, void *obj) } return term_from_resource(obj, &env->heap); } +#pragma GCC diagnostic pop static void enif_select_event_message_dispose(Message *message, GlobalContext *global, bool from_task) { @@ -631,16 +635,13 @@ const ErlNifResourceTypeInit resource_binary_resource_type_init = { .dtor = resource_binary_dtor, }; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" ERL_NIF_TERM enif_make_resource_binary(ErlNifEnv *env, void *obj, const void *data, size_t size) { - if (UNLIKELY(memory_erl_nif_env_ensure_free(env, TERM_BOXED_REFERENCE_RESOURCE_SIZE) != MEMORY_GC_OK)) { + if (UNLIKELY(memory_erl_nif_env_ensure_free(env, TERM_BOXED_REFC_BINARY_SIZE) != MEMORY_GC_OK)) { AVM_ABORT(); } - struct ResourceBinary *resource_binary = enif_alloc_resource(env->global->resource_binary_resource_type, sizeof(struct ResourceBinary)); - resource_binary->managing_resource = refc_binary_from_data(obj); - resource_binary->data = data; - - term result = term_from_resource_binary_pointer(resource_binary, size, &env->heap); - refc_binary_decrement_refcount(refc_binary_from_data(resource_binary), env->global); - return result; + return term_from_resource_binary(obj, data, size, &env->heap, env->global); } +#pragma GCC diagnostic pop diff --git a/src/libAtomVM/term.c b/src/libAtomVM/term.c index eb627dd018..f10d7af4c6 100644 --- a/src/libAtomVM/term.c +++ b/src/libAtomVM/term.c @@ -1373,9 +1373,13 @@ term term_from_resource_type_and_serialize_ref(uint64_t resource_type_ptr, uint6 return term_from_ref_ticks(ref_ticks, heap); } -term term_from_resource_binary_pointer(struct ResourceBinary *resource, size_t size, Heap *heap) +term term_from_resource_binary(void *obj, const void *data, size_t size, Heap *heap, GlobalContext *glb) { - struct RefcBinary *refc = refc_binary_from_data(resource); + struct ResourceBinary *resource_binary = enif_alloc_resource(glb->resource_binary_resource_type, sizeof(struct ResourceBinary)); + resource_binary->managing_resource = refc_binary_from_data(obj); + resource_binary->data = data; + + struct RefcBinary *refc = refc_binary_from_data(resource_binary); term *boxed_value = memory_heap_alloc(heap, TERM_BOXED_REFC_BINARY_SIZE); boxed_value[0] = ((TERM_BOXED_REFC_BINARY_SIZE - 1) << 6) | TERM_BOXED_REFC_BINARY; boxed_value[1] = (term) size; @@ -1385,6 +1389,8 @@ term term_from_resource_binary_pointer(struct ResourceBinary *resource, size_t s // Add the resource to the mso list refc->ref_count++; heap->root->mso_list = term_list_init_prepend(boxed_value + REFC_BINARY_CONS_OFFSET, ret, heap->root->mso_list); - refc_binary_increment_refcount(resource->managing_resource); + refc_binary_increment_refcount(resource_binary->managing_resource); + + refc_binary_decrement_refcount(refc, glb); return ret; } diff --git a/src/libAtomVM/term.h b/src/libAtomVM/term.h index eae9f58635..00c05c42b0 100644 --- a/src/libAtomVM/term.h +++ b/src/libAtomVM/term.h @@ -3012,14 +3012,14 @@ term term_from_resource_type_and_serialize_ref(uint64_t resource_type_ptr, uint6 * @details Increment reference count of resource and create a refc binary for * the pointer and size. * - * @param resource the resource managing the binary + * @param obj the managing resource object * @param data the pointer to the data * @param size the size of the binary * @param heap the heap to allocate memory in * @param glb the global context - * @return a refc binary + * @return a binary term managed by obj */ -term term_from_resource_binary_pointer(struct ResourceBinary *resource, size_t size, Heap *heap); +term term_from_resource_binary(void *obj, const void *data, size_t size, Heap *heap, GlobalContext *glb); #ifdef __cplusplus } diff --git a/src/platforms/emscripten/src/lib/platform_nifs.c b/src/platforms/emscripten/src/lib/platform_nifs.c index ed0a75f871..a60f094db1 100644 --- a/src/platforms/emscripten/src/lib/platform_nifs.c +++ b/src/platforms/emscripten/src/lib/platform_nifs.c @@ -682,7 +682,11 @@ static EM_BOOL html5api_touch_callback(int eventType, const EmscriptenTouchEvent enif_release_resource(resource); \ return term_from_emscripten_result(result, ctx); \ } \ - term resource_term = enif_make_resource(erl_nif_env_from_context(ctx), resource); \ + if (UNLIKELY(memory_ensure_free(ctx, TERM_BOXED_REFERENCE_RESOURCE_SIZE) != MEMORY_GC_OK)) { \ + enif_release_resource(resource); \ + RAISE_ERROR(OUT_OF_MEMORY_ATOM); \ + } \ + term resource_term = term_from_resource(resource, &ctx->heap); \ enif_release_resource(resource); \ if (UNLIKELY(memory_ensure_free_with_roots(ctx, TUPLE_SIZE(3), 1, &resource_term, MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) { \ RAISE_ERROR(OUT_OF_MEMORY_ATOM); \ diff --git a/src/platforms/esp32/components/avm_builtins/adc_driver.c b/src/platforms/esp32/components/avm_builtins/adc_driver.c index 67eaa6ac3b..ecc3d52c75 100644 --- a/src/platforms/esp32/components/avm_builtins/adc_driver.c +++ b/src/platforms/esp32/components/avm_builtins/adc_driver.c @@ -348,7 +348,7 @@ static term nif_adc_init(Context *ctx, int argc, term argv[]) ESP_LOGE(TAG, "failed to allocate memory for resource: %s:%i.", __FILE__, __LINE__); RAISE_ERROR(OUT_OF_MEMORY_ATOM); } - ERL_NIF_TERM unit_obj = enif_make_resource(erl_nif_env_from_context(ctx), unit_rsrc); + ERL_NIF_TERM unit_obj = term_from_resource(unit_rsrc, &ctx->heap); enif_release_resource(unit_rsrc); // decrement refcount after enif_alloc_resource // {ok, {'$adc', Unit :: resource(), ref()}} @@ -500,7 +500,7 @@ static term nif_adc_acquire(Context *ctx, int argc, term argv[]) RAISE_ERROR(OUT_OF_MEMORY_ATOM); } - term chan_obj = enif_make_resource(erl_nif_env_from_context(ctx), chan_rsrc); + term chan_obj = term_from_resource(chan_rsrc, &ctx->heap); enif_release_resource(chan_rsrc); // decrement refcount after enif_alloc_resource // {ok, {'$adc', resource(), ref()}} diff --git a/src/platforms/esp32/components/avm_builtins/dac_driver.c b/src/platforms/esp32/components/avm_builtins/dac_driver.c index 5a3d0d4b44..b5750f0c44 100644 --- a/src/platforms/esp32/components/avm_builtins/dac_driver.c +++ b/src/platforms/esp32/components/avm_builtins/dac_driver.c @@ -115,7 +115,7 @@ static term nif_oneshot_new_channel_p(Context *ctx, int argc, term argv[]) enif_release_resource(chan_rsrc); RAISE_ERROR(OUT_OF_MEMORY_ATOM); } - ERL_NIF_TERM chan_obj = enif_make_resource(erl_nif_env_from_context(ctx), chan_rsrc); + ERL_NIF_TERM chan_obj = term_from_resource(chan_rsrc, &ctx->heap); const dac_oneshot_config_t config = { .chan_id = term_to_uint8(argv[0]) diff --git a/src/platforms/esp32/components/avm_builtins/i2c_resource.c b/src/platforms/esp32/components/avm_builtins/i2c_resource.c index 246b8aa386..34ea4593ba 100644 --- a/src/platforms/esp32/components/avm_builtins/i2c_resource.c +++ b/src/platforms/esp32/components/avm_builtins/i2c_resource.c @@ -222,7 +222,7 @@ static term nif_i2c_open(Context *ctx, int argc, term argv[]) ESP_LOGW(TAG, "Failed to allocate memory: %s:%i.", __FILE__, __LINE__); RAISE_ERROR(OUT_OF_MEMORY_ATOM); } - term obj = enif_make_resource(erl_nif_env_from_context(ctx), rsrc_obj); + term obj = term_from_resource(rsrc_obj, &ctx->heap); enif_release_resource(rsrc_obj); // diff --git a/src/platforms/esp32/components/avm_builtins/storage_nif.c b/src/platforms/esp32/components/avm_builtins/storage_nif.c index f12df62821..0711c12d3e 100644 --- a/src/platforms/esp32/components/avm_builtins/storage_nif.c +++ b/src/platforms/esp32/components/avm_builtins/storage_nif.c @@ -265,7 +265,7 @@ static term nif_esp_mount(Context *ctx, int argc, term argv[]) enif_release_resource(mount); RAISE_ERROR(OUT_OF_MEMORY_ATOM); } - term mount_term = enif_make_resource(erl_nif_env_from_context(ctx), mount); + term mount_term = term_from_resource(mount, &ctx->heap); return_term = term_alloc_tuple(2, &ctx->heap); term_put_tuple_element(return_term, 0, OK_ATOM); term_put_tuple_element(return_term, 1, mount_term); diff --git a/src/platforms/esp32/components/avm_sys/platform_nifs.c b/src/platforms/esp32/components/avm_sys/platform_nifs.c index 473c2fa033..2b554333b0 100644 --- a/src/platforms/esp32/components/avm_sys/platform_nifs.c +++ b/src/platforms/esp32/components/avm_sys/platform_nifs.c @@ -324,8 +324,11 @@ static term nif_esp_partition_mmap(Context *ctx, int argc, term argv[]) return ERROR_ATOM; } - ErlNifEnv *env = erl_nif_env_from_context(ctx); - ERL_NIF_TERM binary = enif_make_resource_binary(env, handle, mmap_ptr, size); + if (UNLIKELY(memory_ensure_free(ctx, TERM_BOXED_REFC_BINARY_SIZE) != MEMORY_GC_OK)) { + enif_release_resource(handle); + RAISE_ERROR(OUT_OF_MEMORY_ATOM); + } + ERL_NIF_TERM binary = term_from_resource_binary(handle, mmap_ptr, size, &ctx->heap, ctx->global); enif_release_resource(handle); if (UNLIKELY(memory_ensure_free_with_roots(ctx, TUPLE_SIZE(2), 1, &binary, MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) { diff --git a/src/platforms/generic_unix/lib/jit_stream_mmap.c b/src/platforms/generic_unix/lib/jit_stream_mmap.c index 096cfe7faf..052308a060 100644 --- a/src/platforms/generic_unix/lib/jit_stream_mmap.c +++ b/src/platforms/generic_unix/lib/jit_stream_mmap.c @@ -89,7 +89,11 @@ static term nif_jit_stream_mmap_new(Context *ctx, int argc, term argv[]) js->stream_offset = 0; js->stream_size = size; - term obj = enif_make_resource(erl_nif_env_from_context(ctx), js); + if (UNLIKELY(memory_ensure_free(ctx, TERM_BOXED_REFERENCE_RESOURCE_SIZE) != MEMORY_GC_OK)) { + enif_release_resource(js); + RAISE_ERROR(OUT_OF_MEMORY_ATOM); + } + term obj = term_from_resource(js, &ctx->heap); enif_release_resource(js); // decrement refcount after enif_alloc_resource return obj; } diff --git a/tests/test-enif.c b/tests/test-enif.c index 3994c45341..555ad0fe38 100644 --- a/tests/test-enif.c +++ b/tests/test-enif.c @@ -28,6 +28,7 @@ #include "erl_nif_priv.h" #include "external_term.h" #include "globalcontext.h" +#include "memory.h" #include "scheduler.h" #include "utils.h" @@ -114,7 +115,8 @@ void test_resource(void) uint32_t *resource = (uint32_t *) ptr; *resource = 42; - ERL_NIF_TERM resource_term = enif_make_resource(env, ptr); + assert(memory_erl_nif_env_ensure_free(env, TERM_BOXED_REFERENCE_RESOURCE_SIZE) == MEMORY_GC_OK); + ERL_NIF_TERM resource_term = term_from_resource(ptr, &env->heap); assert(term_is_reference(resource_term)); assert(term_is_resource_reference(resource_term)); @@ -475,7 +477,8 @@ void test_resource_binary(void) uint32_t *resource = (uint32_t *) ptr; *resource = 42; - ERL_NIF_TERM binary = enif_make_resource_binary(env, ptr, "hello", 5); + assert(memory_erl_nif_env_ensure_free(env, TERM_BOXED_REFC_BINARY_SIZE) == MEMORY_GC_OK); + ERL_NIF_TERM binary = term_from_resource_binary(ptr, "hello", 5, &env->heap, env->global); assert(term_is_binary(binary)); assert(term_is_refc_binary(binary)); assert(term_binary_size(binary) == 5); @@ -548,7 +551,8 @@ void test_resource_binaries(void) uint32_t *resource = (uint32_t *) ptr; *resource = 42; - ERL_NIF_TERM binary1 = enif_make_resource_binary(env1, ptr, "hello", 5); + assert(memory_erl_nif_env_ensure_free(env1, TERM_BOXED_REFC_BINARY_SIZE) == MEMORY_GC_OK); + ERL_NIF_TERM binary1 = term_from_resource_binary(ptr, "hello", 5, &env1->heap, env1->global); assert(term_is_binary(binary1)); assert(term_is_refc_binary(binary1)); assert(term_binary_size(binary1) == 5); @@ -556,7 +560,8 @@ void test_resource_binaries(void) assert(cb_read_resource == 0); - ERL_NIF_TERM binary2 = enif_make_resource_binary(env2, ptr, "world", 5); + assert(memory_erl_nif_env_ensure_free(env2, TERM_BOXED_REFC_BINARY_SIZE) == MEMORY_GC_OK); + ERL_NIF_TERM binary2 = term_from_resource_binary(ptr, "world", 5, &env2->heap, env2->global); assert(term_is_binary(binary2)); assert(term_is_refc_binary(binary2)); assert(term_binary_size(binary2) == 5);