+ 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;
+ String m_lexErrorMessage;
+
+ T m_current;
+
+ IdentifierArena* m_arena;
+
+ VM* m_vm;
+};
+
+template <>
+ALWAYS_INLINE bool Lexer<LChar>::isWhiteSpace(LChar ch)
+{
+ return ch == ' ' || ch == '\t' || ch == 0xB || ch == 0xC || ch == 0xA0;
+}
+
+template <>
+ALWAYS_INLINE bool Lexer<UChar>::isWhiteSpace(UChar ch)
+{
+ return (ch < 256) ? Lexer<LChar>::isWhiteSpace(static_cast<LChar>(ch)) : (WTF::Unicode::isSeparatorSpace(ch) || ch == 0xFEFF);
+}
+
+template <>
+ALWAYS_INLINE bool Lexer<LChar>::isLineTerminator(LChar ch)
+{
+ return ch == '\r' || ch == '\n';
+}
+
+template <>
+ALWAYS_INLINE bool Lexer<UChar>::isLineTerminator(UChar ch)
+{
+ return ch == '\r' || ch == '\n' || (ch & ~1) == 0x2028;
+}
+
+template <typename T>
+inline unsigned char Lexer<T>::convertHex(int c1, int c2)
+{
+ return (toASCIIHexValue(c1) << 4) | toASCIIHexValue(c2);
+}
+
+template <typename T>
+inline UChar Lexer<T>::convertUnicode(int c1, int c2, int c3, int c4)
+{
+ return (convertHex(c1, c2) << 8) | convertHex(c3, c4);
+}
+
+template <typename T>
+ALWAYS_INLINE const Identifier* Lexer<T>::makeIdentifier(const LChar* characters, size_t 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_vm, characters, length);
+}
+
+template <>
+ALWAYS_INLINE const Identifier* Lexer<LChar>::makeRightSizedIdentifier(const UChar* characters, size_t length, UChar)
+{
+ 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_vm, characters, length);
+
+ return &m_arena->makeIdentifier(m_vm, characters, length);
+}
+
+template <>
+ALWAYS_INLINE void Lexer<LChar>::setCodeStart(const StringImpl* sourceString)
+{
+ ASSERT(sourceString->is8Bit());
+ m_codeStart = sourceString->characters8();
+}
+
+template <>
+ALWAYS_INLINE void Lexer<UChar>::setCodeStart(const StringImpl* sourceString)
+{
+ ASSERT(!sourceString->is8Bit());
+ m_codeStart = sourceString->characters16();
+}
+
+template <typename T>
+ALWAYS_INLINE const Identifier* Lexer<T>::makeIdentifierLCharFromUChar(const UChar* characters, size_t 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_vm, characters, length);
+}
+
+template <typename T>
+ALWAYS_INLINE const Identifier* Lexer<T>::makeLCharIdentifier(const UChar* characters, size_t length)
+{
+ return &m_arena->makeIdentifierLCharFromUChar(m_vm, characters, length);
+}
+
+template <typename T>
+ALWAYS_INLINE JSTokenType Lexer<T>::lexExpectIdentifier(JSTokenData* tokenData, JSTokenLocation* tokenLocation, unsigned lexerFlags, bool strictMode)
+{
+ ASSERT((lexerFlags & LexerFlagsIgnoreReservedWords));
+ const T* start = m_code;
+ const T* ptr = start;
+ const T* end = m_codeEnd;
+ if (ptr >= end) {
+ ASSERT(ptr == end);
+ goto slowCase;
+ }
+ if (!WTF::isASCIIAlpha(*ptr))
+ goto slowCase;
+ ++ptr;
+ while (ptr < end) {
+ if (!WTF::isASCIIAlphanumeric(*ptr))
+ break;
+ ++ptr;