@@ -194,6 +194,7 @@ static term nif_code_all_loaded(Context *ctx, int argc, term argv[]);
194194static term nif_code_load_abs (Context * ctx , int argc , term argv []);
195195static term nif_code_load_binary (Context * ctx , int argc , term argv []);
196196static term nif_code_ensure_loaded (Context * ctx , int argc , term argv []);
197+ static term nif_code_get_object_code (Context * ctx , int argc , term argv []);
197198static term nif_erlang_module_loaded (Context * ctx , int argc , term argv []);
198199static term nif_erlang_nif_error (Context * ctx , int argc , term argv []);
199200static term nif_lists_reverse (Context * ctx , int argc , term argv []);
@@ -730,6 +731,11 @@ static const struct Nif code_ensure_loaded_nif = {
730731 .nif_ptr = nif_code_ensure_loaded
731732};
732733
734+ static const struct Nif code_get_object_code_nif = {
735+ .base .type = NIFFunctionType ,
736+ .nif_ptr = nif_code_get_object_code
737+ };
738+
733739static const struct Nif module_loaded_nif = {
734740 .base .type = NIFFunctionType ,
735741 .nif_ptr = nif_erlang_module_loaded
@@ -5390,6 +5396,52 @@ static term nif_code_ensure_loaded(Context *ctx, int argc, term argv[])
53905396 return result ;
53915397}
53925398
5399+ static term nif_code_get_object_code (Context * ctx , int argc , term argv [])
5400+ {
5401+ UNUSED (argc );
5402+ term module_atom = argv [0 ];
5403+ VALIDATE_VALUE (module_atom , term_is_atom );
5404+
5405+ size_t module_name_len ;
5406+ const uint8_t * module_name = atom_table_get_atom_string (ctx -> global -> atom_table , term_to_atom_index (module_atom ), & module_name_len );
5407+
5408+ size_t filename_len = module_name_len + 6 ;
5409+ char * module_file_name = malloc (filename_len );
5410+ if (IS_NULL_PTR (module_file_name )) {
5411+ return ERROR_ATOM ;
5412+ }
5413+ memcpy (module_file_name , module_name , module_name_len );
5414+ memcpy (module_file_name + module_name_len , ".beam" , 6 );
5415+ Module * module = globalcontext_load_module_from_avm (ctx -> global , module_file_name );
5416+
5417+ if (IS_NULL_PTR (module )) {
5418+ module = sys_load_module_from_file (ctx -> global , module_file_name );
5419+ }
5420+ if (UNLIKELY (!module )) {
5421+ free (module_file_name );
5422+ return ERROR_ATOM ;
5423+ }
5424+
5425+ size_t result_size = TUPLE_SIZE (3 ) + term_binary_heap_size (module -> binary_size ) + LIST_SIZE (filename_len , 1 );
5426+ if (UNLIKELY (memory_ensure_free_with_roots (ctx , result_size , 1 , & module_atom , MEMORY_CAN_SHRINK ) != MEMORY_GC_OK )) {
5427+ free (module_file_name );
5428+ RAISE_ERROR (OUT_OF_MEMORY_ATOM );
5429+ }
5430+ // Note: this assumes constness of module->binary and could be use-after-free if we allowed changing module bitcode at runtime.
5431+ // TODO: update this code when module unloading will be supported.
5432+ term binary = term_from_literal_binary ((void * ) module -> binary , module -> binary_size , & ctx -> heap , ctx -> global );
5433+ // TODO: this code has to be changed to return the complete path
5434+ term filename_term = term_from_string ((const uint8_t * ) module_file_name , filename_len , & ctx -> heap );
5435+ term result = term_alloc_tuple (3 , & ctx -> heap );
5436+
5437+ term_put_tuple_element (result , 0 , module_atom );
5438+ term_put_tuple_element (result , 1 , binary );
5439+ term_put_tuple_element (result , 2 , filename_term );
5440+
5441+ free (module_file_name );
5442+ return result ;
5443+ }
5444+
53935445static term nif_erlang_module_loaded (Context * ctx , int argc , term argv [])
53945446{
53955447 UNUSED (argc );
0 commit comments