diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2012-11-07 11:22:47 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-11-07 11:22:47 +0100 |
commit | cfd86b747d32ac22246a1aa908eaa720c63a88c1 (patch) | |
tree | 24d68c6f61c464ecba1e05670b80390ea3b0e50c /Source/JavaScriptCore/parser | |
parent | 69d7c744c9de19d152dbe2d8e46eb7dfd4511d1a (diff) | |
download | qtwebkit-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.cpp | 185 | ||||
-rw-r--r-- | Source/JavaScriptCore/parser/Lexer.h | 9 | ||||
-rw-r--r-- | Source/JavaScriptCore/parser/Parser.h | 74 | ||||
-rw-r--r-- | Source/JavaScriptCore/parser/ParserModes.h | 40 | ||||
-rw-r--r-- | Source/JavaScriptCore/parser/ParserTokens.h | 5 |
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 }; - } |