Skip to content

Commit 5679f11

Browse files
committed
Merge pull request #1199 from pguyot/w25/factorize-sys_load_module
Factorize sys_load_module function The same function was duplicated across platforms. These changes are made under both the "Apache 2.0" and the "GNU Lesser General Public License 2.1 or later" license terms (dual license). SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
2 parents cddb5fc + f53441d commit 5679f11

File tree

10 files changed

+54
-160
lines changed

10 files changed

+54
-160
lines changed

src/libAtomVM/globalcontext.c

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,32 @@ int globalcontext_insert_module(GlobalContext *global, Module *module)
595595
return module_index;
596596
}
597597

598+
Module *globalcontext_load_module_from_avm(GlobalContext *global, const char *module_name)
599+
{
600+
const void *beam_module = NULL;
601+
uint32_t beam_module_size = 0;
602+
603+
struct ListHead *item;
604+
struct ListHead *avmpack_data = synclist_rdlock(&global->avmpack_data);
605+
LIST_FOR_EACH (item, avmpack_data) {
606+
struct AVMPackData *avmpack_data = GET_LIST_ENTRY(item, struct AVMPackData, avmpack_head);
607+
avmpack_data->in_use = true;
608+
if (avmpack_find_section_by_name(avmpack_data->data, module_name, &beam_module, &beam_module_size)) {
609+
break;
610+
}
611+
}
612+
synclist_unlock(&global->avmpack_data);
613+
614+
if (IS_NULL_PTR(beam_module)) {
615+
return NULL;
616+
}
617+
618+
Module *new_module = module_new_from_iff_binary(global, beam_module, beam_module_size);
619+
new_module->module_platform_data = NULL;
620+
621+
return new_module;
622+
}
623+
598624
Module *globalcontext_get_module(GlobalContext *global, AtomString module_name_atom)
599625
{
600626
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
607633

608634
atom_string_to_c(module_name_atom, module_name, 256);
609635
strcat(module_name, ".beam");
610-
Module *loaded_module = sys_load_module(global, module_name);
611-
free(module_name);
612-
636+
Module *loaded_module = globalcontext_load_module_from_avm(global, module_name);
637+
if (IS_NULL_PTR(loaded_module)) {
638+
// Platform may implement sys_load_module_from_file
639+
loaded_module = sys_load_module_from_file(global, module_name);
640+
}
613641
if (UNLIKELY(!loaded_module || (globalcontext_insert_module(global, loaded_module) < 0))) {
642+
fprintf(stderr, "Failed load module: %s\n", module_name);
643+
free(module_name);
614644
return NULL;
615645
}
616646

647+
free(module_name);
648+
617649
return loaded_module;
618650
}
619651

src/libAtomVM/globalcontext.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,19 @@ Module *globalcontext_get_module_by_index(GlobalContext *global, int index);
462462
*/
463463
Module *globalcontext_get_module(GlobalContext *global, AtomString module_name_atom);
464464

465+
/**
466+
* @brief Load a given module from registered AVM packs
467+
*
468+
* @details This function is typically called from sys_load_module. It does
469+
* not check if the module is already loaded and allocates a new module
470+
* structure.
471+
* @param global the global context.
472+
* @param module_name_atom the module name.
473+
* @returns a pointer to a Module struct or NULL if the module could not be
474+
* found.
475+
*/
476+
Module *globalcontext_load_module_from_avm(GlobalContext *global, const char *module_name);
477+
465478
/**
466479
* @brief remove a monitor
467480
*

src/libAtomVM/sys.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -238,14 +238,14 @@ uint64_t sys_monotonic_time_ms_to_u64(uint64_t ms);
238238
uint64_t sys_monotonic_time_u64_to_ms(uint64_t t);
239239

240240
/**
241-
* @brief Loads a BEAM module using platform dependent methods.
241+
* @brief Loads a BEAM module, searching files.
242242
*
243-
* @details Loads a BEAM module into memory using platform dependent methods and returns a pointer to a Module struct.
243+
* @details Loads a BEAM module into memory using platform dependent methods
244+
* and returns a pointer to a Module struct. This function is called if loading
245+
* from avm packs failed and may return NULL if there is no support for files.
244246
* @param global the global context.
245247
* @param module_name the name of the BEAM file (e.g. "mymodule.beam").
246248
*/
247-
Module *sys_load_module(GlobalContext *global, const char *module_name);
248-
249249
Module *sys_load_module_from_file(GlobalContext *global, const char *path);
250250

