Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change port call tuple format #998

Merged
merged 1 commit into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `1`, which now they are deprecated)
- New atom table, which uses less memory, has improved performances and better code.
- SPI: when gpio number is not provided for `miso` or `mosi` default to disabled
- Change port call tuple format to the same format as gen_server, so casts can be supported too

### Fixed

Expand Down
4 changes: 3 additions & 1 deletion UPDATING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@

# AtomVM Update Instructions

## v0.6.0-alpha.1 -> v0.6.0-beta.0
## v0.6.0-alpha.2 -> v0.6.0-beta.0

- Registers are no longer preserved by GC by default when invoking nifs, as part of the fix
of interpretation of the emulator of the live parameter of many opcodes. NIFs may need
to call `memory_ensure_free_with_roots` and pass their arguments are roots, instead of
`memory_ensure_free` or `memory_ensure_free_opt`.
- Port call message tuple format has been changed, hence previous version of the standard library
cannot be used. **Libraries (or boot .avm file) from latest version must be used**.

## v0.6.0-alpha.0 -> v0.6.0-alpha.1

Expand Down
2 changes: 1 addition & 1 deletion libs/eavmlib/src/port.erl
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ call(Port, Message) ->
-spec call(pid(), Message :: term(), Timeout :: timeout()) -> term() | {error, timeout}.
call(Port, Message, Timeout) ->
MonitorRef = monitor(port, Port),
Port ! {self(), MonitorRef, Message},
Port ! {'$call', {self(), MonitorRef}, Message},
Result =
receive
{'DOWN', MonitorRef, port, Port, normal} ->
Expand Down
6 changes: 6 additions & 0 deletions src/libAtomVM/defaultatoms.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ static const char *const bounded_free_atom = "\xC" "bounded_free";
static const char *const minimum_atom = "\x7" "minimum";
static const char *const fibonacci_atom = "\x9" "fibonacci";

static const char *const call_atom = "\x5" "$call";
static const char *const cast_atom = "\x5" "$cast";

void defaultatoms_init(GlobalContext *glb)
{
int ok = 1;
Expand Down Expand Up @@ -294,6 +297,9 @@ void defaultatoms_init(GlobalContext *glb)
ok &= globalcontext_insert_atom(glb, minimum_atom) == MINIMUM_ATOM_INDEX;
ok &= globalcontext_insert_atom(glb, fibonacci_atom) == FIBONACCI_ATOM_INDEX;

ok &= globalcontext_insert_atom(glb, call_atom) == CALL_ATOM_INDEX;
ok &= globalcontext_insert_atom(glb, cast_atom) == CAST_ATOM_INDEX;

if (!ok) {
AVM_ABORT();
}
Expand Down
8 changes: 7 additions & 1 deletion src/libAtomVM/defaultatoms.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,10 @@ extern "C" {
#define MINIMUM_ATOM_INDEX 106
#define FIBONACCI_ATOM_INDEX 107

#define PLATFORM_ATOMS_BASE_INDEX 108
#define CALL_ATOM_INDEX 108
#define CAST_ATOM_INDEX 109

#define PLATFORM_ATOMS_BASE_INDEX 110

#define FALSE_ATOM TERM_FROM_ATOM_INDEX(FALSE_ATOM_INDEX)
#define TRUE_ATOM TERM_FROM_ATOM_INDEX(TRUE_ATOM_INDEX)
Expand Down Expand Up @@ -303,6 +306,9 @@ extern "C" {
#define MINIMUM_ATOM TERM_FROM_ATOM_INDEX(MINIMUM_ATOM_INDEX)
#define FIBONACCI_ATOM TERM_FROM_ATOM_INDEX(FIBONACCI_ATOM_INDEX)

#define CALL_ATOM TERM_FROM_ATOM_INDEX(CALL_ATOM_INDEX)
#define CAST_ATOM TERM_FROM_ATOM_INDEX(CAST_ATOM_INDEX)

void defaultatoms_init(GlobalContext *glb);

void platform_defaultatoms_init(GlobalContext *glb);
Expand Down
18 changes: 14 additions & 4 deletions src/libAtomVM/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,17 +111,27 @@ enum GenMessageParseResult port_parse_gen_message(term msg, GenMessage *gen_mess
return GenMessageParseError;
}

gen_message->pid = term_get_tuple_element(msg, 0);
if (UNLIKELY(!term_is_pid(gen_message->pid))) {
// right now we support just $call
term message_type = term_get_tuple_element(msg, 0);
if (UNLIKELY(message_type != CALL_ATOM)) {
return GenMessageParseError;
}

gen_message->ref = term_get_tuple_element(msg, 1);
if (UNLIKELY(!term_is_reference(gen_message->ref))) {
term from = term_get_tuple_element(msg, 1);
if (UNLIKELY(!term_is_tuple(from) || term_get_tuple_arity(from) != 2)) {
return GenMessageParseError;
}

gen_message->req = term_get_tuple_element(msg, 2);

gen_message->pid = term_get_tuple_element(from, 0);
if (UNLIKELY(!term_is_pid(gen_message->pid))) {
return GenMessageParseError;
}
gen_message->ref = term_get_tuple_element(from, 1);
if (UNLIKELY(!term_is_reference(gen_message->ref))) {
return GenMessageParseError;
}

return GenCallMessage;
}
27 changes: 18 additions & 9 deletions src/platforms/esp32/test/main/test_erl_sources/test_socket.erl
Original file line number Diff line number Diff line change
Expand Up @@ -329,12 +329,21 @@ tcp_client(Active, Port) ->
call(DriverPid, Msg) ->
call(DriverPid, Msg, 5000).

call(DriverPid, Msg, Timeout) ->
Ref = erlang:make_ref(),
DriverPid ! {self(), Ref, Msg},
receive
{Ref, Ret} ->
Ret
after Timeout ->
{driver_call, Msg, timeout}
end.
call(Port, Message, Timeout) ->
MonitorRef = monitor(port, Port),
Port ! {'$call', {self(), MonitorRef}, Message},
Result =
receive
{'DOWN', MonitorRef, port, Port, normal} ->
{error, noproc};
{'DOWN', MonitorRef, port, Port, Reason} ->
{error, Reason};
out_of_memory ->
out_of_memory;
{MonitorRef, Ret} ->
Ret
after Timeout ->
{error, timeout}
end,
demonitor(MonitorRef, [flush]),
Result.
2 changes: 1 addition & 1 deletion tests/erlang_tests/hello_world.erl
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ do_open_port(PortName, Param) ->

write(Console, String) ->
Ref = make_ref(),
Console ! {self(), Ref, {puts, String}},
Console ! {'$call', {self(), Ref}, {puts, String}},
receive
{Ref, ReturnStatus} ->
ReturnStatus
Expand Down
Loading