]> git.saurik.com Git - apple/javascriptcore.git/blob - parser/Nodes.cpp
c32e4c73a24ebeb233cd5e01fffd63a48685c886
[apple/javascriptcore.git] / 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 "JSStaticScopeObject.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)
56 {
57 m_lineNumber = firstLine;
58 m_lastLine = lastLine;
59 }
60
61 // ------------------------------ SourceElements --------------------------------
62
63 void SourceElements::append(StatementNode* statement)
64 {
65 if (statement->isEmptyStatement())
66 return;
67 m_statements.append(statement);
68 }
69
70 StatementNode* SourceElements::singleStatement() const
71 {
72 size_t size = m_statements.size();
73 return size == 1 ? m_statements[0] : 0;
74 }
75
76 // ------------------------------ ScopeNode -----------------------------
77
78 ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, bool inStrictContext)
79 : StatementNode(lineNumber)
80 , ParserArenaRefCounted(globalData)
81 , m_features(inStrictContext ? StrictModeFeature : NoFeatures)
82 , m_numConstants(0)
83 , m_statements(0)
84 {
85 }
86
87 ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants)
88 : StatementNode(lineNumber)
89 , ParserArenaRefCounted(globalData)
90 , m_features(features)
91 , m_source(source)
92 , m_numConstants(numConstants)
93 , m_statements(children)
94 {
95 m_arena.swap(*globalData->parserArena);
96 if (varStack)
97 m_varStack.swap(*varStack);
98 if (funcStack)
99 m_functionStack.swap(*funcStack);
100 m_capturedVariables.swap(capturedVariables);
101 }
102
103 StatementNode* ScopeNode::singleStatement() const
104 {
105 return m_statements ? m_statements->singleStatement() : 0;
106 }
107
108 // ------------------------------ ProgramNode -----------------------------
109
110 inline ProgramNode::ProgramNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
111 : ScopeNode(globalData, lineNumber, source, children, varStack, funcStack, capturedVariables, features, numConstants)
112 {
113 }
114
115 PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
116 {
117 RefPtr<ProgramNode> node = new ProgramNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, source, features, numConstants);
118
119 ASSERT(node->m_arena.last() == node);
120 node->m_arena.removeLast();
121 ASSERT(!node->m_arena.contains(node.get()));
122
123 return node.release();
124 }
125
126 // ------------------------------ EvalNode -----------------------------
127
128 inline EvalNode::EvalNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
129 : ScopeNode(globalData, lineNumber, source, children, varStack, funcStack, capturedVariables, features, numConstants)
130 {
131 }
132
133 PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
134 {
135 RefPtr<EvalNode> node = new EvalNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, source, features, numConstants);
136
137 ASSERT(node->m_arena.last() == node);
138 node->m_arena.removeLast();
139 ASSERT(!node->m_arena.contains(node.get()));
140
141 return node.release();
142 }
143
144 // ------------------------------ FunctionBodyNode -----------------------------
145
146 FunctionParameters::FunctionParameters(ParameterNode* firstParameter)
147 {
148 for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
149 append(parameter->ident());
150 }
151
152 inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, int lineNumber, bool inStrictContext)
153 : ScopeNode(globalData, lineNumber, inStrictContext)
154 {
155 }
156
157 inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
158 : ScopeNode(globalData, lineNumber, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants)
159 {
160 }
161
162 void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter, const Identifier& ident)
163 {
164 setSource(source);
165 finishParsing(FunctionParameters::create(firstParameter), ident);
166 }
167
168 void FunctionBodyNode::finishParsing(PassRefPtr<FunctionParameters> parameters, const Identifier& ident)
169 {
170 ASSERT(!source().isNull());
171 m_parameters = parameters;
172 m_ident = ident;
173 }
174
175 FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, bool inStrictContext)
176 {
177 return new FunctionBodyNode(globalData, lineNumber, inStrictContext);
178 }
179
180 PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
181 {
182 RefPtr<FunctionBodyNode> node = new FunctionBodyNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants);
183
184 ASSERT(node->m_arena.last() == node);
185 node->m_arena.removeLast();
186 ASSERT(!node->m_arena.contains(node.get()));
187
188 return node.release();
189 }
190
191 } // namespace JSC