|
1 /* |
|
2 * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) |
|
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com) |
|
4 * Copyright (C) 2003, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
|
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 |
|
26 #include "Debugger.h" |
|
27 #include "ExceptionHelpers.h" |
|
28 #include "Executable.h" |
|
29 #include "JSGlobalObject.h" |
|
30 #include "Lexer.h" |
|
31 #include "Nodes.h" |
|
32 #include "ParserArena.h" |
|
33 #include "SourceProvider.h" |
|
34 #include <wtf/Forward.h> |
|
35 #include <wtf/Noncopyable.h> |
|
36 #include <wtf/OwnPtr.h> |
|
37 #include <wtf/RefPtr.h> |
|
38 |
|
39 namespace JSC { |
|
40 |
|
41 class FunctionBodyNode; |
|
42 |
|
43 class ProgramNode; |
|
44 class UString; |
|
45 |
|
46 template <typename T> struct ParserArenaData : ParserArenaDeletable { T data; }; |
|
47 |
|
48 class Parser : public Noncopyable { |
|
49 public: |
|
50 template <class ParsedNode> |
|
51 PassRefPtr<ParsedNode> parse(JSGlobalData* globalData, JSGlobalObject* lexicalGlobalObject, Debugger*, ExecState*, const SourceCode& source, JSObject** exception); |
|
52 |
|
53 void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*, |
|
54 ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures features, int lastLine, int numConstants); |
|
55 |
|
56 ParserArena& arena() { return m_arena; } |
|
57 |
|
58 private: |
|
59 void parse(JSGlobalData*, int* errLine, UString* errMsg); |
|
60 |
|
61 // Used to determine type of error to report. |
|
62 bool isFunctionBodyNode(ScopeNode*) { return false; } |
|
63 bool isFunctionBodyNode(FunctionBodyNode*) { return true; } |
|
64 |
|
65 ParserArena m_arena; |
|
66 const SourceCode* m_source; |
|
67 SourceElements* m_sourceElements; |
|
68 ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations; |
|
69 ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations; |
|
70 CodeFeatures m_features; |
|
71 int m_lastLine; |
|
72 int m_numConstants; |
|
73 }; |
|
74 |
|
75 template <class ParsedNode> |
|
76 PassRefPtr<ParsedNode> Parser::parse(JSGlobalData* globalData, JSGlobalObject* lexicalGlobalObject, Debugger* debugger, ExecState* debuggerExecState, const SourceCode& source, JSObject** exception) |
|
77 { |
|
78 ASSERT(exception && !*exception); |
|
79 int errLine; |
|
80 UString errMsg; |
|
81 |
|
82 m_source = &source; |
|
83 if (ParsedNode::scopeIsFunction) |
|
84 globalData->lexer->setIsReparsing(); |
|
85 parse(globalData, &errLine, &errMsg); |
|
86 |
|
87 RefPtr<ParsedNode> result; |
|
88 if (m_sourceElements) { |
|
89 result = ParsedNode::create(globalData, |
|
90 m_sourceElements, |
|
91 m_varDeclarations ? &m_varDeclarations->data : 0, |
|
92 m_funcDeclarations ? &m_funcDeclarations->data : 0, |
|
93 source, |
|
94 m_features, |
|
95 m_numConstants); |
|
96 result->setLoc(m_source->firstLine(), m_lastLine); |
|
97 } else if (lexicalGlobalObject) { |
|
98 // We can never see a syntax error when reparsing a function, since we should have |
|
99 // reported the error when parsing the containing program or eval code. So if we're |
|
100 // parsing a function body node, we assume that what actually happened here is that |
|
101 // we ran out of stack while parsing. If we see an error while parsing eval or program |
|
102 // code we assume that it was a syntax error since running out of stack is much less |
|
103 // likely, and we are currently unable to distinguish between the two cases. |
|
104 if (isFunctionBodyNode(static_cast<ParsedNode*>(0))) |
|
105 *exception = createStackOverflowError(lexicalGlobalObject); |
|
106 else |
|
107 *exception = addErrorInfo(globalData, createSyntaxError(lexicalGlobalObject, errMsg), errLine, source); |
|
108 } |
|
109 |
|
110 m_arena.reset(); |
|
111 |
|
112 m_source = 0; |
|
113 m_sourceElements = 0; |
|
114 m_varDeclarations = 0; |
|
115 m_funcDeclarations = 0; |
|
116 |
|
117 if (debugger && !ParsedNode::scopeIsFunction) |
|
118 debugger->sourceParsed(debuggerExecState, source, errLine, errMsg); |
|
119 return result.release(); |
|
120 } |
|
121 |
|
122 } // namespace JSC |
|
123 |
|
124 #endif // Parser_h |