c057517464fa9a169cb04b1c5fb1dfb9ff5f9613
[WebKit-https.git] / Source / JavaScriptCore / parser / Nodes.cpp
1 /*
2 *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
3 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
5 *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
6 *  Copyright (C) 2007 Maks Orlovich
7 *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
8 *
9 *  This library is free software; you can redistribute it and/or
10 *  modify it under the terms of the GNU Library General Public
11 *  License as published by the Free Software Foundation; either
12 *  version 2 of the License, or (at your option) any later version.
13 *
14 *  This library is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 *  Library General Public License for more details.
18 *
19 *  You should have received a copy of the GNU Library General Public License
20 *  along with this library; see the file COPYING.LIB.  If not, write to
21 *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 */
25
26 #include "config.h"
27 #include "Nodes.h"
28 #include "NodeConstructors.h"
29
30 #include "BytecodeGenerator.h"
31 #include "CallFrame.h"
32 #include "Debugger.h"
33 #include "JIT.h"
34 #include "JSFunction.h"
35 #include "JSGlobalObject.h"
36 #include "JSNameScope.h"
37 #include "LabelScope.h"
38 #include "Lexer.h"
39 #include "Operations.h"
40 #include "Parser.h"
41 #include "PropertyNameArray.h"
42 #include "RegExpObject.h"
43 #include "SamplingTool.h"
44 #include <wtf/Assertions.h>
45 #include <wtf/RefCountedLeakCounter.h>
46 #include <wtf/Threading.h>
47
48 using namespace WTF;
49
50 namespace JSC {
51
52
53 // ------------------------------ StatementNode --------------------------------
54
55 void StatementNode::setLoc(int firstLine, int lastLine, int column)
56 {
57     m_lineNumber = firstLine;
58     m_lastLine = lastLine;
59     m_columnNumber = column;
60 }
61
62 void StatementNode::setLoc(int firstLine, int lastLine)
63 {
64     m_lineNumber = firstLine;
65     m_lastLine = lastLine;
66     m_columnNumber = 0;
67 }
68
69 // ------------------------------ SourceElements --------------------------------
70
71 void SourceElements::append(StatementNode* statement)
72 {
73     if (statement->isEmptyStatement())
74         return;
75     m_statements.append(statement);
76 }
77
78 StatementNode* SourceElements::singleStatement() const
79 {
80     size_t size = m_statements.size();
81     return size == 1 ? m_statements[0] : 0;
82 }
83
84 // ------------------------------ ScopeNode -----------------------------
85
86 ScopeNode::ScopeNode(JSGlobalData* globalData, const JSTokenLocation& location, bool inStrictContext)
87     : StatementNode(location)
88     , ParserArenaRefCounted(globalData)
89     , m_features(inStrictContext ? StrictModeFeature : NoFeatures)
90     , m_numConstants(0)
91     , m_statements(0)
92 {
93 }
94
95 ScopeNode::ScopeNode(JSGlobalData* globalData, const JSTokenLocation& location, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants)
96     : StatementNode(location)
97     , ParserArenaRefCounted(globalData)
98     , m_features(features)
99     , m_source(source)
100     , m_numConstants(numConstants)
101     , m_statements(children)
102 {
103     m_arena.swap(*globalData->parserArena);
104     if (varStack)
105         m_varStack.swap(*varStack);
106     if (funcStack)
107         m_functionStack.swap(*funcStack);
108     m_capturedVariables.swap(capturedVariables);
109 }
110
111 StatementNode* ScopeNode::singleStatement() const
112 {
113     return m_statements ? m_statements->singleStatement() : 0;
114 }
115
116 // ------------------------------ ProgramNode -----------------------------
117
118 inline ProgramNode::ProgramNode(JSGlobalData* globalData, const JSTokenLocation& location, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
119     : ScopeNode(globalData, location, source, children, varStack, funcStack, capturedVariables, features, numConstants)
120 {
121 }
122
123 PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, const JSTokenLocation& location, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
124 {
125     RefPtr<ProgramNode> node = new ProgramNode(globalData, location, children, varStack, funcStack,  capturedVariables, source, features, numConstants);
126
127     ASSERT(node->m_arena.last() == node);
128     node->m_arena.removeLast();
129     ASSERT(!node->m_arena.contains(node.get()));
130
131     return node.release();
132 }
133
134 // ------------------------------ EvalNode -----------------------------
135
136 inline EvalNode::EvalNode(JSGlobalData* globalData, const JSTokenLocation& location, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
137     : ScopeNode(globalData, location, source, children, varStack, funcStack, capturedVariables, features, numConstants)
138 {
139 }
140
141 PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, const JSTokenLocation& location, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
142 {
143     RefPtr<EvalNode> node = new EvalNode(globalData, location, children, varStack, funcStack, capturedVariables, source, features, numConstants);
144
145     ASSERT(node->m_arena.last() == node);
146     node->m_arena.removeLast();
147     ASSERT(!node->m_arena.contains(node.get()));
148
149     return node.release();
150 }
151
152 // ------------------------------ FunctionBodyNode -----------------------------
153
154 FunctionParameters::FunctionParameters(ParameterNode* firstParameter)
155 {
156     for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
157         append(parameter->ident());
158 }
159
160 inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, const JSTokenLocation& location, bool inStrictContext)
161     : ScopeNode(globalData, location, inStrictContext)
162 {
163 }
164
165 inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, const JSTokenLocation& location, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
166     : ScopeNode(globalData, location, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants)
167 {
168 }
169
170 void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter, const Identifier& ident)
171 {
172     setSource(source);
173     finishParsing(FunctionParameters::create(firstParameter), ident);
174 }
175
176 void FunctionBodyNode::finishParsing(PassRefPtr<FunctionParameters> parameters, const Identifier& ident)
177 {
178     ASSERT(!source().isNull());
179     m_parameters = parameters;
180     m_ident = ident;
181 }
182
183 FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, const JSTokenLocation& location, bool inStrictContext)
184 {
185     return new FunctionBodyNode(globalData, location, inStrictContext);
186 }
187
188 PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, const JSTokenLocation& location, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
189 {
190     RefPtr<FunctionBodyNode> node = new FunctionBodyNode(globalData, location, children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants);
191
192     ASSERT(node->m_arena.last() == node);
193     node->m_arena.removeLast();
194     ASSERT(!node->m_arena.contains(node.get()));
195
196     return node.release();
197 }
198
199 } // namespace JSC