Changeset 62628 in webkit for trunk/JavaScriptCore/parser/Lexer.cpp
- Timestamp:
- Jul 7, 2010, 12:04:46 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/parser/Lexer.cpp
r62449 r62628 358 358 case 'r': 359 359 return 0x0D; 360 case '\\': 361 return '\\'; 362 case '\'': 363 return '\''; 364 case '"': 365 return '"'; 360 366 default: 361 return c;367 return 0; 362 368 } 363 369 } … … 380 386 ASSERT(c <= USHRT_MAX); 381 387 record16(UChar(static_cast<unsigned short>(c))); 388 } 389 390 ALWAYS_INLINE bool Lexer::parseString(void* lvalp) 391 { 392 int stringQuoteCharacter = m_current; 393 shift(); 394 395 const UChar* stringStart = currentCharacter(); 396 397 while (m_current != stringQuoteCharacter) { 398 if (UNLIKELY(m_current == '\\')) { 399 if (stringStart != currentCharacter()) 400 m_buffer16.append(stringStart, currentCharacter() - stringStart); 401 shift(); 402 403 int escape = singleEscape(m_current); 404 405 // Most common escape sequences first 406 if (escape) { 407 record16(escape); 408 shift(); 409 } else if (UNLIKELY(isLineTerminator(m_current))) 410 shiftLineTerminator(); 411 else if (m_current == 'x') { 412 shift(); 413 if (isASCIIHexDigit(m_current) && isASCIIHexDigit(peek(1))) { 414 int prev = m_current; 415 shift(); 416 record16(convertHex(prev, m_current)); 417 shift(); 418 } else 419 record16('x'); 420 } else if (m_current == 'u') { 421 shift(); 422 int character = getUnicodeCharacter(); 423 if (character != -1) 424 record16(character); 425 else if (m_current == stringQuoteCharacter) 426 record16('u'); 427 else // Only stringQuoteCharacter allowed after \u 428 return false; 429 } else if (isASCIIOctalDigit(m_current)) { 430 // Octal character sequences 431 int character1 = m_current; 432 shift(); 433 if (isASCIIOctalDigit(m_current)) { 434 // Two octal characters 435 int character2 = m_current; 436 shift(); 437 if (character1 >= '0' && character1 <= '3' && isASCIIOctalDigit(m_current)) { 438 record16((character1 - '0') * 64 + (character2 - '0') * 8 + m_current - '0'); 439 shift(); 440 } else 441 record16((character1 - '0') * 8 + character2 - '0'); 442 } else 443 record16(character1 - '0'); 444 } else if (m_current != -1) { 445 record16(m_current); 446 shift(); 447 } else 448 return false; 449 450 stringStart = currentCharacter(); 451 continue; 452 } else if (UNLIKELY(((static_cast<unsigned>(m_current) - 0xE) & 0x2000))) { 453 // New-line or end of input is not allowed 454 if (UNLIKELY(isLineTerminator(m_current)) || UNLIKELY(m_current == -1)) 455 return false; 456 // Anything else is just a normal character 457 } 458 shift(); 459 } 460 461 if (currentCharacter() != stringStart) 462 m_buffer16.append(stringStart, currentCharacter() - stringStart); 463 reinterpret_cast<YYSTYPE*>(lvalp)->ident = makeIdentifier(m_buffer16.data(), m_buffer16.size()); 464 m_buffer16.resize(0); 465 return true; 382 466 } 383 467 … … 402 486 if (!m_terminator && !m_delimited && !m_isReparsing) { 403 487 // automatic semicolon insertion if program incomplete 404 token = ';';405 488 goto doneSemicolon; 406 489 } … … 409 492 410 493 m_delimited = false; 411 ASSERT(m_current >= 0); 412 413 if (m_current < 128) { 414 ASSERT(isASCII(m_current)); 494 495 if (isASCII(m_current)) { 496 ASSERT(m_current >= 0 && m_current < 128); 415 497 416 498 switch (AsciiCharacters[m_current]) { … … 634 716 goto startNumber; 635 717 case CharacterQuote: 636 goto startString; 718 if (UNLIKELY(!parseString(lvalp))) 719 goto returnError; 720 shift(); 721 m_delimited = false; 722 token = STRING; 723 break; 637 724 case CharacterAlpha: 638 725 ASSERT(isIdentStart(m_current)); … … 656 743 } else { 657 744 // Rare characters 658 ASSERT(!isASCII(m_current));659 745 660 746 if (isNonASCIIIdentStart(m_current)) … … 664 750 m_atLineStart = true; 665 751 m_terminator = true; 666 if (lastTokenWasRestrKeyword()) { 667 token = ';'; 752 if (lastTokenWasRestrKeyword()) 668 753 goto doneSemicolon; 669 }670 754 goto start; 671 755 } … … 675 759 m_atLineStart = false; 676 760 goto returnToken; 677 678 startString: {679 int stringQuoteCharacter = m_current;680 shift();681 682 const UChar* stringStart = currentCharacter();683 while (m_current != stringQuoteCharacter) {684 // Fast check for characters that require special handling.685 // Catches -1, \n, \r, \, 0x2028, and 0x2029 as efficiently686 // as possible, and lets through all common ASCII characters.687 if (UNLIKELY(m_current == '\\') || UNLIKELY(((static_cast<unsigned>(m_current) - 0xE) & 0x2000))) {688 m_buffer16.append(stringStart, currentCharacter() - stringStart);689 goto inString;690 }691 shift();692 }693 lvalp->ident = makeIdentifier(stringStart, currentCharacter() - stringStart);694 shift();695 m_atLineStart = false;696 m_delimited = false;697 token = STRING;698 goto returnToken;699 700 inString:701 while (m_current != stringQuoteCharacter) {702 if (m_current == '\\')703 goto inStringEscapeSequence;704 if (UNLIKELY(isLineTerminator(m_current)))705 goto returnError;706 if (UNLIKELY(m_current == -1))707 goto returnError;708 record16(m_current);709 shift();710 }711 goto doneString;712 713 inStringEscapeSequence:714 shift();715 if (m_current == 'x') {716 shift();717 if (isASCIIHexDigit(m_current) && isASCIIHexDigit(peek(1))) {718 int prev = m_current;719 shift();720 record16(convertHex(prev, m_current));721 shift();722 goto inString;723 }724 record16('x');725 if (m_current == stringQuoteCharacter)726 goto doneString;727 goto inString;728 }729 if (m_current == 'u') {730 shift();731 token = getUnicodeCharacter();732 if (token != -1) {733 record16(token);734 goto inString;735 }736 if (m_current == stringQuoteCharacter) {737 record16('u');738 goto doneString;739 }740 goto returnError;741 }742 if (isASCIIOctalDigit(m_current)) {743 int char1 = m_current;744 shift();745 if (char1 >= '0' && char1 <= '3' && isASCIIOctalDigit(m_current) && isASCIIOctalDigit(peek(1))) {746 int char2 = m_current;747 shift();748 record16((char1 - '0') * 64 + (char2 - '0') * 8 + m_current - '0');749 shift();750 goto inString;751 }752 if (isASCIIOctalDigit(m_current)) {753 record16((char1 - '0') * 8 + m_current - '0');754 shift();755 goto inString;756 }757 record16(char1 - '0');758 goto inString;759 }760 if (isLineTerminator(m_current)) {761 shiftLineTerminator();762 goto inString;763 }764 if (m_current == -1)765 goto returnError;766 record16(singleEscape(m_current));767 shift();768 goto inString;769 }770 761 771 762 startIdentifierWithBackslash: { … … 1004 995 const HashEntry* entry = m_keywordTable.entry(m_globalData, *lvalp->ident); 1005 996 token = entry ? entry->lexerValue() : static_cast<int>(IDENT); 1006 goto returnToken;1007 }1008 1009 doneString:1010 // Atomize constant strings in case they're later used in property lookup.1011 shift();1012 m_atLineStart = false;1013 m_delimited = false;1014 lvalp->ident = makeIdentifier(m_buffer16.data(), m_buffer16.size());1015 m_buffer16.resize(0);1016 token = STRING;1017 997 1018 998 // Fall through into returnToken. 999 } 1019 1000 1020 1001 returnToken: {
Note:
See TracChangeset
for help on using the changeset viewer.