1703 {
1704#if defined(__GNUC__) && defined(__BYTE_ORDER__)
1705
1706 ASSERT(details->characters() == 1 ||
1707 (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__));
1708#endif
1709
1710
1712 ASSERT(characters_filled_in < details->characters());
1713 intptr_t characters = details->characters();
1714 int32_t char_mask;
1717 } else {
1719 }
1720 for (intptr_t k = 0; k < elms_->length(); k++) {
1721 TextElement elm = elms_->At(k);
1723 ZoneGrowableArray<uint16_t>* quarks = elm.atom()->data();
1724 for (intptr_t
i = 0;
i < characters &&
i < quarks->length();
i++) {
1725 QuickCheckDetails::Position*
pos =
1726 details->positions(characters_filled_in);
1727 uint16_t c = quarks->At(
i);
1728 if (c > char_mask) {
1729
1730
1731
1732
1733
1734
1735 details->set_cannot_match();
1736 pos->determines_perfectly =
false;
1737 return;
1738 }
1739 if (elm.atom()->ignore_case()) {
1745
1746
1747
1748 pos->mask = char_mask;
1750 pos->determines_perfectly =
true;
1751 } else {
1752 uint32_t common_bits = char_mask;
1753 uint32_t
bits = chars[0];
1754 for (intptr_t j = 1; j <
length; j++) {
1755 uint32_t differing_bits = ((chars[j] & common_bits) ^
bits);
1756 common_bits ^= differing_bits;
1757 bits &= common_bits;
1758 }
1759
1760
1761
1762
1763 uint32_t one_zero = (common_bits | ~char_mask);
1764 if (
length == 2 && ((~one_zero) & ((~one_zero) - 1)) == 0) {
1765 pos->determines_perfectly =
true;
1766 }
1767 pos->mask = common_bits;
1769 }
1770 } else {
1771
1772
1773
1774 pos->mask = char_mask;
1776 pos->determines_perfectly =
true;
1777 }
1778 characters_filled_in++;
1779 ASSERT(characters_filled_in <= details->characters());
1780 if (characters_filled_in == details->characters()) {
1781 return;
1782 }
1783 }
1784 } else {
1785 QuickCheckDetails::Position*
pos =
1786 details->positions(characters_filled_in);
1787 RegExpCharacterClass* tree = elm.char_class();
1788 ZoneGrowableArray<CharacterRange>* ranges = tree->ranges();
1789 ASSERT(!ranges->is_empty());
1792 }
1793 if (tree->is_negated()) {
1794
1795
1796
1797
1800 } else {
1801 intptr_t first_range = 0;
1802 while (ranges->At(first_range).from() > char_mask) {
1803 first_range++;
1804 if (first_range == ranges->length()) {
1805 details->set_cannot_match();
1806 pos->determines_perfectly =
false;
1807 return;
1808 }
1809 }
1810 CharacterRange range = ranges->At(first_range);
1811 uint16_t from = range.from();
1812 uint16_t to = range.to();
1813 if (to > char_mask) {
1814 to = char_mask;
1815 }
1816 uint32_t differing_bits = (from ^ to);
1817
1818
1819 if ((differing_bits & (differing_bits + 1)) == 0 &&
1820 from + differing_bits == to) {
1821 pos->determines_perfectly =
true;
1822 }
1823 uint32_t common_bits = ~SmearBitsRight(differing_bits);
1824 uint32_t
bits = (from & common_bits);
1825 for (intptr_t
i = first_range + 1;
i < ranges->length();
i++) {
1826 CharacterRange range = ranges->At(
i);
1827 uint16_t from = range.from();
1828 uint16_t to = range.to();
1829 if (from > char_mask) continue;
1830 if (to > char_mask) to = char_mask;
1831
1832
1833
1834
1835
1836 pos->determines_perfectly =
false;
1837 uint32_t new_common_bits = (from ^ to);
1838 new_common_bits = ~SmearBitsRight(new_common_bits);
1839 common_bits &= new_common_bits;
1840 bits &= new_common_bits;
1841 uint32_t differing_bits = (from & common_bits) ^
bits;
1842 common_bits ^= differing_bits;
1843 bits &= common_bits;
1844 }
1845 pos->mask = common_bits;
1847 }
1848 characters_filled_in++;
1849 ASSERT(characters_filled_in <= details->characters());
1850 if (characters_filled_in == details->characters()) {
1851 return;
1852 }
1853 }
1854 }
1855 ASSERT(characters_filled_in != details->characters());
1856 if (!details->cannot_match()) {
1858 true);
1859 }
1860}
virtual void GetQuickCheckDetails(QuickCheckDetails *details, RegExpCompiler *compiler, intptr_t characters_filled_in, bool not_at_start)=0
static constexpr int32_t kMaxCodeUnit