diff --git a/src/libAtomVM/globalcontext.c b/src/libAtomVM/globalcontext.c index 298e31bf9..f3e63a2b0 100644 --- a/src/libAtomVM/globalcontext.c +++ b/src/libAtomVM/globalcontext.c @@ -595,6 +595,32 @@ int globalcontext_insert_module(GlobalContext *global, Module *module) return module_index; } +Module *globalcontext_load_module_from_avm(GlobalContext *global, const char *module_name) +{ + const void *beam_module = NULL; + uint32_t beam_module_size = 0; + + struct ListHead *item; + struct ListHead *avmpack_data = synclist_rdlock(&global->avmpack_data); + LIST_FOR_EACH (item, avmpack_data) { + struct AVMPackData *avmpack_data = GET_LIST_ENTRY(item, struct AVMPackData, avmpack_head); + avmpack_data->in_use = true; + if (avmpack_find_section_by_name(avmpack_data->data, module_name, &beam_module, &beam_module_size)) { + break; + } + } + synclist_unlock(&global->avmpack_data); + + if (IS_NULL_PTR(beam_module)) { + return NULL; + } + + Module *new_module = module_new_from_iff_binary(global, beam_module, beam_module_size); + new_module->module_platform_data = NULL; + + return new_module; +} + Module *globalcontext_get_module(GlobalContext *global, AtomString module_name_atom) { Module *found_module = (Module *) atomshashtable_get_value(global->modules_table, module_name_atom, (unsigned long) NULL); @@ -607,13 +633,19 @@ Module *globalcontext_get_module(GlobalContext *global, AtomString module_name_a atom_string_to_c(module_name_atom, module_name, 256); strcat(module_name, ".beam"); - Module *loaded_module = sys_load_module(global, module_name); - free(module_name); - + Module *loaded_module = globalcontext_load_module_from_avm(global, module_name); + if (IS_NULL_PTR(loaded_module)) { + // Platform may implement sys_load_module_from_file + loaded_module = sys_load_module_from_file(global, module_name); + } if (UNLIKELY(!loaded_module || (globalcontext_insert_module(global, loaded_module) < 0))) { + fprintf(stderr, "Failed load module: %s\n", module_name); + free(module_name); return NULL; } + free(module_name); + return loaded_module; } diff --git a/src/libAtomVM/globalcontext.h b/src/libAtomVM/globalcontext.h index 3a090e3b4..488d2b655 100644 --- a/src/libAtomVM/globalcontext.h +++ b/src/libAtomVM/globalcontext.h @@ -462,6 +462,19 @@ Module *globalcontext_get_module_by_index(GlobalContext *global, int index); */ Module *globalcontext_get_module(GlobalContext *global, AtomString module_name_atom); +/** + * @brief Load a given module from registered AVM packs + * + * @details This function is typically called from sys_load_module. It does + * not check if the module is already loaded and allocates a new module + * structure. + * @param global the global context. + * @param module_name_atom the module name. + * @returns a pointer to a Module struct or NULL if the module could not be + * found. + */ +Module *globalcontext_load_module_from_avm(GlobalContext *global, const char *module_name); + /** * @brief remove a monitor * diff --git a/src/libAtomVM/sys.h b/src/libAtomVM/sys.h index bba967487..72d1d1788 100644 --- a/src/libAtomVM/sys.h +++ b/src/libAtomVM/sys.h @@ -238,14 +238,14 @@ uint64_t sys_monotonic_time_ms_to_u64(uint64_t ms); uint64_t sys_monotonic_time_u64_to_ms(uint64_t t); /** - * @brief Loads a BEAM module using platform dependent methods. + * @brief Loads a BEAM module, searching files. * - * @details Loads a BEAM module into memory using platform dependent methods and returns a pointer to a Module struct. + * @details Loads a BEAM module into memory using platform dependent methods + * and returns a pointer to a Module struct. This function is called if loading + * from avm packs failed and may return NULL if there is no support for files. * @param global the global context. * @param module_name the name of the BEAM file (e.g. "mymodule.beam"). */ -Module *sys_load_module(GlobalContext *global, const char *module_name); - Module *sys_load_module_from_file(GlobalContext *global, const char *path); /** diff --git a/src/platforms/emscripten/src/lib/sys.c b/src/platforms/emscripten/src/lib/sys.c index 4a136e68d..5ca6474b0 100644 --- a/src/platforms/emscripten/src/lib/sys.c +++ b/src/platforms/emscripten/src/lib/sys.c @@ -711,33 +711,6 @@ Module *sys_load_module_from_file(GlobalContext *global, const char *path) return new_module; } -Module *sys_load_module(GlobalContext *global, const char *module_name) -{ - const void *beam_module = NULL; - uint32_t beam_module_size = 0; - - struct ListHead *avmpack_data_list = synclist_rdlock(&global->avmpack_data); - struct ListHead *item; - LIST_FOR_EACH (item, avmpack_data_list) { - struct AVMPackData *avmpack_data = GET_LIST_ENTRY(item, struct AVMPackData, avmpack_head); - avmpack_data->in_use = true; - if (avmpack_find_section_by_name(avmpack_data->data, module_name, &beam_module, &beam_module_size)) { - break; - } - } - synclist_unlock(&global->avmpack_data); - - if (IS_NULL_PTR(beam_module)) { - fprintf(stderr, "Failed to open module: %s\n", module_name); - return NULL; - } - - Module *new_module = module_new_from_iff_binary(global, beam_module, beam_module_size); - new_module->module_platform_data = NULL; - - return new_module; -} - Context *sys_create_port(GlobalContext *glb, const char *driver_name, term opts) { UNUSED(glb); diff --git a/src/platforms/esp32/components/avm_sys/sys.c b/src/platforms/esp32/components/avm_sys/sys.c index 4ba09d281..f8226c3ee 100644 --- a/src/platforms/esp32/components/avm_sys/sys.c +++ b/src/platforms/esp32/components/avm_sys/sys.c @@ -418,33 +418,6 @@ Module *sys_load_module_from_file(GlobalContext *global, const char *path) return NULL; } -Module *sys_load_module(GlobalContext *global, const char *module_name) -{ - const void *beam_module = NULL; - uint32_t beam_module_size = 0; - - struct ListHead *item; - struct ListHead *avmpack_data = synclist_rdlock(&global->avmpack_data); - LIST_FOR_EACH (item, avmpack_data) { - struct AVMPackData *avmpack_data = GET_LIST_ENTRY(item, struct AVMPackData, avmpack_head); - avmpack_data->in_use = true; - if (avmpack_find_section_by_name(avmpack_data->data, module_name, &beam_module, &beam_module_size)) { - break; - } - } - synclist_unlock(&global->avmpack_data); - - if (IS_NULL_PTR(beam_module)) { - fprintf(stderr, "Failed to open module: %s\n", module_name); - return NULL; - } - - Module *new_module = module_new_from_iff_binary(global, beam_module, beam_module_size); - new_module->module_platform_data = NULL; - - return new_module; -} - // This function allows to use AtomVM as a component on ESP32 and customize it __attribute__((weak)) Context *sys_create_port_fallback(const char *driver_name, GlobalContext *global, term opts) { diff --git a/src/platforms/esp32/test/main/test_main.c b/src/platforms/esp32/test/main/test_main.c index 83076c348..d82c97950 100644 --- a/src/platforms/esp32/test/main/test_main.c +++ b/src/platforms/esp32/test/main/test_main.c @@ -143,7 +143,7 @@ term avm_test_case(const char *test_module) avmpack_data->base.data = main_avm; synclist_append(&glb->avmpack_data, &avmpack_data->base.avmpack_head); - Module *mod = sys_load_module(glb, test_module); + Module *mod = globalcontext_load_module_from_avm(glb, test_module); TEST_ASSERT(mod != NULL); globalcontext_insert_module(glb, mod); diff --git a/src/platforms/generic_unix/lib/sys.c b/src/platforms/generic_unix/lib/sys.c index 92bed9b25..229dd16d0 100644 --- a/src/platforms/generic_unix/lib/sys.c +++ b/src/platforms/generic_unix/lib/sys.c @@ -473,50 +473,6 @@ Module *sys_load_module_from_file(GlobalContext *global, const char *path) return new_module; } -Module *sys_find_and_load_module_from_avm(GlobalContext *global, const char *module_name) -{ - TRACE("sys_find_and_load_module_from_avm: Going to load: %s\n", module_name); - - const void *beam_module = NULL; - uint32_t beam_module_size = 0; - - Module *new_module = NULL; - - struct ListHead *item; - struct ListHead *avmpack_data = synclist_rdlock(&global->avmpack_data); - LIST_FOR_EACH (item, avmpack_data) { - struct AVMPackData *avmpack_data = GET_LIST_ENTRY(item, struct AVMPackData, avmpack_head); - bool prev_in_use = avmpack_data->in_use; - avmpack_data->in_use = true; - if (avmpack_find_section_by_name(avmpack_data->data, module_name, &beam_module, &beam_module_size)) { - new_module = module_new_from_iff_binary(global, beam_module, beam_module_size); - if (IS_NULL_PTR(new_module)) { - avmpack_data->in_use = prev_in_use; - synclist_unlock(&global->avmpack_data); - return NULL; - } - new_module->module_platform_data = NULL; - - break; - } - } - synclist_unlock(&global->avmpack_data); - - return new_module; -} - -Module *sys_load_module(GlobalContext *global, const char *module_name) -{ - TRACE("sys_load_module: Going to load: %s\n", module_name); - - Module *new_module = sys_find_and_load_module_from_avm(global, module_name); - if (new_module) { - return new_module; - } - - return sys_load_module_from_file(global, module_name); -} - Context *sys_create_port(GlobalContext *glb, const char *driver_name, term opts) { if (!strcmp(driver_name, "socket")) { diff --git a/src/platforms/rp2040/src/lib/sys.c b/src/platforms/rp2040/src/lib/sys.c index 344d72cf8..b4d4ac612 100644 --- a/src/platforms/rp2040/src/lib/sys.c +++ b/src/platforms/rp2040/src/lib/sys.c @@ -275,32 +275,6 @@ Module *sys_load_module_from_file(GlobalContext *global, const char *path) return NULL; } -Module *sys_load_module(GlobalContext *global, const char *module_name) -{ - const void *beam_module = NULL; - uint32_t beam_module_size = 0; - - struct ListHead *item; - struct ListHead *avmpack_data = synclist_rdlock(&global->avmpack_data); - LIST_FOR_EACH (item, avmpack_data) { - struct AVMPackData *avmpack_data = GET_LIST_ENTRY(item, struct AVMPackData, avmpack_head); - if (avmpack_find_section_by_name(avmpack_data->data, module_name, &beam_module, &beam_module_size)) { - break; - } - } - synclist_unlock(&global->avmpack_data); - - if (IS_NULL_PTR(beam_module)) { - fprintf(stderr, "Failed to open module: %s\n", module_name); - return NULL; - } - - Module *new_module = module_new_from_iff_binary(global, beam_module, beam_module_size); - new_module->module_platform_data = NULL; - - return new_module; -} - Context *sys_create_port(GlobalContext *glb, const char *port_name, term opts) { for (struct PortDriverDefListItem *item = port_driver_list; item != NULL; item = item->next) { diff --git a/src/platforms/rp2040/tests/test_main.c b/src/platforms/rp2040/tests/test_main.c index c011dd031..62e3fa1a1 100644 --- a/src/platforms/rp2040/tests/test_main.c +++ b/src/platforms/rp2040/tests/test_main.c @@ -111,7 +111,7 @@ static term avm_test_case(const char *test_module) synclist_append(&glb->avmpack_data, &avmpack_data->base.avmpack_head); - Module *mod = sys_load_module(glb, test_module); + Module *mod = globalcontext_load_module_from_avm(glb, test_module); TEST_ASSERT(mod != NULL); globalcontext_insert_module(glb, mod); diff --git a/src/platforms/stm32/src/lib/sys.c b/src/platforms/stm32/src/lib/sys.c index cbd0decb2..c65a39cab 100644 --- a/src/platforms/stm32/src/lib/sys.c +++ b/src/platforms/stm32/src/lib/sys.c @@ -251,33 +251,6 @@ Module *sys_load_module_from_file(GlobalContext *global, const char *path) return NULL; } -Module *sys_load_module(GlobalContext *global, const char *module_name) -{ - const void *beam_module = NULL; - uint32_t beam_module_size = 0; - - struct ListHead *avmpack_data_list = synclist_rdlock(&global->avmpack_data); - struct ListHead *item; - LIST_FOR_EACH (item, avmpack_data_list) { - struct AVMPackData *avmpack_data = GET_LIST_ENTRY(item, struct AVMPackData, avmpack_head); - avmpack_data->in_use = true; - if (avmpack_find_section_by_name(avmpack_data->data, module_name, &beam_module, &beam_module_size)) { - break; - } - } - synclist_unlock(&global->avmpack_data); - - if (IS_NULL_PTR(beam_module)) { - AVM_LOGE(TAG, "Failed to open module: %s.", module_name); - return NULL; - } - - Module *new_module = module_new_from_iff_binary(global, beam_module, beam_module_size); - new_module->module_platform_data = NULL; - - return new_module; -} - Context *sys_create_port(GlobalContext *glb, const char *driver_name, term opts) { Context *new_ctx = port_driver_create_port(driver_name, glb, opts);