summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/parser/Lexer.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/parser/Lexer.h')
-rw-r--r--Source/JavaScriptCore/parser/Lexer.h105
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;