Ignore:
Timestamp:
Jun 28, 2010, 1:17:13 PM (15 years ago)
Author:
[email protected]
Message:

Only one character lookahead should be enough for the lexer
https://bugs.webkit.org/show_bug.cgi?id=41213

Reviewed by Oliver Hunt.

The lexer had 4 character lookahead before, which required
a complex shifting mechanism. This can be improved by using
only one character lookahead for most decisions, and a
peek() function as a fallback when it is absolutely necessary.

  • parser/Lexer.cpp:

(JSC::Lexer::currentCharacter):
(JSC::Lexer::currentOffset):
(JSC::Lexer::setCode):
(JSC::Lexer::shift):
(JSC::Lexer::peek):
(JSC::Lexer::getUnicodeCharacter):
(JSC::Lexer::shiftLineTerminator):
(JSC::Lexer::lastTokenWasRestrKeyword):
(JSC::Lexer::lex):
(JSC::Lexer::scanRegExp):
(JSC::Lexer::skipRegExp):

  • parser/Lexer.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/parser/Lexer.cpp

    r61878 r62031  
    33 *  Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All Rights Reserved.
    44 *  Copyright (C) 2007 Cameron Zwarich ([email protected])
     5 *  Copyright (C) 2010 Zoltan Herczeg ([email protected])
    56 *
    67 *  This library is free software; you can redistribute it and/or
     
    5960}
    6061
    61 inline const UChar* Lexer::currentCharacter() const
    62 {
    63     return m_code - 4;
    64 }
    65 
    66 inline int Lexer::currentOffset() const
     62ALWAYS_INLINE const UChar* Lexer::currentCharacter() const
     63{
     64    ASSERT(m_code <= m_codeEnd);
     65    return m_code;
     66}
     67
     68ALWAYS_INLINE int Lexer::currentOffset() const
    6769{
    6870    return currentCharacter() - m_codeStart;
    69 }
    70 
    71 ALWAYS_INLINE void Lexer::shift1()
    72 {
    73     m_current = m_next1;
    74     m_next1 = m_next2;
    75     m_next2 = m_next3;
    76     if (LIKELY(m_code < m_codeEnd))
    77         m_next3 = m_code[0];
    78     else
    79         m_next3 = -1;
    80 
    81     ++m_code;
    82 }
    83 
    84 ALWAYS_INLINE void Lexer::shift2()
    85 {
    86     m_current = m_next2;
    87     m_next1 = m_next3;
    88     if (LIKELY(m_code + 1 < m_codeEnd)) {
    89         m_next2 = m_code[0];
    90         m_next3 = m_code[1];
    91     } else {
    92         m_next2 = m_code < m_codeEnd ? m_code[0] : -1;
    93         m_next3 = -1;
    94     }
    95 
    96     m_code += 2;
    97 }
    98 
    99 ALWAYS_INLINE void Lexer::shift3()
    100 {
    101     m_current = m_next3;
    102     if (LIKELY(m_code + 2 < m_codeEnd)) {
    103         m_next1 = m_code[0];
    104         m_next2 = m_code[1];
    105         m_next3 = m_code[2];
    106     } else {
    107         m_next1 = m_code < m_codeEnd ? m_code[0] : -1;
    108         m_next2 = m_code + 1 < m_codeEnd ? m_code[1] : -1;
    109         m_next3 = -1;
    110     }
    111 
    112     m_code += 3;
    113 }
    114 
    115 ALWAYS_INLINE void Lexer::shift4()
    116 {
    117     if (LIKELY(m_code + 3 < m_codeEnd)) {
    118         m_current = m_code[0];
    119         m_next1 = m_code[1];
    120         m_next2 = m_code[2];
    121         m_next3 = m_code[3];
    122     } else {
    123         m_current = m_code < m_codeEnd ? m_code[0] : -1;
    124         m_next1 = m_code + 1 < m_codeEnd ? m_code[1] : -1;
    125         m_next2 = m_code + 2 < m_codeEnd ? m_code[2] : -1;
    126         m_next3 = -1;
    127     }
    128 
    129     m_code += 4;
    13071}
    13172
     
    161102    }
    162103
    163     // Read the first characters into the 4-character buffer.
    164     shift4();
     104    if (LIKELY(m_code < m_codeEnd))
     105        m_current = *m_code;
     106    else
     107        m_current = -1;
    165108    ASSERT(currentOffset() == source.startOffset());
    166109}
     
    185128}
    186129
     130ALWAYS_INLINE void Lexer::shift()
     131{
     132    // Faster than an if-else sequence
     133    ASSERT(m_current != -1);
     134    m_current = -1;
     135    ++m_code;
     136    if (LIKELY(m_code < m_codeEnd))
     137        m_current = *m_code;
     138}
     139
     140ALWAYS_INLINE int Lexer::peek(int offset)
     141{
     142    // Only use if necessary
     143    ASSERT(offset > 0 && offset < 5);
     144    const UChar* code = m_code + offset;
     145    return (code < m_codeEnd) ? *code : -1;
     146}
     147
     148int Lexer::getUnicodeCharacter()
     149{
     150    int char1 = peek(1);
     151    int char2 = peek(2);
     152    int char3 = peek(3);
     153
     154    if (UNLIKELY(!isASCIIHexDigit(m_current) || !isASCIIHexDigit(char1) || !isASCIIHexDigit(char2) || !isASCIIHexDigit(char3)))
     155        return -1;
     156
     157    int result = convertUnicode(m_current, char1, char2, char3);
     158    shift();
     159    shift();
     160    shift();
     161    shift();
     162    return result;
     163}
     164
    187165void Lexer::shiftLineTerminator()
    188166{
    189167    ASSERT(isLineTerminator(m_current));
    190168
     169    int m_prev = m_current;
     170    shift();
     171
    191172    // Allow both CRLF and LFCR.
    192     if (m_current + m_next1 == '\n' + '\r')
    193         shift2();
    194     else
    195         shift1();
     173    if (m_prev + m_current == '\n' + '\r')
     174        shift();
    196175
    197176    ++m_lineNumber;
     
    203182}
    204183
    205 inline bool Lexer::lastTokenWasRestrKeyword() const
     184ALWAYS_INLINE bool Lexer::lastTokenWasRestrKeyword() const
    206185{
    207186    return m_lastToken == CONTINUE || m_lastToken == BREAK || m_lastToken == RETURN || m_lastToken == THROW;
     
    281260start:
    282261    while (isWhiteSpace(m_current))
    283         shift1();
     262        shift();
    284263
    285264    int startOffset = currentOffset();
     
    296275    m_delimited = false;
    297276    switch (m_current) {
    298         case '>':
    299             if (m_next1 == '>' && m_next2 == '>') {
    300                 if (m_next3 == '=') {
    301                     shift4();
     277    case '>':
     278        shift();
     279        if (m_current == '>') {
     280            shift();
     281            if (m_current == '>') {
     282                shift();
     283                if (m_current == '=') {
     284                    shift();
    302285                    token = URSHIFTEQUAL;
    303286                    break;
    304287                }
    305                 shift3();
    306288                token = URSHIFT;
    307289                break;
    308290            }
    309             if (m_next1 == '>') {
    310                 if (m_next2 == '=') {
    311                     shift3();
    312                     token = RSHIFTEQUAL;
    313                     break;
    314                 }
    315                 shift2();
    316                 token = RSHIFT;
     291            if (m_current == '=') {
     292                shift();
     293                token = RSHIFTEQUAL;
    317294                break;
    318295            }
    319             if (m_next1 == '=') {
    320                 shift2();
    321                 token = GE;
     296            token = RSHIFT;
     297            break;
     298        }
     299        if (m_current == '=') {
     300            shift();
     301            token = GE;
     302            break;
     303        }
     304        token = '>';
     305        break;
     306    case '=':
     307        shift();
     308        if (m_current == '=') {
     309            shift();
     310            if (m_current == '=') {
     311                shift();
     312                token = STREQ;
    322313                break;
    323314            }
    324             shift1();
    325             token = '>';
    326             break;
    327         case '=':
    328             if (m_next1 == '=') {
    329                 if (m_next2 == '=') {
    330                     shift3();
    331                     token = STREQ;
    332                     break;
    333                 }
    334                 shift2();
    335                 token = EQEQ;
     315            token = EQEQ;
     316            break;
     317        }
     318        token = '=';
     319        break;
     320    case '!':
     321        shift();
     322        if (m_current == '=') {
     323            shift();
     324            if (m_current == '=') {
     325                shift();
     326                token = STRNEQ;
    336327                break;
    337328            }
    338             shift1();
    339             token = '=';
    340             break;
    341         case '!':
    342             if (m_next1 == '=') {
    343                 if (m_next2 == '=') {
    344                     shift3();
    345                     token = STRNEQ;
    346                     break;
    347                 }
    348                 shift2();
    349                 token = NE;
     329            token = NE;
     330            break;
     331        }
     332        token = '!';
     333        break;
     334    case '<':
     335        shift();
     336        if (m_current == '!' && peek(1) == '-' && peek(2) == '-') {
     337            // <!-- marks the beginning of a line comment (for www usage)
     338            goto inSingleLineComment;
     339        }
     340        if (m_current == '<') {
     341            shift();
     342            if (m_current == '=') {
     343                shift();
     344                token = LSHIFTEQUAL;
    350345                break;
    351346            }
    352             shift1();
    353             token = '!';
    354             break;
    355         case '<':
    356             if (m_next1 == '!' && m_next2 == '-' && m_next3 == '-') {
    357                 // <!-- marks the beginning of a line comment (for www usage)
    358                 shift4();
     347            token = LSHIFT;
     348            break;
     349        }
     350        if (m_current == '=') {
     351            shift();
     352            token = LE;
     353            break;
     354        }
     355        token = '<';
     356        break;
     357    case '+':
     358        shift();
     359        if (m_current == '+') {
     360            shift();
     361            token = (!m_terminator) ? PLUSPLUS : AUTOPLUSPLUS;
     362            break;
     363        }
     364        if (m_current == '=') {
     365            shift();
     366            token = PLUSEQUAL;
     367            break;
     368        }
     369        token = '+';
     370        break;
     371    case '-':
     372        shift();
     373        if (m_current == '-') {
     374            shift();
     375            if (m_atLineStart && m_current == '>') {
     376                shift();
    359377                goto inSingleLineComment;
    360378            }
    361             if (m_next1 == '<') {
    362                 if (m_next2 == '=') {
    363                     shift3();
    364                     token = LSHIFTEQUAL;
    365                     break;
    366                 }
    367                 shift2();
    368                 token = LSHIFT;
    369                 break;
     379            token = (!m_terminator) ? MINUSMINUS : AUTOMINUSMINUS;
     380            break;
     381        }
     382        if (m_current == '=') {
     383            shift();
     384            token = MINUSEQUAL;
     385            break;
     386        }
     387        token = '-';
     388        break;
     389    case '*':
     390        shift();
     391        if (m_current == '=') {
     392            shift();
     393            token = MULTEQUAL;
     394            break;
     395        }
     396        token = '*';
     397        break;
     398    case '/':
     399        shift();
     400        if (m_current == '/') {
     401            shift();
     402            goto inSingleLineComment;
     403        }
     404        if (m_current == '*') {
     405            shift();
     406            goto inMultiLineComment;
     407        }
     408        if (m_current == '=') {
     409            shift();
     410            token = DIVEQUAL;
     411            break;
     412        }
     413        token = '/';
     414        break;
     415    case '&':
     416        shift();
     417        if (m_current == '&') {
     418            shift();
     419            token = AND;
     420            break;
     421        }
     422        if (m_current == '=') {
     423            shift();
     424            token = ANDEQUAL;
     425            break;
     426        }
     427        token = '&';
     428        break;
     429    case '^':
     430        shift();
     431        if (m_current == '=') {
     432            shift();
     433            token = XOREQUAL;
     434            break;
     435        }
     436        token = '^';
     437        break;
     438    case '%':
     439        shift();
     440        if (m_current == '=') {
     441            shift();
     442            token = MODEQUAL;
     443            break;
     444        }
     445        token = '%';
     446        break;
     447    case '|':
     448        shift();
     449        if (m_current == '=') {
     450            shift();
     451            token = OREQUAL;
     452            break;
     453        }
     454        if (m_current == '|') {
     455            shift();
     456            token = OR;
     457            break;
     458        }
     459        token = '|';
     460        break;
     461    case '.':
     462        shift();
     463        if (isASCIIDigit(m_current)) {
     464            record8('.');
     465            goto inNumberAfterDecimalPoint;
     466        }
     467        token = '.';
     468        break;
     469    case ',':
     470    case '~':
     471    case '?':
     472    case ':':
     473    case '(':
     474    case ')':
     475    case '[':
     476    case ']':
     477        token = m_current;
     478        shift();
     479        break;
     480    case ';':
     481        m_delimited = true;
     482        shift();
     483        token = ';';
     484        break;
     485    case '{':
     486        lvalp->intValue = currentOffset();
     487        shift();
     488        token = OPENBRACE;
     489        break;
     490    case '}':
     491        lvalp->intValue = currentOffset();
     492        m_delimited = true;
     493        shift();
     494        token = CLOSEBRACE;
     495        break;
     496    case '\\':
     497        goto startIdentifierWithBackslash;
     498    case '0':
     499        goto startNumberWithZeroDigit;
     500    case '1':
     501    case '2':
     502    case '3':
     503    case '4':
     504    case '5':
     505    case '6':
     506    case '7':
     507    case '8':
     508    case '9':
     509        goto startNumber;
     510    case '"':
     511    case '\'':
     512        goto startString;
     513    default:
     514        if (isIdentStart(m_current))
     515            goto startIdentifierOrKeyword;
     516        if (isLineTerminator(m_current)) {
     517            shiftLineTerminator();
     518            m_atLineStart = true;
     519            m_terminator = true;
     520            if (lastTokenWasRestrKeyword()) {
     521                token = ';';
     522                goto doneSemicolon;
    370523            }
    371             if (m_next1 == '=') {
    372                 shift2();
    373                 token = LE;
    374                 break;
    375             }
    376             shift1();
    377             token = '<';
    378             break;
    379         case '+':
    380             if (m_next1 == '+') {
    381                 shift2();
    382                 if (m_terminator) {
    383                     token = AUTOPLUSPLUS;
    384                     break;
    385                 }
    386                 token = PLUSPLUS;
    387                 break;
    388             }
    389             if (m_next1 == '=') {
    390                 shift2();
    391                 token = PLUSEQUAL;
    392                 break;
    393             }
    394             shift1();
    395             token = '+';
    396             break;
    397         case '-':
    398             if (m_next1 == '-') {
    399                 if (m_atLineStart && m_next2 == '>') {
    400                     shift3();
    401                     goto inSingleLineComment;
    402                 }
    403                 shift2();
    404                 if (m_terminator) {
    405                     token = AUTOMINUSMINUS;
    406                     break;
    407                 }
    408                 token = MINUSMINUS;
    409                 break;
    410             }
    411             if (m_next1 == '=') {
    412                 shift2();
    413                 token = MINUSEQUAL;
    414                 break;
    415             }
    416             shift1();
    417             token = '-';
    418             break;
    419         case '*':
    420             if (m_next1 == '=') {
    421                 shift2();
    422                 token = MULTEQUAL;
    423                 break;
    424             }
    425             shift1();
    426             token = '*';
    427             break;
    428         case '/':
    429             if (m_next1 == '/') {
    430                 shift2();
    431                 goto inSingleLineComment;
    432             }
    433             if (m_next1 == '*')
    434                 goto inMultiLineComment;
    435             if (m_next1 == '=') {
    436                 shift2();
    437                 token = DIVEQUAL;
    438                 break;
    439             }
    440             shift1();
    441             token = '/';
    442             break;
    443         case '&':
    444             if (m_next1 == '&') {
    445                 shift2();
    446                 token = AND;
    447                 break;
    448             }
    449             if (m_next1 == '=') {
    450                 shift2();
    451                 token = ANDEQUAL;
    452                 break;
    453             }
    454             shift1();
    455             token = '&';
    456             break;
    457         case '^':
    458             if (m_next1 == '=') {
    459                 shift2();
    460                 token = XOREQUAL;
    461                 break;
    462             }
    463             shift1();
    464             token = '^';
    465             break;
    466         case '%':
    467             if (m_next1 == '=') {
    468                 shift2();
    469                 token = MODEQUAL;
    470                 break;
    471             }
    472             shift1();
    473             token = '%';
    474             break;
    475         case '|':
    476             if (m_next1 == '=') {
    477                 shift2();
    478                 token = OREQUAL;
    479                 break;
    480             }
    481             if (m_next1 == '|') {
    482                 shift2();
    483                 token = OR;
    484                 break;
    485             }
    486             shift1();
    487             token = '|';
    488             break;
    489         case '.':
    490             if (isASCIIDigit(m_next1)) {
    491                 record8('.');
    492                 shift1();
    493                 goto inNumberAfterDecimalPoint;
    494             }
    495             token = '.';
    496             shift1();
    497             break;
    498         case ',':
    499         case '~':
    500         case '?':
    501         case ':':
    502         case '(':
    503         case ')':
    504         case '[':
    505         case ']':
    506             token = m_current;
    507             shift1();
    508             break;
    509         case ';':
    510             shift1();
    511             m_delimited = true;
    512             token = ';';
    513             break;
    514         case '{':
    515             lvalp->intValue = currentOffset();
    516             shift1();
    517             token = OPENBRACE;
    518             break;
    519         case '}':
    520             lvalp->intValue = currentOffset();
    521             shift1();
    522             m_delimited = true;
    523             token = CLOSEBRACE;
    524             break;
    525         case '\\':
    526             goto startIdentifierWithBackslash;
    527         case '0':
    528             goto startNumberWithZeroDigit;
    529         case '1':
    530         case '2':
    531         case '3':
    532         case '4':
    533         case '5':
    534         case '6':
    535         case '7':
    536         case '8':
    537         case '9':
    538             goto startNumber;
    539         case '"':
    540         case '\'':
    541             goto startString;
    542         default:
    543             if (isIdentStart(m_current))
    544                 goto startIdentifierOrKeyword;
    545             if (isLineTerminator(m_current)) {
    546                 shiftLineTerminator();
    547                 m_atLineStart = true;
    548                 m_terminator = true;
    549                 if (lastTokenWasRestrKeyword()) {
    550                     token = ';';
    551                     goto doneSemicolon;
    552                 }
    553                 goto start;
    554             }
    555             goto returnError;
     524            goto start;
     525        }
     526        goto returnError;
    556527    }
    557528
     
    561532startString: {
    562533    int stringQuoteCharacter = m_current;
    563     shift1();
     534    shift();
    564535
    565536    const UChar* stringStart = currentCharacter();
     
    572543            goto inString;
    573544        }
    574         shift1();
     545        shift();
    575546    }
    576547    lvalp->ident = makeIdentifier(stringStart, currentCharacter() - stringStart);
    577     shift1();
     548    shift();
    578549    m_atLineStart = false;
    579550    m_delimited = false;
     
    590561            goto returnError;
    591562        record16(m_current);
    592         shift1();
     563        shift();
    593564    }
    594565    goto doneString;
    595566
    596567inStringEscapeSequence:
    597     shift1();
     568    shift();
    598569    if (m_current == 'x') {
    599         shift1();
    600         if (isASCIIHexDigit(m_current) && isASCIIHexDigit(m_next1)) {
    601             record16(convertHex(m_current, m_next1));
    602             shift2();
     570        shift();
     571        if (isASCIIHexDigit(m_current) && isASCIIHexDigit(peek(1))) {
     572            int prev = m_current;
     573            shift();
     574            record16(convertHex(prev, m_current));
     575            shift();
    603576            goto inString;
    604577        }
     
    609582    }
    610583    if (m_current == 'u') {
    611         shift1();
    612         if (isASCIIHexDigit(m_current) && isASCIIHexDigit(m_next1) && isASCIIHexDigit(m_next2) && isASCIIHexDigit(m_next3)) {
    613             record16(convertUnicode(m_current, m_next1, m_next2, m_next3));
    614             shift4();
     584        shift();
     585        token = getUnicodeCharacter();
     586        if (token != -1) {
     587            record16(token);
    615588            goto inString;
    616589        }
     
    622595    }
    623596    if (isASCIIOctalDigit(m_current)) {
    624         if (m_current >= '0' && m_current <= '3' && isASCIIOctalDigit(m_next1) && isASCIIOctalDigit(m_next2)) {
    625             record16((m_current - '0') * 64 + (m_next1 - '0') * 8 + m_next2 - '0');
    626             shift3();
     597        int char1 = m_current;
     598        shift();
     599        if (char1 >= '0' && char1 <= '3' && isASCIIOctalDigit(m_current) && isASCIIOctalDigit(peek(1))) {
     600            int char2 = m_current;
     601            shift();
     602            record16((char1 - '0') * 64 + (char2 - '0') * 8 + m_current - '0');
     603            shift();
    627604            goto inString;
    628605        }
    629         if (isASCIIOctalDigit(m_next1)) {
    630             record16((m_current - '0') * 8 + m_next1 - '0');
    631             shift2();
     606        if (isASCIIOctalDigit(m_current)) {
     607            record16((char1 - '0') * 8 + m_current - '0');
     608            shift();
    632609            goto inString;
    633610        }
    634         record16(m_current - '0');
    635         shift1();
     611        record16(char1 - '0');
    636612        goto inString;
    637613    }
     
    643619        goto returnError;
    644620    record16(singleEscape(m_current));
    645     shift1();
     621    shift();
    646622    goto inString;
    647623}
    648624
    649 startIdentifierWithBackslash:
    650     shift1();
     625startIdentifierWithBackslash: {
     626    shift();
    651627    if (UNLIKELY(m_current != 'u'))
    652628        goto returnError;
    653     shift1();
    654     if (UNLIKELY(!isASCIIHexDigit(m_current) || !isASCIIHexDigit(m_next1) || !isASCIIHexDigit(m_next2) || !isASCIIHexDigit(m_next3)))
     629    shift();
     630
     631    token = getUnicodeCharacter();
     632    if (UNLIKELY(token == -1))
    655633        goto returnError;
    656     token = convertUnicode(m_current, m_next1, m_next2, m_next3);
    657634    if (UNLIKELY(!isIdentStart(token)))
    658635        goto returnError;
    659636    goto inIdentifierAfterCharacterCheck;
     637}
    660638
    661639startIdentifierOrKeyword: {
    662640    const UChar* identifierStart = currentCharacter();
    663     shift1();
     641    shift();
    664642    while (isIdentPart(m_current))
    665         shift1();
     643        shift();
    666644    if (LIKELY(m_current != '\\')) {
     645        // Fast case for idents which does not contain \uCCCC characters
    667646        lvalp->ident = makeIdentifier(identifierStart, currentCharacter() - identifierStart);
    668647        goto doneIdentifierOrKeyword;
     
    672651
    673652    do {
    674         shift1();
     653        shift();
    675654        if (UNLIKELY(m_current != 'u'))
    676655            goto returnError;
    677         shift1();
    678         if (UNLIKELY(!isASCIIHexDigit(m_current) || !isASCIIHexDigit(m_next1) || !isASCIIHexDigit(m_next2) || !isASCIIHexDigit(m_next3)))
     656        shift();
     657        token = getUnicodeCharacter();
     658        if (UNLIKELY(token == -1))
    679659            goto returnError;
    680         token = convertUnicode(m_current, m_next1, m_next2, m_next3);
    681660        if (UNLIKELY(!isIdentPart(token)))
    682661            goto returnError;
    683662inIdentifierAfterCharacterCheck:
    684663        record16(token);
    685         shift4();
    686664
    687665        while (isIdentPart(m_current)) {
    688666            record16(m_current);
    689             shift1();
     667            shift();
    690668        }
    691669    } while (UNLIKELY(m_current == '\\'));
     
    696674        if (UNLIKELY(m_current == -1))
    697675            return 0;
    698         shift1();
     676        shift();
    699677    }
    700678    shiftLineTerminator();
     
    706684
    707685inMultiLineComment:
    708     shift2();
    709     while (m_current != '*' || m_next1 != '/') {
     686    while (true) {
     687        if (UNLIKELY(m_current == '*')) {
     688            shift();
     689            if (m_current == '/')
     690                break;
     691            if (m_current == '*')
     692                continue;
     693        }
     694
     695        if (UNLIKELY(m_current == -1))
     696            goto returnError;
     697
    710698        if (isLineTerminator(m_current))
    711699            shiftLineTerminator();
    712         else {
    713             shift1();
    714             if (UNLIKELY(m_current == -1))
    715                 goto returnError;
    716         }
    717     }
    718     shift2();
     700        else
     701            shift();
     702    }
     703    shift();
    719704    m_atLineStart = false;
    720705    goto start;
    721706
    722707startNumberWithZeroDigit:
    723     shift1();
    724     if ((m_current | 0x20) == 'x' && isASCIIHexDigit(m_next1)) {
    725         shift1();
     708    shift();
     709    if ((m_current | 0x20) == 'x' && isASCIIHexDigit(peek(1))) {
     710        shift();
    726711        goto inHex;
    727712    }
     
    729714        record8('0');
    730715        record8('.');
    731         shift1();
     716        shift();
    732717        goto inNumberAfterDecimalPoint;
    733718    }
     
    735720        record8('0');
    736721        record8('e');
    737         shift1();
     722        shift();
    738723        goto inExponentIndicator;
    739724    }
     
    748733    while (isASCIIDigit(m_current)) {
    749734        record8(m_current);
    750         shift1();
     735        shift();
    751736    }
    752737    if ((m_current | 0x20) == 'e') {
    753738        record8('e');
    754         shift1();
     739        shift();
    755740        goto inExponentIndicator;
    756741    }
     
    760745    if (m_current == '+' || m_current == '-') {
    761746        record8(m_current);
    762         shift1();
     747        shift();
    763748    }
    764749    if (!isASCIIDigit(m_current))
     
    766751    do {
    767752        record8(m_current);
    768         shift1();
     753        shift();
    769754    } while (isASCIIDigit(m_current));
    770755    goto doneNumber;
     
    773758    do {
    774759        record8(m_current);
    775         shift1();
     760        shift();
    776761    } while (isASCIIOctalDigit(m_current));
    777762    if (isASCIIDigit(m_current))
     
    797782    do {
    798783        record8(m_current);
    799         shift1();
     784        shift();
    800785    } while (isASCIIHexDigit(m_current));
    801786
     
    818803startNumber:
    819804    record8(m_current);
    820     shift1();
     805    shift();
    821806    while (isASCIIDigit(m_current)) {
    822807        record8(m_current);
    823         shift1();
     808        shift();
    824809    }
    825810    if (m_current == '.') {
    826811        record8('.');
    827         shift1();
     812        shift();
    828813        goto inNumberAfterDecimalPoint;
    829814    }
    830815    if ((m_current | 0x20) == 'e') {
    831816        record8('e');
    832         shift1();
     817        shift();
    833818        goto inExponentIndicator;
    834819    }
     
    878863doneString:
    879864    // Atomize constant strings in case they're later used in property lookup.
    880     shift1();
     865    shift();
    881866    m_atLineStart = false;
    882867    m_delimited = false;
     
    924909        }
    925910
    926         shift1();
     911        shift();
    927912
    928913        if (current == '/' && !lastWasEscape && !inBrackets)
     
    954939    while (isIdentPart(m_current)) {
    955940        record16(m_current);
    956         shift1();
     941        shift();
    957942    }
    958943
     
    974959            return false;
    975960
    976         shift1();
     961        shift();
    977962
    978963        if (current == '/' && !lastWasEscape && !inBrackets)
     
    998983
    999984    while (isIdentPart(m_current))
    1000         shift1();
     985        shift();
    1001986
    1002987    return true;
Note: See TracChangeset for help on using the changeset viewer.