summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/parser
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-11-07 11:22:47 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2012-11-07 11:22:47 +0100
commitcfd86b747d32ac22246a1aa908eaa720c63a88c1 (patch)
tree24d68c6f61c464ecba1e05670b80390ea3b0e50c /Source/JavaScriptCore/parser
parent69d7c744c9de19d152dbe2d8e46eb7dfd4511d1a (diff)
downloadqtwebkit-cfd86b747d32ac22246a1aa908eaa720c63a88c1.tar.gz
Imported WebKit commit 20271caf2e2c016d5cef40184cddeefeac4f1876 (http://svn.webkit.org/repository/webkit/trunk@133733)
New snapshot that contains all previous fixes as well as build fix for latest QtMultimedia API changes.
Diffstat (limited to 'Source/JavaScriptCore/parser')
-rw-r--r--Source/JavaScriptCore/parser/Lexer.cpp185
-rw-r--r--Source/JavaScriptCore/parser/Lexer.h9
-rw-r--r--Source/JavaScriptCore/parser/Parser.h74
-rw-r--r--Source/JavaScriptCore/parser/ParserModes.h40
-rw-r--r--Source/JavaScriptCore/parser/ParserTokens.h5
5 files changed, 263 insertions, 50 deletions
diff --git a/Source/JavaScriptCore/parser/Lexer.cpp b/Source/JavaScriptCore/parser/Lexer.cpp
index 8b2020987..477d403c1 100644
--- a/Source/JavaScriptCore/parser/Lexer.cpp
+++ b/Source/JavaScriptCore/parser/Lexer.cpp
@@ -355,6 +355,139 @@ static const unsigned short typesOfLatin1Characters[256] = {
/* 255 - Ll category */ CharacterIdentifierStart
};
+// This table provides the character that results from \X where X is the index in the table beginning
+// with SPACE. A table value of 0 means that more processing needs to be done.
+static const LChar singleCharacterEscapeValuesForASCII[128] = {
+/* 0 - Null */ 0,
+/* 1 - Start of Heading */ 0,
+/* 2 - Start of Text */ 0,
+/* 3 - End of Text */ 0,
+/* 4 - End of Transm. */ 0,
+/* 5 - Enquiry */ 0,
+/* 6 - Acknowledgment */ 0,
+/* 7 - Bell */ 0,
+/* 8 - Back Space */ 0,
+/* 9 - Horizontal Tab */ 0,
+/* 10 - Line Feed */ 0,
+/* 11 - Vertical Tab */ 0,
+/* 12 - Form Feed */ 0,
+/* 13 - Carriage Return */ 0,
+/* 14 - Shift Out */ 0,
+/* 15 - Shift In */ 0,
+/* 16 - Data Line Escape */ 0,
+/* 17 - Device Control 1 */ 0,
+/* 18 - Device Control 2 */ 0,
+/* 19 - Device Control 3 */ 0,
+/* 20 - Device Control 4 */ 0,
+/* 21 - Negative Ack. */ 0,
+/* 22 - Synchronous Idle */ 0,
+/* 23 - End of Transmit */ 0,
+/* 24 - Cancel */ 0,
+/* 25 - End of Medium */ 0,
+/* 26 - Substitute */ 0,
+/* 27 - Escape */ 0,
+/* 28 - File Separator */ 0,
+/* 29 - Group Separator */ 0,
+/* 30 - Record Separator */ 0,
+/* 31 - Unit Separator */ 0,
+/* 32 - Space */ ' ',
+/* 33 - ! */ '!',
+/* 34 - " */ '"',
+/* 35 - # */ '#',
+/* 36 - $ */ '$',
+/* 37 - % */ '%',
+/* 38 - & */ '&',
+/* 39 - ' */ '\'',
+/* 40 - ( */ '(',
+/* 41 - ) */ ')',
+/* 42 - * */ '*',
+/* 43 - + */ '+',
+/* 44 - , */ ',',
+/* 45 - - */ '-',
+/* 46 - . */ '.',
+/* 47 - / */ '/',
+/* 48 - 0 */ 0,
+/* 49 - 1 */ 0,
+/* 50 - 2 */ 0,
+/* 51 - 3 */ 0,
+/* 52 - 4 */ 0,
+/* 53 - 5 */ 0,
+/* 54 - 6 */ 0,
+/* 55 - 7 */ 0,
+/* 56 - 8 */ 0,
+/* 57 - 9 */ 0,
+/* 58 - : */ ':',
+/* 59 - ; */ ';',
+/* 60 - < */ '<',
+/* 61 - = */ '=',
+/* 62 - > */ '>',
+/* 63 - ? */ '?',
+/* 64 - @ */ '@',
+/* 65 - A */ 'A',
+/* 66 - B */ 'B',
+/* 67 - C */ 'C',
+/* 68 - D */ 'D',
+/* 69 - E */ 'E',
+/* 70 - F */ 'F',
+/* 71 - G */ 'G',
+/* 72 - H */ 'H',
+/* 73 - I */ 'I',
+/* 74 - J */ 'J',
+/* 75 - K */ 'K',
+/* 76 - L */ 'L',
+/* 77 - M */ 'M',
+/* 78 - N */ 'N',
+/* 79 - O */ 'O',
+/* 80 - P */ 'P',
+/* 81 - Q */ 'Q',
+/* 82 - R */ 'R',
+/* 83 - S */ 'S',
+/* 84 - T */ 'T',
+/* 85 - U */ 'U',
+/* 86 - V */ 'V',
+/* 87 - W */ 'W',
+/* 88 - X */ 'X',
+/* 89 - Y */ 'Y',
+/* 90 - Z */ 'Z',
+/* 91 - [ */ '[',
+/* 92 - \ */ '\\',
+/* 93 - ] */ ']',
+/* 94 - ^ */ '^',
+/* 95 - _ */ '_',
+/* 96 - ` */ '`',
+/* 97 - a */ 'a',
+/* 98 - b */ 0x08,
+/* 99 - c */ 'c',
+/* 100 - d */ 'd',
+/* 101 - e */ 'e',
+/* 102 - f */ 0x0C,
+/* 103 - g */ 'g',
+/* 104 - h */ 'h',
+/* 105 - i */ 'i',
+/* 106 - j */ 'j',
+/* 107 - k */ 'k',
+/* 108 - l */ 'l',
+/* 109 - m */ 'm',
+/* 110 - n */ 0x0A,
+/* 111 - o */ 'o',
+/* 112 - p */ 'p',
+/* 113 - q */ 'q',
+/* 114 - r */ 0x0D,
+/* 115 - s */ 's',
+/* 116 - t */ 0x09,
+/* 117 - u */ 0,
+/* 118 - v */ 0x0B,
+/* 119 - w */ 'w',
+/* 120 - x */ 0,
+/* 121 - y */ 'y',
+/* 122 - z */ 'z',
+/* 123 - { */ '{',
+/* 124 - | */ '|',
+/* 125 - } */ '}',
+/* 126 - ~ */ '~',
+/* 127 - Delete */ 0
+};
+
template <typename T>
Lexer<T>::Lexer(JSGlobalData* globalData)
: m_isReparsing(false)
@@ -547,30 +680,13 @@ static ALWAYS_INLINE bool isIdentPart(UChar c)
return isLatin1(c) ? isIdentPart(static_cast<LChar>(c)) : isNonLatin1IdentPart(c);
}
-static inline int singleEscape(int c)
+static inline LChar singleEscape(int c)
{
- switch (c) {
- case 'b':
- return 0x08;
- case 't':
- return 0x09;
- case 'n':
- return 0x0A;
- case 'v':
- return 0x0B;
- case 'f':
- return 0x0C;
- case 'r':
- return 0x0D;
- case '\\':
- return '\\';
- case '\'':
- return '\'';
- case '"':
- return '"';
- default:
- return 0;
+ if (c < 128) {
+ ASSERT(static_cast<size_t>(c) < ARRAY_SIZE(singleCharacterEscapeValuesForASCII));
+ return singleCharacterEscapeValuesForASCII[c];
}
+ return 0;
}
template <typename T>
@@ -842,7 +958,7 @@ template <bool shouldBuildStrings> ALWAYS_INLINE bool Lexer<T>::parseString(JSTo
append8(stringStart, currentCharacter() - stringStart);
shift();
- int escape = singleEscape(m_current);
+ LChar escape = singleEscape(m_current);
// Most common escape sequences first
if (escape) {
@@ -907,7 +1023,7 @@ template <bool shouldBuildStrings> bool Lexer<T>::parseStringSlowCase(JSTokenDat
append16(stringStart, currentCharacter() - stringStart);
shift();
- int escape = singleEscape(m_current);
+ LChar escape = singleEscape(m_current);
// Most common escape sequences first
if (escape) {
@@ -1570,12 +1686,25 @@ returnError:
}
template <typename T>
+static inline void orCharacter(UChar&, UChar);
+
+template <>
+inline void orCharacter<LChar>(UChar&, UChar) { }
+
+template <>
+inline void orCharacter<UChar>(UChar& orAccumulator, UChar character)
+{
+ orAccumulator |= character;
+}
+
+template <typename T>
bool Lexer<T>::scanRegExp(const Identifier*& pattern, const Identifier*& flags, UChar patternPrefix)
{
ASSERT(m_buffer16.isEmpty());
bool lastWasEscape = false;
bool inBrackets = false;
+ UChar charactersOredTogether = 0;
if (patternPrefix) {
ASSERT(!isLineTerminator(patternPrefix));
@@ -1598,6 +1727,7 @@ bool Lexer<T>::scanRegExp(const Identifier*& pattern, const Identifier*& flags,
break;
record16(prev);
+ orCharacter<T>(charactersOredTogether, prev);
if (lastWasEscape) {
lastWasEscape = false;
@@ -1617,15 +1747,18 @@ bool Lexer<T>::scanRegExp(const Identifier*& pattern, const Identifier*& flags,
}
}
- pattern = makeIdentifierSameType(m_buffer16.data(), m_buffer16.size());
+ pattern = makeRightSizedIdentifier(m_buffer16.data(), m_buffer16.size(), charactersOredTogether);
+
m_buffer16.resize(0);
+ charactersOredTogether = 0;
while (isIdentPart(m_current)) {
record16(m_current);
+ orCharacter<T>(charactersOredTogether, m_current);
shift();
}
- flags = makeIdentifierSameType(m_buffer16.data(), m_buffer16.size());
+ flags = makeRightSizedIdentifier(m_buffer16.data(), m_buffer16.size(), charactersOredTogether);
m_buffer16.resize(0);
return true;
diff --git a/Source/JavaScriptCore/parser/Lexer.h b/Source/JavaScriptCore/parser/Lexer.h
index aa1599b96..78c8c8cbd 100644
--- a/Source/JavaScriptCore/parser/Lexer.h
+++ b/Source/JavaScriptCore/parser/Lexer.h
@@ -148,7 +148,7 @@ private:
ALWAYS_INLINE const Identifier* makeIdentifier(const UChar* characters, size_t length);
ALWAYS_INLINE const Identifier* makeLCharIdentifier(const LChar* characters, size_t length);
ALWAYS_INLINE const Identifier* makeLCharIdentifier(const UChar* characters, size_t length);
- ALWAYS_INLINE const Identifier* makeIdentifierSameType(const UChar* characters, size_t length);
+ ALWAYS_INLINE const Identifier* makeRightSizedIdentifier(const UChar* characters, size_t length, UChar orAllChars);
ALWAYS_INLINE const Identifier* makeIdentifierLCharFromUChar(const UChar* characters, size_t length);
ALWAYS_INLINE bool lastTokenWasRestrKeyword() const;
@@ -242,14 +242,17 @@ ALWAYS_INLINE const Identifier* Lexer<T>::makeIdentifier(const UChar* characters
}
template <>
-ALWAYS_INLINE const Identifier* Lexer<LChar>::makeIdentifierSameType(const UChar* characters, size_t length)
+ALWAYS_INLINE const Identifier* Lexer<LChar>::makeRightSizedIdentifier(const UChar* characters, size_t length, UChar)
{
return &m_arena->makeIdentifierLCharFromUChar(m_globalData, characters, length);
}
template <>
-ALWAYS_INLINE const Identifier* Lexer<UChar>::makeIdentifierSameType(const UChar* characters, size_t length)
+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->makeIdentifier(m_globalData, characters, length);
}
diff --git a/Source/JavaScriptCore/parser/Parser.h b/Source/JavaScriptCore/parser/Parser.h
index 3b0316f81..615d09eb7 100644
--- a/Source/JavaScriptCore/parser/Parser.h
+++ b/Source/JavaScriptCore/parser/Parser.h
@@ -76,6 +76,49 @@ COMPILE_ASSERT(LastUntaggedToken < 64, LessThan64UntaggedTokens);
enum SourceElementsMode { CheckForStrictMode, DontCheckForStrictMode };
enum FunctionRequirements { FunctionNoRequirements, FunctionNeedsName };
+struct ParserError {
+ enum ErrorType { ErrorNone, StackOverflow, SyntaxError, EvalError, OutOfMemory } m_type;
+ String m_message;
+ int m_line;
+ ParserError()
+ : m_type(ErrorNone)
+ , m_line(-1)
+ {
+ }
+
+ ParserError(ErrorType type)
+ : m_type(type)
+ , m_line(-1)
+ {
+ }
+
+ ParserError(ErrorType type, String msg, int line)
+ : m_type(type)
+ , m_message(msg)
+ , m_line(line)
+ {
+ }
+
+ JSObject* toErrorObject(JSGlobalObject* globalObject, const SourceCode& source)
+ {
+ switch (m_type) {
+ case ErrorNone:
+ return 0;
+ case SyntaxError:
+ return addErrorInfo(globalObject->globalExec(), createSyntaxError(globalObject, m_message), m_line, source);
+ case EvalError:
+ return createSyntaxError(globalObject, m_message);
+ case StackOverflow:
+ return createStackOverflowError(globalObject);
+ case OutOfMemory:
+ return createOutOfMemoryError(globalObject);
+ }
+ CRASH();
+ return createOutOfMemoryError(globalObject); // Appease Qt bot
+ }
+
+};
+
template <typename T> inline bool isEvalNode() { return false; }
template <> inline bool isEvalNode<EvalNode>() { return true; }
@@ -370,7 +413,7 @@ public:
~Parser();
template <class ParsedNode>
- PassRefPtr<ParsedNode> parse(JSGlobalObject* lexicalGlobalObject, Debugger*, ExecState*, JSObject**);
+ PassRefPtr<ParsedNode> parse(ParserError&);
private:
struct AllowInOverride {
@@ -890,7 +933,7 @@ private:
return m_lastTokenEnd;
}
- mutable const JSGlobalData* m_globalData;
+ JSGlobalData* m_globalData;
const SourceCode* m_source;
ParserArena* m_arena;
OwnPtr<LexerType> m_lexer;
@@ -935,12 +978,11 @@ private:
};
};
+
template <typename LexerType>
template <class ParsedNode>
-PassRefPtr<ParsedNode> Parser<LexerType>::parse(JSGlobalObject* lexicalGlobalObject, Debugger* debugger, ExecState* debuggerExecState, JSObject** exception)
+PassRefPtr<ParsedNode> Parser<LexerType>::parse(ParserError& error)
{
- ASSERT(lexicalGlobalObject);
- ASSERT(exception && !*exception);
int errLine;
String errMsg;
@@ -971,7 +1013,7 @@ PassRefPtr<ParsedNode> Parser<LexerType>::parse(JSGlobalObject* lexicalGlobalObj
JSTokenLocation location;
location.line = m_lexer->lastLineNumber();
location.column = m_lexer->currentColumnNumber();
- result = ParsedNode::create(&lexicalGlobalObject->globalData(),
+ result = ParsedNode::create(m_globalData,
location,
m_sourceElements,
m_varDeclarations ? &m_varDeclarations->data : 0,
@@ -981,7 +1023,7 @@ PassRefPtr<ParsedNode> Parser<LexerType>::parse(JSGlobalObject* lexicalGlobalObj
m_features,
m_numConstants);
result->setLoc(m_source->firstLine(), m_lastLine, m_lexer->currentColumnNumber());
- } else if (lexicalGlobalObject) {
+ } else {
// We can never see a syntax error when reparsing a function, since we should have
// reported the error when parsing the containing program or eval code. So if we're
// parsing a function body node, we assume that what actually happened here is that
@@ -989,35 +1031,31 @@ PassRefPtr<ParsedNode> Parser<LexerType>::parse(JSGlobalObject* lexicalGlobalObj
// code we assume that it was a syntax error since running out of stack is much less
// likely, and we are currently unable to distinguish between the two cases.
if (isFunctionBodyNode(static_cast<ParsedNode*>(0)) || m_hasStackOverflow)
- *exception = createStackOverflowError(lexicalGlobalObject);
+ error = ParserError::StackOverflow;
else if (isEvalNode<ParsedNode>())
- *exception = createSyntaxError(lexicalGlobalObject, errMsg);
+ error = ParserError(ParserError::EvalError, errMsg, errLine);
else
- *exception = addErrorInfo(lexicalGlobalObject->globalExec(), createSyntaxError(lexicalGlobalObject, errMsg), errLine, *m_source);
+ error = ParserError(ParserError::SyntaxError, errMsg, errLine);
}
- if (debugger && !ParsedNode::scopeIsFunction)
- debugger->sourceParsed(debuggerExecState, m_source->provider(), errLine, errMsg);
-
m_arena->reset();
return result.release();
}
template <class ParsedNode>
-PassRefPtr<ParsedNode> parse(JSGlobalData* globalData, JSGlobalObject* lexicalGlobalObject, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode, Debugger* debugger, ExecState* execState, JSObject** exception)
+PassRefPtr<ParsedNode> parse(JSGlobalData* globalData, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode, ParserError& error)
{
SamplingRegion samplingRegion("Parsing");
ASSERT(!source.provider()->source().isNull());
-
if (source.provider()->source().is8Bit()) {
Parser< Lexer<LChar> > parser(globalData, source, parameters, name, strictness, parserMode);
- return parser.parse<ParsedNode>(lexicalGlobalObject, debugger, execState, exception);
+ return parser.parse<ParsedNode>(error);
}
Parser< Lexer<UChar> > parser(globalData, source, parameters, name, strictness, parserMode);
- return parser.parse<ParsedNode>(lexicalGlobalObject, debugger, execState, exception);
+ return parser.parse<ParsedNode>(error);
}
-} // namespace
+} // namespace
#endif
diff --git a/Source/JavaScriptCore/parser/ParserModes.h b/Source/JavaScriptCore/parser/ParserModes.h
new file mode 100644
index 000000000..41fb7fdf9
--- /dev/null
+++ b/Source/JavaScriptCore/parser/ParserModes.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef ParserModes_h
+#define ParserModes_h
+
+namespace JSC {
+
+enum JSParserStrictness { JSParseNormal, JSParseStrict };
+enum JSParserMode { JSParseProgramCode, JSParseFunctionCode };
+
+enum ProfilerMode { ProfilerOff, ProfilerOn };
+enum DebuggerMode { DebuggerOff, DebuggerOn };
+
+}
+
+#endif
diff --git a/Source/JavaScriptCore/parser/ParserTokens.h b/Source/JavaScriptCore/parser/ParserTokens.h
index 6e6cec114..14191b95d 100644
--- a/Source/JavaScriptCore/parser/ParserTokens.h
+++ b/Source/JavaScriptCore/parser/ParserTokens.h
@@ -26,6 +26,8 @@
#ifndef ParserTokens_h
#define ParserTokens_h
+#include "ParserModes.h"
+
namespace JSC {
class Identifier;
@@ -161,9 +163,6 @@ struct JSToken {
JSTokenLocation m_location;
};
-enum JSParserStrictness { JSParseNormal, JSParseStrict };
-enum JSParserMode { JSParseProgramCode, JSParseFunctionCode };
-
}