Skip to content

Commit 312f7c6

Browse files
committed
Forward port changes from v0.6 release branch
Merge a number of fixes from release-0.6 into main. Some commits will not add any meaningful change since they are backports from main.
2 parents 7396812 + f30ff07 commit 312f7c6

File tree

15 files changed

+178
-99
lines changed

15 files changed

+178
-99
lines changed

.github/workflows/build-and-test-on-freebsd.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ jobs:
6161
copyback: false
6262

6363
prepare: |
64-
pkg install -y curl cmake gperf erlang elixir rebar3 mbedtls
64+
pkg install -y curl cmake gperf erlang elixir rebar3 mbedtls3
6565
6666
run: |
6767
set -e
@@ -80,6 +80,8 @@ jobs:
8080
echo "**hw.ncpu:**"
8181
sysctl -n hw.ncpu
8282
83+
sed -i '' 's/test_http_server/%test_http_server/g' tests/libs/eavmlib/tests.erl
84+
8385
echo "%%"
8486
echo "%% Running CMake ..."
8587
echo "%%"

.github/workflows/build-and-test-other.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ jobs:
6363

6464
build-and-test-other:
6565
needs: compile_tests
66-
runs-on: ubuntu-24.04
66+
# GCC on qemu segfaults on s390x and arm64v8 when using 24.04
67+
# See also https://github.com/actions/runner-images/issues/11471
68+
runs-on: ubuntu-22.04
6769

6870
strategy:
6971
fail-fast: false
@@ -128,7 +130,7 @@ jobs:
128130
path: build_tests
129131

130132
- name: Set up QEMU
131-
run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
133+
uses: docker/setup-qemu-action@v3
132134

133135
- name: "Build and Test: AtomVM on foreign arch"
134136
timeout-minutes: 15

.github/workflows/stm32-build.yaml

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ jobs:
3232
id: builddeps-cache
3333
with:
3434
path: |
35-
/home/runner/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi
3635
/home/runner/libopencm3
3736
key: ${{ runner.os }}-build-deps
3837

@@ -44,24 +43,23 @@ jobs:
4443
https://repo.hex.pm
4544
https://cdn.jsdelivr.net/hex
4645
46+
- name: "apt update"
47+
run: sudo apt update
48+
49+
- name: "Install deps"
50+
run: sudo apt install -y cmake gperf gcc-arm-none-eabi
51+
4752
- name: Checkout and build libopencm3
4853
if: ${{ steps.builddeps-cache.outputs.cache-hit != 'true' }}
4954
working-directory: /home/runner
5055
run: |
5156
set -euo pipefail
5257
cd /home/runner
5358
test -d libopencm3 && rm -fr libopencm3
54-
export PATH=/home/runner/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin:${PATH}
5559
git clone https://github.com/libopencm3/libopencm3.git -b v0.8.0
5660
cd libopencm3
5761
make
5862
59-
- name: "apt update"
60-
run: sudo apt update
61-
62-
- name: "Install deps"
63-
run: sudo apt install -y cmake gperf gcc-arm-none-eabi
64-
6563
- name: Checkout repo
6664
uses: actions/checkout@v4
6765