251251
/**

src/platforms/emscripten/src/lib/sys.c

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -711,33 +711,6 @@ Module *sys_load_module_from_file(GlobalContext *global, const char *path)
711711
return new_module;
712712
}
713713

714-
Module *sys_load_module(GlobalContext *global, const char *module_name)
715-
{
716-
const void *beam_module = NULL;
717-
uint32_t beam_module_size = 0;
718-
719-
struct ListHead *avmpack_data_list = synclist_rdlock(&global->avmpack_data);
720-
struct ListHead *item;
721-
LIST_FOR_EACH (item, avmpack_data_list) {
722-
struct AVMPackData *avmpack_data = GET_LIST_ENTRY(item, struct AVMPackData, avmpack_head);
723-
avmpack_data->in_use = true;
724-
if (avmpack_find_section_by_name(avmpack_data->data, module_name, &beam_module, &beam_module_size)) {
725-
break;
726-
}
727-
}
728-
synclist_unlock(&global->avmpack_data);
729-
730-
if (IS_NULL_PTR(beam_module)) {
731-
fprintf(stderr, "Failed to open module: %s\n", module_name);
732-
return NULL;
733-
}
734-
735-
Module *new_module = module_new_from_iff_binary(global, beam_module, beam_module_size);
736-
new_module->module_platform_data = NULL;
737-
738-
return new_module;
739-
}
740-
741714
Context *sys_create_port(GlobalContext *glb, const char *driver_name, term opts)
742715
{
743716
UNUSED(glb);

src/platforms/esp32/components/avm_sys/sys.c

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -418,33 +418,6 @@ Module *sys_load_module_from_file(GlobalContext *global, const char *path)
418418
return NULL;
419419
}
420420

421-
Module *sys_load_module(GlobalContext *global, const char *module_name)
422-
{
423-
const void *beam_module = NULL;
424-
uint32_t beam_module_size = 0;
425-
426-
struct ListHead *item;
427-
struct ListHead *avmpack_data = synclist_rdlock(&global->avmpack_data);
428-
LIST_FOR_EACH (item, avmpack_data) {
429-
struct AVMPackData *avmpack_data = GET_LIST_ENTRY(item, struct AVMPackData, avmpack_head);
430-
avmpack_data->in_use = true;
431-
if (avmpack_find_section_by_name(avmpack_data->data, module_name, &beam_module, &beam_module_size)) {
432-
break;
433-
}
434-
}
435-
synclist_unlock(&global->avmpack_data);
436-
437-
if (IS_NULL_PTR(beam_module)) {
438-
fprintf(stderr, "Failed to open module: %s\n", module_name);
439-
return NULL;
440-
}
441-
442-
Module *new_module = module_new_from_iff_binary(global, beam_module, beam_module_size);
443-
new_module->module_platform_data = NULL;
444-
445-
return new_module;
446-
}
447-
448421
// This function allows to use AtomVM as a component on ESP32 and customize it
449422
__attribute__((weak)) Context *sys_create_port_fallback(const char *driver_name, GlobalContext *global, term opts)
450423
{

src/platforms/esp32/test/main/test_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ term avm_test_case(const char *test_module)
143143
avmpack_data->base.data = main_avm;
144144
synclist_append(&glb->avmpack_data, &avmpack_data->base.avmpack_head);
145145

146-
Module *mod = sys_load_module(glb, test_module);
146+
Module *mod = globalcontext_load_module_from_avm(glb, test_module);
147147
TEST_ASSERT(mod != NULL);
148148

149149
globalcontext_insert_module(glb, mod);

src/platforms/generic_unix/lib/sys.c

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -473,50 +473,6 @@ Module *sys_load_module_from_file(GlobalContext *global, const char *path)
473473
return new_module;
474474
}
475475

476-
Module *sys_find_and_load_module_from_avm(GlobalContext *global, const char *module_name)
477-
{
478-
TRACE("sys_find_and_load_module_from_avm: Going to load: %s\n", module_name);
479-
480-
const void *beam_module = NULL;
481-
uint32_t beam_module_size = 0;
482-
483-
Module *new_module = NULL;
484-
485-
struct ListHead *item;
486-
struct ListHead *avmpack_data = synclist_rdlock(&global->avmpack_data);
487-
LIST_FOR_EACH (item, avmpack_data) {
488-
struct AVMPackData *avmpack_data = GET_LIST_ENTRY(item, struct AVMPackData, avmpack_head);
489-
bool prev_in_use = avmpack_data->in_use;
490-
avmpack_data->in_use = true;
491-
if (avmpack_find_section_by_name(avmpack_data->data, module_name, &beam_module, &beam_module_size)) {
492-
new_module = module_new_from_iff_binary(global, beam_module, beam_module_size);
493-
if (IS_NULL_PTR(new_module)) {
494-
avmpack_data->in_use = prev_in_use;
495-
synclist_unlock(&global->avmpack_data);
496-
return NULL;
497-
}
498-
new_module->module_platform_data = NULL;
499-
500-
break;
501-
}
502-
}
503-
synclist_unlock(&global->avmpack_data);
504-
505-
return new_module;
506-
}
507-
508-
Module *sys_load_module(GlobalContext *global, const char *module_name)
509-
{
510-
TRACE("sys_load_module: Going to load: %s\n", module_name);
511-
512-
Module *new_module = sys_find_and_load_module_from_avm(global, module_name);
513-
if (new_module) {
514-
return new_module;
515-
}
516-
517-
return sys_load_module_from_file(global, module_name);
518-
}
519-
520476
Context *sys_create_port(GlobalContext *glb, const char *driver_name, term opts)
521477
{
522478
if (!strcmp(driver_name, "socket")) {

src/platforms/rp2040/src/lib/sys.c

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -275,32 +275,6 @@ Module *sys_load_module_from_file(GlobalContext *global, const char *path)
275275
return NULL;
276276
}
277277

278-
Module *sys_load_module(GlobalContext *global, const char *module_name)
279-
{
280-
const void *beam_module = NULL;
281-
uint32_t beam_module_size = 0;
282-
283-
struct ListHead *item;
284-
struct ListHead *avmpack_data = synclist_rdlock(&global->avmpack_data);
285-
LIST_FOR_EACH (item, avmpack_data) {
286-
struct AVMPackData *avmpack_data = GET_LIST_ENTRY(item, struct AVMPackData, avmpack_head);
287-
if (avmpack_find_section_by_name(avmpack_data->data, module_name, &beam_module, &beam_module_size)) {
288-
break;
289-
}
290-
}
291-
synclist_unlock(&global->avmpack_data);
292-
293-
if (IS_NULL_PTR(beam_module)) {
294-
fprintf(stderr, "Failed to open module: %s\n", module_name);
295-
return NULL;
296-
}
297-
298-
Module *new_module = module_new_from_iff_binary(global, beam_module, beam_module_size);
299-
new_module->module_platform_data = NULL;
300-
301-
return new_module;
302-
}
303-
304278
Context *sys_create_port(GlobalContext *glb, const char *port_name, term opts)
305279
{
306280
for (struct PortDriverDefListItem *item = port_driver_list; item != NULL; item = item->next) {

src/platforms/rp2040/tests/test_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ static term avm_test_case(const char *test_module)
111111

112112
synclist_append(&glb->avmpack_data, &avmpack_data->base.avmpack_head);
113113

114-
Module *mod = sys_load_module(glb, test_module);
114+
Module *mod = globalcontext_load_module_from_avm(glb, test_module);
115115
TEST_ASSERT(mod != NULL);
116116

117117
globalcontext_insert_module(glb, mod);

src/platforms/stm32/src/lib/sys.c

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -251,33 +251,6 @@ Module *sys_load_module_from_file(GlobalContext *global, const char *path)
251251
return NULL;
252252
}
253253

254-
Module *sys_load_module(GlobalContext *global, const char *module_name)
255-
{
256-
const void *beam_module = NULL;
257-
uint32_t beam_module_size = 0;
258-
259-
struct ListHead *avmpack_data_list = synclist_rdlock(&global->avmpack_data);
260-
struct ListHead *item;
261-
LIST_FOR_EACH (item, avmpack_data_list) {
262-
struct AVMPackData *avmpack_data = GET_LIST_ENTRY(item, struct AVMPackData, avmpack_head);
263-
avmpack_data->in_use = true;
264-
if (avmpack_find_section_by_name(avmpack_data->data, module_name, &beam_module, &beam_module_size)) {
265-
break;
266-
}
267-
}
268-
synclist_unlock(&global->avmpack_data);
269-
270-
if (IS_NULL_PTR(beam_module)) {
271-
AVM_LOGE(TAG, "Failed to open module: %s.", module_name);
272-
return NULL;
273-
}
274-
275-
Module *new_module = module_new_from_iff_binary(global, beam_module, beam_module_size);
276-
new_module->module_platform_data = NULL;
277-
278-
return new_module;
279-
}
280-
281254
Context *sys_create_port(GlobalContext *glb, const char *driver_name, term opts)
282255
{
283256
Context *new_ctx = port_driver_create_port(driver_name, glb, opts);

0 commit comments

Comments
 (0)