Changeset 245634 in webkit for trunk/Source/JavaScriptCore/parser/Lexer.cpp
- Timestamp:
- May 22, 2019, 12:06:03 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/parser/Lexer.cpp
r244038 r245634 814 814 } 815 815 816 template<typename CharacterType> 817 static inline bool isASCIIDigitOrSeparator(CharacterType character) 818 { 819 return isASCIIDigit(character) || character == '_'; 820 } 821 822 template<typename CharacterType> 823 static inline bool isASCIIHexDigitOrSeparator(CharacterType character) 824 { 825 return isASCIIHexDigit(character) || character == '_'; 826 } 827 828 template<typename CharacterType> 829 static inline bool isASCIIBinaryDigitOrSeparator(CharacterType character) 830 { 831 return isASCIIBinaryDigit(character) || character == '_'; 832 } 833 834 template<typename CharacterType> 835 static inline bool isASCIIOctalDigitOrSeparator(CharacterType character) 836 { 837 return isASCIIOctalDigit(character) || character == '_'; 838 } 839 816 840 static inline LChar singleEscape(int c) 817 841 { … … 1491 1515 1492 1516 template <typename T> 1493 ALWAYS_INLINE auto Lexer<T>::parseHex() -> NumberParseResult 1494 { 1517 ALWAYS_INLINE auto Lexer<T>::parseHex() -> Optional<NumberParseResult> 1518 { 1519 ASSERT(isASCIIHexDigit(m_current)); 1520 1495 1521 // Optimization: most hexadecimal values fit into 4 bytes. 1496 1522 uint32_t hexValue = 0; … … 1498 1524 1499 1525 do { 1526 if (m_current == '_') { 1527 if (UNLIKELY(!isASCIIHexDigit(peek(1)))) 1528 return WTF::nullopt; 1529 1530 shift(); 1531 } 1532 1500 1533 hexValue = (hexValue << 4) + toASCIIHexValue(m_current); 1501 1534 shift(); 1502 1535 --maximumDigits; 1503 } while (isASCIIHexDigit (m_current) && maximumDigits >= 0);1536 } while (isASCIIHexDigitOrSeparator(m_current) && maximumDigits >= 0); 1504 1537 1505 1538 if (LIKELY(maximumDigits >= 0 && m_current != 'n')) 1506 return hexValue;1539 return NumberParseResult { hexValue }; 1507 1540 1508 1541 // No more place in the hexValue buffer. … … 1517 1550 } 1518 1551 1519 while (isASCIIHexDigit(m_current)) { 1552 while (isASCIIHexDigitOrSeparator(m_current)) { 1553 if (m_current == '_') { 1554 if (UNLIKELY(!isASCIIHexDigit(peek(1)))) 1555 return WTF::nullopt; 1556 1557 shift(); 1558 } 1559 1520 1560 record8(m_current); 1521 1561 shift(); … … 1523 1563 1524 1564 if (UNLIKELY(Options::useBigInt() && m_current == 'n')) 1525 return makeIdentifier(m_buffer8.data(), m_buffer8.size());1565 return NumberParseResult { makeIdentifier(m_buffer8.data(), m_buffer8.size()) }; 1526 1566 1527 return parseIntOverflow(m_buffer8.data(), m_buffer8.size(), 16);1567 return NumberParseResult { parseIntOverflow(m_buffer8.data(), m_buffer8.size(), 16) }; 1528 1568 } 1529 1569 … … 1531 1571 ALWAYS_INLINE auto Lexer<T>::parseBinary() -> Optional<NumberParseResult> 1532 1572 { 1573 ASSERT(isASCIIBinaryDigit(m_current)); 1574 1533 1575 // Optimization: most binary values fit into 4 bytes. 1534 1576 uint32_t binaryValue = 0; … … 1540 1582 1541 1583 do { 1584 if (m_current == '_') { 1585 if (UNLIKELY(!isASCIIBinaryDigit(peek(1)))) 1586 return WTF::nullopt; 1587 1588 shift(); 1589 } 1590 1542 1591 binaryValue = (binaryValue << 1) + (m_current - '0'); 1543 1592 digits[digit] = m_current; 1544 1593 shift(); 1545 1594 --digit; 1546 } while (isASCIIBinaryDigit (m_current) && digit >= 0);1547 1548 if (LIKELY(!isASCIIDigit (m_current) && digit >= 0 && m_current != 'n'))1549 return Variant<double, const Identifier*>{ binaryValue };1595 } while (isASCIIBinaryDigitOrSeparator(m_current) && digit >= 0); 1596 1597 if (LIKELY(!isASCIIDigitOrSeparator(m_current) && digit >= 0 && m_current != 'n')) 1598 return NumberParseResult { binaryValue }; 1550 1599 1551 1600 for (int i = maximumDigits - 1; i > digit; --i) 1552 1601 record8(digits[i]); 1553 1602 1554 while (isASCIIBinaryDigit(m_current)) { 1603 while (isASCIIBinaryDigitOrSeparator(m_current)) { 1604 if (m_current == '_') { 1605 if (UNLIKELY(!isASCIIBinaryDigit(peek(1)))) 1606 return WTF::nullopt; 1607 1608 shift(); 1609 } 1610 1555 1611 record8(m_current); 1556 1612 shift(); … … 1558 1614 1559 1615 if (UNLIKELY(Options::useBigInt() && m_current == 'n')) 1560 return Variant<double, const Identifier*>{ makeIdentifier(m_buffer8.data(), m_buffer8.size()) };1616 return NumberParseResult { makeIdentifier(m_buffer8.data(), m_buffer8.size()) }; 1561 1617 1562 1618 if (isASCIIDigit(m_current)) 1563 1619 return WTF::nullopt; 1564 1620 1565 return Variant<double, const Identifier*>{ parseIntOverflow(m_buffer8.data(), m_buffer8.size(), 2) };1621 return NumberParseResult { parseIntOverflow(m_buffer8.data(), m_buffer8.size(), 2) }; 1566 1622 } 1567 1623 … … 1569 1625 ALWAYS_INLINE auto Lexer<T>::parseOctal() -> Optional<NumberParseResult> 1570 1626 { 1627 ASSERT(isASCIIOctalDigit(m_current)); 1628 1571 1629 // Optimization: most octal values fit into 4 bytes. 1572 1630 uint32_t octalValue = 0; … … 1578 1636 1579 1637 do { 1638 if (m_current == '_') { 1639 if (UNLIKELY(!isASCIIOctalDigit(peek(1)))) 1640 return WTF::nullopt; 1641 1642 shift(); 1643 } 1644 1580 1645 octalValue = octalValue * 8 + (m_current - '0'); 1581 1646 digits[digit] = m_current; 1582 1647 shift(); 1583 1648 --digit; 1584 } while (isASCIIOctalDigit(m_current) && digit >= 0); 1585 1586 if (LIKELY(!isASCIIDigit(m_current) && digit >= 0 && m_current != 'n')) 1587 return Variant<double, const Identifier*> { octalValue }; 1588 1649 } while (isASCIIOctalDigitOrSeparator(m_current) && digit >= 0); 1650 1651 if (LIKELY(!isASCIIDigitOrSeparator(m_current) && digit >= 0 && m_current != 'n')) 1652 return NumberParseResult { octalValue }; 1589 1653 1590 1654 for (int i = maximumDigits - 1; i > digit; --i) 1591 1655 record8(digits[i]); 1592 1656 1593 while (isASCIIOctalDigit(m_current)) { 1657 while (isASCIIOctalDigitOrSeparator(m_current)) { 1658 if (m_current == '_') { 1659 if (UNLIKELY(!isASCIIOctalDigit(peek(1)))) 1660 return WTF::nullopt; 1661 1662 shift(); 1663 } 1664 1594 1665 record8(m_current); 1595 1666 shift(); … … 1597 1668 1598 1669 if (UNLIKELY(Options::useBigInt() && m_current == 'n')) 1599 return Variant<double, const Identifier*>{ makeIdentifier(m_buffer8.data(), m_buffer8.size()) };1670 return NumberParseResult { makeIdentifier(m_buffer8.data(), m_buffer8.size()) }; 1600 1671 1601 1672 if (isASCIIDigit(m_current)) 1602 1673 return WTF::nullopt; 1603 1674 1604 return Variant<double, const Identifier*>{ parseIntOverflow(m_buffer8.data(), m_buffer8.size(), 8) };1675 return NumberParseResult { parseIntOverflow(m_buffer8.data(), m_buffer8.size(), 8) }; 1605 1676 } 1606 1677 … … 1608 1679 ALWAYS_INLINE auto Lexer<T>::parseDecimal() -> Optional<NumberParseResult> 1609 1680 { 1681 ASSERT(isASCIIDigit(m_current)); 1682 1610 1683 // Optimization: most decimal values fit into 4 bytes. 1611 1684 uint32_t decimalValue = 0; … … 1621 1694 1622 1695 do { 1696 if (m_current == '_') { 1697 if (UNLIKELY(!isASCIIDigit(peek(1)))) 1698 return WTF::nullopt; 1699 1700 shift(); 1701 } 1702 1623 1703 decimalValue = decimalValue * 10 + (m_current - '0'); 1624 1704 digits[digit] = m_current; 1625 1705 shift(); 1626 1706 --digit; 1627 } while (isASCIIDigit (m_current) && digit >= 0);1707 } while (isASCIIDigitOrSeparator(m_current) && digit >= 0); 1628 1708 1629 1709 if (digit >= 0 && m_current != '.' && !isASCIIAlphaCaselessEqual(m_current, 'e') && m_current != 'n') 1630 return Variant<double, const Identifier*>{ decimalValue };1710 return NumberParseResult { decimalValue }; 1631 1711 1632 1712 for (int i = maximumDigits - 1; i > digit; --i) … … 1634 1714 } 1635 1715 1636 while (isASCIIDigit(m_current)) { 1716 while (isASCIIDigitOrSeparator(m_current)) { 1717 if (m_current == '_') { 1718 if (UNLIKELY(!isASCIIDigit(peek(1)))) 1719 return WTF::nullopt; 1720 1721 shift(); 1722 } 1723 1637 1724 record8(m_current); 1638 1725 shift(); … … 1640 1727 1641 1728 if (UNLIKELY(Options::useBigInt() && m_current == 'n')) 1642 return Variant<double, const Identifier*>{ makeIdentifier(m_buffer8.data(), m_buffer8.size()) };1729 return NumberParseResult { makeIdentifier(m_buffer8.data(), m_buffer8.size()) }; 1643 1730 1644 1731 return WTF::nullopt; … … 1646 1733 1647 1734 template <typename T> 1648 ALWAYS_INLINE void Lexer<T>::parseNumberAfterDecimalPoint() 1649 { 1735 ALWAYS_INLINE bool Lexer<T>::parseNumberAfterDecimalPoint() 1736 { 1737 ASSERT(isASCIIDigit(m_current)); 1650 1738 record8('.'); 1651 while (isASCIIDigit(m_current)) { 1739 1740 do { 1741 if (m_current == '_') { 1742 if (UNLIKELY(!isASCIIDigit(peek(1)))) 1743 return false; 1744 1745 shift(); 1746 } 1747 1652 1748 record8(m_current); 1653 1749 shift(); 1654 } 1750 } while (isASCIIDigitOrSeparator(m_current)); 1751 1752 return true; 1655 1753 } 1656 1754 … … 1669 1767 1670 1768 do { 1769 if (m_current == '_') { 1770 if (UNLIKELY(!isASCIIDigit(peek(1)))) 1771 return false; 1772 1773 shift(); 1774 } 1775 1671 1776 record8(m_current); 1672 1777 shift(); 1673 } while (isASCIIDigit(m_current)); 1778 } while (isASCIIDigitOrSeparator(m_current)); 1779 1674 1780 return true; 1675 1781 } … … 2091 2197 break; 2092 2198 } 2093 parseNumberAfterDecimalPoint(); 2199 if (UNLIKELY(!parseNumberAfterDecimalPoint())) { 2200 m_lexErrorMessage = "Non-number found after decimal point"_s; 2201 token = INVALID_NUMERIC_LITERAL_ERRORTOK; 2202 goto returnError; 2203 } 2094 2204 token = DOUBLE; 2095 2205 if (isASCIIAlphaCaselessEqual(m_current, 'e')) { … … 2125 2235 2126 2236 auto parseNumberResult = parseHex(); 2127 if (WTF::holds_alternative<double>(parseNumberResult)) 2128 tokenData->doubleValue = WTF::get<double>(parseNumberResult); 2237 if (!parseNumberResult) 2238 tokenData->doubleValue = 0; 2239 else if (WTF::holds_alternative<double>(*parseNumberResult)) 2240 tokenData->doubleValue = WTF::get<double>(*parseNumberResult); 2129 2241 else { 2130 2242 token = BIGINT; 2131 2243 shift(); 2132 tokenData->bigIntString = WTF::get<const Identifier*>( parseNumberResult);2244 tokenData->bigIntString = WTF::get<const Identifier*>(*parseNumberResult); 2133 2245 tokenData->radix = 16; 2134 2246 } … … 2208 2320 m_buffer8.shrink(0); 2209 2321 break; 2322 } 2323 2324 if (UNLIKELY(m_current == '_')) { 2325 m_lexErrorMessage = "Numeric literals may not begin with 0_"_s; 2326 token = UNTERMINATED_OCTAL_NUMBER_ERRORTOK; 2327 goto returnError; 2210 2328 } 2211 2329 … … 2241 2359 if (m_current == '.') { 2242 2360 shift(); 2243 parseNumberAfterDecimalPoint(); 2361 if (UNLIKELY(isASCIIDigit(m_current) && !parseNumberAfterDecimalPoint())) { 2362 m_lexErrorMessage = "Non-number found after decimal point"_s; 2363 token = INVALID_NUMERIC_LITERAL_ERRORTOK; 2364 goto returnError; 2365 } 2244 2366 token = DOUBLE; 2245 2367 }
Note:
See TracChangeset
for help on using the changeset viewer.