@@ -70,7 +68,6 @@ jobs:
7068
working-directory: ./src/platforms/stm32/
7169
run: |
7270
set -euo pipefail
73-
export PATH=/home/runner/arm-gnu-toolchain-11.3.rel1-x86_64-arm-none-eabi/bin:${PATH}
7471
mkdir build
7572
cd build
7673
# -DAVM_WARNINGS_ARE_ERRORS=ON

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@ certain VM instructions are used.
5252
- Fix `network:stop/0` on ESP32 so the network can be started again
5353
- Fix matching of binaries on unaligned boundaries for code compiled with older versions of OTP
5454
- Fix a memory corruption caused by `binary:split/2,3`
55+
- Fix deadlock in socket code
56+
- Fix bug in opcode implementation (`select_val`): when selecting a value among many others a
57+
shallow comparison was performed, so it was working just for plain values such as atoms and small
58+
integers
59+
- Fixed support for setting esp32 boot_path in NVS.
60+
- Fixed race conditions in network:start/stop.
61+
- Fixed crash calling network:sta_rssi(), when network not up.
62+
- Fix error handling when calling `min` and `max` with code compiled before OTP-26: there was a
63+
bug when handling errors from BIFs used as NIFs (when called with `CALL_EXT` and similar opcodes)`
64+
- Fix matching of binaries on unaligned boundaries for code compiled with older versions of OTP
5565

5666
## [0.6.5] - 2024-10-15
5767

doc/src/programmers-guide.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ The configuration map supplied to the logger_manager may contain the following k
466466
| Key | Type | Default| Description |
467467
|-----|------|--------|-------------|
468468
| `log_level` | `log_level()` | `notice` | Primary log level |
469-
| `logger` | `logger_config()` | `{handler, default, logger_std_h, undefined}` | Log configuration |
469+
| `logger` | `logger_config()` | `{handler, default, logger_std_h, #{}}` | Log configuration |
470470
| `module_level` | `module_level()` | `undefined` | Log level specific to a set of modules |
471471

472472
where `log_level()` is defined to be:

libs/eavmlib/rebar.config

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,18 @@
1818
% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
1919
%
2020

21-
{erl_opts, [debug_info]}.
21+
{erl_opts, [debug_info, {i, "../include"}]}.
2222
{deps, []}.
23-
{plugins, [rebar3_hex]}.
23+
{plugins, [rebar3_hex, rebar3_ex_doc]}.
2424

2525
{shell, [
2626
{apps, [eavmlib]}
2727
]}.
28+
{ex_doc, [
29+
{version, "0.1.0"},
30+
{source_url, "https://github.com/atomvm/AtomVM"},
31+
{extras, []},
32+
{main, "atomvm"},
33+
{output, "doc"},
34+
{api_reference, true}
35+
]}.

libs/eavmlib/src/ledc.erl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,13 @@
4545
stop/3
4646
]).
4747

48-
-include("ledc.hrl").
49-
5048
-type duty_resolution() :: non_neg_integer().
5149
-type duty_resolution_cfg() :: {duty_resolution, duty_resolution()}.
5250
-type freq_hz() :: non_neg_integer().
5351
-type freq_hz_cfg() :: {freq_hz, freq_hz()}.
54-
-type speed_mode() :: ?LEDC_LOW_SPEED_MODE | ?LEDC_HIGH_SPEED_MODE.
52+
-type speed_mode() :: 0 | 1.
53+
%% Speed modes: use `0' for high speed, `1' for low speed.
54+
5555
-type speed_mode_cfg() :: {speed_mode, speed_mode()}.
5656
-type timer_num() :: 0..3.
5757
-type timer_num_cfg() :: {timer_num, timer_num()}.

libs/eavmlib/src/network.erl

Lines changed: 41 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
init/1,
3333
handle_call/3,
3434
handle_cast/2,
35+
handle_continue/2,
3536
handle_info/2,
3637
terminate/2
3738
]).
@@ -270,31 +271,11 @@ wait_for_ap(ApConfig, Timeout) ->
270271
%%-----------------------------------------------------------------------------
271272
-spec start(Config :: network_config()) -> {ok, pid()} | {error, Reason :: term()}.
272273
start(Config) ->
273-
case gen_server:start({local, ?MODULE}, ?MODULE, Config, []) of
274-
{ok, Pid} = R ->
275-
case gen_server:call(Pid, start) of
276-
ok ->
277-
R;
278-
Error ->
279-
Error
280-
end;
281-
Error ->
282-
Error
283-
end.
274+
gen_server:start({local, ?MODULE}, ?MODULE, Config, []).
284275

285276
-spec start_link(Config :: network_config()) -> {ok, pid()} | {error, Reason :: term()}.
286277
start_link(Config) ->
287-
case gen_server:start_link({local, ?MODULE}, ?MODULE, Config, []) of
288-
{ok, Pid} = R ->
289-
case gen_server:call(Pid, start) of
290-
ok ->
291-
R;
292-
Error ->
293-
Error
294-
end;
295-
Error ->
296-
Error
297-
end.
278+
gen_server:start_link({local, ?MODULE}, ?MODULE, Config, []).
298279

299280
%%-----------------------------------------------------------------------------
300281
%% @returns ok, if the network interface was stopped, or {error, Reason} if
@@ -314,13 +295,17 @@ stop() ->
314295
%%-----------------------------------------------------------------------------
315296
-spec sta_rssi() -> {ok, Rssi :: db()} | {error, Reason :: term()}.
316297
sta_rssi() ->
317-
Port = get_port(),
318-
Ref = make_ref(),
319-
Port ! {self(), Ref, rssi},
320-
receive
321-
{Ref, {error, Reason}} -> {error, Reason};
322-
{Ref, {rssi, Rssi}} -> {ok, Rssi};
323-
Other -> {error, Other}
298+
case whereis(network_port) of
299+
undefined ->
300+
{error, network_down};
301+
Port ->
302+
Ref = make_ref(),
303+
Port ! {self(), Ref, rssi},
304+
receive
305+
{Ref, {error, Reason}} -> {error, Reason};
306+
{Ref, {rssi, Rssi}} -> {ok, Rssi};
307+
Other -> {error, Other}
308+
end
324309
end.
325310

326311
%%
@@ -329,28 +314,23 @@ sta_rssi() ->
329314

330315
%% @hidden
331316
init(Config) ->
332-
{ok, #state{config = Config}}.
333-
334-
%% @hidden
335-
handle_call(start, From, #state{config = Config} = State) ->
336317
Port = get_port(),
337318
Ref = make_ref(),
338-
Port ! {self(), Ref, {start, Config}},
339-
wait_start_reply(Ref, From, Port, State);
340-
handle_call(_Msg, _From, State) ->
341-
{reply, {error, unknown_message}, State}.
319+
{ok, #state{config = Config, port = Port, ref = Ref}, {continue, start_port}}.
342320

343-
%% @private
344-
wait_start_reply(Ref, From, Port, State) ->
321+
handle_continue(start_port, #state{config = Config, port = Port, ref = Ref} = State) ->
322+
Port ! {self(), Ref, {start, Config}},
345323
receive
346324
{Ref, ok} ->
347-
gen_server:reply(From, ok),
348-
{noreply, State#state{port = Port, ref = Ref}};
349-
{Ref, {error, Reason} = ER} ->
350-
gen_server:reply(From, {error, Reason}),
351-
{stop, {start_failed, Reason}, ER, State}
325+
{noreply, State};
326+
{Ref, {error, Reason}} ->
327+
{stop, {start_port_failed, Reason}, State}
352328
end.
353329

330+
%% @hidden
331+
handle_call(_Msg, _From, State) ->
332+
{reply, {error, unknown_message}, State}.
333+
354334
%% @hidden
355335
handle_cast(_Msg, State) ->
356336
{noreply, State}.
@@ -390,10 +370,25 @@ handle_info(Msg, State) ->
390370
{noreply, State}.
391371

392372
%% @hidden
393-
terminate(_Reason, _State) ->
373+
%% Wait for port to be closed
374+
terminate(_Reason, State) ->
394375
Ref = make_ref(),
376+
Port = State#state.port,
377+
PortMonitor = erlang:monitor(port, Port),
395378
network_port ! {?SERVER, Ref, stop},
396-
ok.
379+
wait_for_port_close(PortMonitor, Port).
380+
381+
wait_for_port_close(PortMonitor, Port) ->
382+
receive
383+
{'DOWN', PortMonitor, port, Port, _DownReason} ->
384+
ok;
385+
_Other ->
386+
% Handle unexpected messages if necessary
387+
wait_for_port_close(PortMonitor, Port)
388+
% Timeout after 1 second just in case.
389+
after 1000 ->
390+
{error, timeout}
391+
end.
397392

398393
%%
399394
%% Internal operations

libs/esp32boot/esp32init.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ get_boot_path() ->
8585
undefined ->
8686
"/dev/partition/by-name/main.avm";
8787
Path ->
88-
Path
88+
binary_to_list(Path)
8989
end.
9090

9191
get_start_module() ->

src/libAtomVM/opcodesswitch.h

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,19 +1990,23 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
19901990
// Support compilers < OTP26 that generate CALL_EXT
19911991
// for min/2 and max/2
19921992
const struct Bif *bif = EXPORTED_FUNCTION_TO_BIF(func);
1993+
term return_value;
19931994
switch (arity) {
19941995
case 0:
1995-
x_regs[0] = bif->bif0_ptr(ctx);
1996+
return_value = bif->bif0_ptr(ctx);
19961997
break;
19971998
case 1:
1998-
x_regs[0] = bif->bif1_ptr(ctx, 0, x_regs[0]);
1999+
return_value = bif->bif1_ptr(ctx, 0, x_regs[0]);
19992000
break;
20002001
case 2:
2001-
x_regs[0] = bif->bif2_ptr(ctx, 0, x_regs[0], x_regs[1]);
2002+
return_value = bif->bif2_ptr(ctx, 0, x_regs[0], x_regs[1]);
20022003
break;
20032004
default:
20042005
fprintf(stderr, "Invalid arity %" PRIu32 " for bif\n", arity);
2006+
AVM_ABORT();
20052007
}
2008+
PROCESS_MAYBE_TRAP_RETURN_VALUE_RESTORE_PC(return_value, orig_pc);
2009+
x_regs[0] = return_value;
20062010

20072011
break;
20082012
}
@@ -2090,19 +2094,23 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
20902094
ctx->e += (n_words + 1);
20912095

20922096
const struct Bif *bif = EXPORTED_FUNCTION_TO_BIF(func);
2097+
term return_value;
20932098
switch (arity) {
20942099
case 0:
2095-
x_regs[0] = bif->bif0_ptr(ctx);
2100+
return_value = bif->bif0_ptr(ctx);
20962101
break;
20972102
case 1:
2098-
x_regs[0] = bif->bif1_ptr(ctx, 0, x_regs[0]);
2103+
return_value = bif->bif1_ptr(ctx, 0, x_regs[0]);
20992104
break;
21002105
case 2:
2101-
x_regs[0] = bif->bif2_ptr(ctx, 0, x_regs[0], x_regs[1]);
2106+
return_value = bif->bif2_ptr(ctx, 0, x_regs[0], x_regs[1]);
21022107
break;
21032108
default:
21042109
fprintf(stderr, "Invalid arity %" PRIu32 " for bif\n", arity);
2110+
AVM_ABORT();
21052111
}
2112+
PROCESS_MAYBE_TRAP_RETURN_VALUE_LAST(return_value);
2113+
x_regs[0] = return_value;
21062114

21072115
DO_RETURN();
21082116

@@ -3107,8 +3115,14 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
31073115
#endif
31083116

31093117
#ifdef IMPL_EXECUTE_LOOP
3110-
if (!jump_to_address && (src_value == cmp_value)) {
3111-
jump_to_address = mod->labels[jmp_label];
3118+
if (!jump_to_address) {
3119+
TermCompareResult result = term_compare(
3120+
src_value, cmp_value, TermCompareExact, ctx->global);
3121+
if (result == TermEquals) {
3122+
jump_to_address = mod->labels[jmp_label];
3123+
} else if (UNLIKELY(result == TermCompareMemoryAllocFail)) {
3124+
RAISE_ERROR(OUT_OF_MEMORY_ATOM);
3125+
}
31123126
}
31133127
#endif
31143128
}
@@ -3535,19 +3549,23 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
35353549
// Support compilers < OTP26 that generate CALL_EXT_ONLY
35363550
// for min/2 and max/2
35373551
const struct Bif *bif = EXPORTED_FUNCTION_TO_BIF(func);
3552+
term return_value;
35383553
switch (arity) {
35393554
case 0:
3540-
x_regs[0] = bif->bif0_ptr(ctx);
3555+
return_value = bif->bif0_ptr(ctx);
35413556
break;
35423557
case 1:
3543-
x_regs[0] = bif->bif1_ptr(ctx, 0, x_regs[0]);
3558+
return_value = bif->bif1_ptr(ctx, 0, x_regs[0]);
35443559
break;
35453560
case 2:
3546-
x_regs[0] = bif->bif2_ptr(ctx, 0, x_regs[0], x_regs[1]);
3561+
return_value = bif->bif2_ptr(ctx, 0, x_regs[0], x_regs[1]);
35473562
break;
35483563
default:
35493564
fprintf(stderr, "Invalid arity %" PRIu32 " for bif\n", arity);
3565+
AVM_ABORT();
35503566
}
3567+
PROCESS_MAYBE_TRAP_RETURN_VALUE_LAST(return_value);
3568+
x_regs[0] = return_value;
35513569

35523570
DO_RETURN();
35533571

0 commit comments

Comments
 (0)