Changeset 66375 in webkit for trunk/JavaScriptCore/parser/Lexer.cpp
- Timestamp:
- Aug 30, 2010, 1:24:40 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/parser/Lexer.cpp
r66135 r66375 536 536 } 537 537 538 ALWAYS_INLINE void Lexer::parseHex(double& returnValue) 539 { 540 // Optimization: most hexadecimal values fit into 4 bytes. 541 uint32_t hexValue = 0; 542 int maximumDigits = 7; 543 544 // Shift out the 'x' prefix. 545 shift(); 546 547 do { 548 hexValue = (hexValue << 4) + toASCIIHexValue(m_current); 549 shift(); 550 --maximumDigits; 551 } while (isASCIIHexDigit(m_current) && maximumDigits >= 0); 552 553 if (maximumDigits >= 0) { 554 returnValue = hexValue; 555 return; 556 } 557 558 // No more place in the hexValue buffer. 559 // The values are shifted out and placed into the m_buffer8 vector. 560 for (int i = 0; i < 8; ++i) { 561 int digit = hexValue >> 28; 562 if (digit < 10) 563 record8(digit + '0'); 564 else 565 record8(digit - 10 + 'a'); 566 hexValue <<= 4; 567 } 568 569 while (isASCIIHexDigit(m_current)) { 570 record8(m_current); 571 shift(); 572 } 573 574 returnValue = parseIntOverflow(m_buffer8.data(), m_buffer8.size(), 16); 575 } 576 577 ALWAYS_INLINE bool Lexer::parseOctal(double& returnValue) 578 { 579 // Optimization: most octal values fit into 4 bytes. 580 uint32_t octalValue = 0; 581 int maximumDigits = 9; 582 // Temporary buffer for the digits. Makes easier 583 // to reconstruct the input characters when needed. 584 char digits[10]; 585 586 do { 587 octalValue = octalValue * 8 + (m_current - '0'); 588 digits[maximumDigits] = m_current; 589 shift(); 590 --maximumDigits; 591 } while (isASCIIOctalDigit(m_current) && maximumDigits >= 0); 592 593 if (!isASCIIDigit(m_current) && maximumDigits >= 0) { 594 returnValue = octalValue; 595 return true; 596 } 597 598 for (int i = 9; i > maximumDigits; --i) 599 record8(digits[i]); 600 601 while (isASCIIOctalDigit(m_current)) { 602 record8(m_current); 603 shift(); 604 } 605 606 if (isASCIIDigit(m_current)) 607 return false; 608 609 returnValue = parseIntOverflow(m_buffer8.data(), m_buffer8.size(), 8); 610 return true; 611 } 612 613 ALWAYS_INLINE bool Lexer::parseDecimal(double& returnValue) 614 { 615 // Optimization: most decimal values fit into 4 bytes. 616 uint32_t decimalValue = 0; 617 618 // Since parseOctal may be executed before parseDecimal, 619 // the m_buffer8 may hold ascii digits. 620 if (!m_buffer8.size()) { 621 int maximumDigits = 9; 622 // Temporary buffer for the digits. Makes easier 623 // to reconstruct the input characters when needed. 624 char digits[10]; 625 626 do { 627 decimalValue = decimalValue * 10 + (m_current - '0'); 628 digits[maximumDigits] = m_current; 629 shift(); 630 --maximumDigits; 631 } while (isASCIIDigit(m_current) && maximumDigits >= 0); 632 633 if (maximumDigits >= 0 && m_current != '.' && (m_current | 0x20) != 'e') { 634 returnValue = decimalValue; 635 return true; 636 } 637 638 for (int i = 9; i > maximumDigits; --i) 639 record8(digits[i]); 640 } 641 642 while (isASCIIDigit(m_current)) { 643 record8(m_current); 644 shift(); 645 } 646 647 return false; 648 } 649 650 ALWAYS_INLINE void Lexer::parseNumberAfterDecimalPoint() 651 { 652 record8('.'); 653 while (isASCIIDigit(m_current)) { 654 record8(m_current); 655 shift(); 656 } 657 } 658 659 ALWAYS_INLINE bool Lexer::parseNumberAfterExponentIndicator() 660 { 661 record8('e'); 662 shift(); 663 if (m_current == '+' || m_current == '-') { 664 record8(m_current); 665 shift(); 666 } 667 668 if (!isASCIIDigit(m_current)) 669 return false; 670 671 do { 672 record8(m_current); 673 shift(); 674 } while (isASCIIDigit(m_current)); 675 return true; 676 } 677 538 678 JSTokenType Lexer::lex(JSTokenData* lvalp, JSTokenInfo* llocp, LexType lexType) 539 679 { … … 751 891 token = BITOR; 752 892 break; 753 case CharacterDot:754 shift();755 if (isASCIIDigit(m_current)) {756 record8('.');757 goto inNumberAfterDecimalPoint;758 }759 token = DOT;760 break;761 893 case CharacterOpenParen: 762 894 token = OPENPAREN; … … 807 939 token = CLOSEBRACE; 808 940 break; 941 case CharacterDot: 942 shift(); 943 if (!isASCIIDigit(m_current)) { 944 token = DOT; 945 break; 946 } 947 goto inNumberAfterDecimalPoint; 809 948 case CharacterZero: 810 goto startNumberWithZeroDigit; 949 shift(); 950 if ((m_current | 0x20) == 'x' && isASCIIHexDigit(peek(1))) { 951 parseHex(lvalp->doubleValue); 952 token = NUMBER; 953 } else { 954 record8('0'); 955 if (isASCIIOctalDigit(m_current)) { 956 if (parseOctal(lvalp->doubleValue)) 957 token = NUMBER; 958 } 959 } 960 // Fall through into CharacterNumber 811 961 case CharacterNumber: 812 goto startNumber; 962 if (LIKELY(token != NUMBER)) { 963 if (!parseDecimal(lvalp->doubleValue)) { 964 if (m_current == '.') { 965 shift(); 966 inNumberAfterDecimalPoint: 967 parseNumberAfterDecimalPoint(); 968 } 969 if ((m_current | 0x20) == 'e') 970 if (!parseNumberAfterExponentIndicator()) 971 goto returnError; 972 // Null-terminate string for strtod. 973 m_buffer8.append('\0'); 974 lvalp->doubleValue = WTF::strtod(m_buffer8.data(), 0); 975 } 976 token = NUMBER; 977 } 978 979 // No identifiers allowed directly after numeric literal, e.g. "3in" is bad. 980 if (UNLIKELY(isIdentStart(m_current))) 981 goto returnError; 982 m_buffer8.resize(0); 983 m_delimited = false; 984 break; 813 985 case CharacterQuote: 814 986 if (UNLIKELY(!parseString(lvalp))) … … 878 1050 goto start; 879 1051 880 startNumberWithZeroDigit:881 shift();882 if ((m_current | 0x20) == 'x' && isASCIIHexDigit(peek(1))) {883 shift();884 goto inHex;885 }886 if (m_current == '.') {887 record8('0');888 record8('.');889 shift();890 goto inNumberAfterDecimalPoint;891 }892 if ((m_current | 0x20) == 'e') {893 record8('0');894 record8('e');895 shift();896 goto inExponentIndicator;897 }898 if (isASCIIOctalDigit(m_current))899 goto inOctal;900 if (isASCIIDigit(m_current))901 goto startNumber;902 lvalp->doubleValue = 0;903 goto doneNumeric;904 905 inNumberAfterDecimalPoint:906 while (isASCIIDigit(m_current)) {907 record8(m_current);908 shift();909 }910 if ((m_current | 0x20) == 'e') {911 record8('e');912 shift();913 goto inExponentIndicator;914 }915 goto doneNumber;916 917 inExponentIndicator:918 if (m_current == '+' || m_current == '-') {919 record8(m_current);920 shift();921 }922 if (!isASCIIDigit(m_current))923 goto returnError;924 do {925 record8(m_current);926 shift();927 } while (isASCIIDigit(m_current));928 goto doneNumber;929 930 inOctal: {931 do {932 record8(m_current);933 shift();934 } while (isASCIIOctalDigit(m_current));935 if (isASCIIDigit(m_current))936 goto startNumber;937 938 double dval = 0;939 940 const char* end = m_buffer8.end();941 for (const char* p = m_buffer8.data(); p < end; ++p) {942 dval *= 8;943 dval += *p - '0';944 }945 if (dval >= mantissaOverflowLowerBound)946 dval = parseIntOverflow(m_buffer8.data(), end - m_buffer8.data(), 8);947 948 m_buffer8.resize(0);949 950 lvalp->doubleValue = dval;951 goto doneNumeric;952 }953 954 inHex: {955 do {956 record8(m_current);957 shift();958 } while (isASCIIHexDigit(m_current));959 960 double dval = 0;961 962 const char* end = m_buffer8.end();963 for (const char* p = m_buffer8.data(); p < end; ++p) {964 dval *= 16;965 dval += toASCIIHexValue(*p);966 }967 if (dval >= mantissaOverflowLowerBound)968 dval = parseIntOverflow(m_buffer8.data(), end - m_buffer8.data(), 16);969 970 m_buffer8.resize(0);971 972 lvalp->doubleValue = dval;973 goto doneNumeric;974 }975 976 startNumber:977 record8(m_current);978 shift();979 while (isASCIIDigit(m_current)) {980 record8(m_current);981 shift();982 }983 if (m_current == '.') {984 record8('.');985 shift();986 goto inNumberAfterDecimalPoint;987 }988 if ((m_current | 0x20) == 'e') {989 record8('e');990 shift();991 goto inExponentIndicator;992 }993 994 // Fall through into doneNumber.995 996 doneNumber:997 // Null-terminate string for strtod.998 m_buffer8.append('\0');999 lvalp->doubleValue = WTF::strtod(m_buffer8.data(), 0);1000 m_buffer8.resize(0);1001 1002 // Fall through into doneNumeric.1003 1004 doneNumeric:1005 // No identifiers allowed directly after numeric literal, e.g. "3in" is bad.1006 if (UNLIKELY(isIdentStart(m_current)))1007 goto returnError;1008 1009 m_atLineStart = false;1010 m_delimited = false;1011 token = NUMBER;1012 goto returnToken;1013 1014 1052 doneSemicolon: 1015 1053 token = SEMICOLON;
Note:
See TracChangeset
for help on using the changeset viewer.