Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Factorize sys_load_module function #1199

Merged
merged 1 commit into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 35 additions & 3 deletions src/libAtomVM/globalcontext.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
github-advanced-security[bot] marked this conversation as resolved.
Fixed
Show resolved Hide resolved
free(module_name);
return NULL;
}

free(module_name);

return loaded_module;
}

Expand Down
13 changes: 13 additions & 0 deletions src/libAtomVM/globalcontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down
8 changes: 4 additions & 4 deletions src/libAtomVM/sys.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/**
Expand Down
27 changes: 0 additions & 27 deletions src/platforms/emscripten/src/lib/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
27 changes: 0 additions & 27 deletions src/platforms/esp32/components/avm_sys/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
2 changes: 1 addition & 1 deletion src/platforms/esp32/test/main/test_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
44 changes: 0 additions & 44 deletions src/platforms/generic_unix/lib/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -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")) {
Expand Down
26 changes: 0 additions & 26 deletions src/platforms/rp2040/src/lib/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion src/platforms/rp2040/tests/test_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
27 changes: 0 additions & 27 deletions src/platforms/stm32/src/lib/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading