Skip to content

Commit e368b0e

Browse files
committed
Forward port changes from v0.6 release branch
Merge fixes for bnot support to boxed integers (#1743) and stacktrace with OP_APPLY_LAST (#1758).
2 parents eadb7da + 38d2fca commit e368b0e

File tree

7 files changed

+93
-5
lines changed

7 files changed

+93
-5
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8080

8181
- Fixed a bug where binary matching could fail due to a missing preservation of the matched binary.
8282
- Fixed a bug where `lists:seq/2` wouldn't return the empty list in valid cases.
83+
- bnot operator wasn't supporting boxed integers (integers bigger than 28-bit on 32-bit CPUs, and
84+
bigger than 60-bit on 64-bit CPUs).
8385

8486
### Changed
8587

src/libAtomVM/bif.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1473,6 +1473,34 @@ term bif_erlang_bsr_2(Context *ctx, uint32_t fail_label, int live, term arg1, te
14731473
return bitshift_helper(ctx, fail_label, live, arg1, arg2, bsr);
14741474
}
14751475

1476+
static term bnot_boxed_helper(Context *ctx, uint32_t fail_label, uint32_t live, term arg1)
1477+
{
1478+
if (term_is_boxed_integer(arg1)) {
1479+
switch (term_boxed_size(arg1)) {
1480+
case 0:
1481+
//BUG
1482+
AVM_ABORT();
1483+
1484+
case 1: {
1485+
avm_int_t val = term_unbox_int(arg1);
1486+
return make_boxed_int(ctx, fail_label, live, ~val);
1487+
}
1488+
1489+
#if BOXED_TERMS_REQUIRED_FOR_INT64 == 2
1490+
case 2: {
1491+
avm_int64_t val = term_unbox_int64(arg1);
1492+
return make_boxed_int64(ctx, fail_label, live, ~val);
1493+
}
1494+
#endif
1495+
default:
1496+
RAISE_ERROR_BIF(fail_label, OVERFLOW_ATOM);
1497+
}
1498+
} else {
1499+
TRACE("error: arg1: 0x%lx\n", arg1);
1500+
RAISE_ERROR_BIF(fail_label, BADARITH_ATOM);
1501+
}
1502+
}
1503+
14761504
term bif_erlang_bnot_1(Context *ctx, uint32_t fail_label, int live, term arg1)
14771505
{
14781506
UNUSED(live);
@@ -1481,7 +1509,7 @@ term bif_erlang_bnot_1(Context *ctx, uint32_t fail_label, int live, term arg1)
14811509
return ~arg1 | TERM_INTEGER_TAG;
14821510

14831511
} else {
1484-
RAISE_ERROR_BIF(fail_label, BADARITH_ATOM);
1512+
return bnot_boxed_helper(ctx, fail_label, live, arg1);
14851513
}
14861514
}
14871515

src/libAtomVM/opcodesswitch.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5302,13 +5302,13 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
53025302
READ_ANY_XREG(function, arity + 1);
53035303
TRACE("apply_last/1, module=%lu, function=%lu arity=%i deallocate=%i\n", module, function, arity, n_words);
53045304

5305-
ctx->cp = ctx->e[n_words];
5306-
ctx->e += (n_words + 1);
5307-
53085305
if (UNLIKELY(!term_is_atom(module) || !term_is_atom(function))) {
53095306
RAISE_ERROR(BADARG_ATOM);
53105307
}
53115308

5309+
ctx->cp = ctx->e[n_words];
5310+
ctx->e += (n_words + 1);
5311+
53125312
atom_index_t module_name = term_to_atom_index(module);
53135313
atom_index_t function_name = term_to_atom_index(function);
53145314

tests/erlang_tests/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ compile_erlang(literal_test0)
345345
compile_erlang(literal_test1)
346346
compile_erlang(literal_test2)
347347
compile_erlang(test_extended_literal_large)
348+
compile_erlang(bnot64)
348349

349350
compile_erlang(test_list_eq)
350351
compile_erlang(test_tuple_eq)
@@ -864,6 +865,8 @@ add_custom_target(erlang_test_modules DEPENDS
864865
literal_test2.beam
865866
test_extended_literal_large.beam
866867

868+
bnot64.beam
869+
867870
test_list_eq.beam
868871
test_tuple_eq.beam
869872
test_tuple_list_eq.beam

tests/erlang_tests/bnot64.erl

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
%
2+
% This file is part of AtomVM.
3+
%
4+
% Copyright 2025 Davide Bettio <davide@uninstall.it>
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(bnot64).
22+
-export([start/0, mybnot/1, id/1]).
23+
24+
start() ->
25+
-16#7AFECAFF = ?MODULE:mybnot(?MODULE:id(16#7AFECAFE)),
26+
16#7AFECAFD = ?MODULE:mybnot(?MODULE:id(-16#7AFECAFE)),
27+
-16#CAFECAFF = ?MODULE:mybnot(?MODULE:id(16#CAFECAFE)),
28+
16#CAFECAFD = ?MODULE:mybnot(?MODULE:id(-16#CAFECAFE)),
29+
-16#7AFECAFE12345679 = ?MODULE:mybnot(?MODULE:id(16#7AFECAFE12345678)),
30+
16#7AFECAFE12345677 = ?MODULE:mybnot(?MODULE:id(-16#7AFECAFE12345678)),
31+
0.
32+
33+
mybnot(I) when is_integer(I) ->
34+
bnot ?MODULE:id(I);
35+
mybnot(X) ->
36+
{error, X}.
37+
38+
id(X) ->
39+
X.

tests/erlang_tests/fail_apply_last.erl

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,25 @@ try_apply_last(M, F) ->
5353
try
5454
?MODULE:do_apply0(M, F)
5555
catch
56-
_Class:_Reason -> 1
56+
_Class:_Reason:Stack ->
57+
test_stacktrace(Stack, false, false, 1)
5758
end.
5859

5960
pad_some_calls() ->
6061
X = 1,
6162
Y = 2,
6263
Z = X + Y,
6364
Z.
65+
66+
% if try_apply_last/2 is in stacktrace, we also want do_apply0/2
67+
test_stacktrace([], _, _, R) ->
68+
R;
69+
test_stacktrace([{?MODULE, try_apply_last, 2, _} | T], false, DoApply0, R) ->
70+
test_stacktrace(T, true, DoApply0, R - 1);
71+
test_stacktrace([{?MODULE, do_apply0, 2, _} | T], TryApplyLast, false, R) ->
72+
test_stacktrace(T, TryApplyLast, true, R + 1);
73+
test_stacktrace([_ | T], TryApplyLast, DoApply0, R) ->
74+
test_stacktrace(T, TryApplyLast, DoApply0, R);
75+
test_stacktrace(undefined, _, _, R) ->
76+
% AVM_CREATE_STACKTRACES=off
77+
R.

tests/test.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,8 @@ struct Test tests[] = {
379379
TEST_CASE(literal_test2),
380380
TEST_CASE(test_extended_literal_large),
381381

382+
TEST_CASE(bnot64),
383+
382384
TEST_CASE_EXPECTED(test_list_eq, 1),
383385
TEST_CASE_EXPECTED(test_tuple_eq, 1),
384386
TEST_CASE_EXPECTED(test_tuple_list_eq, 1),

0 commit comments

Comments
 (0)