1 | /*
|
---|
2 | * Copyright (C) 1999-2002 Harri Porten ([email protected])
|
---|
3 | * Copyright (C) 2001 Peter Kelly ([email protected])
|
---|
4 | * Copyright (C) 2003-2009, 2013, 2016 Apple Inc. All rights reserved.
|
---|
5 | * Copyright (C) 2007 Cameron Zwarich ([email protected])
|
---|
6 | * Copyright (C) 2007 Maks Orlovich
|
---|
7 | * Copyright (C) 2007 Eric Seidel <[email protected]>
|
---|
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 "ExecutableInfo.h"
|
---|
31 | #include "ModuleScopeData.h"
|
---|
32 | #include <wtf/Assertions.h>
|
---|
33 |
|
---|
34 | namespace JSC {
|
---|
35 |
|
---|
36 | DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(ParserArenaRoot);
|
---|
37 |
|
---|
38 | // ------------------------------ StatementNode --------------------------------
|
---|
39 |
|
---|
40 | void StatementNode::setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset)
|
---|
41 | {
|
---|
42 | m_lastLine = lastLine;
|
---|
43 | m_position = JSTextPosition(firstLine, startOffset, lineStartOffset);
|
---|
44 | ASSERT(m_position.offset >= m_position.lineStartOffset);
|
---|
45 | }
|
---|
46 |
|
---|
47 | // ------------------------------ SourceElements --------------------------------
|
---|
48 |
|
---|
49 | void SourceElements::append(StatementNode* statement)
|
---|
50 | {
|
---|
51 | if (statement->isEmptyStatement())
|
---|
52 | return;
|
---|
53 |
|
---|
54 | if (!m_head) {
|
---|
55 | m_head = statement;
|
---|
56 | m_tail = statement;
|
---|
57 | return;
|
---|
58 | }
|
---|
59 |
|
---|
60 | m_tail->setNext(statement);
|
---|
61 | m_tail = statement;
|
---|
62 | }
|
---|
63 |
|
---|
64 | StatementNode* SourceElements::singleStatement() const
|
---|
65 | {
|
---|
66 | return m_head == m_tail ? m_head : nullptr;
|
---|
67 | }
|
---|
68 |
|
---|
69 | StatementNode* SourceElements::lastStatement() const
|
---|
70 | {
|
---|
71 | return m_tail;
|
---|
72 | }
|
---|
73 |
|
---|
74 | bool SourceElements::hasCompletionValue() const
|
---|
75 | {
|
---|
76 | for (StatementNode* statement = m_head; statement; statement = statement->next()) {
|
---|
77 | if (statement->hasCompletionValue())
|
---|
78 | return true;
|
---|
79 | }
|
---|
80 |
|
---|
81 | return false;
|
---|
82 | }
|
---|
83 |
|
---|
84 | bool SourceElements::hasEarlyBreakOrContinue() const
|
---|
85 | {
|
---|
86 | for (StatementNode* statement = m_head; statement; statement = statement->next()) {
|
---|
87 | if (statement->isBreak() || statement->isContinue())
|
---|
88 | return true;
|
---|
89 | if (statement->hasCompletionValue())
|
---|
90 | return false;
|
---|
91 | }
|
---|
92 |
|
---|
93 | return false;
|
---|
94 | }
|
---|
95 |
|
---|
96 | // ------------------------------ BlockNode ------------------------------------
|
---|
97 |
|
---|
98 | StatementNode* BlockNode::lastStatement() const
|
---|
99 | {
|
---|
100 | return m_statements ? m_statements->lastStatement() : nullptr;
|
---|
101 | }
|
---|
102 |
|
---|
103 | StatementNode* BlockNode::singleStatement() const
|
---|
104 | {
|
---|
105 | return m_statements ? m_statements->singleStatement() : nullptr;
|
---|
106 | }
|
---|
107 |
|
---|
108 | bool BlockNode::hasCompletionValue() const
|
---|
109 | {
|
---|
110 | return m_statements ? m_statements->hasCompletionValue() : false;
|
---|
111 | }
|
---|
112 |
|
---|
113 | bool BlockNode::hasEarlyBreakOrContinue() const
|
---|
114 | {
|
---|
115 | return m_statements ? m_statements->hasEarlyBreakOrContinue() : false;
|
---|
116 | }
|
---|
117 |
|
---|
118 | // ------------------------------ ScopeNode -----------------------------
|
---|
119 |
|
---|
120 | ScopeNode::ScopeNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, LexicalScopeFeatures lexicalScopeFeatures)
|
---|
121 | : StatementNode(endLocation)
|
---|
122 | , ParserArenaRoot(parserArena)
|
---|
123 | , m_startLineNumber(startLocation.line)
|
---|
124 | , m_startStartOffset(startLocation.startOffset)
|
---|
125 | , m_startLineStartOffset(startLocation.lineStartOffset)
|
---|
126 | , m_features(NoFeatures)
|
---|
127 | , m_lexicalScopeFeatures(lexicalScopeFeatures)
|
---|
128 | , m_innerArrowFunctionCodeFeatures(NoInnerArrowFunctionFeatures)
|
---|
129 | , m_numConstants(0)
|
---|
130 | , m_statements(nullptr)
|
---|
131 | {
|
---|
132 | }
|
---|
133 |
|
---|
134 | ScopeNode::ScopeNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, const SourceCode& source, SourceElements* children, VariableEnvironment&& varEnvironment, FunctionStack&& funcStack, VariableEnvironment&& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants)
|
---|
135 | : StatementNode(endLocation)
|
---|
136 | , ParserArenaRoot(parserArena)
|
---|
137 | , VariableEnvironmentNode(WTFMove(lexicalVariables), WTFMove(funcStack))
|
---|
138 | , m_startLineNumber(startLocation.line)
|
---|
139 | , m_startStartOffset(startLocation.startOffset)
|
---|
140 | , m_startLineStartOffset(startLocation.lineStartOffset)
|
---|
141 | , m_features(features)
|
---|
142 | , m_lexicalScopeFeatures(lexicalScopeFeatures)
|
---|
143 | , m_innerArrowFunctionCodeFeatures(innerArrowFunctionCodeFeatures)
|
---|
144 | , m_source(source)
|
---|
145 | , m_varDeclarations(WTFMove(varEnvironment))
|
---|
146 | , m_sloppyModeHoistedFunctions(WTFMove(sloppyModeHoistedFunctions))
|
---|
147 | , m_numConstants(numConstants)
|
---|
148 | , m_statements(children)
|
---|
149 | {
|
---|
150 | }
|
---|
151 |
|
---|
152 | StatementNode* ScopeNode::singleStatement() const
|
---|
153 | {
|
---|
154 | return m_statements ? m_statements->singleStatement() : nullptr;
|
---|
155 | }
|
---|
156 |
|
---|
157 | bool ScopeNode::hasCompletionValue() const
|
---|
158 | {
|
---|
159 | return m_statements ? m_statements->hasCompletionValue() : false;
|
---|
160 | }
|
---|
161 |
|
---|
162 | bool ScopeNode::hasEarlyBreakOrContinue() const
|
---|
163 | {
|
---|
164 | return m_statements ? m_statements->hasEarlyBreakOrContinue() : false;
|
---|
165 | }
|
---|
166 |
|
---|
167 | // ------------------------------ ProgramNode -----------------------------
|
---|
168 |
|
---|
169 | ProgramNode::ProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment&& varEnvironment, FunctionStack&& funcStack, VariableEnvironment&& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&)
|
---|
170 | : ScopeNode(parserArena, startLocation, endLocation, source, children, WTFMove(varEnvironment), WTFMove(funcStack), WTFMove(lexicalVariables), WTFMove(sloppyModeHoistedFunctions), features, lexicalScopeFeatures, innerArrowFunctionCodeFeatures, numConstants)
|
---|
171 | , m_startColumn(startColumn)
|
---|
172 | , m_endColumn(endColumn)
|
---|
173 | {
|
---|
174 | }
|
---|
175 |
|
---|
176 | // ------------------------------ ModuleProgramNode -----------------------------
|
---|
177 |
|
---|
178 | ModuleProgramNode::ModuleProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment&& varEnvironment, FunctionStack&& funcStack, VariableEnvironment&& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&& moduleScopeData)
|
---|
179 | : ScopeNode(parserArena, startLocation, endLocation, source, children, WTFMove(varEnvironment), WTFMove(funcStack), WTFMove(lexicalVariables), WTFMove(sloppyModeHoistedFunctions), features, lexicalScopeFeatures, innerArrowFunctionCodeFeatures, numConstants)
|
---|
180 | , m_startColumn(startColumn)
|
---|
181 | , m_endColumn(endColumn)
|
---|
182 | , m_usesAwait(features & AwaitFeature)
|
---|
183 | , m_moduleScopeData(*WTFMove(moduleScopeData))
|
---|
184 | {
|
---|
185 | }
|
---|
186 |
|
---|
187 | // ------------------------------ EvalNode -----------------------------
|
---|
188 |
|
---|
189 | EvalNode::EvalNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned, unsigned endColumn, SourceElements* children, VariableEnvironment&& varEnvironment, FunctionStack&& funcStack, VariableEnvironment&& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&)
|
---|
190 | : ScopeNode(parserArena, startLocation, endLocation, source, children, WTFMove(varEnvironment), WTFMove(funcStack), WTFMove(lexicalVariables), WTFMove(sloppyModeHoistedFunctions), features, lexicalScopeFeatures, innerArrowFunctionCodeFeatures, numConstants)
|
---|
191 | , m_endColumn(endColumn)
|
---|
192 | {
|
---|
193 | }
|
---|
194 |
|
---|
195 | // ------------------------------ FunctionMetadataNode -----------------------------
|
---|
196 |
|
---|
197 | FunctionMetadataNode::FunctionMetadataNode(
|
---|
198 | ParserArena&, const JSTokenLocation& startLocation,
|
---|
199 | const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn,
|
---|
200 | int functionKeywordStart, int functionNameStart, int parametersStart, LexicalScopeFeatures lexicalScopeFeatures,
|
---|
201 | ConstructorKind constructorKind, SuperBinding superBinding, unsigned parameterCount, SourceParseMode mode, bool isArrowFunctionBodyExpression)
|
---|
202 | : Node(endLocation)
|
---|
203 | , m_lexicalScopeFeatures(lexicalScopeFeatures)
|
---|
204 | , m_superBinding(static_cast<unsigned>(superBinding))
|
---|
205 | , m_constructorKind(static_cast<unsigned>(constructorKind))
|
---|
206 | , m_needsClassFieldInitializer(static_cast<unsigned>(NeedsClassFieldInitializer::No))
|
---|
207 | , m_isArrowFunctionBodyExpression(isArrowFunctionBodyExpression)
|
---|
208 | , m_privateBrandRequirement(static_cast<unsigned>(PrivateBrandRequirement::None))
|
---|
209 | , m_parseMode(mode)
|
---|
210 | , m_startColumn(startColumn)
|
---|
211 | , m_endColumn(endColumn)
|
---|
212 | , m_functionKeywordStart(functionKeywordStart)
|
---|
213 | , m_functionNameStart(functionNameStart)
|
---|
214 | , m_parametersStart(parametersStart)
|
---|
215 | , m_startStartOffset(startLocation.startOffset)
|
---|
216 | , m_parameterCount(parameterCount)
|
---|
217 | {
|
---|
218 | ASSERT(m_superBinding == static_cast<unsigned>(superBinding));
|
---|
219 | ASSERT(m_constructorKind == static_cast<unsigned>(constructorKind));
|
---|
220 | }
|
---|
221 |
|
---|
222 | FunctionMetadataNode::FunctionMetadataNode(
|
---|
223 | const JSTokenLocation& startLocation,
|
---|
224 | const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn,
|
---|
225 | int functionKeywordStart, int functionNameStart, int parametersStart, LexicalScopeFeatures lexicalScopeFeatures,
|
---|
226 | ConstructorKind constructorKind, SuperBinding superBinding, unsigned parameterCount, SourceParseMode mode, bool isArrowFunctionBodyExpression)
|
---|
227 | : Node(endLocation)
|
---|
228 | , m_lexicalScopeFeatures(lexicalScopeFeatures)
|
---|
229 | , m_superBinding(static_cast<unsigned>(superBinding))
|
---|
230 | , m_constructorKind(static_cast<unsigned>(constructorKind))
|
---|
231 | , m_needsClassFieldInitializer(static_cast<unsigned>(NeedsClassFieldInitializer::No))
|
---|
232 | , m_isArrowFunctionBodyExpression(isArrowFunctionBodyExpression)
|
---|
233 | , m_privateBrandRequirement(static_cast<unsigned>(PrivateBrandRequirement::None))
|
---|
234 | , m_parseMode(mode)
|
---|
235 | , m_startColumn(startColumn)
|
---|
236 | , m_endColumn(endColumn)
|
---|
237 | , m_functionKeywordStart(functionKeywordStart)
|
---|
238 | , m_functionNameStart(functionNameStart)
|
---|
239 | , m_parametersStart(parametersStart)
|
---|
240 | , m_startStartOffset(startLocation.startOffset)
|
---|
241 | , m_parameterCount(parameterCount)
|
---|
242 | {
|
---|
243 | ASSERT(m_superBinding == static_cast<unsigned>(superBinding));
|
---|
244 | ASSERT(m_constructorKind == static_cast<unsigned>(constructorKind));
|
---|
245 | }
|
---|
246 |
|
---|
247 | void FunctionMetadataNode::finishParsing(const SourceCode& source, const Identifier& ident, FunctionMode functionMode)
|
---|
248 | {
|
---|
249 | m_source = source;
|
---|
250 | m_ident = ident;
|
---|
251 | m_functionMode = functionMode;
|
---|
252 | }
|
---|
253 |
|
---|
254 | void FunctionMetadataNode::setEndPosition(JSTextPosition position)
|
---|
255 | {
|
---|
256 | m_lastLine = position.line;
|
---|
257 | m_endColumn = position.offset - position.lineStartOffset;
|
---|
258 | }
|
---|
259 |
|
---|
260 | bool FunctionMetadataNode::operator==(const FunctionMetadataNode& other) const
|
---|
261 | {
|
---|
262 | return m_parseMode == other.m_parseMode
|
---|
263 | && m_lexicalScopeFeatures == other.m_lexicalScopeFeatures
|
---|
264 | && m_superBinding == other.m_superBinding
|
---|
265 | && m_constructorKind == other.m_constructorKind
|
---|
266 | && m_isArrowFunctionBodyExpression == other.m_isArrowFunctionBodyExpression
|
---|
267 | && m_ident == other.m_ident
|
---|
268 | && m_ecmaName == other.m_ecmaName
|
---|
269 | && m_functionMode == other.m_functionMode
|
---|
270 | && m_startColumn == other.m_startColumn
|
---|
271 | && m_endColumn == other.m_endColumn
|
---|
272 | && m_functionKeywordStart == other.m_functionKeywordStart
|
---|
273 | && m_functionNameStart == other.m_functionNameStart
|
---|
274 | && m_parametersStart == other.m_parametersStart
|
---|
275 | && m_source == other.m_source
|
---|
276 | && m_classSource == other.m_classSource
|
---|
277 | && m_startStartOffset == other.m_startStartOffset
|
---|
278 | && m_parameterCount == other.m_parameterCount
|
---|
279 | && m_lastLine == other.m_lastLine
|
---|
280 | && m_position == other.m_position;
|
---|
281 | }
|
---|
282 |
|
---|
283 | void FunctionMetadataNode::dump(PrintStream& stream) const
|
---|
284 | {
|
---|
285 | stream.println("m_parseMode ", static_cast<uint32_t>(m_parseMode));
|
---|
286 | stream.println("m_lexicalScopeFeatures ", m_lexicalScopeFeatures);
|
---|
287 | stream.println("m_superBinding ", m_superBinding);
|
---|
288 | stream.println("m_constructorKind ", m_constructorKind);
|
---|
289 | stream.println("m_isArrowFunctionBodyExpression ", m_isArrowFunctionBodyExpression);
|
---|
290 | stream.println("m_ident ", m_ident);
|
---|
291 | stream.println("m_ecmaName ", m_ecmaName);
|
---|
292 | stream.println("m_functionMode ", static_cast<uint32_t>(m_functionMode));
|
---|
293 | stream.println("m_startColumn ", m_startColumn);
|
---|
294 | stream.println("m_endColumn ", m_endColumn);
|
---|
295 | stream.println("m_functionKeywordStart ", m_functionKeywordStart);
|
---|
296 | stream.println("m_functionNameStart ", m_functionNameStart);
|
---|
297 | stream.println("m_parametersStart ", m_parametersStart);
|
---|
298 | stream.println("m_classSource.isNull() ", m_classSource.isNull());
|
---|
299 | stream.println("m_startStartOffset ", m_startStartOffset);
|
---|
300 | stream.println("m_parameterCount ", m_parameterCount);
|
---|
301 | stream.println("m_lastLine ", m_lastLine);
|
---|
302 | stream.println("position().line ", position().line);
|
---|
303 | stream.println("position().offset ", position().offset);
|
---|
304 | stream.println("position().lineStartOffset ", position().lineStartOffset);
|
---|
305 | }
|
---|
306 |
|
---|
307 | // ------------------------------ FunctionNode -----------------------------
|
---|
308 |
|
---|
309 | FunctionNode::FunctionNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment&& varEnvironment, FunctionStack&& funcStack, VariableEnvironment&& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters* parameters, const SourceCode& sourceCode, CodeFeatures features, LexicalScopeFeatures lexicalScopeFeatures, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&)
|
---|
310 | : ScopeNode(parserArena, startLocation, endLocation, sourceCode, children, WTFMove(varEnvironment), WTFMove(funcStack), WTFMove(lexicalVariables), WTFMove(sloppyModeHoistedFunctions), features, lexicalScopeFeatures, innerArrowFunctionCodeFeatures, numConstants)
|
---|
311 | , m_parameters(parameters)
|
---|
312 | , m_startColumn(startColumn)
|
---|
313 | , m_endColumn(endColumn)
|
---|
314 | {
|
---|
315 | }
|
---|
316 |
|
---|
317 | void FunctionNode::finishParsing(const Identifier& ident, FunctionMode functionMode)
|
---|
318 | {
|
---|
319 | ASSERT(!source().isNull());
|
---|
320 | m_ident = ident;
|
---|
321 | m_functionMode = functionMode;
|
---|
322 | }
|
---|
323 |
|
---|
324 | bool PropertyListNode::hasStaticallyNamedProperty(const Identifier& propName)
|
---|
325 | {
|
---|
326 | PropertyListNode* list = this;
|
---|
327 | while (list) {
|
---|
328 | if (list->m_node->isStaticClassProperty()) {
|
---|
329 | const Identifier* currentNodeName = list->m_node->name();
|
---|
330 | if (currentNodeName && *currentNodeName == propName)
|
---|
331 | return true;
|
---|
332 | }
|
---|
333 | list = list->m_next;
|
---|
334 | }
|
---|
335 | return false;
|
---|
336 | }
|
---|
337 |
|
---|
338 | // FIXME: calculate this feature once when parsing the property list.
|
---|
339 | // https://bugs.webkit.org/show_bug.cgi?id=206174
|
---|
340 | bool PropertyListNode::shouldCreateLexicalScopeForClass(PropertyListNode* list)
|
---|
341 | {
|
---|
342 | while (list) {
|
---|
343 | if (list->m_node->isComputedClassField() || list->m_node->isPrivate())
|
---|
344 | return true;
|
---|
345 | list = list->m_next;
|
---|
346 | }
|
---|
347 | return false;
|
---|
348 | }
|
---|
349 |
|
---|
350 | // ------------------------------ ClassExprNode -----------------------------
|
---|
351 |
|
---|
352 | // FIXME: calculate this feature once when parsing the property list.
|
---|
353 | // https://bugs.webkit.org/show_bug.cgi?id=206174
|
---|
354 | bool PropertyListNode::hasInstanceFields() const
|
---|
355 | {
|
---|
356 | for (auto list = this; list; list = list->m_next) {
|
---|
357 | if (list->m_node->isInstanceClassField())
|
---|
358 | return true;
|
---|
359 | }
|
---|
360 | return false;
|
---|
361 | }
|
---|
362 |
|
---|
363 | VariableEnvironmentNode::VariableEnvironmentNode(VariableEnvironment&& lexicalVariables)
|
---|
364 | : m_lexicalVariables(WTFMove(lexicalVariables))
|
---|
365 | {
|
---|
366 | }
|
---|
367 |
|
---|
368 | VariableEnvironmentNode::VariableEnvironmentNode(VariableEnvironment&& lexicalVariables, FunctionStack&& functionStack)
|
---|
369 | : m_lexicalVariables(WTFMove(lexicalVariables))
|
---|
370 | , m_functionStack(WTFMove(functionStack))
|
---|
371 | {
|
---|
372 | }
|
---|
373 |
|
---|
374 | } // namespace JSC
|
---|