Skip to content

Commit 542d36b

Browse files
committed
Merge pull request #1705 from jgonet/jgonet/module-loaded
Add erlang:module_loaded/1 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
2 parents f629e56 + 897e596 commit 542d36b

File tree

7 files changed

+63
-0
lines changed

7 files changed

+63
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4949
- Added Function.ex and Protocol.ex improving Elixir 1.18 support
5050
- Added WiFi support for ESP32P4 via esp-wifi-external for build with ESP-IDF v5.4 and later
5151
- Added Process.link/1 and unlink/1 to Elixir Process.ex
52+
- Added `erlang:module_loaded/1`
5253

5354
### Changed
5455

libs/estdlib/src/erlang.erl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
erase/0,
5252
erase/1,
5353
function_exported/3,
54+
module_loaded/1,
5455
display/1,
5556
list_to_atom/1,
5657
list_to_existing_atom/1,
@@ -603,6 +604,14 @@ erase(_Key) ->
603604
function_exported(_Module, _Function, _Arity) ->
604605
erlang:nif_error(undefined).
605606

607+
%% @param Module name of module
608+
%% @returns boolean
609+
%% @doc Returns true if module is loaded without attempting to do it.
610+
%% @end
611+
-spec module_loaded(Module :: atom()) -> boolean().
612+
module_loaded(_Module) ->
613+
erlang:nif_error(undefined).
614+
606615
%%-----------------------------------------------------------------------------
607616
%% @param Term term to print
608617
%% @returns `true'

src/libAtomVM/nifs.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ static term nif_code_all_loaded(Context *ctx, int argc, term argv[]);
189189
static term nif_code_load_abs(Context *ctx, int argc, term argv[]);
190190
static term nif_code_load_binary(Context *ctx, int argc, term argv[]);
191191
static term nif_code_ensure_loaded(Context *ctx, int argc, term argv[]);
192+
static term nif_erlang_module_loaded(Context *ctx, int argc, term argv[]);
192193
static term nif_lists_reverse(Context *ctx, int argc, term argv[]);
193194
static term nif_maps_from_keys(Context *ctx, int argc, term argv[]);
194195
static term nif_maps_next(Context *ctx, int argc, term argv[]);
@@ -806,6 +807,13 @@ static const struct Nif code_ensure_loaded_nif =
806807
.base.type = NIFFunctionType,
807808
.nif_ptr = nif_code_ensure_loaded
808809
};
810+
811+
static const struct Nif module_loaded_nif =
812+
{
813+
.base.type = NIFFunctionType,
814+
.nif_ptr = nif_erlang_module_loaded
815+
};
816+
809817
static const struct Nif lists_reverse_nif =
810818
{
811819
.base.type = NIFFunctionType,
@@ -5161,6 +5169,19 @@ static term nif_code_ensure_loaded(Context *ctx, int argc, term argv[])
51615169
return result;
51625170
}
51635171

5172+
static term nif_erlang_module_loaded(Context *ctx, int argc, term argv[])
5173+
{
5174+
UNUSED(argc);
5175+
5176+
term module_atom = argv[0];
5177+
VALIDATE_VALUE(module_atom, term_is_atom);
5178+
5179+
AtomString module_string = globalcontext_atomstring_from_term(ctx->global, module_atom);
5180+
Module *module = (Module *) atomshashtable_get_value(ctx->global->modules_table, module_string, (unsigned long) NULL);
5181+
5182+
return module != NULL ? TRUE_ATOM : FALSE_ATOM;
5183+
}
5184+
51645185
static term nif_lists_reverse(Context *ctx, int argc, term argv[])
51655186
{
51665187
// Compared to erlang version, compute the length of the list and allocate

src/libAtomVM/nifs.gperf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ erlang:setnode/3, &setnode_3_nif
133133
erlang:dist_ctrl_get_data_notification/1, &dist_ctrl_get_data_notification_nif
134134
erlang:dist_ctrl_get_data/1, &dist_ctrl_get_data_nif
135135
erlang:dist_ctrl_put_data/2, &dist_ctrl_put_data_nif
136+
erlang:module_loaded/1,&module_loaded_nif
136137
erts_debug:flat_size/1, &flat_size_nif
137138
ets:new/2, &ets_new_nif
138139
ets:insert/2, &ets_insert_nif

tests/erlang_tests/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,7 @@ compile_erlang(test_add_avm_pack_file)
503503
compile_erlang(test_close_avm_pack)
504504

505505
compile_erlang(test_module_info)
506+
compile_erlang(erlang_module_loaded)
506507

507508
compile_erlang(int64_build_binary)
508509

@@ -996,6 +997,7 @@ add_custom_target(erlang_test_modules DEPENDS
996997
test_close_avm_pack.beam
997998

998999
test_module_info.beam
1000+
erlang_module_loaded.beam
9991001

10001002
int64_build_binary.beam
10011003

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
%
2+
% This file is part of AtomVM.
3+
%
4+
% Copyright 2025 Tomasz Sobkiewicz <tomasz.sobkiewicz@swmansion.com>
5+
%
6+
% Licensed under the Apache License, Version 2.0 (the "License");
7+
% you may not use this file except in compliance with the License.
8+
% You may obtain a copy of the License at
9+
%
10+
% http://www.apache.org/licenses/LICENSE-2.0
11+
%
12+
% Unless required by applicable law or agreed to in writing, software
13+
% distributed under the License is distributed on an "AS IS" BASIS,
14+
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
% See the License for the specific language governing permissions and
16+
% limitations under the License.
17+
%
18+
% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
19+
%
20+
21+
-module(erlang_module_loaded).
22+
23+
-export([start/0]).
24+
25+
start() ->
26+
true = erlang:module_loaded(?MODULE),
27+
false = erlang:module_loaded(undefined_module),
28+
0.

tests/test.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,7 @@ struct Test tests[] = {
542542
TEST_CASE_ATOMVM_ONLY(test_close_avm_pack, 0),
543543

544544
TEST_CASE(test_module_info),
545+
TEST_CASE(erlang_module_loaded),
545546

546547
// noisy tests, keep them at the end
547548
TEST_CASE_EXPECTED(spawn_opt_monitor_normal, 1),

0 commit comments

Comments
 (0)