Skip to content

Commit 7bb58f2

Browse files
committed
Support creating and matching bitstrings that are in fact binaries (size divisible by 8)
Signed-off-by: Mateusz Front <[email protected]>
1 parent d4877b9 commit 7bb58f2

File tree

1 file changed

+22
-10
lines changed

1 file changed

+22
-10
lines changed

src/libAtomVM/opcodesswitch.h

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5447,20 +5447,21 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
54475447
term bs_bin = term_get_match_state_binary(src);
54485448
avm_int_t bs_offset = term_get_match_state_offset(src);
54495449

5450-
if (unit != 8) {
5451-
TRACE("bs_get_binary2: Unsupported: unit must be 8.\n");
5452-
RAISE_ERROR(UNSUPPORTED_ATOM);
5453-
}
54545450
avm_int_t size_val = 0;
54555451
if (term_is_integer(size)) {
5456-
size_val = term_to_int(size);
5452+
size_val = term_to_int(size) * unit;
5453+
if (size_val % 8) {
5454+
TRACE("bs_get_binary2: Unsupported: size must be divisible by 8, got: %ld\n", size_val);
5455+
RAISE_ERROR(UNSUPPORTED_ATOM);
5456+
}
5457+
size_val = size_val / 8;
54575458
} else if (size == ALL_ATOM) {
54585459
size_val = term_binary_size(bs_bin) - bs_offset / 8;
54595460
} else {
54605461
TRACE("bs_get_binary2: size is neither an integer nor the atom `all`\n");
54615462
RAISE_ERROR(BADARG_ATOM);
54625463
}
5463-
if (bs_offset % unit != 0) {
5464+
if (bs_offset % 8 != 0) {
54645465
TRACE("bs_get_binary2: Unsupported. Offset on binary read must be aligned on byte boundaries.\n");
54655466
RAISE_ERROR(BADARG_ATOM);
54665467
}
@@ -5471,11 +5472,11 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
54715472

54725473
TRACE("bs_get_binary2/7, fail=%u src=%p live=%u unit=%u\n", (unsigned) fail, (void *) bs_bin, (unsigned) live, (unsigned) unit);
54735474

5474-
if ((unsigned int) (bs_offset / unit + size_val) > term_binary_size(bs_bin)) {
5475+
if ((unsigned int) (bs_offset / 8 + size_val) > term_binary_size(bs_bin)) {
54755476
TRACE("bs_get_binary2: insufficient capacity -- bs_offset = %d, size_val = %d\n", (int) bs_offset, (int) size_val);
54765477
JUMP_TO_ADDRESS(mod->labels[fail]);
54775478
} else {
5478-
term_set_match_state_offset(src, bs_offset + size_val * unit);
5479+
term_set_match_state_offset(src, bs_offset + size_val * 8);
54795480

54805481
TRIM_LIVE_REGS(live);
54815482
// there is always room for a MAX_REG + 1 register, used as working register
@@ -6940,7 +6941,12 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
69406941
}
69416942
} else {
69426943
VERIFY_IS_INTEGER(size, "bs_create_bin/6", fail);
6943-
avm_int_t signed_size_value = term_to_int(size);
6944+
avm_int_t signed_size_value = term_to_int(size) * segment_unit;
6945+
if (UNLIKELY(signed_size_value % 8)) {
6946+
TRACE("bs_create_bin/6: Unsupported: size must be dvisible by 8, got: %ld\n", signed_size_value);
6947+
RAISE_ERROR(UNSUPPORTED_ATOM);
6948+
}
6949+
signed_size_value = signed_size_value / 8;
69446950
if (UNLIKELY(signed_size_value < 0)) {
69456951
if (fail == 0) {
69466952
RAISE_ERROR(BADARG_ATOM);
@@ -6957,6 +6963,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
69576963
}
69586964
}
69596965
segment_size = signed_size_value;
6966+
segment_unit = 8;
69606967
}
69616968
break;
69626969
}
@@ -7109,7 +7116,12 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
71097116
TRACE("bs_create_bin/6: size value less than 0: %i\n", (int) signed_size_value);
71107117
RAISE_ERROR(BADARG_ATOM);
71117118
}
7112-
size_value = (size_t) signed_size_value;
7119+
size_value = (size_t) signed_size_value * segment_unit;
7120+
if (UNLIKELY(size_value % 8)) {
7121+
TRACE("bs_create_bin/6: Unsupported: bitstring size (%d) is not evenly divisible by 8\n", (int) size_value);
7122+
RAISE_ERROR(UNSUPPORTED_ATOM);
7123+
}
7124+
size_value = size_value / 8;
71137125
if (size_value > src_size) {
71147126
if (fail == 0) {
71157127
RAISE_ERROR(BADARG_ATOM);

0 commit comments

Comments
 (0)