diff options
author | Kristian Monsen <kristianm@google.com> | 2010-09-08 12:18:00 +0100 |
---|---|---|
committer | Kristian Monsen <kristianm@google.com> | 2010-09-11 12:08:58 +0100 |
commit | 5ddde30071f639962dd557c453f2ad01f8f0fd00 (patch) | |
tree | 775803c4ab35af50aa5f5472cd1fb95fe9d5152d /JavaScriptCore/parser | |
parent | 3e63d9b33b753ca86d0765d1b3d711114ba9e34f (diff) | |
download | external_webkit-5ddde30071f639962dd557c453f2ad01f8f0fd00.zip external_webkit-5ddde30071f639962dd557c453f2ad01f8f0fd00.tar.gz external_webkit-5ddde30071f639962dd557c453f2ad01f8f0fd00.tar.bz2 |
Merge WebKit at r66666 : Initial merge by git.
Change-Id: I57dedeb49859adc9c539e760f0e749768c66626f
Diffstat (limited to 'JavaScriptCore/parser')
-rw-r--r-- | JavaScriptCore/parser/JSParser.cpp | 8 | ||||
-rw-r--r-- | JavaScriptCore/parser/Lexer.cpp | 327 | ||||
-rw-r--r-- | JavaScriptCore/parser/Lexer.h | 5 |
3 files changed, 189 insertions, 151 deletions
diff --git a/JavaScriptCore/parser/JSParser.cpp b/JavaScriptCore/parser/JSParser.cpp index 3baceba..6852de1 100644 --- a/JavaScriptCore/parser/JSParser.cpp +++ b/JavaScriptCore/parser/JSParser.cpp @@ -33,6 +33,7 @@ using namespace JSC; #include "NodeInfo.h" #include "ASTBuilder.h" #include <wtf/HashFunctions.h> +#include <wtf/WTFThreadData.h> #include <utility> using namespace std; @@ -220,12 +221,7 @@ JSParser::JSParser(Lexer* lexer, JSGlobalData* globalData, SourceProvider* provi , m_nonLHSCount(0) , m_syntaxAlreadyValidated(provider->isValid()) { - m_endAddress = *(globalData->stackGuards); - if (!m_endAddress) { - char sample = 0; - m_endAddress = &sample - kMaxParserStackUsage; - *(globalData->stackGuards) = m_endAddress; - } + m_endAddress = wtfThreadData().approximatedStackStart() - kMaxParserStackUsage; next(); m_lexer->setLastLineNumber(tokenLine()); } diff --git a/JavaScriptCore/parser/Lexer.cpp b/JavaScriptCore/parser/Lexer.cpp index 877e89a..6c4db32 100644 --- a/JavaScriptCore/parser/Lexer.cpp +++ b/JavaScriptCore/parser/Lexer.cpp @@ -535,6 +535,146 @@ ALWAYS_INLINE bool Lexer::parseString(JSTokenData* lvalp) return true; } +ALWAYS_INLINE void Lexer::parseHex(double& returnValue) +{ + // Optimization: most hexadecimal values fit into 4 bytes. + uint32_t hexValue = 0; + int maximumDigits = 7; + + // Shift out the 'x' prefix. + shift(); + + do { + hexValue = (hexValue << 4) + toASCIIHexValue(m_current); + shift(); + --maximumDigits; + } while (isASCIIHexDigit(m_current) && maximumDigits >= 0); + + if (maximumDigits >= 0) { + returnValue = hexValue; + return; + } + + // No more place in the hexValue buffer. + // The values are shifted out and placed into the m_buffer8 vector. + for (int i = 0; i < 8; ++i) { + int digit = hexValue >> 28; + if (digit < 10) + record8(digit + '0'); + else + record8(digit - 10 + 'a'); + hexValue <<= 4; + } + + while (isASCIIHexDigit(m_current)) { + record8(m_current); + shift(); + } + + returnValue = parseIntOverflow(m_buffer8.data(), m_buffer8.size(), 16); +} + +ALWAYS_INLINE bool Lexer::parseOctal(double& returnValue) +{ + // Optimization: most octal values fit into 4 bytes. + uint32_t octalValue = 0; + int maximumDigits = 9; + // Temporary buffer for the digits. Makes easier + // to reconstruct the input characters when needed. + char digits[10]; + + do { + octalValue = octalValue * 8 + (m_current - '0'); + digits[maximumDigits] = m_current; + shift(); + --maximumDigits; + } while (isASCIIOctalDigit(m_current) && maximumDigits >= 0); + + if (!isASCIIDigit(m_current) && maximumDigits >= 0) { + returnValue = octalValue; + return true; + } + + for (int i = 9; i > maximumDigits; --i) + record8(digits[i]); + + while (isASCIIOctalDigit(m_current)) { + record8(m_current); + shift(); + } + + if (isASCIIDigit(m_current)) + return false; + + returnValue = parseIntOverflow(m_buffer8.data(), m_buffer8.size(), 8); + return true; +} + +ALWAYS_INLINE bool Lexer::parseDecimal(double& returnValue) +{ + // Optimization: most decimal values fit into 4 bytes. + uint32_t decimalValue = 0; + + // Since parseOctal may be executed before parseDecimal, + // the m_buffer8 may hold ascii digits. + if (!m_buffer8.size()) { + int maximumDigits = 9; + // Temporary buffer for the digits. Makes easier + // to reconstruct the input characters when needed. + char digits[10]; + + do { + decimalValue = decimalValue * 10 + (m_current - '0'); + digits[maximumDigits] = m_current; + shift(); + --maximumDigits; + } while (isASCIIDigit(m_current) && maximumDigits >= 0); + + if (maximumDigits >= 0 && m_current != '.' && (m_current | 0x20) != 'e') { + returnValue = decimalValue; + return true; + } + + for (int i = 9; i > maximumDigits; --i) + record8(digits[i]); + } + + while (isASCIIDigit(m_current)) { + record8(m_current); + shift(); + } + + return false; +} + +ALWAYS_INLINE void Lexer::parseNumberAfterDecimalPoint() +{ + record8('.'); + while (isASCIIDigit(m_current)) { + record8(m_current); + shift(); + } +} + +ALWAYS_INLINE bool Lexer::parseNumberAfterExponentIndicator() +{ + record8('e'); + shift(); + if (m_current == '+' || m_current == '-') { + record8(m_current); + shift(); + } + + if (!isASCIIDigit(m_current)) + return false; + + do { + record8(m_current); + shift(); + } while (isASCIIDigit(m_current)); + return true; +} + JSTokenType Lexer::lex(JSTokenData* lvalp, JSTokenInfo* llocp, LexType lexType) { ASSERT(!m_error); @@ -750,14 +890,6 @@ start: } token = BITOR; break; - case CharacterDot: - shift(); - if (isASCIIDigit(m_current)) { - record8('.'); - goto inNumberAfterDecimalPoint; - } - token = DOT; - break; case CharacterOpenParen: token = OPENPAREN; shift(); @@ -806,10 +938,50 @@ start: shift(); token = CLOSEBRACE; break; + case CharacterDot: + shift(); + if (!isASCIIDigit(m_current)) { + token = DOT; + break; + } + goto inNumberAfterDecimalPoint; case CharacterZero: - goto startNumberWithZeroDigit; + shift(); + if ((m_current | 0x20) == 'x' && isASCIIHexDigit(peek(1))) { + parseHex(lvalp->doubleValue); + token = NUMBER; + } else { + record8('0'); + if (isASCIIOctalDigit(m_current)) { + if (parseOctal(lvalp->doubleValue)) + token = NUMBER; + } + } + // Fall through into CharacterNumber case CharacterNumber: - goto startNumber; + if (LIKELY(token != NUMBER)) { + if (!parseDecimal(lvalp->doubleValue)) { + if (m_current == '.') { + shift(); +inNumberAfterDecimalPoint: + parseNumberAfterDecimalPoint(); + } + if ((m_current | 0x20) == 'e') + if (!parseNumberAfterExponentIndicator()) + goto returnError; + // Null-terminate string for strtod. + m_buffer8.append('\0'); + lvalp->doubleValue = WTF::strtod(m_buffer8.data(), 0); + } + token = NUMBER; + } + + // No identifiers allowed directly after numeric literal, e.g. "3in" is bad. + if (UNLIKELY(isIdentStart(m_current))) + goto returnError; + m_buffer8.resize(0); + m_delimited = false; + break; case CharacterQuote: if (UNLIKELY(!parseString(lvalp))) goto returnError; @@ -875,143 +1047,8 @@ inMultiLineComment: shift(); } shift(); - m_atLineStart = false; goto start; -startNumberWithZeroDigit: - shift(); - if ((m_current | 0x20) == 'x' && isASCIIHexDigit(peek(1))) { - shift(); - goto inHex; - } - if (m_current == '.') { - record8('0'); - record8('.'); - shift(); - goto inNumberAfterDecimalPoint; - } - if ((m_current | 0x20) == 'e') { - record8('0'); - record8('e'); - shift(); - goto inExponentIndicator; - } - if (isASCIIOctalDigit(m_current)) - goto inOctal; - if (isASCIIDigit(m_current)) - goto startNumber; - lvalp->doubleValue = 0; - goto doneNumeric; - -inNumberAfterDecimalPoint: - while (isASCIIDigit(m_current)) { - record8(m_current); - shift(); - } - if ((m_current | 0x20) == 'e') { - record8('e'); - shift(); - goto inExponentIndicator; - } - goto doneNumber; - -inExponentIndicator: - if (m_current == '+' || m_current == '-') { - record8(m_current); - shift(); - } - if (!isASCIIDigit(m_current)) - goto returnError; - do { - record8(m_current); - shift(); - } while (isASCIIDigit(m_current)); - goto doneNumber; - -inOctal: { - do { - record8(m_current); - shift(); - } while (isASCIIOctalDigit(m_current)); - if (isASCIIDigit(m_current)) - goto startNumber; - - double dval = 0; - - const char* end = m_buffer8.end(); - for (const char* p = m_buffer8.data(); p < end; ++p) { - dval *= 8; - dval += *p - '0'; - } - if (dval >= mantissaOverflowLowerBound) - dval = parseIntOverflow(m_buffer8.data(), end - m_buffer8.data(), 8); - - m_buffer8.resize(0); - - lvalp->doubleValue = dval; - goto doneNumeric; -} - -inHex: { - do { - record8(m_current); - shift(); - } while (isASCIIHexDigit(m_current)); - - double dval = 0; - - const char* end = m_buffer8.end(); - for (const char* p = m_buffer8.data(); p < end; ++p) { - dval *= 16; - dval += toASCIIHexValue(*p); - } - if (dval >= mantissaOverflowLowerBound) - dval = parseIntOverflow(m_buffer8.data(), end - m_buffer8.data(), 16); - - m_buffer8.resize(0); - - lvalp->doubleValue = dval; - goto doneNumeric; -} - -startNumber: - record8(m_current); - shift(); - while (isASCIIDigit(m_current)) { - record8(m_current); - shift(); - } - if (m_current == '.') { - record8('.'); - shift(); - goto inNumberAfterDecimalPoint; - } - if ((m_current | 0x20) == 'e') { - record8('e'); - shift(); - goto inExponentIndicator; - } - - // Fall through into doneNumber. - -doneNumber: - // Null-terminate string for strtod. - m_buffer8.append('\0'); - lvalp->doubleValue = WTF::strtod(m_buffer8.data(), 0); - m_buffer8.resize(0); - - // Fall through into doneNumeric. - -doneNumeric: - // No identifiers allowed directly after numeric literal, e.g. "3in" is bad. - if (UNLIKELY(isIdentStart(m_current))) - goto returnError; - - m_atLineStart = false; - m_delimited = false; - token = NUMBER; - goto returnToken; - doneSemicolon: token = SEMICOLON; m_delimited = true; diff --git a/JavaScriptCore/parser/Lexer.h b/JavaScriptCore/parser/Lexer.h index 3d97cc1..da84a6b 100644 --- a/JavaScriptCore/parser/Lexer.h +++ b/JavaScriptCore/parser/Lexer.h @@ -96,6 +96,11 @@ namespace JSC { ALWAYS_INLINE JSTokenType parseIdentifier(JSTokenData*, LexType); ALWAYS_INLINE bool parseString(JSTokenData* lvalp); + ALWAYS_INLINE void parseHex(double& returnValue); + ALWAYS_INLINE bool parseOctal(double& returnValue); + ALWAYS_INLINE bool parseDecimal(double& returnValue); + ALWAYS_INLINE void parseNumberAfterDecimalPoint(); + ALWAYS_INLINE bool parseNumberAfterExponentIndicator(); static const size_t initialReadBufferCapacity = 32; |