diff options
Diffstat (limited to 'Source/JavaScriptCore/parser/Lexer.h')
-rw-r--r-- | Source/JavaScriptCore/parser/Lexer.h | 105 |
1 files changed, 74 insertions, 31 deletions
diff --git a/Source/JavaScriptCore/parser/Lexer.h b/Source/JavaScriptCore/parser/Lexer.h index 78c8c8cbd..5ecdcc650 100644 --- a/Source/JavaScriptCore/parser/Lexer.h +++ b/Source/JavaScriptCore/parser/Lexer.h @@ -1,6 +1,6 @@ /* * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All rights reserved. + * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012, 2013 Apple Inc. All rights reserved. * Copyright (C) 2010 Zoltan Herczeg (zherczeg@inf.u-szeged.hu) * * This library is free software; you can redistribute it and/or @@ -28,7 +28,6 @@ #include "ParserTokens.h" #include "SourceCode.h" #include <wtf/ASCIICType.h> -#include <wtf/AlwaysInline.h> #include <wtf/SegmentedVector.h> #include <wtf/Vector.h> #include <wtf/unicode/Unicode.h> @@ -39,12 +38,12 @@ class Keywords { public: bool isKeyword(const Identifier& ident) const { - return m_keywordTable.entry(m_globalData, ident); + return m_keywordTable.entry(m_vm, ident); } const HashEntry* getKeyword(const Identifier& ident) const { - return m_keywordTable.entry(m_globalData, ident); + return m_keywordTable.entry(m_vm, ident); } ~Keywords() @@ -53,11 +52,11 @@ public: } private: - friend class JSGlobalData; + friend class VM; - Keywords(JSGlobalData*); + Keywords(VM*); - JSGlobalData* m_globalData; + VM* m_vm; const HashTable m_keywordTable; }; @@ -73,7 +72,7 @@ class Lexer { WTF_MAKE_FAST_ALLOCATED; public: - Lexer(JSGlobalData*); + Lexer(VM*); ~Lexer(); // Character manipulation functions. @@ -90,11 +89,12 @@ public: JSTokenType lex(JSTokenData*, JSTokenLocation*, unsigned, bool strictMode); bool nextTokenIsColon(); int lineNumber() const { return m_lineNumber; } - int currentColumnNumber() const { return m_columnNumber; } + ALWAYS_INLINE int currentOffset() const { return offsetFromSourcePtr(m_code); } + ALWAYS_INLINE int currentLineStartOffset() const { return offsetFromSourcePtr(m_lineStart); } void setLastLineNumber(int lastLineNumber) { m_lastLineNumber = lastLineNumber; } int lastLineNumber() const { return m_lastLineNumber; } bool prevTerminator() const { return m_terminator; } - SourceCode sourceCode(int openBrace, int closeBrace, int firstLine); + SourceCode sourceCode(int openBrace, int closeBrace, int firstLine, unsigned startColumn); bool scanRegExp(const Identifier*& pattern, const Identifier*& flags, UChar patternPrefix = 0); bool skipRegExp(); @@ -102,11 +102,15 @@ public: bool sawError() const { return m_error; } String getErrorMessage() const { return m_lexErrorMessage; } void clear(); - void setOffset(int offset) + void setOffset(int offset, int lineStartOffset) { m_error = 0; m_lexErrorMessage = String(); - m_code = m_codeStart + offset; + + m_code = sourcePtrFromOffset(offset); + m_lineStart = sourcePtrFromOffset(lineStartOffset); + ASSERT(currentOffset() >= currentLineStartOffset()); + m_buffer8.resize(0); m_buffer16.resize(0); if (LIKELY(m_code < m_codeEnd)) @@ -134,13 +138,44 @@ private: ALWAYS_INLINE void shift(); ALWAYS_INLINE bool atEnd() const; ALWAYS_INLINE T peek(int offset) const; - int parseFourDigitUnicodeHex(); + struct UnicodeHexValue { + + enum ValueType { ValidHex, IncompleteHex, InvalidHex }; + + explicit UnicodeHexValue(int value) + : m_value(value) + { + } + explicit UnicodeHexValue(ValueType type) + : m_value(type == IncompleteHex ? -2 : -1) + { + } + + ValueType valueType() const + { + if (m_value >= 0) + return ValidHex; + return m_value == -2 ? IncompleteHex : InvalidHex; + } + bool isValid() const { return m_value >= 0; } + int value() const + { + ASSERT(m_value >= 0); + return m_value; + } + + private: + int m_value; + }; + UnicodeHexValue parseFourDigitUnicodeHex(); void shiftLineTerminator(); + ALWAYS_INLINE int offsetFromSourcePtr(const T* ptr) const { return ptr - m_codeStart; } + ALWAYS_INLINE const T* sourcePtrFromOffset(int offset) const { return m_codeStart + offset; } + String invalidCharacterMessage() const; - ALWAYS_INLINE const T* currentCharacter() const; - ALWAYS_INLINE int currentOffset() const { return m_code - m_codeStart; } - ALWAYS_INLINE void setOffsetFromCharOffset(const T* charOffset) { setOffset(charOffset - m_codeStart); } + ALWAYS_INLINE const T* currentSourcePtr() const; + ALWAYS_INLINE void setOffsetFromSourcePtr(const T* sourcePtr, unsigned lineStartOffset) { setOffset(offsetFromSourcePtr(sourcePtr), lineStartOffset); } ALWAYS_INLINE void setCodeStart(const StringImpl*); @@ -157,8 +192,13 @@ private: template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType parseKeyword(JSTokenData*); template <bool shouldBuildIdentifiers> ALWAYS_INLINE JSTokenType parseIdentifier(JSTokenData*, unsigned lexerFlags, bool strictMode); template <bool shouldBuildIdentifiers> NEVER_INLINE JSTokenType parseIdentifierSlowCase(JSTokenData*, unsigned lexerFlags, bool strictMode); - template <bool shouldBuildStrings> ALWAYS_INLINE bool parseString(JSTokenData*, bool strictMode); - template <bool shouldBuildStrings> NEVER_INLINE bool parseStringSlowCase(JSTokenData*, bool strictMode); + enum StringParseResult { + StringParsedSuccessfully, + StringUnterminated, + StringCannotBeParsed + }; + template <bool shouldBuildStrings> ALWAYS_INLINE StringParseResult parseString(JSTokenData*, bool strictMode); + template <bool shouldBuildStrings> NEVER_INLINE StringParseResult parseStringSlowCase(JSTokenData*, bool strictMode); ALWAYS_INLINE void parseHex(double& returnValue); ALWAYS_INLINE bool parseOctal(double& returnValue); ALWAYS_INLINE bool parseDecimal(double& returnValue); @@ -170,7 +210,6 @@ private: int m_lineNumber; int m_lastLineNumber; - int m_columnNumber; Vector<LChar> m_buffer8; Vector<UChar> m_buffer16; @@ -178,9 +217,12 @@ private: int m_lastToken; const SourceCode* m_source; + unsigned m_sourceOffset; const T* m_code; const T* m_codeStart; const T* m_codeEnd; + const T* m_codeStartPlusOffset; + const T* m_lineStart; bool m_isReparsing; bool m_atLineStart; bool m_error; @@ -190,7 +232,7 @@ private: IdentifierArena* m_arena; - JSGlobalData* m_globalData; + VM* m_vm; }; template <> @@ -232,28 +274,28 @@ inline UChar Lexer<T>::convertUnicode(int c1, int c2, int c3, int c4) template <typename T> ALWAYS_INLINE const Identifier* Lexer<T>::makeIdentifier(const LChar* characters, size_t length) { - return &m_arena->makeIdentifier(m_globalData, characters, length); + return &m_arena->makeIdentifier(m_vm, characters, length); } template <typename T> ALWAYS_INLINE const Identifier* Lexer<T>::makeIdentifier(const UChar* characters, size_t length) { - return &m_arena->makeIdentifier(m_globalData, characters, length); + return &m_arena->makeIdentifier(m_vm, characters, length); } template <> ALWAYS_INLINE const Identifier* Lexer<LChar>::makeRightSizedIdentifier(const UChar* characters, size_t length, UChar) { - return &m_arena->makeIdentifierLCharFromUChar(m_globalData, characters, length); + return &m_arena->makeIdentifierLCharFromUChar(m_vm, characters, length); } template <> ALWAYS_INLINE const Identifier* Lexer<UChar>::makeRightSizedIdentifier(const UChar* characters, size_t length, UChar orAllChars) { if (!(orAllChars & ~0xff)) - return &m_arena->makeIdentifierLCharFromUChar(m_globalData, characters, length); + return &m_arena->makeIdentifierLCharFromUChar(m_vm, characters, length); - return &m_arena->makeIdentifier(m_globalData, characters, length); + return &m_arena->makeIdentifier(m_vm, characters, length); } template <> @@ -273,19 +315,19 @@ ALWAYS_INLINE void Lexer<UChar>::setCodeStart(const StringImpl* sourceString) template <typename T> ALWAYS_INLINE const Identifier* Lexer<T>::makeIdentifierLCharFromUChar(const UChar* characters, size_t length) { - return &m_arena->makeIdentifierLCharFromUChar(m_globalData, characters, length); + return &m_arena->makeIdentifierLCharFromUChar(m_vm, characters, length); } template <typename T> ALWAYS_INLINE const Identifier* Lexer<T>::makeLCharIdentifier(const LChar* characters, size_t length) { - return &m_arena->makeIdentifier(m_globalData, characters, length); + return &m_arena->makeIdentifier(m_vm, characters, length); } template <typename T> ALWAYS_INLINE const Identifier* Lexer<T>::makeLCharIdentifier(const UChar* characters, size_t length) { - return &m_arena->makeIdentifierLCharFromUChar(m_globalData, characters, length); + return &m_arena->makeIdentifierLCharFromUChar(m_vm, characters, length); } template <typename T> @@ -317,7 +359,7 @@ ALWAYS_INLINE JSTokenType Lexer<T>::lexExpectIdentifier(JSTokenData* tokenData, m_current = 0; m_code = ptr; - m_columnNumber = m_columnNumber + (m_code - start); + ASSERT(currentOffset() >= currentLineStartOffset()); // Create the identifier if needed if (lexerFlags & LexexFlagsDontBuildKeywords) @@ -325,9 +367,10 @@ ALWAYS_INLINE JSTokenType Lexer<T>::lexExpectIdentifier(JSTokenData* tokenData, else tokenData->ident = makeLCharIdentifier(start, ptr - start); tokenLocation->line = m_lineNumber; - tokenLocation->startOffset = start - m_codeStart; + tokenLocation->lineStartOffset = currentLineStartOffset(); + tokenLocation->startOffset = offsetFromSourcePtr(start); tokenLocation->endOffset = currentOffset(); - tokenLocation->column = m_columnNumber; + ASSERT(tokenLocation->startOffset >= tokenLocation->lineStartOffset); m_lastToken = IDENT; return IDENT; |