Skip to content

Commit 0f858c6

Browse files
committed
BIFs: bnot: add support to boxed integers
bnot was missing support to boxed integers, so it wasn't supporting integers > 28 bits on 32 bit systems, and > 60 bits on 64 bit systems. Signed-off-by: Davide Bettio <davide@uninstall.it>
1 parent c462803 commit 0f858c6

File tree

5 files changed

+75
-1
lines changed

5 files changed

+75
-1
lines changed

CHANGELOG.md

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

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

1921
### Changed
2022

src/libAtomVM/bif.c

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

1375+
static term bnot_boxed_helper(Context *ctx, uint32_t fail_label, uint32_t live, term arg1)
1376+
{
1377+
if (term_is_boxed_integer(arg1)) {
1378+
switch (term_boxed_size(arg1)) {
1379+
case 0:
1380+
//BUG
1381+
AVM_ABORT();
1382+
1383+
case 1: {
1384+
avm_int_t val = term_unbox_int(arg1);
1385+
return make_boxed_int(ctx, fail_label, live, ~val);
1386+
}
1387+
1388+
#if BOXED_TERMS_REQUIRED_FOR_INT64 == 2
1389+
case 2: {
1390+
avm_int64_t val = term_unbox_int64(arg1);
1391+
return make_boxed_int64(ctx, fail_label, live, ~val);
1392+
}
1393+
#endif
1394+
default:
1395+
RAISE_ERROR_BIF(fail_label, OVERFLOW_ATOM);
1396+
}
1397+
} else {
1398+
TRACE("error: arg1: 0x%lx\n", arg1);
1399+
RAISE_ERROR_BIF(fail_label, BADARITH_ATOM);
1400+
}
1401+
}
1402+
13751403
term bif_erlang_bnot_1(Context *ctx, uint32_t fail_label, int live, term arg1)
13761404
{
13771405
UNUSED(live);
@@ -1380,7 +1408,7 @@ term bif_erlang_bnot_1(Context *ctx, uint32_t fail_label, int live, term arg1)
13801408
return ~arg1 | TERM_INTEGER_TAG;
13811409

13821410
} else {
1383-
RAISE_ERROR_BIF(fail_label, BADARITH_ATOM);
1411+
return bnot_boxed_helper(ctx, fail_label, live, arg1);
13841412
}
13851413
}
13861414

tests/erlang_tests/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ compile_erlang(literal_test0)
337337
compile_erlang(literal_test1)
338338
compile_erlang(literal_test2)
339339
compile_erlang(test_extended_literal_large)
340+
compile_erlang(bnot64)
340341

341342
compile_erlang(test_list_eq)
342343
compile_erlang(test_tuple_eq)
@@ -839,6 +840,8 @@ add_custom_target(erlang_test_modules DEPENDS
839840
literal_test2.beam
840841
test_extended_literal_large.beam
841842

843+
bnot64.beam
844+
842845
test_list_eq.beam
843846
test_tuple_eq.beam
844847
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/test.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,8 @@ struct Test tests[] = {
371371
TEST_CASE(literal_test2),
372372
TEST_CASE(test_extended_literal_large),
373373

374+
TEST_CASE(bnot64),
375+
374376
TEST_CASE_EXPECTED(test_list_eq, 1),
375377
TEST_CASE_EXPECTED(test_tuple_eq, 1),
376378
TEST_CASE_EXPECTED(test_tuple_list_eq, 1),

0 commit comments

Comments
 (0)