[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

zherczeg at webkit.org zherczeg at webkit.org
Wed Dec 22 12:47:33 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit bd30602a67463fa78fc2393132e3eb73a88e37e0
Author: zherczeg at webkit.org <zherczeg at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Aug 30 08:24:40 2010 +0000

    Refactor number parsing in the lexer
    https://bugs.webkit.org/show_bug.cgi?id=44104
    
    Reviewed by Darin Adler.
    
    Number parsing was full of gotos, and needed a complete
    redesign to remove them (Only one remained). Furthermore
    integer arithmetic is empolyed for fast cases (= small
    integer numbers).
    
    * parser/Lexer.cpp:
    (JSC::Lexer::parseHex):
    (JSC::Lexer::parseOctal):
    (JSC::Lexer::parseDecimal):
    (JSC::Lexer::parseNumberAfterDecimalPoint):
    (JSC::Lexer::parseNumberAfterExponentIndicator):
    (JSC::Lexer::lex):
    * parser/Lexer.h:
    
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@66375 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 5bcded8..27ea3b0 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,24 @@
+2010-08-30  Zoltan Herczeg  <zherczeg at webkit.org>
+
+        Reviewed by Darin Adler.
+
+        Refactor number parsing in the lexer
+        https://bugs.webkit.org/show_bug.cgi?id=44104
+
+        Number parsing was full of gotos, and needed a complete
+        redesign to remove them (Only one remained). Furthermore
+        integer arithmetic is empolyed for fast cases (= small
+        integer numbers).
+
+        * parser/Lexer.cpp:
+        (JSC::Lexer::parseHex):
+        (JSC::Lexer::parseOctal):
+        (JSC::Lexer::parseDecimal):
+        (JSC::Lexer::parseNumberAfterDecimalPoint):
+        (JSC::Lexer::parseNumberAfterExponentIndicator):
+        (JSC::Lexer::lex):
+        * parser/Lexer.h:
+
 2010-08-29  Darin Adler  <darin at apple.com>
 
         Fix Qt build.
diff --git a/JavaScriptCore/parser/Lexer.cpp b/JavaScriptCore/parser/Lexer.cpp
index f9e62e1..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;
@@ -877,140 +1049,6 @@ inMultiLineComment:
     shift();
     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;
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list