Skip to content

Commit

Permalink
Merge pull request #699 from bettio/add-get_start_beam
Browse files Browse the repository at this point in the history
NIFs: add atomvm:get_start_beam/1

This change is required in order to implement #657.

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
  • Loading branch information
bettio committed Jul 24, 2023
2 parents 900b601 + c6aa270 commit 4d0131b
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
64 changes: 64 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_start_beam(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_start_beam_nif =
{
.base.type = NIFFunctionType,
.nif_ptr = nif_atomvm_get_start_beam
};
static const struct Nif atomvm_read_priv_nif =
{
.base.type = NIFFunctionType,
Expand Down Expand Up @@ -3544,6 +3550,64 @@ static term nif_atomvm_close_avm_pack(Context *ctx, int argc, term argv[])
return OK_ATOM;
}

// AtomVM extension
static term nif_atomvm_get_start_beam(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);
if (UNLIKELY(memory_ensure_free(ctx, TUPLE_SIZE(2)) != MEMORY_GC_OK)) {
RAISE_ERROR(OUT_OF_MEMORY_ATOM);
}
term no_start = globalcontext_make_atom(ctx->global, ATOM_STR("\xD", "no_start_beam"));
term result = term_alloc_tuple(2, &ctx->heap);
term_put_tuple_element(result, 0, ERROR_ATOM);
term_put_tuple_element(result, 1, no_start);
return result;
}

int module_name_len = strlen(module_name);
int needed = TUPLE_SIZE(2) + 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 start_bin = term_from_literal_binary(module_name, module_name_len, &ctx->heap, ctx->global);
term result = term_alloc_tuple(2, &ctx->heap);
term_put_tuple_element(result, 0, OK_ATOM);
term_put_tuple_element(result, 1, start_bin);
synclist_unlock(&ctx->global->avmpack_data);
return result;
}
}
synclist_unlock(&ctx->global->avmpack_data);

if (UNLIKELY(memory_ensure_free(ctx, TUPLE_SIZE(2)) != MEMORY_GC_OK)) {
RAISE_ERROR(OUT_OF_MEMORY_ATOM);
}
term not_found = globalcontext_make_atom(ctx->global, ATOM_STR("\x12", "avm_pack_not_found"));
term result = term_alloc_tuple(2, &ctx->heap);
term_put_tuple_element(result, 0, ERROR_ATOM);
term_put_tuple_element(result, 1, not_found);
return result;
}

// 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_start_beam/1, &atomvm_get_start_beam_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 4d0131b

Please sign in to comment.