]>
Commit | Line | Data |
---|---|---|
b37bf2e1 | 1 | /* |
b37bf2e1 A |
2 | * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) |
3 | * Copyright (C) 2001 Peter Kelly (pmk@post.com) | |
9dae56ea | 4 | * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
b37bf2e1 A |
5 | * |
6 | * This library is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU Library General Public | |
8 | * License as published by the Free Software Foundation; either | |
9 | * version 2 of the License, or (at your option) any later version. | |
10 | * | |
11 | * This library is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * Library General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU Library General Public License | |
17 | * along with this library; see the file COPYING.LIB. If not, write to | |
18 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
19 | * Boston, MA 02110-1301, USA. | |
20 | * | |
21 | */ | |
22 | ||
23 | #ifndef Parser_h | |
24 | #define Parser_h | |
25 | ||
9dae56ea | 26 | #include "Debugger.h" |
14957cd0 | 27 | #include "ExceptionHelpers.h" |
f9bf01c6 A |
28 | #include "Executable.h" |
29 | #include "JSGlobalObject.h" | |
30 | #include "Lexer.h" | |
9dae56ea | 31 | #include "Nodes.h" |
f9bf01c6 | 32 | #include "ParserArena.h" |
ba379fdc | 33 | #include "SourceProvider.h" |
b37bf2e1 A |
34 | #include <wtf/Forward.h> |
35 | #include <wtf/Noncopyable.h> | |
36 | #include <wtf/OwnPtr.h> | |
37 | #include <wtf/RefPtr.h> | |
b37bf2e1 | 38 | |
9dae56ea | 39 | namespace JSC { |
b37bf2e1 A |
40 | |
41 | class FunctionBodyNode; | |
14957cd0 | 42 | |
b37bf2e1 A |
43 | class ProgramNode; |
44 | class UString; | |
45 | ||
ba379fdc | 46 | template <typename T> struct ParserArenaData : ParserArenaDeletable { T data; }; |
b37bf2e1 | 47 | |
14957cd0 A |
48 | class Parser { |
49 | WTF_MAKE_NONCOPYABLE(Parser); WTF_MAKE_FAST_ALLOCATED; | |
b37bf2e1 | 50 | public: |
14957cd0 | 51 | Parser() { } |
f9bf01c6 | 52 | template <class ParsedNode> |
14957cd0 | 53 | PassRefPtr<ParsedNode> parse(JSGlobalObject* lexicalGlobalObject, Debugger*, ExecState*, const SourceCode& source, FunctionParameters*, JSParserStrictness strictness, JSObject** exception); |
b37bf2e1 | 54 | |
ba379fdc | 55 | void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*, |
14957cd0 A |
56 | ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures features, |
57 | int lastLine, int numConstants, IdentifierSet&); | |
ba379fdc A |
58 | |
59 | ParserArena& arena() { return m_arena; } | |
b5422865 | 60 | |
b37bf2e1 | 61 | private: |
14957cd0 A |
62 | void parse(JSGlobalData*, FunctionParameters*, JSParserStrictness strictness, JSParserMode mode, int* errLine, UString* errMsg); |
63 | ||
64 | // Used to determine type of error to report. | |
65 | bool isFunctionBodyNode(ScopeNode*) { return false; } | |
66 | bool isFunctionBodyNode(FunctionBodyNode*) { return true; } | |
b37bf2e1 | 67 | |
ba379fdc | 68 | ParserArena m_arena; |
b5422865 | 69 | const SourceCode* m_source; |
ba379fdc A |
70 | SourceElements* m_sourceElements; |
71 | ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations; | |
72 | ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations; | |
14957cd0 | 73 | IdentifierSet m_capturedVariables; |
9dae56ea | 74 | CodeFeatures m_features; |
b37bf2e1 | 75 | int m_lastLine; |
9dae56ea | 76 | int m_numConstants; |
b37bf2e1 | 77 | }; |
b37bf2e1 | 78 | |
f9bf01c6 | 79 | template <class ParsedNode> |
14957cd0 | 80 | PassRefPtr<ParsedNode> Parser::parse(JSGlobalObject* lexicalGlobalObject, Debugger* debugger, ExecState* debuggerExecState, const SourceCode& source, FunctionParameters* parameters, JSParserStrictness strictness, JSObject** exception) |
b37bf2e1 | 81 | { |
14957cd0 A |
82 | ASSERT(lexicalGlobalObject); |
83 | ASSERT(exception && !*exception); | |
84 | int errLine; | |
85 | UString errMsg; | |
86 | ||
b5422865 | 87 | m_source = &source; |
f9bf01c6 | 88 | if (ParsedNode::scopeIsFunction) |
14957cd0 A |
89 | lexicalGlobalObject->globalData().lexer->setIsReparsing(); |
90 | parse(&lexicalGlobalObject->globalData(), parameters, strictness, ParsedNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, &errLine, &errMsg); | |
9dae56ea | 91 | |
b5422865 A |
92 | RefPtr<ParsedNode> result; |
93 | if (m_sourceElements) { | |
14957cd0 A |
94 | result = ParsedNode::create(&lexicalGlobalObject->globalData(), |
95 | m_sourceElements, | |
96 | m_varDeclarations ? &m_varDeclarations->data : 0, | |
97 | m_funcDeclarations ? &m_funcDeclarations->data : 0, | |
98 | m_capturedVariables, | |
99 | source, | |
100 | m_features, | |
101 | m_numConstants); | |
b5422865 | 102 | result->setLoc(m_source->firstLine(), m_lastLine); |
14957cd0 A |
103 | } else if (lexicalGlobalObject) { |
104 | // We can never see a syntax error when reparsing a function, since we should have | |
105 | // reported the error when parsing the containing program or eval code. So if we're | |
106 | // parsing a function body node, we assume that what actually happened here is that | |
107 | // we ran out of stack while parsing. If we see an error while parsing eval or program | |
108 | // code we assume that it was a syntax error since running out of stack is much less | |
109 | // likely, and we are currently unable to distinguish between the two cases. | |
110 | if (isFunctionBodyNode(static_cast<ParsedNode*>(0))) | |
111 | *exception = createStackOverflowError(lexicalGlobalObject); | |
112 | else | |
113 | *exception = addErrorInfo(&lexicalGlobalObject->globalData(), createSyntaxError(lexicalGlobalObject, errMsg), errLine, source); | |
b37bf2e1 | 114 | } |
b5422865 | 115 | |
ba379fdc A |
116 | m_arena.reset(); |
117 | ||
b5422865 | 118 | m_source = 0; |
f9bf01c6 | 119 | m_sourceElements = 0; |
b37bf2e1 A |
120 | m_varDeclarations = 0; |
121 | m_funcDeclarations = 0; | |
9dae56ea | 122 | |
f9bf01c6 | 123 | if (debugger && !ParsedNode::scopeIsFunction) |
14957cd0 | 124 | debugger->sourceParsed(debuggerExecState, source.provider(), errLine, errMsg); |
b5422865 | 125 | return result.release(); |
b37bf2e1 A |
126 | } |
127 | ||
9dae56ea | 128 | } // namespace JSC |
b37bf2e1 A |
129 | |
130 | #endif // Parser_h |