]> git.saurik.com Git - apple/javascriptcore.git/blob - parser/Nodes.cpp
JavaScriptCore-7600.1.4.15.12.tar.gz
[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, 2013 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 "JSCInlines.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(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset)
56 {
57 m_lastLine = lastLine;
58 m_position = JSTextPosition(firstLine, startOffset, lineStartOffset);
59 ASSERT(m_position.offset >= m_position.lineStartOffset);
60 }
61
62 // ------------------------------ SourceElements --------------------------------
63
64 void SourceElements::append(StatementNode* statement)
65 {
66 if (statement->isEmptyStatement())
67 return;
68 m_statements.append(statement);
69 }
70
71 StatementNode* SourceElements::singleStatement() const
72 {
73 size_t size = m_statements.size();
74 return size == 1 ? m_statements[0] : 0;
75 }
76
77 // ------------------------------ ScopeNode -----------------------------
78
79 ScopeNode::ScopeNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, bool inStrictContext)
80 : StatementNode(endLocation)
81 , ParserArenaRefCounted(vm)
82 , m_startLineNumber(startLocation.line)
83 , m_startStartOffset(startLocation.startOffset)
84 , m_startLineStartOffset(startLocation.lineStartOffset)
85 , m_features(inStrictContext ? StrictModeFeature : NoFeatures)
86 , m_numConstants(0)
87 , m_statements(0)
88 {
89 }
90
91 ScopeNode::ScopeNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants)
92 : StatementNode(endLocation)
93 , ParserArenaRefCounted(vm)
94 , m_startLineNumber(startLocation.line)
95 , m_startStartOffset(startLocation.startOffset)
96 , m_startLineStartOffset(startLocation.lineStartOffset)
97 , m_features(features)
98 , m_source(source)
99 , m_numConstants(numConstants)
100 , m_statements(children)
101 {
102 m_arena.swap(*vm->parserArena);
103 if (varStack)
104 m_varStack.swap(*varStack);
105 if (funcStack)
106 m_functionStack.swap(*funcStack);
107 m_capturedVariables.swap(capturedVariables);
108 }
109
110 StatementNode* ScopeNode::singleStatement() const
111 {
112 return m_statements ? m_statements->singleStatement() : 0;
113 }
114
115 // ------------------------------ ProgramNode -----------------------------
116
117 inline ProgramNode::ProgramNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
118 : ScopeNode(vm, startLocation, endLocation, source, children, varStack, funcStack, capturedVariables, features, numConstants)
119 , m_startColumn(startColumn)
120 , m_endColumn(endColumn)
121 {
122 }
123
124 PassRefPtr<ProgramNode> ProgramNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
125 {
126 RefPtr<ProgramNode> node = new ProgramNode(vm, startLocation, endLocation, startColumn, endColumn, children, varStack, funcStack, capturedVariables, source, features, numConstants);
127
128 ASSERT(node->m_arena.last() == node);
129 node->m_arena.removeLast();
130 ASSERT(!node->m_arena.contains(node.get()));
131
132 return node.release();
133 }
134
135
136 void ProgramNode::setClosedVariables(Vector<RefPtr<StringImpl>>&& closedVariables)
137 {
138 m_closedVariables = WTF::move(closedVariables);
139 }
140
141 // ------------------------------ EvalNode -----------------------------
142
143 inline EvalNode::EvalNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned endColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
144 : ScopeNode(vm, startLocation, endLocation, source, children, varStack, funcStack, capturedVariables, features, numConstants)
145 , m_endColumn(endColumn)
146 {
147 }
148
149 PassRefPtr<EvalNode> EvalNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned, unsigned endColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
150 {
151 RefPtr<EvalNode> node = new EvalNode(vm, startLocation, endLocation, endColumn, children, varStack, funcStack, capturedVariables, source, features, numConstants);
152
153 ASSERT(node->m_arena.last() == node);
154 node->m_arena.removeLast();
155 ASSERT(!node->m_arena.contains(node.get()));
156
157 return node.release();
158 }
159
160 // ------------------------------ FunctionBodyNode -----------------------------
161
162 PassRefPtr<FunctionParameters> FunctionParameters::create(ParameterNode* firstParameter)
163 {
164 unsigned parameterCount = 0;
165 for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
166 ++parameterCount;
167
168 size_t objectSize = sizeof(FunctionParameters) - sizeof(void*) + sizeof(DeconstructionPatternNode*) * parameterCount;
169 void* slot = fastMalloc(objectSize);
170 return adoptRef(new (slot) FunctionParameters(firstParameter, parameterCount));
171 }
172
173 FunctionParameters::FunctionParameters(ParameterNode* firstParameter, unsigned size)
174 : m_size(size)
175 {
176 unsigned i = 0;
177 for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam()) {
178 auto pattern = parameter->pattern();
179 pattern->ref();
180 patterns()[i++] = pattern;
181 }
182 }
183
184 FunctionParameters::~FunctionParameters()
185 {
186 for (unsigned i = 0; i < m_size; ++i)
187 patterns()[i]->deref();
188 }
189
190 inline FunctionBodyNode::FunctionBodyNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, bool inStrictContext)
191 : ScopeNode(vm, startLocation, endLocation, inStrictContext)
192 , m_startColumn(startColumn)
193 , m_endColumn(endColumn)
194 {
195 }
196
197 inline FunctionBodyNode::FunctionBodyNode(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
198 : ScopeNode(vm, startLocation, endLocation, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants)
199 , m_startColumn(startColumn)
200 , m_endColumn(endColumn)
201 {
202 }
203
204 void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter, const Identifier& ident, enum FunctionMode functionMode)
205 {
206 setSource(source);
207 finishParsing(FunctionParameters::create(firstParameter), ident, functionMode);
208 }
209
210 void FunctionBodyNode::finishParsing(PassRefPtr<FunctionParameters> parameters, const Identifier& ident, enum FunctionMode functionMode)
211 {
212 ASSERT(!source().isNull());
213 m_parameters = parameters;
214 m_ident = ident;
215 m_functionMode = functionMode;
216 }
217
218 FunctionBodyNode* FunctionBodyNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, bool inStrictContext)
219 {
220 return new FunctionBodyNode(vm, startLocation, endLocation, startColumn, endColumn, inStrictContext);
221 }
222
223 PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(VM* vm, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
224 {
225 RefPtr<FunctionBodyNode> node = new FunctionBodyNode(vm, startLocation, endLocation, startColumn, endColumn , children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants);
226
227 ASSERT(node->m_arena.last() == node);
228 node->m_arena.removeLast();
229 ASSERT(!node->m_arena.contains(node.get()));
230
231 return node.release();
232 }
233
234 void FunctionBodyNode::setEndPosition(JSTextPosition position)
235 {
236 m_lastLine = position.line;
237 m_endColumn = position.offset - position.lineStartOffset;
238 }
239
240 } // namespace JSC