Changeset 245634 in webkit


Ignore:
Timestamp:
May 22, 2019 12:06:03 PM (5 years ago)
Author:
Ross Kirsling
Message:

[ESNext] Implement support for Numeric Separators
https://bugs.webkit.org/show_bug.cgi?id=196351

Reviewed by Keith Miller.

JSTests:

  • stress/numeric-literal-separators.js: Added.

Add tests for feature.

  • test262/expectations.yaml:

Mark 60 test cases as passing.

Source/JavaScriptCore:

Implement the following proposal, which is now Stage 3:

https://github.com/tc39/proposal-numeric-separator

Specifically, this allows _ to be used as a separator in numeric literals.
It may be inserted arbitrarily without semantic effect, but it may not occur:

  • multiple times in a row
  • at the beginning or end of the literal
  • adjacent to 0x, 0b, 0o, ., e, or n
  • after a leading zero (e.g. 0_123), even in sloppy mode
  • parser/Lexer.cpp:

(JSC::isASCIIDigitOrSeparator): Added.
(JSC::isASCIIHexDigitOrSeparator): Added.
(JSC::isASCIIBinaryDigitOrSeparator): Added.
(JSC::isASCIIOctalDigitOrSeparator): Added.
(JSC::Lexer<T>::parseHex):
(JSC::Lexer<T>::parseBinary):
(JSC::Lexer<T>::parseOctal):
(JSC::Lexer<T>::parseDecimal):
(JSC::Lexer<T>::parseNumberAfterDecimalPoint):
(JSC::Lexer<T>::parseNumberAfterExponentIndicator):
(JSC::Lexer<T>::lexWithoutClearingLineTerminator):

  • parser/Lexer.h:
Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r245622 r245634  
     12019-05-22  Ross Kirsling  <ross.kirsling@sony.com>
     2
     3        [ESNext] Implement support for Numeric Separators
     4        https://bugs.webkit.org/show_bug.cgi?id=196351
     5
     6        Reviewed by Keith Miller.
     7
     8        * stress/numeric-literal-separators.js: Added.
     9        Add tests for feature.
     10
     11        * test262/expectations.yaml:
     12        Mark 60 test cases as passing.
     13
    1142019-05-22  Yusuke Suzuki  <ysuzuki@apple.com>
    215
  • trunk/JSTests/test262/expectations.yaml

    r245406 r245634  
    26012601  default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
    26022602  strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
    2603 test/language/literals/numeric/numeric-separator-literal-bil-bd-nsl-bd.js:
    2604   default: 'SyntaxError: No space between binary literal and identifier'
    2605   strict mode: 'SyntaxError: No space between binary literal and identifier'
    2606 test/language/literals/numeric/numeric-separator-literal-bil-bd-nsl-bds.js:
    2607   default: 'SyntaxError: No space between binary literal and identifier'
    2608   strict mode: 'SyntaxError: No space between binary literal and identifier'
    2609 test/language/literals/numeric/numeric-separator-literal-bil-bds-nsl-bd.js:
    2610   default: 'SyntaxError: No space between binary literal and identifier'
    2611   strict mode: 'SyntaxError: No space between binary literal and identifier'
    2612 test/language/literals/numeric/numeric-separator-literal-bil-bds-nsl-bds.js:
    2613   default: 'SyntaxError: No space between binary literal and identifier'
    2614   strict mode: 'SyntaxError: No space between binary literal and identifier'
    2615 test/language/literals/numeric/numeric-separator-literal-dd-dot-dd-ep-sign-minus-dd-nsl-dd.js:
    2616   default: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2617   strict mode: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2618 test/language/literals/numeric/numeric-separator-literal-dd-dot-dd-ep-sign-minus-dds-nsl-dd.js:
    2619   default: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2620   strict mode: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2621 test/language/literals/numeric/numeric-separator-literal-dd-dot-dd-ep-sign-plus-dd-nsl-dd.js:
    2622   default: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2623   strict mode: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2624 test/language/literals/numeric/numeric-separator-literal-dd-dot-dd-ep-sign-plus-dds-nsl-dd.js:
    2625   default: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2626   strict mode: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2627 test/language/literals/numeric/numeric-separator-literal-dd-nsl-dd-one-of.js:
    2628   default: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2629   strict mode: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2630 test/language/literals/numeric/numeric-separator-literal-dds-dot-dd-nsl-dd-ep-dd.js:
    2631   default: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2632   strict mode: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2633 test/language/literals/numeric/numeric-separator-literal-dds-nsl-dd.js:
    2634   default: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2635   strict mode: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2636 test/language/literals/numeric/numeric-separator-literal-dot-dd-nsl-dd-ep.js:
    2637   default: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2638   strict mode: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2639 test/language/literals/numeric/numeric-separator-literal-dot-dd-nsl-dds-ep.js:
    2640   default: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2641   strict mode: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2642 test/language/literals/numeric/numeric-separator-literal-dot-dds-nsl-dd-ep.js:
    2643   default: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2644   strict mode: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2645 test/language/literals/numeric/numeric-separator-literal-dot-dds-nsl-dds-ep.js:
    2646   default: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2647   strict mode: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2648 test/language/literals/numeric/numeric-separator-literal-hil-hd-nsl-hd.js:
    2649   default: 'SyntaxError: No space between hexadecimal literal and identifier'
    2650   strict mode: 'SyntaxError: No space between hexadecimal literal and identifier'
    2651 test/language/literals/numeric/numeric-separator-literal-hil-hd-nsl-hds.js:
    2652   default: 'SyntaxError: No space between hexadecimal literal and identifier'
    2653   strict mode: 'SyntaxError: No space between hexadecimal literal and identifier'
    2654 test/language/literals/numeric/numeric-separator-literal-hil-hds-nsl-hd.js:
    2655   default: 'SyntaxError: No space between hexadecimal literal and identifier'
    2656   strict mode: 'SyntaxError: No space between hexadecimal literal and identifier'
    2657 test/language/literals/numeric/numeric-separator-literal-hil-hds-nsl-hds.js:
    2658   default: 'SyntaxError: No space between hexadecimal literal and identifier'
    2659   strict mode: 'SyntaxError: No space between hexadecimal literal and identifier'
    2660 test/language/literals/numeric/numeric-separator-literal-hil-od-nsl-od-one-of.js:
    2661   default: 'SyntaxError: No space between hexadecimal literal and identifier'
    2662   strict mode: 'SyntaxError: No space between hexadecimal literal and identifier'
    2663 test/language/literals/numeric/numeric-separator-literal-nzd-nsl-dd-one-of.js:
    2664   default: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2665   strict mode: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2666 test/language/literals/numeric/numeric-separator-literal-nzd-nsl-dd.js:
    2667   default: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2668   strict mode: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2669 test/language/literals/numeric/numeric-separator-literal-nzd-nsl-dds.js:
    2670   default: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2671   strict mode: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2672 test/language/literals/numeric/numeric-separator-literal-oil-od-nsl-od-one-of.js:
    2673   default: 'SyntaxError: No space between octal literal and identifier'
    2674   strict mode: 'SyntaxError: No space between octal literal and identifier'
    2675 test/language/literals/numeric/numeric-separator-literal-oil-od-nsl-od.js:
    2676   default: 'SyntaxError: No space between octal literal and identifier'
    2677   strict mode: 'SyntaxError: No space between octal literal and identifier'
    2678 test/language/literals/numeric/numeric-separator-literal-oil-od-nsl-ods.js:
    2679   default: 'SyntaxError: No space between octal literal and identifier'
    2680   strict mode: 'SyntaxError: No space between octal literal and identifier'
    2681 test/language/literals/numeric/numeric-separator-literal-oil-ods-nsl-od.js:
    2682   default: 'SyntaxError: No space between octal literal and identifier'
    2683   strict mode: 'SyntaxError: No space between octal literal and identifier'
    2684 test/language/literals/numeric/numeric-separator-literal-oil-ods-nsl-ods.js:
    2685   default: 'SyntaxError: No space between octal literal and identifier'
    2686   strict mode: 'SyntaxError: No space between octal literal and identifier'
    2687 test/language/literals/numeric/numeric-separator-literal-sign-minus-dds-nsl-dd.js:
    2688   default: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2689   strict mode: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2690 test/language/literals/numeric/numeric-separator-literal-sign-plus-dds-nsl-dd.js:
    2691   default: 'SyntaxError: No identifiers allowed directly after numeric literal'
    2692   strict mode: 'SyntaxError: No identifiers allowed directly after numeric literal'
    26932603test/language/literals/regexp/named-groups/invalid-dangling-groupname-2-u.js:
    26942604  default: 'Test262: This statement should not be evaluated.'
  • trunk/Source/JavaScriptCore/ChangeLog

    r245622 r245634  
     12019-05-22  Ross Kirsling  <ross.kirsling@sony.com>
     2
     3        [ESNext] Implement support for Numeric Separators
     4        https://bugs.webkit.org/show_bug.cgi?id=196351
     5
     6        Reviewed by Keith Miller.
     7
     8        Implement the following proposal, which is now Stage 3:
     9          https://github.com/tc39/proposal-numeric-separator
     10
     11        Specifically, this allows `_` to be used as a separator in numeric literals.
     12        It may be inserted arbitrarily without semantic effect, but it may not occur:
     13          - multiple times in a row
     14          - at the beginning or end of the literal
     15          - adjacent to `0x`, `0b`, `0o`, `.`, `e`, or `n`
     16          - after a leading zero (e.g. `0_123`), even in sloppy mode
     17
     18        * parser/Lexer.cpp:
     19        (JSC::isASCIIDigitOrSeparator): Added.
     20        (JSC::isASCIIHexDigitOrSeparator): Added.
     21        (JSC::isASCIIBinaryDigitOrSeparator): Added.
     22        (JSC::isASCIIOctalDigitOrSeparator): Added.
     23        (JSC::Lexer<T>::parseHex):
     24        (JSC::Lexer<T>::parseBinary):
     25        (JSC::Lexer<T>::parseOctal):
     26        (JSC::Lexer<T>::parseDecimal):
     27        (JSC::Lexer<T>::parseNumberAfterDecimalPoint):
     28        (JSC::Lexer<T>::parseNumberAfterExponentIndicator):
     29        (JSC::Lexer<T>::lexWithoutClearingLineTerminator):
     30        * parser/Lexer.h:
     31
    1322019-05-22  Yusuke Suzuki  <ysuzuki@apple.com>
    233
  • trunk/Source/JavaScriptCore/parser/Lexer.cpp

    r244038 r245634  
    814814}
    815815
     816template<typename CharacterType>
     817static inline bool isASCIIDigitOrSeparator(CharacterType character)
     818{
     819    return isASCIIDigit(character) || character == '_';
     820}
     821
     822template<typename CharacterType>
     823static inline bool isASCIIHexDigitOrSeparator(CharacterType character)
     824{
     825    return isASCIIHexDigit(character) || character == '_';
     826}
     827
     828template<typename CharacterType>
     829static inline bool isASCIIBinaryDigitOrSeparator(CharacterType character)
     830{
     831    return isASCIIBinaryDigit(character) || character == '_';
     832}
     833
     834template<typename CharacterType>
     835static inline bool isASCIIOctalDigitOrSeparator(CharacterType character)
     836{
     837    return isASCIIOctalDigit(character) || character == '_';
     838}
     839
    816840static inline LChar singleEscape(int c)
    817841{
     
    14911515
    14921516template <typename T>
    1493 ALWAYS_INLINE auto Lexer<T>::parseHex() -> NumberParseResult
    1494 {
     1517ALWAYS_INLINE auto Lexer<T>::parseHex() -> Optional<NumberParseResult>
     1518{
     1519    ASSERT(isASCIIHexDigit(m_current));
     1520
    14951521    // Optimization: most hexadecimal values fit into 4 bytes.
    14961522    uint32_t hexValue = 0;
     
    14981524
    14991525    do {
     1526        if (m_current == '_') {
     1527            if (UNLIKELY(!isASCIIHexDigit(peek(1))))
     1528                return WTF::nullopt;
     1529
     1530            shift();
     1531        }
     1532
    15001533        hexValue = (hexValue << 4) + toASCIIHexValue(m_current);
    15011534        shift();
    15021535        --maximumDigits;
    1503     } while (isASCIIHexDigit(m_current) && maximumDigits >= 0);
     1536    } while (isASCIIHexDigitOrSeparator(m_current) && maximumDigits >= 0);
    15041537
    15051538    if (LIKELY(maximumDigits >= 0 && m_current != 'n'))
    1506         return hexValue;
     1539        return NumberParseResult { hexValue };
    15071540
    15081541    // No more place in the hexValue buffer.
     
    15171550    }
    15181551
    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
    15201560        record8(m_current);
    15211561        shift();
     
    15231563
    15241564    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()) };
    15261566   
    1527     return parseIntOverflow(m_buffer8.data(), m_buffer8.size(), 16);
     1567    return NumberParseResult { parseIntOverflow(m_buffer8.data(), m_buffer8.size(), 16) };
    15281568}
    15291569
     
    15311571ALWAYS_INLINE auto Lexer<T>::parseBinary() -> Optional<NumberParseResult>
    15321572{
     1573    ASSERT(isASCIIBinaryDigit(m_current));
     1574
    15331575    // Optimization: most binary values fit into 4 bytes.
    15341576    uint32_t binaryValue = 0;
     
    15401582
    15411583    do {
     1584        if (m_current == '_') {
     1585            if (UNLIKELY(!isASCIIBinaryDigit(peek(1))))
     1586                return WTF::nullopt;
     1587
     1588            shift();
     1589        }
     1590
    15421591        binaryValue = (binaryValue << 1) + (m_current - '0');
    15431592        digits[digit] = m_current;
    15441593        shift();
    15451594        --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 };
    15501599
    15511600    for (int i = maximumDigits - 1; i > digit; --i)
    15521601        record8(digits[i]);
    15531602
    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
    15551611        record8(m_current);
    15561612        shift();
     
    15581614
    15591615    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()) };
    15611617
    15621618    if (isASCIIDigit(m_current))
    15631619        return WTF::nullopt;
    15641620
    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) };
    15661622}
    15671623
     
    15691625ALWAYS_INLINE auto Lexer<T>::parseOctal() -> Optional<NumberParseResult>
    15701626{
     1627    ASSERT(isASCIIOctalDigit(m_current));
     1628
    15711629    // Optimization: most octal values fit into 4 bytes.
    15721630    uint32_t octalValue = 0;
     
    15781636
    15791637    do {
     1638        if (m_current == '_') {
     1639            if (UNLIKELY(!isASCIIOctalDigit(peek(1))))
     1640                return WTF::nullopt;
     1641
     1642            shift();
     1643        }
     1644
    15801645        octalValue = octalValue * 8 + (m_current - '0');
    15811646        digits[digit] = m_current;
    15821647        shift();
    15831648        --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 };
    15891653
    15901654    for (int i = maximumDigits - 1; i > digit; --i)
    15911655         record8(digits[i]);
    15921656
    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
    15941665        record8(m_current);
    15951666        shift();
     
    15971668
    15981669    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()) };
    16001671
    16011672    if (isASCIIDigit(m_current))
    16021673        return WTF::nullopt;
    16031674
    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) };
    16051676}
    16061677
     
    16081679ALWAYS_INLINE auto Lexer<T>::parseDecimal() -> Optional<NumberParseResult>
    16091680{
     1681    ASSERT(isASCIIDigit(m_current));
     1682
    16101683    // Optimization: most decimal values fit into 4 bytes.
    16111684    uint32_t decimalValue = 0;
     
    16211694
    16221695        do {
     1696            if (m_current == '_') {
     1697                if (UNLIKELY(!isASCIIDigit(peek(1))))
     1698                    return WTF::nullopt;
     1699
     1700                shift();
     1701            }
     1702
    16231703            decimalValue = decimalValue * 10 + (m_current - '0');
    16241704            digits[digit] = m_current;
    16251705            shift();
    16261706            --digit;
    1627         } while (isASCIIDigit(m_current) && digit >= 0);
     1707        } while (isASCIIDigitOrSeparator(m_current) && digit >= 0);
    16281708
    16291709        if (digit >= 0 && m_current != '.' && !isASCIIAlphaCaselessEqual(m_current, 'e') && m_current != 'n')
    1630             return Variant<double, const Identifier*> { decimalValue };
     1710            return NumberParseResult { decimalValue };
    16311711
    16321712        for (int i = maximumDigits - 1; i > digit; --i)
     
    16341714    }
    16351715
    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
    16371724        record8(m_current);
    16381725        shift();
     
    16401727   
    16411728    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()) };
    16431730
    16441731    return WTF::nullopt;
     
    16461733
    16471734template <typename T>
    1648 ALWAYS_INLINE void Lexer<T>::parseNumberAfterDecimalPoint()
    1649 {
     1735ALWAYS_INLINE bool Lexer<T>::parseNumberAfterDecimalPoint()
     1736{
     1737    ASSERT(isASCIIDigit(m_current));
    16501738    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
    16521748        record8(m_current);
    16531749        shift();
    1654     }
     1750    } while (isASCIIDigitOrSeparator(m_current));
     1751
     1752    return true;
    16551753}
    16561754
     
    16691767
    16701768    do {
     1769        if (m_current == '_') {
     1770            if (UNLIKELY(!isASCIIDigit(peek(1))))
     1771                return false;
     1772
     1773            shift();
     1774        }
     1775
    16711776        record8(m_current);
    16721777        shift();
    1673     } while (isASCIIDigit(m_current));
     1778    } while (isASCIIDigitOrSeparator(m_current));
     1779
    16741780    return true;
    16751781}
     
    20912197            break;
    20922198        }
    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        }
    20942204        token = DOUBLE;
    20952205        if (isASCIIAlphaCaselessEqual(m_current, 'e')) {
     
    21252235
    21262236            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);
    21292241            else {
    21302242                token = BIGINT;
    21312243                shift();
    2132                 tokenData->bigIntString = WTF::get<const Identifier*>(parseNumberResult);
     2244                tokenData->bigIntString = WTF::get<const Identifier*>(*parseNumberResult);
    21332245                tokenData->radix = 16;
    21342246            }
     
    22082320            m_buffer8.shrink(0);
    22092321            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;
    22102328        }
    22112329
     
    22412359                    if (m_current == '.') {
    22422360                        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                        }
    22442366                        token = DOUBLE;
    22452367                    }
  • trunk/Source/JavaScriptCore/parser/Lexer.h

    r244038 r245634  
    180180   
    181181    using NumberParseResult = Variant<double, const Identifier*>;
    182     ALWAYS_INLINE NumberParseResult parseHex();
     182    ALWAYS_INLINE Optional<NumberParseResult> parseHex();
    183183    ALWAYS_INLINE Optional<NumberParseResult> parseBinary();
    184184    ALWAYS_INLINE Optional<NumberParseResult> parseOctal();
    185185    ALWAYS_INLINE Optional<NumberParseResult> parseDecimal();
    186     ALWAYS_INLINE void parseNumberAfterDecimalPoint();
     186    ALWAYS_INLINE bool parseNumberAfterDecimalPoint();
    187187    ALWAYS_INLINE bool parseNumberAfterExponentIndicator();
    188188    ALWAYS_INLINE bool parseMultilineComment();
Note: See TracChangeset for help on using the changeset viewer.