Skip to content

Conversation

@FKubisSWM
Copy link
Contributor

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


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

@FKubisSWM FKubisSWM changed the title Implement code:get_object_code/1 (#143) Implement code:get_object_code/1 Aug 28, 2025
@FKubisSWM FKubisSWM changed the title Implement code:get_object_code/1 Implement code:get_object_code/1 nif Aug 28, 2025
Copy link
Collaborator

@bettio bettio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code must compile first, after that there are some changes that are required.

Copy link
Collaborator

@bettio bettio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a small change that is still required. Also, "Run tests with BEAM" is really important for us, so CI must be green also for all those tests.
What we got:

Raised {badmatch,error}, stacktrace:
[{test_code_get_object_code,get_object_from_export_test_module,0,
                            [{file,"/Users/runner/work/AtomVM/AtomVM/tests/erlang_tests/test_code_get_object_code.erl"},
                             {line,52}]},
 {test_code_get_object_code,start,0,
test_code_get_object_code:
test_code_get_object_code:FAILED
                            [{file,"/Users/runner/work/AtomVM/AtomVM/tests/erlang_tests/test_code_get_object_code.erl"},
                             {line,28}]},
 {erl_eval,do_apply,7,[{file,"erl_eval.erl"},{line,746}]},
 {erl_eval,try_clauses,10,[{file,"erl_eval.erl"},{line,1052}]},
 {erl_eval,expr,6,[{file,"erl_eval.erl"},{line,494}]},
 {erl_eval,exprs,6,[{file,"erl_eval.erl"},{line,136}]},
 {init,start_it,1,[]},
 {init,start_em,1,[]}]

const uint8_t *filename;
size_t filename_len;
uint32_t line;
if (LIKELY(module_find_line(module, module->line_refs_offsets[0], &line, &filename_len, &filename))) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This requires debug information to be available, that it is frequently true, but not mandatory. And making this function work according to debug info availability might be counter intuitive.
If you know module name, you can just return module_name <> ".beam".
This is not 100% correct, but the correct solution would be tracking where the file has been loaded from, and standardizing how to refer to .beam files stored into .avm, that is some other work (not that much).
So I suggest leaving a TODO that just says that code has to be changed to return the complete path, not just the beam file name.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, code:get_object_code/1 returns the path of the beam when it was loaded into the VM, which is unrelated to whatever path is stored in the beam itself. We can start with ModuleName ++ ".beam" (it's not a binary but a list), and if it adds anything useful, we could at some point put the path of the avm or the partition.

I also wonder if we really need this nif and if returning error is not sufficient. It seems that BEAM returns error if a module is loaded from a binary with code:load_binary/3 and doesn't return the path passed to this function (which is what I would have expected).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the code according to beam behaviour.
It seems like only either code:add_path or initial module loading causes code:get_object_code to return the tuple, otherwise it returns error.
I think we had to implement this function for popcorn needs because some of the stdlib modules used it to check if there is a loaded module as far as i remember.

Copy link
Collaborator

@bettio bettio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI is still failing since code is not compiling on certain platforms / compiler versions due to some missing cast. Let's fix build error and squash everything.
This is the compile error I'm talking about:

[  2%] Building C object src/platforms/generic_unix/libAtomVM/CMakeFiles/libAtomVM.dir/nifs.c.o
/home/runner/work/AtomVM/AtomVM/src/libAtomVM/nifs.c:5379:43: error: passing 'char *' to parameter of type 'const uint8_t *' (aka 'const unsigned char *') converts between pointers to integer types where one is of the unique plain 'char' type and the other is not [-Werror,-Wpointer-sign]
 5379 |     term filename_term = term_from_string(module_file_name, filename_len, &ctx->heap);
      |                                           ^~~~~~~~~~~~~~~~
/home/runner/work/AtomVM/AtomVM/src/libAtomVM/term.h:1747:52: note: passing argument to parameter 'data' here
 1747 | static inline term term_from_string(const uint8_t *data, uint16_t size, Heap *heap)
      |                                                    ^
1 error generated.

@FKubisSWM FKubisSWM force-pushed the fkubis/implement-code-get-object-code branch 9 times, most recently from 23036aa to 0d96986 Compare September 25, 2025 10:34
Copy link
Collaborator

@bettio bettio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything looks good, let's do git commit --amend --signoff so DCO CI step will be green as well.

@FKubisSWM FKubisSWM force-pushed the fkubis/implement-code-get-object-code branch 2 times, most recently from 981c5e6 to c4bc515 Compare October 2, 2025 06:38
bettio added a commit to bettio/AtomVM-fork that referenced this pull request Oct 2, 2025
…et-object-code

Implement code:get_object_code/1 nif

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
}
memcpy(module_file_name, module_name, module_name_len);
memcpy(module_file_name + module_name_len, ".beam", 6);
Module *module = globalcontext_load_module_from_avm(ctx->global, module_file_name);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should use globalcontext_get_module instead as here you are replacing the existing module with another copy. We don't support hot code reloading yet and bad things definitely happens when JIT is enabled. But even if we did, we don't want to reload a new module everytime this nif is called.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that OTP version of get_object_code function checks for the loaded code in the file system. Thats why the test:

get_object_from_export_test_module() ->
    Bin = ?EXPORT_TEST_MODULE_DATA,
    error = code:get_object_code(export_test_module),
    {module, export_test_module} = code:load_binary(
        export_test_module, "export_test_module.beam", Bin
    ),
    {module, export_test_module} = code:ensure_loaded(export_test_module),
    error = code:get_object_code(export_test_module),
    24 = export_test_module:exported_func(4),
    ok.

fails on error = code:get_object_code(export_test_module), in AVM (badmatch) for modules loaded with code:load_binary/3.
The same test is successful in beam.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I skip BEAM testing for this one, or rather implement sys_get_module_file (which would try to open beam file in file system) function in every sys.c (+ sys.h) and use it in get_object_code/1?

@FKubisSWM FKubisSWM force-pushed the fkubis/implement-code-get-object-code branch from c4bc515 to 8160928 Compare October 6, 2025 07:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants