@@ -4750,7 +4750,6 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
47504750 }
47514751#endif
47524752
4753- #if MINIMUM_OTP_COMPILER_VERSION <= 25
47544753 case OP_BS_MATCH_STRING : {
47554754 uint32_t fail ;
47564755 DECODE_LABEL (fail , pc )
@@ -4771,58 +4770,67 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
47714770 avm_int_t bs_offset = term_get_match_state_offset (src );
47724771 term bs_bin = term_get_match_state_binary (src );
47734772
4773+ TRACE ("bs_match_string/4, fail=%u src=%p bits=%u offset=%u\n" , (unsigned ) fail , (void * ) src , (unsigned ) bits , (unsigned ) offset );
4774+
47744775 size_t remaining = 0 ;
47754776 const uint8_t * str = module_get_str (mod , offset , & remaining );
47764777 if (IS_NULL_PTR (str )) {
47774778 TRACE ("bs_match_string: Bad offset in strings table.\n" );
47784779 RAISE_ERROR (BADARG_ATOM );
47794780 }
47804781
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 ]);
47914785 } 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 ) {
48034791 TRACE ("bs_match_string: failed to match\n" );
48044792 JUMP_TO_ADDRESS (mod -> labels [fail ]);
4805- }
4806- if (str_bit_offset ) {
4807- str_bit_offset -- ;
48084793 } else {
4809- str_bit_offset = 7 ;
4810- str ++ ;
4794+ term_set_match_state_offset (src , bs_offset + bits );
48114795 }
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 );
48174828 }
4818- remaining_bits -- ;
48194829 }
48204830 }
4821- term_set_match_state_offset (src , bs_offset + bits );
48224831 #endif
48234832 break ;
48244833 }
4825- #endif
48264834
48274835#if MINIMUM_OTP_COMPILER_VERSION <= 21
48284836 case OP_BS_SAVE2 : {
0 commit comments