Skip to content

Commit 84828ec

Browse files
committed
Add erlang node/1 BIF
Implement erlang:node/1 for pid, port, and reference terms.\nAdd coverage for local, external, and badarg cases in test_node. Signed-off-by: Peter M <petermm@gmail.com>
1 parent 7c4cf55 commit 84828ec

File tree

5 files changed

+61
-0
lines changed

5 files changed

+61
-0
lines changed

libs/estdlib/src/erlang.erl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@
158158
length/1,
159159
list_to_float/1,
160160
node/0,
161+
node/1,
161162
round/1,
162163
self/0,
163164
setelement/3,
@@ -1894,6 +1895,17 @@ list_to_float(_String) ->
18941895
node() ->
18951896
erlang:nif_error(undefined).
18961897

1898+
%%-----------------------------------------------------------------------------
1899+
%% @param Item a pid, port, or reference
1900+
%% @returns the node name associated with `Item'
1901+
%% @doc Return the node name for a pid, port, or reference.
1902+
%% Raises `badarg' if `Item' is not a pid, port, or reference.
1903+
%% @end
1904+
%%-----------------------------------------------------------------------------
1905+
-spec node(Item :: pid() | port() | reference()) -> node().
1906+
node(_Item) ->
1907+
erlang:nif_error(undefined).
1908+
18971909
%%-----------------------------------------------------------------------------
18981910
%% @param Number the number to round
18991911
%% @returns `Number' rounded to the nearest integer

src/libAtomVM/bif.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,15 @@ term bif_erlang_node_0(Context *ctx)
104104
return ctx->global->node_name;
105105
}
106106

107+
term bif_erlang_node_1(Context *ctx, uint32_t fail_label, term arg1)
108+
{
109+
if (term_is_pid(arg1) || term_is_port(arg1) || term_is_reference(arg1)) {
110+
return term_is_external(arg1) ? term_get_external_node(arg1) : ctx->global->node_name;
111+
}
112+
113+
RAISE_ERROR_BIF(fail_label, BADARG_ATOM);
114+
}
115+
107116
term bif_erlang_byte_size_1(Context *ctx, uint32_t fail_label, int live, term arg1)
108117
{
109118
UNUSED(live);

src/libAtomVM/bif.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const struct ExportedFunction *bif_registry_get_handler(const char *mfa);
4343

4444
term bif_erlang_self_0(Context *ctx);
4545
term bif_erlang_node_0(Context *ctx);
46+
term bif_erlang_node_1(Context *ctx, uint32_t fail_label, term arg1);
4647
term bif_erlang_byte_size_1(Context *ctx, uint32_t fail_label, int live, term arg1);
4748
term bif_erlang_bit_size_1(Context *ctx, uint32_t fail_label, int live, term arg1);
4849
term bif_erlang_binary_part_3(Context *ctx, uint32_t fail_label, int live, term arg1, term arg2, term arg3);

src/libAtomVM/bifs.gperf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ struct BifNameAndPtr
4242
%%
4343
erlang:self/0, {.bif.base.type = BIFFunctionType, .bif.bif0_ptr = bif_erlang_self_0}
4444
erlang:node/0, {.bif.base.type = BIFFunctionType, .bif.bif0_ptr = bif_erlang_node_0}
45+
erlang:node/1, {.bif.base.type = BIFFunctionType, .bif.bif1_ptr = bif_erlang_node_1}
4546
erlang:length/1, {.gcbif.base.type = GCBIFFunctionType, .gcbif.gcbif1_ptr = bif_erlang_length_1}
4647
erlang:byte_size/1, {.gcbif.base.type = GCBIFFunctionType, .gcbif.gcbif1_ptr = bif_erlang_byte_size_1}
4748
erlang:bit_size/1, {.gcbif.base.type = GCBIFFunctionType, .gcbif.gcbif1_ptr = bif_erlang_bit_size_1}

tests/erlang_tests/test_node.erl

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ start() ->
3434

3535
test_node_no_distribution() ->
3636
nonode@nohost = node(),
37+
nonode@nohost = node(self()),
38+
nonode@nohost = node(make_ref()),
39+
nonode@nohost = node(external_port(nonode@nohost, 0)),
40+
ok = assert_badarg(fun() -> node(test) end),
41+
ok = assert_badarg(fun() -> node({test, nonode@nohost}) end),
42+
test@test_node = node(external_pid()),
43+
test@test_node = node(external_ref()),
44+
test@test_node = node(external_port(test@test_node, 42)),
3745
ok.
3846

3947
test_node_distribution() ->
@@ -49,6 +57,9 @@ test_node_distribution() ->
4957
true = erlang:setnode(test@test_node, 42),
5058
42 = get_creation(),
5159
test@test_node = node(),
60+
test@test_node = node(self()),
61+
test@test_node = node(make_ref()),
62+
test@test_node = node(external_port(test@test_node, 42)),
5263
NetKernelPid ! quit,
5364
ok =
5465
receive
@@ -83,6 +94,33 @@ get_creation() ->
8394
erts_internal:get_creation()
8495
end.
8596

97+
external_pid() ->
98+
binary_to_term(
99+
<<131, 88, 119, 14, "test@test_node", 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 42>>
100+
).
101+
102+
external_ref() ->
103+
binary_to_term(
104+
<<131, 90, 0, 1, 119, 14, "test@test_node", 42:32, 1:32>>
105+
).
106+
107+
external_port(Node, Creation) ->
108+
term_from_node(Node, fun(NodeBin) ->
109+
binary_to_term(<<131, 120, NodeBin/binary, 43:64, Creation:32>>)
110+
end).
111+
112+
term_from_node(Node, Fun) ->
113+
NodeBin = atom_to_binary(Node, utf8),
114+
Fun(<<119, (byte_size(NodeBin)), NodeBin/binary>>).
115+
116+
assert_badarg(Fun) ->
117+
try
118+
Fun(),
119+
unexpected_success
120+
catch
121+
error:badarg -> ok
122+
end.
123+
86124
sleep(Ms) ->
87125
receive
88126
after Ms -> ok

0 commit comments

Comments
 (0)