Skip to content

Commit 4f81b85

Browse files
committed
Merge pull request #1751 from pguyot/w28/bs_start_match4-fix-live-usage
OP_BS_MATCH4: fix preservation of src 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
2 parents 5cf5406 + 3f90f10 commit 4f81b85

File tree

5 files changed

+52
-3
lines changed

5 files changed

+52
-3
lines changed

CHANGELOG.md

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

77
## [0.6.7] - Unreleased
88

9+
### Fixed
10+
11+
- Fixed a bug where binary matching could fail due to a missing preservation of the matched binary.
12+
913
## [0.6.6] - 2025-06-23
1014

1115
### Added

src/libAtomVM/opcodesswitch.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6439,15 +6439,17 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
64396439
#endif
64406440
uint32_t live;
64416441
DECODE_LITERAL(live, pc);
6442+
term src;
6443+
DECODE_COMPACT_TERM(src, pc);
64426444
#ifdef IMPL_EXECUTE_LOOP
64436445
TRIM_LIVE_REGS(live);
6446+
x_regs[live] = src;
64446447
// MEMORY_CAN_SHRINK because bs_start_match is classified as gc in beam_ssa_codegen.erl
6445-
if (memory_ensure_free_with_roots(ctx, TERM_BOXED_BIN_MATCH_STATE_SIZE, live, x_regs, MEMORY_CAN_SHRINK) != MEMORY_GC_OK) {
6448+
if (memory_ensure_free_with_roots(ctx, TERM_BOXED_BIN_MATCH_STATE_SIZE, live + 1, x_regs, MEMORY_CAN_SHRINK) != MEMORY_GC_OK) {
64466449
RAISE_ERROR(OUT_OF_MEMORY_ATOM);
64476450
}
6451+
src = x_regs[live];
64486452
#endif
6449-
term src;
6450-
DECODE_COMPACT_TERM(src, pc);
64516453
DEST_REGISTER(dreg);
64526454
DECODE_DEST_REGISTER(dreg, pc);
64536455

tests/erlang_tests/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ compile_erlang(test_ordering_1)
361361
compile_erlang(test_bs)
362362
compile_erlang(test_bs_int)
363363
compile_erlang(test_bs_int_unaligned)
364+
compile_erlang(test_bs_start_match_live)
364365
compile_erlang(test_bs_utf)
365366
compile_erlang(test_catch)
366367
compile_erlang(test_gc)
@@ -851,6 +852,7 @@ add_custom_target(erlang_test_modules DEPENDS
851852
test_bs.beam
852853
test_bs_int.beam
853854
test_bs_int_unaligned.beam
855+
test_bs_start_match_live.beam
854856
test_bs_utf.beam
855857
test_catch.beam
856858
test_gc.beam
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
%
2+
% This file is part of AtomVM.
3+
%
4+
% Copyright 2025 Paul Guyot <pguyot@kallisys.net>
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(test_bs_start_match_live).
22+
23+
-export([start/0, id/1]).
24+
25+
-define(CODE_CHUNK_0,
26+
<<0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, 7, 0, 0, 0, 3, 1, 16, 153, 16, 2, 18, 34, 0,
27+
1, 32, 64, 50, 3, 19, 1, 48, 153, 0, 2, 18, 66, 0, 1, 64, 64, 18, 3, 78, 16, 0, 1, 80, 153,
28+
0, 2, 18, 66, 16, 1, 96, 64, 3, 19, 64, 18, 3, 78, 32, 16, 3>>
29+
).
30+
31+
%% This compiles to:
32+
%% {move,{literal,?CODE_CHUNK_0}, {x, 0}}.
33+
%% {bs_start_match4,{atom,no_fail},0,{x,0},{x,0}}.
34+
%% Live is 0 here, but we need to preserve {x, 0}.
35+
start() ->
36+
<<16:32, 0:32, _OpcodeMax:32, LabelsCount:32, _FunctionsCount:32, _Opcodes/binary>> = ?CODE_CHUNK_0,
37+
7 = id(LabelsCount),
38+
0.
39+
40+
id(X) -> X.

tests/test.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ struct Test tests[] = {
398398
TEST_CASE(test_bs),
399399
TEST_CASE(test_bs_int),
400400
TEST_CASE(test_bs_int_unaligned),
401+
TEST_CASE(test_bs_start_match_live),
401402
TEST_CASE(test_bs_utf),
402403
TEST_CASE(test_catch),
403404
TEST_CASE(test_gc),

0 commit comments

Comments
 (0)