From: Martin Jones Date: Fri, 18 May 2012 04:24:59 +0000 (+1000) Subject: Optimize QML parser X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=6e55080ddca35ffb06cb212143b98d96f09549c7;p=konrad%2Fqtdeclarative.git Optimize QML parser Inlining and faster number parsing. Reduces parsing of large project from 20.5mil instr to 19mil instr. Change-Id: I83aff3eaf03fd19b07f5e84ec6f9d17b7f0cb931 Reviewed-by: Roberto Raggi --- diff --git a/src/qml/qml/parser/qqmljslexer.cpp b/src/qml/qml/parser/qqmljslexer.cpp index c34fc81..a4c5f72 100644 --- a/src/qml/qml/parser/qqmljslexer.cpp +++ b/src/qml/qml/parser/qqmljslexer.cpp @@ -671,6 +671,17 @@ again: _errorMessage = QCoreApplication::translate("QQmlParser", "Unclosed string at end of line"); return T_ERROR; } + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return scanNumber(ch); default: if (ch.isLetter() || ch == QLatin1Char('$') || ch == QLatin1Char('_') || (ch == QLatin1Char('\\') && _char == QLatin1Char('u'))) { @@ -727,118 +738,127 @@ again: return kind; } } - } else if (ch.isDigit()) { - if (ch != QLatin1Char('0')) { - double integer = ch.unicode() - '0'; - - QChar n = _char; - const QChar *code = _codePtr; - while (n.isDigit()) { - integer = integer * 10 + (n.unicode() - '0'); - n = *code++; - } + } - if (n != QLatin1Char('.') && n != QLatin1Char('e') && n != QLatin1Char('E')) { - if (code != _codePtr) { - _codePtr = code - 1; - scanChar(); - } - _tokenValue = integer; - return T_NUMERIC_LITERAL; - } - } + break; + } - QVarLengthArray chars; - chars.append(ch.unicode()); + return T_ERROR; +} - if (ch == QLatin1Char('0') && (_char == QLatin1Char('x') || _char == QLatin1Char('X'))) { - // parse hex integer literal +int Lexer::scanNumber(QChar ch) +{ + if (ch != QLatin1Char('0')) { + double integer = ch.unicode() - '0'; + + QChar n = _char; + const QChar *code = _codePtr; + while (n.isDigit()) { + integer = integer * 10 + (n.unicode() - '0'); + n = *code++; + } - chars.append(_char.unicode()); - scanChar(); // consume `x' + if (n != QLatin1Char('.') && n != QLatin1Char('e') && n != QLatin1Char('E')) { + if (code != _codePtr) { + _codePtr = code - 1; + scanChar(); + } + _tokenValue = integer; + return T_NUMERIC_LITERAL; + } + } - while (isHexDigit(_char)) { - chars.append(_char.unicode()); - scanChar(); - } + QVarLengthArray chars; + chars.append(ch.unicode()); - _tokenValue = integerFromString(chars.constData(), chars.size(), 16); - return T_NUMERIC_LITERAL; - } + if (ch == QLatin1Char('0') && (_char == QLatin1Char('x') || _char == QLatin1Char('X'))) { + // parse hex integer literal - // decimal integer literal - while (_char.isDigit()) { - chars.append(_char.unicode()); - scanChar(); // consume the digit - } + chars.append(_char.unicode()); + scanChar(); // consume `x' - if (_char == QLatin1Char('.')) { - chars.append(_char.unicode()); - scanChar(); // consume `.' + while (isHexDigit(_char)) { + chars.append(_char.unicode()); + scanChar(); + } - while (_char.isDigit()) { - chars.append(_char.unicode()); - scanChar(); - } + _tokenValue = integerFromString(chars.constData(), chars.size(), 16); + return T_NUMERIC_LITERAL; + } - if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) { - if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) && - _codePtr[1].isDigit())) { + // decimal integer literal + while (_char.isDigit()) { + chars.append(_char.unicode()); + scanChar(); // consume the digit + } - chars.append(_char.unicode()); - scanChar(); // consume `e' + if (_char == QLatin1Char('.')) { + chars.append(_char.unicode()); + scanChar(); // consume `.' - if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) { - chars.append(_char.unicode()); - scanChar(); // consume the sign - } + while (_char.isDigit()) { + chars.append(_char.unicode()); + scanChar(); + } - while (_char.isDigit()) { - chars.append(_char.unicode()); - scanChar(); - } - } + if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) { + if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) && + _codePtr[1].isDigit())) { + + chars.append(_char.unicode()); + scanChar(); // consume `e' + + if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) { + chars.append(_char.unicode()); + scanChar(); // consume the sign } - } else if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) { - if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) && - _codePtr[1].isDigit())) { + while (_char.isDigit()) { chars.append(_char.unicode()); - scanChar(); // consume `e' + scanChar(); + } + } + } + } else if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) { + if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) && + _codePtr[1].isDigit())) { - if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) { - chars.append(_char.unicode()); - scanChar(); // consume the sign - } + chars.append(_char.unicode()); + scanChar(); // consume `e' - while (_char.isDigit()) { - chars.append(_char.unicode()); - scanChar(); - } - } + if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) { + chars.append(_char.unicode()); + scanChar(); // consume the sign } - chars.append('\0'); + while (_char.isDigit()) { + chars.append(_char.unicode()); + scanChar(); + } + } + } - const char *begin = chars.constData(); - const char *end = 0; - bool ok = false; + if (chars.length() == 1) { + // if we ended up with a single digit, then it was a '0' + _tokenValue = 0; + return T_NUMERIC_LITERAL; + } - _tokenValue = qstrtod(begin, &end, &ok); + chars.append('\0'); - if (end - begin != chars.size() - 1) { - _errorCode = IllegalExponentIndicator; - _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal syntax for exponential number"); - return T_ERROR; - } + const char *begin = chars.constData(); + const char *end = 0; + bool ok = false; - return T_NUMERIC_LITERAL; - } + _tokenValue = qstrtod(begin, &end, &ok); - break; + if (end - begin != chars.size() - 1) { + _errorCode = IllegalExponentIndicator; + _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal syntax for exponential number"); + return T_ERROR; } - return T_ERROR; + return T_NUMERIC_LITERAL; } bool Lexer::scanRegExp(RegExpBodyPrefix prefix) @@ -970,31 +990,6 @@ bool Lexer::isOctalDigit(ushort c) return (c >= '0' && c <= '7'); } -int Lexer::tokenKind() const -{ - return _tokenKind; -} - -int Lexer::tokenOffset() const -{ - return _tokenStartPtr - _code.unicode(); -} - -int Lexer::tokenLength() const -{ - return _tokenLength; -} - -int Lexer::tokenStartLine() const -{ - return _tokenLine; -} - -int Lexer::tokenStartColumn() const -{ - return _tokenStartPtr - _tokenLinePtr + 1; -} - int Lexer::tokenEndLine() const { return _currentLineNumber; @@ -1005,16 +1000,6 @@ int Lexer::tokenEndColumn() const return _codePtr - _lastLinePtr; } -QStringRef Lexer::tokenSpell() const -{ - return _tokenSpell; -} - -double Lexer::tokenValue() const -{ - return _tokenValue; -} - QString Lexer::tokenText() const { if (_validTokenText) diff --git a/src/qml/qml/parser/qqmljslexer_p.h b/src/qml/qml/parser/qqmljslexer_p.h index 6b51852..65adf0a 100644 --- a/src/qml/qml/parser/qqmljslexer_p.h +++ b/src/qml/qml/parser/qqmljslexer_p.h @@ -158,18 +158,18 @@ public: int regExpFlags() const { return _patternFlags; } QString regExpPattern() const { return _tokenText; } - int tokenKind() const; - int tokenOffset() const; - int tokenLength() const; + int tokenKind() const { return _tokenKind; } + int tokenOffset() const { return _tokenStartPtr - _code.unicode(); } + int tokenLength() const { return _tokenLength; } - int tokenStartLine() const; - int tokenStartColumn() const; + int tokenStartLine() const { return _tokenLine; } + int tokenStartColumn() const { return _tokenStartPtr - _tokenLinePtr + 1; } int tokenEndLine() const; int tokenEndColumn() const; - QStringRef tokenSpell() const; - double tokenValue() const; + inline QStringRef tokenSpell() const { return _tokenSpell; } + double tokenValue() const { return _tokenValue; } QString tokenText() const; Error errorCode() const; @@ -191,6 +191,7 @@ protected: private: inline void scanChar(); int scanToken(); + int scanNumber(QChar ch); bool isLineTerminator() const; static bool isIdentLetter(QChar c);