@@ -196,6 +196,7 @@ static term nif_code_all_loaded(Context *ctx, int argc, term argv[]);
196196static term nif_code_load_abs (Context * ctx , int argc , term argv []);
197197static term nif_code_load_binary (Context * ctx , int argc , term argv []);
198198static term nif_code_ensure_loaded (Context * ctx , int argc , term argv []);
199+ static term nif_code_get_object_code (Context * ctx , int argc , term argv []);
199200static term nif_code_server_is_loaded (Context * ctx , int argc , term argv []);
200201static term nif_code_server_resume (Context * ctx , int argc , term argv []);
201202#ifndef AVM_NO_JIT
@@ -747,6 +748,11 @@ static const struct Nif code_ensure_loaded_nif = {
747748 .nif_ptr = nif_code_ensure_loaded
748749};
749750
751+ static const struct Nif code_get_object_code_nif = {
752+ .base .type = NIFFunctionType ,
753+ .nif_ptr = nif_code_get_object_code
754+ };
755+
750756static const struct Nif code_server_is_loaded_nif = {
751757 .base .type = NIFFunctionType ,
752758 .nif_ptr = nif_code_server_is_loaded
@@ -5509,6 +5515,48 @@ static term nif_code_ensure_loaded(Context *ctx, int argc, term argv[])
55095515 return result ;
55105516}
55115517
5518+ static term nif_code_get_object_code (Context * ctx , int argc , term argv [])
5519+ {
5520+ UNUSED (argc );
5521+ term module_atom = argv [0 ];
5522+ VALIDATE_VALUE (module_atom , term_is_atom );
5523+
5524+ size_t module_name_len ;
5525+ const uint8_t * module_name = atom_table_get_atom_string (ctx -> global -> atom_table , term_to_atom_index (module_atom ), & module_name_len );
5526+
5527+ size_t filename_len = module_name_len + 6 ;
5528+ char * module_file_name = malloc (filename_len );
5529+ if (IS_NULL_PTR (module_file_name )) {
5530+ return ERROR_ATOM ;
5531+ }
5532+ memcpy (module_file_name , module_name , module_name_len );
5533+ memcpy (module_file_name + module_name_len , ".beam" , 6 );
5534+ Module * module = globalcontext_get_module (ctx -> global , term_to_atom_index (module_atom ));
5535+
5536+ if (UNLIKELY (!module )) {
5537+ free (module_file_name );
5538+ return ERROR_ATOM ;
5539+ }
5540+ size_t result_size = TUPLE_SIZE (3 ) + term_binary_heap_size (module -> binary_size ) + LIST_SIZE (filename_len , 1 );
5541+ if (UNLIKELY (memory_ensure_free_with_roots (ctx , result_size , 1 , & module_atom , MEMORY_CAN_SHRINK ) != MEMORY_GC_OK )) {
5542+ free (module_file_name );
5543+ RAISE_ERROR (OUT_OF_MEMORY_ATOM );
5544+ }
5545+ // Note: this assumes constness of module->binary and could be use-after-free if we allowed changing module bitcode at runtime.
5546+ // TODO: update this code when module unloading will be supported.
5547+ term binary = term_from_literal_binary ((void * ) module -> binary , module -> binary_size , & ctx -> heap , ctx -> global );
5548+ // TODO: this code has to be changed to return the complete path
5549+ term filename_term = term_from_string ((const uint8_t * ) module_file_name , filename_len , & ctx -> heap );
5550+ term result = term_alloc_tuple (3 , & ctx -> heap );
5551+
5552+ term_put_tuple_element (result , 0 , module_atom );
5553+ term_put_tuple_element (result , 1 , binary );
5554+ term_put_tuple_element (result , 2 , filename_term );
5555+
5556+ free (module_file_name );
5557+ return result ;
5558+ }
5559+
55125560static term nif_code_server_is_loaded (Context * ctx , int argc , term argv [])
55135561{
55145562 UNUSED (argc );
0 commit comments