Skip to content

Commit

Permalink
NIFs: add atomvm:get_entry_point/1
Browse files Browse the repository at this point in the history
Add function for getting the entry point for a given .avm file.

Signed-off-by: Davide Bettio <[email protected]>
  • Loading branch information
bettio committed Jul 9, 2023
1 parent 24f8e20 commit afefb0b
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
47 changes: 47 additions & 0 deletions src/libAtomVM/nifs.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ static term nif_erlang_unlink(Context *ctx, int argc, term argv[]);
static term nif_atomvm_add_avm_pack_binary(Context *ctx, int argc, term argv[]);
static term nif_atomvm_add_avm_pack_file(Context *ctx, int argc, term argv[]);
static term nif_atomvm_close_avm_pack(Context *ctx, int argc, term argv[]);
static term nif_atomvm_get_entry_point(Context *ctx, int argc, term argv[]);
static term nif_atomvm_read_priv(Context *ctx, int argc, term argv[]);
static term nif_console_print(Context *ctx, int argc, term argv[]);
static term nif_base64_encode(Context *ctx, int argc, term argv[]);
Expand Down Expand Up @@ -648,6 +649,11 @@ static const struct Nif atomvm_close_avm_pack_nif =
.base.type = NIFFunctionType,
.nif_ptr = nif_atomvm_close_avm_pack
};
static const struct Nif atomvm_get_entry_point_nif =
{
.base.type = NIFFunctionType,
.nif_ptr = nif_atomvm_get_entry_point
};
static const struct Nif atomvm_read_priv_nif =
{
.base.type = NIFFunctionType,
Expand Down Expand Up @@ -3519,6 +3525,47 @@ static term nif_atomvm_close_avm_pack(Context *ctx, int argc, term argv[])
return OK_ATOM;
}

// AtomVM extension
static term nif_atomvm_get_entry_point(Context *ctx, int argc, term argv[])
{
UNUSED(argc);

term name = argv[0];
if (UNLIKELY(!term_is_atom(name))) {
RAISE_ERROR(BADARG_ATOM);
}

int name_atom_id = term_to_atom_index(name);

struct ListHead *open_avm_packs = synclist_wrlock(&ctx->global->avmpack_data);
struct ListHead *item;
LIST_FOR_EACH (item, open_avm_packs) {
struct AVMPackData *avmpack_data = GET_LIST_ENTRY(item, struct AVMPackData, avmpack_head);
if (avmpack_data->name_atom_id == name_atom_id) {
uint32_t size;
const void *beam;
const char *module_name;
if (!avmpack_find_section_by_flag(avmpack_data->data, BEAM_START_FLAG, &beam, &size, &module_name)) {
synclist_unlock(&ctx->global->avmpack_data);
return UNDEFINED_ATOM;
}

int module_name_len = strlen(module_name);
int needed = term_binary_heap_size(module_name_len);
if (UNLIKELY(memory_ensure_free(ctx, needed) != MEMORY_GC_OK)) {
synclist_unlock(&ctx->global->avmpack_data);
RAISE_ERROR(OUT_OF_MEMORY_ATOM);
}
term entry_bin = term_from_literal_binary(module_name, module_name_len, &ctx->heap, ctx->global);
synclist_unlock(&ctx->global->avmpack_data);
return entry_bin;
}
}
synclist_unlock(&ctx->global->avmpack_data);

return UNDEFINED_ATOM;
}

// AtomVM extension
static term nif_atomvm_read_priv(Context *ctx, int argc, term argv[])
{
Expand Down
1 change: 1 addition & 0 deletions src/libAtomVM/nifs.gperf
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ erts_debug:flat_size/1, &flat_size_nif
atomvm:add_avm_pack_binary/2, &atomvm_add_avm_pack_binary_nif
atomvm:add_avm_pack_file/2, &atomvm_add_avm_pack_file_nif
atomvm:close_avm_pack/2, &atomvm_close_avm_pack_nif
atomvm:get_entry_point/1, &atomvm_get_entry_point_nif
atomvm:read_priv/2, &atomvm_read_priv_nif
atomvm:posix_open/2, IF_HAVE_OPEN_CLOSE(&atomvm_posix_open_nif)
atomvm:posix_open/3, IF_HAVE_OPEN_CLOSE(&atomvm_posix_open_nif)
Expand Down

0 comments on commit afefb0b

Please sign in to comment.