Skip to content

Commit

Permalink
Merge pull request #1047 from UncleGrumpy/send_registered
Browse files Browse the repository at this point in the history
Allow sending messages to registered process with `!`

Enables sending messages to registered processes using the shorthand `!`
operator. If a message is sent to an atom name that is not registered using the
`!` operator a `badarg` run-time error occurs, matching OTP behaviour.

Closes #1011
Closes #98

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
  • Loading branch information
bettio committed Feb 22, 2024
2 parents de832ec + eab4e32 commit e7ac8fc
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed

- ESP32: fix i2c_driver_acquire and i2c_driver_release functions, that were working only once.
- Sending messages to registered processes using the `!` operator now works.
- Fixed bug in `OP_SEND` that would accept sending a message to any integer or term without raising an error.

## [0.6.0-beta.0] - 2024-02-08

Expand Down
13 changes: 12 additions & 1 deletion src/libAtomVM/opcodesswitch.h
Original file line number Diff line number Diff line change
Expand Up @@ -2213,7 +2213,18 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
#endif

#ifdef IMPL_EXECUTE_LOOP
int local_process_id = term_to_local_process_id(x_regs[0]);
term recipient_term = x_regs[0];
int local_process_id;
if (term_is_pid(recipient_term)) {
local_process_id = term_to_local_process_id(recipient_term);
} else if (term_is_atom(recipient_term)) {
local_process_id = globalcontext_get_registered_process(ctx->global, term_to_atom_index(recipient_term));
if (UNLIKELY(local_process_id == 0)) {
RAISE_ERROR(BADARG_ATOM);
}
} else {
RAISE_ERROR(BADARG_ATOM);
}
TRACE("send/0 target_pid=%i\n", local_process_id);
TRACE_SEND(ctx, x_regs[0], x_regs[1]);
globalcontext_send_message(ctx->global, local_process_id, x_regs[1]);
Expand Down
40 changes: 37 additions & 3 deletions tests/erlang_tests/send_receive.erl
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,44 @@
-export([start/0, send_test/2]).

start() ->
Test0 = test_send2(),
Test1 = test_send(),
Test2 = test_send_to_int(),
Test3 = test_non_resitered_name(),
Test0 + Test1 + Test2 + Test3.

send_test(V, P) ->
P ! V.

%priv

%% test send to pid
test_send2() ->
send_test(9, self()),
receive
Value -> Value * 2
Value -> Value
end.

send_test(V, P) ->
P ! V.
%% test send to registered process
test_send() ->
erlang:register(tester, self()),
send_test(6, tester),
receive
RegisteredVal -> RegisteredVal
end.

%% test send to integer
test_send_to_int() ->
try 1 ! 1 of
_Any -> 0
catch
error:badarg -> 2
end.

%% test send to non-registered atom
test_non_resitered_name() ->
try nobody ! test of
_Any -> 0
catch
error:badarg -> 1
end.

0 comments on commit e7ac8fc

Please sign in to comment.