@@ -4750,7 +4750,6 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
4750
4750
}
4751
4751
#endif
4752
4752
4753
- #if MINIMUM_OTP_COMPILER_VERSION <= 25
4754
4753
case OP_BS_MATCH_STRING : {
4755
4754
uint32_t fail ;
4756
4755
DECODE_LABEL (fail , pc )
@@ -4771,58 +4770,67 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
4771
4770
avm_int_t bs_offset = term_get_match_state_offset (src );
4772
4771
term bs_bin = term_get_match_state_binary (src );
4773
4772
4773
+ TRACE ("bs_match_string/4, fail=%u src=%p bits=%u offset=%u\n" , (unsigned ) fail , (void * ) src , (unsigned ) bits , (unsigned ) offset );
4774
+
4774
4775
size_t remaining = 0 ;
4775
4776
const uint8_t * str = module_get_str (mod , offset , & remaining );
4776
4777
if (IS_NULL_PTR (str )) {
4777
4778
TRACE ("bs_match_string: Bad offset in strings table.\n" );
4778
4779
RAISE_ERROR (BADARG_ATOM );
4779
4780
}
4780
4781
4781
- TRACE ("bs_match_string/4, fail=%u src=%p bits=%u offset=%u\n" , (unsigned ) fail , (void * ) src , (unsigned ) bits , (unsigned ) offset );
4782
-
4783
- if (bits % 8 == 0 && bs_offset % 8 == 0 ) {
4784
- avm_int_t bytes = bits / 8 ;
4785
- avm_int_t byte_offset = bs_offset / 8 ;
4786
-
4787
- if (memcmp (term_binary_data (bs_bin ) + byte_offset , str , MIN (remaining , (unsigned int ) bytes )) != 0 ) {
4788
- TRACE ("bs_match_string: failed to match\n" );
4789
- JUMP_TO_ADDRESS (mod -> labels [fail ]);
4790
- }
4782
+ if (term_binary_size (bs_bin ) * 8 - bs_offset < MIN (remaining * 8 , bits )) {
4783
+ TRACE ("bs_match_string: failed to match (binary is shorter)\n" );
4784
+ JUMP_TO_ADDRESS (mod -> labels [fail ]);
4791
4785
} else {
4792
- // Compare unaligned bits
4793
- const uint8_t * bs_str = (const uint8_t * ) term_binary_data (bs_bin ) + (bs_offset / 8 );
4794
- uint8_t bin_bit_offset = 7 - (bs_offset - (8 * (bs_offset / 8 )));
4795
- uint8_t str_bit_offset = 7 ;
4796
- size_t remaining_bits = bits ;
4797
- while (remaining_bits > 0 ) {
4798
- uint8_t str_ch = * str ;
4799
- uint8_t bin_ch = * bs_str ;
4800
- uint8_t str_ch_bit = (str_ch >> str_bit_offset ) & 1 ;
4801
- uint8_t bin_ch_bit = (bin_ch >> bin_bit_offset ) & 1 ;
4802
- if (str_ch_bit ^ bin_ch_bit ) {
4786
+ if (bits % 8 == 0 && bs_offset % 8 == 0 ) {
4787
+ avm_int_t bytes = bits / 8 ;
4788
+ avm_int_t byte_offset = bs_offset / 8 ;
4789
+
4790
+ if (memcmp (term_binary_data (bs_bin ) + byte_offset , str , MIN (remaining , (unsigned int ) bytes )) != 0 ) {
4803
4791
TRACE ("bs_match_string: failed to match\n" );
4804
4792
JUMP_TO_ADDRESS (mod -> labels [fail ]);
4805
- }
4806
- if (str_bit_offset ) {
4807
- str_bit_offset -- ;
4808
4793
} else {
4809
- str_bit_offset = 7 ;
4810
- str ++ ;
4794
+ term_set_match_state_offset (src , bs_offset + bits );
4811
4795
}
4812
- if (bin_bit_offset ) {
4813
- bin_bit_offset -- ;
4814
- } else {
4815
- bin_bit_offset = 7 ;
4816
- bs_str ++ ;
4796
+ } else {
4797
+ // Compare unaligned bits
4798
+ const uint8_t * bs_str = (const uint8_t * ) term_binary_data (bs_bin ) + (bs_offset / 8 );
4799
+ uint8_t bin_bit_offset = 7 - (bs_offset - (8 * (bs_offset / 8 )));
4800
+ uint8_t str_bit_offset = 7 ;
4801
+ size_t remaining_bits = bits ;
4802
+ while (remaining_bits > 0 ) {
4803
+ uint8_t str_ch = * str ;
4804
+ uint8_t bin_ch = * bs_str ;
4805
+ uint8_t str_ch_bit = (str_ch >> str_bit_offset ) & 1 ;
4806
+ uint8_t bin_ch_bit = (bin_ch >> bin_bit_offset ) & 1 ;
4807
+ if (str_ch_bit ^ bin_ch_bit ) {
4808
+ TRACE ("bs_match_string: failed to match\n" );
4809
+ JUMP_TO_ADDRESS (mod -> labels [fail ]);
4810
+ break ;
4811
+ }
4812
+ if (str_bit_offset ) {
4813
+ str_bit_offset -- ;
4814
+ } else {
4815
+ str_bit_offset = 7 ;
4816
+ str ++ ;
4817
+ }
4818
+ if (bin_bit_offset ) {
4819
+ bin_bit_offset -- ;
4820
+ } else {
4821
+ bin_bit_offset = 7 ;
4822
+ bs_str ++ ;
4823
+ }
4824
+ remaining_bits -- ;
4825
+ }
4826
+ if (remaining_bits == 0 ) {
4827
+ term_set_match_state_offset (src , bs_offset + bits );
4817
4828
}
4818
- remaining_bits -- ;
4819
4829
}
4820
4830
}
4821
- term_set_match_state_offset (src , bs_offset + bits );
4822
4831
#endif
4823
4832
break ;
4824
4833
}
4825
- #endif
4826
4834
4827
4835
#if MINIMUM_OTP_COMPILER_VERSION <= 21
4828
4836
case OP_BS_SAVE2 : {
0 commit comments