1/*
2 * Copyright (C) 1999-2001 Harri Porten ([email protected])
3 * Copyright (C) 2001 Peter Kelly ([email protected])
4 * Copyright (C) 2003-2019 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#pragma once
24
25#include "ExecutableInfo.h"
26#include "Lexer.h"
27#include "ModuleScopeData.h"
28#include "Nodes.h"
29#include "ParseHash.h"
30#include "ParserArena.h"
31#include "ParserError.h"
32#include "ParserFunctionInfo.h"
33#include "ParserTokens.h"
34#include "SourceProvider.h"
35#include "SourceProviderCache.h"
36#include "SourceProviderCacheItem.h"
37#include "VariableEnvironment.h"
38#include <wtf/Forward.h>
39#include <wtf/Noncopyable.h>
40#include <wtf/RefPtr.h>
41
42namespace JSC {
43
44class FunctionMetadataNode;
45class FunctionParameters;
46class Identifier;
47class VM;
48class SourceCode;
49class SyntaxChecker;
50struct DebuggerParseData;
51
52// Macros to make the more common TreeBuilder types a little less verbose
53#define TreeStatement typename TreeBuilder::Statement
54#define TreeExpression typename TreeBuilder::Expression
55#define TreeFormalParameterList typename TreeBuilder::FormalParameterList
56#define TreeSourceElements typename TreeBuilder::SourceElements
57#define TreeClause typename TreeBuilder::Clause
58#define TreeClauseList typename TreeBuilder::ClauseList
59#define TreeArguments typename TreeBuilder::Arguments
60#define TreeArgumentsList typename TreeBuilder::ArgumentsList
61#define TreeFunctionBody typename TreeBuilder::FunctionBody
62#define TreeClassExpression typename TreeBuilder::ClassExpression
63#define TreeProperty typename TreeBuilder::Property
64#define TreePropertyList typename TreeBuilder::PropertyList
65#define TreeDestructuringPattern typename TreeBuilder::DestructuringPattern
66
67COMPILE_ASSERT(LastUntaggedToken < 64, LessThan64UntaggedTokens);
68
69enum SourceElementsMode { CheckForStrictMode, DontCheckForStrictMode };
70enum FunctionBodyType { ArrowFunctionBodyExpression, ArrowFunctionBodyBlock, StandardFunctionBodyBlock };
71enum class FunctionNameRequirements { None, Named, Unnamed };
72
73enum class DestructuringKind {
74 DestructureToVariables,
75 DestructureToLet,
76 DestructureToConst,
77 DestructureToCatchParameters,
78 DestructureToParameters,
79 DestructureToExpressions
80};
81
82enum class DeclarationType {
83 VarDeclaration,
84 LetDeclaration,
85 ConstDeclaration
86};
87
88enum class DeclarationImportType {
89 Imported,
90 ImportedNamespace,
91 NotImported
92};
93
94enum DeclarationResult {
95 Valid = 0,
96 InvalidStrictMode = 1 << 0,
97 InvalidDuplicateDeclaration = 1 << 1
98};
99
100typedef uint8_t DeclarationResultMask;
101
102enum class DeclarationDefaultContext {
103 Standard,
104 ExportDefault,
105};
106
107enum class InferName {
108 Allowed,
109 Disallowed,
110};
111
112template <typename T> inline bool isEvalNode() { return false; }
113template <> inline bool isEvalNode<EvalNode>() { return true; }
114
115struct ScopeLabelInfo {
116 UniquedStringImpl* uid;
117 bool isLoop;
118};
119
120ALWAYS_INLINE static bool isArguments(const VM& vm, const Identifier* ident)
121{
122 return vm.propertyNames->arguments == *ident;
123}
124ALWAYS_INLINE static bool isEval(const VM& vm, const Identifier* ident)
125{
126 return vm.propertyNames->eval == *ident;
127}
128ALWAYS_INLINE static bool isEvalOrArgumentsIdentifier(const VM& vm, const Identifier* ident)
129{
130 return isEval(vm, ident) || isArguments(vm, ident);
131}
132ALWAYS_INLINE static bool isIdentifierOrKeyword(const JSToken& token)
133{
134 return token.m_type == IDENT || token.m_type & KeywordTokenFlag;
135}
136// _Any_ContextualKeyword includes keywords such as "let" or "yield", which have a specific meaning depending on the current parse mode
137// or strict mode. These helpers allow to treat all contextual keywords as identifiers as required.
138ALWAYS_INLINE static bool isAnyContextualKeyword(const JSToken& token)
139{
140 return token.m_type >= FirstContextualKeywordToken && token.m_type <= LastContextualKeywordToken;
141}
142ALWAYS_INLINE static bool isIdentifierOrAnyContextualKeyword(const JSToken& token)
143{
144 return token.m_type == IDENT || isAnyContextualKeyword(token);
145}
146// _Safe_ContextualKeyword includes only contextual keywords which can be treated as identifiers independently from parse mode. The exeption
147// to this rule is `await`, but matchSpecIdentifier() always treats it as an identifier regardless.
148ALWAYS_INLINE static bool isSafeContextualKeyword(const JSToken& token)
149{
150 return token.m_type >= FirstSafeContextualKeywordToken && token.m_type <= LastSafeContextualKeywordToken;
151}
152
153JS_EXPORT_PRIVATE extern std::atomic<unsigned> globalParseCount;
154
155struct Scope {
156 WTF_MAKE_NONCOPYABLE(Scope);
157
158public:
159 Scope(const VM& vm, bool isFunction, bool isGenerator, bool strictMode, bool isArrowFunction, bool isAsyncFunction)
160 : m_vm(vm)
161 , m_shadowsArguments(false)
162 , m_usesEval(false)
163 , m_needsFullActivation(false)
164 , m_hasDirectSuper(false)
165 , m_needsSuperBinding(false)
166 , m_allowsVarDeclarations(true)
167 , m_allowsLexicalDeclarations(true)
168 , m_strictMode(strictMode)
169 , m_isFunction(isFunction)
170 , m_isGenerator(isGenerator)
171 , m_isGeneratorBoundary(false)
172 , m_isArrowFunction(isArrowFunction)
173 , m_isArrowFunctionBoundary(false)
174 , m_isAsyncFunction(isAsyncFunction)
175 , m_isAsyncFunctionBoundary(false)
176 , m_isLexicalScope(false)
177 , m_isGlobalCodeScope(false)
178 , m_isSimpleCatchParameterScope(false)
179 , m_isFunctionBoundary(false)
180 , m_isValidStrictMode(true)
181 , m_hasArguments(false)
182 , m_isEvalContext(false)
183 , m_hasNonSimpleParameterList(false)
184 , m_evalContextType(EvalContextType::None)
185 , m_constructorKind(static_cast<unsigned>(ConstructorKind::None))
186 , m_expectedSuperBinding(static_cast<unsigned>(SuperBinding::NotNeeded))
187 , m_loopDepth(0)
188 , m_switchDepth(0)
189 , m_innerArrowFunctionFeatures(0)
190 {
191 m_usedVariables.append(UniquedStringImplPtrSet());
192 }
193
194 Scope(Scope&&) = default;
195
196 void startSwitch() { m_switchDepth++; }
197 void endSwitch() { m_switchDepth--; }
198 void startLoop() { m_loopDepth++; }
199 void endLoop() { ASSERT(m_loopDepth); m_loopDepth--; }
200 bool inLoop() { return !!m_loopDepth; }
201 bool breakIsValid() { return m_loopDepth || m_switchDepth; }
202 bool continueIsValid() { return m_loopDepth; }
203
204 void pushLabel(const Identifier* label, bool isLoop)
205 {
206 if (!m_labels)
207 m_labels = makeUnique<LabelStack>();
208 m_labels->append(ScopeLabelInfo { label->impl(), isLoop });
209 }
210
211 void popLabel()
212 {
213 ASSERT(m_labels);
214 ASSERT(m_labels->size());
215 m_labels->removeLast();
216 }
217
218 ScopeLabelInfo* getLabel(const Identifier* label)
219 {
220 if (!m_labels)
221 return 0;
222 for (int i = m_labels->size(); i > 0; i--) {
223 if (m_labels->at(i - 1).uid == label->impl())
224 return &m_labels->at(i - 1);
225 }
226 return 0;
227 }
228
229 void setSourceParseMode(SourceParseMode mode)
230 {
231 switch (mode) {
232 case SourceParseMode::AsyncGeneratorBodyMode:
233 setIsAsyncGeneratorFunctionBody();
234 break;
235 case SourceParseMode::AsyncArrowFunctionBodyMode:
236 setIsAsyncArrowFunctionBody();
237 break;
238
239 case SourceParseMode::AsyncFunctionBodyMode:
240 setIsAsyncFunctionBody();
241 break;
242
243 case SourceParseMode::GeneratorBodyMode:
244 setIsGenerator();
245 break;
246
247 case SourceParseMode::GeneratorWrapperFunctionMode:
248 case SourceParseMode::GeneratorWrapperMethodMode:
249 setIsGeneratorFunction();
250 break;
251
252 case SourceParseMode::AsyncGeneratorWrapperMethodMode:
253 case SourceParseMode::AsyncGeneratorWrapperFunctionMode:
254 setIsAsyncGeneratorFunction();
255 break;
256
257 case SourceParseMode::NormalFunctionMode:
258 case SourceParseMode::GetterMode:
259 case SourceParseMode::SetterMode:
260 case SourceParseMode::MethodMode:
261 setIsFunction();
262 break;
263
264 case SourceParseMode::ArrowFunctionMode:
265 setIsArrowFunction();
266 break;
267
268 case SourceParseMode::AsyncFunctionMode:
269 case SourceParseMode::AsyncMethodMode:
270 setIsAsyncFunction();
271 break;
272
273 case SourceParseMode::AsyncArrowFunctionMode:
274 setIsAsyncArrowFunction();
275 break;
276
277 case SourceParseMode::ProgramMode:
278 case SourceParseMode::ModuleAnalyzeMode:
279 case SourceParseMode::ModuleEvaluateMode:
280 break;
281 }
282 }
283
284 bool isFunction() const { return m_isFunction; }
285 bool isFunctionBoundary() const { return m_isFunctionBoundary; }
286 bool isGenerator() const { return m_isGenerator; }
287 bool isGeneratorBoundary() const { return m_isGeneratorBoundary; }
288 bool isAsyncFunction() const { return m_isAsyncFunction; }
289 bool isAsyncFunctionBoundary() const { return m_isAsyncFunctionBoundary; }
290
291 bool hasArguments() const { return m_hasArguments; }
292
293 void setIsGlobalCodeScope() { m_isGlobalCodeScope = true; }
294 bool isGlobalCodeScope() const { return m_isGlobalCodeScope; }
295
296 void setIsSimpleCatchParameterScope() { m_isSimpleCatchParameterScope = true; }
297 bool isSimpleCatchParameterScope() { return m_isSimpleCatchParameterScope; }
298
299 void setIsLexicalScope()
300 {
301 m_isLexicalScope = true;
302 m_allowsLexicalDeclarations = true;
303 }
304 bool isLexicalScope() { return m_isLexicalScope; }
305 bool usesEval() { return m_usesEval; }
306
307 const HashSet<UniquedStringImpl*>& closedVariableCandidates() const { return m_closedVariableCandidates; }
308 VariableEnvironment& declaredVariables() { return m_declaredVariables; }
309 VariableEnvironment& lexicalVariables() { return m_lexicalVariables; }
310 VariableEnvironment& finalizeLexicalEnvironment()
311 {
312 if (m_usesEval || m_needsFullActivation)
313 m_lexicalVariables.markAllVariablesAsCaptured();
314 else
315 computeLexicallyCapturedVariablesAndPurgeCandidates();
316
317 return m_lexicalVariables;
318 }
319
320 void computeLexicallyCapturedVariablesAndPurgeCandidates()
321 {
322 // Because variables may be defined at any time in the range of a lexical scope, we must
323 // track lexical variables that might be captured. Then, when we're preparing to pop the top
324 // lexical scope off the stack, we should find which variables are truly captured, and which
325 // variable still may be captured in a parent scope.
326 if (m_lexicalVariables.size() && m_closedVariableCandidates.size()) {
327 for (UniquedStringImpl* impl : m_closedVariableCandidates)
328 m_lexicalVariables.markVariableAsCapturedIfDefined(impl);
329 }
330
331 // We can now purge values from the captured candidates because they're captured in this scope.
332 {
333 for (const auto& entry : m_lexicalVariables) {
334 if (entry.value.isCaptured())
335 m_closedVariableCandidates.remove(entry.key.get());
336 }
337 }
338 }
339
340 DeclarationResultMask declareCallee(const Identifier* ident)
341 {
342 auto addResult = m_declaredVariables.add(ident->impl());
343 // We want to track if callee is captured, but we don't want to act like it's a 'var'
344 // because that would cause the BytecodeGenerator to emit bad code.
345 addResult.iterator->value.clearIsVar();
346
347 DeclarationResultMask result = DeclarationResult::Valid;
348 if (isEvalOrArgumentsIdentifier(m_vm, ident))
349 result |= DeclarationResult::InvalidStrictMode;
350 return result;
351 }
352
353 DeclarationResultMask declareVariable(const Identifier* ident)
354 {
355 ASSERT(m_allowsVarDeclarations);
356 DeclarationResultMask result = DeclarationResult::Valid;
357 bool isValidStrictMode = !isEvalOrArgumentsIdentifier(m_vm, ident);
358 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
359 auto addResult = m_declaredVariables.add(ident->impl());
360 addResult.iterator->value.setIsVar();
361 if (!isValidStrictMode)
362 result |= DeclarationResult::InvalidStrictMode;
363 return result;
364 }
365
366 DeclarationResultMask declareFunction(const Identifier* ident, bool declareAsVar, bool isSloppyModeHoistingCandidate)
367 {
368 ASSERT(m_allowsVarDeclarations || m_allowsLexicalDeclarations);
369 DeclarationResultMask result = DeclarationResult::Valid;
370 bool isValidStrictMode = !isEvalOrArgumentsIdentifier(m_vm, ident);
371 if (!isValidStrictMode)
372 result |= DeclarationResult::InvalidStrictMode;
373 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
374 auto addResult = declareAsVar ? m_declaredVariables.add(ident->impl()) : m_lexicalVariables.add(ident->impl());
375 if (isSloppyModeHoistingCandidate)
376 addResult.iterator->value.setIsSloppyModeHoistingCandidate();
377 if (declareAsVar) {
378 addResult.iterator->value.setIsVar();
379 if (m_lexicalVariables.contains(ident->impl()))
380 result |= DeclarationResult::InvalidDuplicateDeclaration;
381 } else {
382 addResult.iterator->value.setIsLet();
383 ASSERT_WITH_MESSAGE(!m_declaredVariables.size(), "We should only declare a function as a lexically scoped variable in scopes where var declarations aren't allowed. I.e, in strict mode and not at the top-level scope of a function or program.");
384 if (!addResult.isNewEntry) {
385 if (!isSloppyModeHoistingCandidate || !addResult.iterator->value.isFunction())
386 result |= DeclarationResult::InvalidDuplicateDeclaration;
387 }
388 }
389
390 addResult.iterator->value.setIsFunction();
391
392 return result;
393 }
394
395 void addVariableBeingHoisted(const Identifier* ident)
396 {
397 ASSERT(!m_allowsVarDeclarations);
398 m_variablesBeingHoisted.add(ident->impl());
399 }
400
401 void addSloppyModeHoistableFunctionCandidate(const Identifier* ident)
402 {
403 ASSERT(m_allowsVarDeclarations);
404 m_sloppyModeHoistableFunctionCandidates.add(ident->impl());
405 }
406
407 void appendFunction(FunctionMetadataNode* node)
408 {
409 ASSERT(node);
410 m_functionDeclarations.append(node);
411 }
412 DeclarationStacks::FunctionStack&& takeFunctionDeclarations() { return WTFMove(m_functionDeclarations); }
413
414
415 DeclarationResultMask declareLexicalVariable(const Identifier* ident, bool isConstant, DeclarationImportType importType = DeclarationImportType::NotImported)
416 {
417 ASSERT(m_allowsLexicalDeclarations);
418 DeclarationResultMask result = DeclarationResult::Valid;
419 bool isValidStrictMode = !isEvalOrArgumentsIdentifier(m_vm, ident);
420 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
421 auto addResult = m_lexicalVariables.add(ident->impl());
422 if (isConstant)
423 addResult.iterator->value.setIsConst();
424 else
425 addResult.iterator->value.setIsLet();
426
427 if (importType == DeclarationImportType::Imported)
428 addResult.iterator->value.setIsImported();
429 else if (importType == DeclarationImportType::ImportedNamespace) {
430 addResult.iterator->value.setIsImported();
431 addResult.iterator->value.setIsImportedNamespace();
432 }
433
434 if (!addResult.isNewEntry || m_variablesBeingHoisted.contains(ident->impl()))
435 result |= DeclarationResult::InvalidDuplicateDeclaration;
436 if (!isValidStrictMode)
437 result |= DeclarationResult::InvalidStrictMode;
438
439 return result;
440 }
441
442 ALWAYS_INLINE bool hasDeclaredVariable(const Identifier& ident)
443 {
444 return hasDeclaredVariable(ident.impl());
445 }
446
447 bool hasDeclaredVariable(const RefPtr<UniquedStringImpl>& ident)
448 {
449 auto iter = m_declaredVariables.find(ident.get());
450 if (iter == m_declaredVariables.end())
451 return false;
452 VariableEnvironmentEntry entry = iter->value;
453 return entry.isVar(); // The callee isn't a "var".
454 }
455
456 ALWAYS_INLINE bool hasLexicallyDeclaredVariable(const Identifier& ident)
457 {
458 return hasLexicallyDeclaredVariable(ident.impl());
459 }
460
461 bool hasLexicallyDeclaredVariable(const RefPtr<UniquedStringImpl>& ident) const
462 {
463 return m_lexicalVariables.contains(ident.get());
464 }
465
466 ALWAYS_INLINE bool hasDeclaredParameter(const Identifier& ident)
467 {
468 return hasDeclaredParameter(ident.impl());
469 }
470
471 bool hasDeclaredParameter(const RefPtr<UniquedStringImpl>& ident)
472 {
473 return m_declaredParameters.contains(ident.get()) || hasDeclaredVariable(ident);
474 }
475
476 void preventAllVariableDeclarations()
477 {
478 m_allowsVarDeclarations = false;
479 m_allowsLexicalDeclarations = false;
480 }
481 void preventVarDeclarations() { m_allowsVarDeclarations = false; }
482 bool allowsVarDeclarations() const { return m_allowsVarDeclarations; }
483 bool allowsLexicalDeclarations() const { return m_allowsLexicalDeclarations; }
484
485 DeclarationResultMask declareParameter(const Identifier* ident)
486 {
487 ASSERT(m_allowsVarDeclarations);
488 DeclarationResultMask result = DeclarationResult::Valid;
489 bool isArgumentsIdent = isArguments(m_vm, ident);
490 auto addResult = m_declaredVariables.add(ident->impl());
491 bool isValidStrictMode = (addResult.isNewEntry || !addResult.iterator->value.isParameter())
492 && m_vm.propertyNames->eval != *ident && !isArgumentsIdent;
493 addResult.iterator->value.clearIsVar();
494 addResult.iterator->value.setIsParameter();
495 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
496 m_declaredParameters.add(ident->impl());
497 if (!isValidStrictMode)
498 result |= DeclarationResult::InvalidStrictMode;
499 if (isArgumentsIdent)
500 m_shadowsArguments = true;
501 if (!addResult.isNewEntry)
502 result |= DeclarationResult::InvalidDuplicateDeclaration;
503
504 return result;
505 }
506
507 bool usedVariablesContains(UniquedStringImpl* impl) const
508 {
509 for (const UniquedStringImplPtrSet& set : m_usedVariables) {
510 if (set.contains(impl))
511 return true;
512 }
513 return false;
514 }
515 template <typename Func>
516 void forEachUsedVariable(const Func& func)
517 {
518 for (const UniquedStringImplPtrSet& set : m_usedVariables) {
519 for (UniquedStringImpl* impl : set)
520 func(impl);
521 }
522 }
523 void useVariable(const Identifier* ident, bool isEval)
524 {
525 useVariable(ident->impl(), isEval);
526 }
527 void useVariable(UniquedStringImpl* impl, bool isEval)
528 {
529 m_usesEval |= isEval;
530 m_usedVariables.last().add(impl);
531 }
532
533 void pushUsedVariableSet() { m_usedVariables.append(UniquedStringImplPtrSet()); }
534 size_t currentUsedVariablesSize() { return m_usedVariables.size(); }
535
536 void revertToPreviousUsedVariables(size_t size) { m_usedVariables.resize(size); }
537
538 void setNeedsFullActivation() { m_needsFullActivation = true; }
539 bool needsFullActivation() const { return m_needsFullActivation; }
540 bool isArrowFunctionBoundary() { return m_isArrowFunctionBoundary; }
541 bool isArrowFunction() { return m_isArrowFunction; }
542
543 bool hasDirectSuper() const { return m_hasDirectSuper; }
544 bool setHasDirectSuper() { return std::exchange(m_hasDirectSuper, true); }
545
546 bool needsSuperBinding() const { return m_needsSuperBinding; }
547 bool setNeedsSuperBinding() { return std::exchange(m_needsSuperBinding, true); }
548
549 void setEvalContextType(EvalContextType evalContextType) { m_evalContextType = evalContextType; }
550 EvalContextType evalContextType() { return m_evalContextType; }
551
552 InnerArrowFunctionCodeFeatures innerArrowFunctionFeatures() { return m_innerArrowFunctionFeatures; }
553
554 void setExpectedSuperBinding(SuperBinding superBinding) { m_expectedSuperBinding = static_cast<unsigned>(superBinding); }
555 SuperBinding expectedSuperBinding() const { return static_cast<SuperBinding>(m_expectedSuperBinding); }
556 void setConstructorKind(ConstructorKind constructorKind) { m_constructorKind = static_cast<unsigned>(constructorKind); }
557 ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); }
558
559 void setInnerArrowFunctionUsesSuperCall() { m_innerArrowFunctionFeatures |= SuperCallInnerArrowFunctionFeature; }
560 void setInnerArrowFunctionUsesSuperProperty() { m_innerArrowFunctionFeatures |= SuperPropertyInnerArrowFunctionFeature; }
561 void setInnerArrowFunctionUsesEval() { m_innerArrowFunctionFeatures |= EvalInnerArrowFunctionFeature; }
562 void setInnerArrowFunctionUsesThis() { m_innerArrowFunctionFeatures |= ThisInnerArrowFunctionFeature; }
563 void setInnerArrowFunctionUsesNewTarget() { m_innerArrowFunctionFeatures |= NewTargetInnerArrowFunctionFeature; }
564 void setInnerArrowFunctionUsesArguments() { m_innerArrowFunctionFeatures |= ArgumentsInnerArrowFunctionFeature; }
565
566 bool isEvalContext() const { return m_isEvalContext; }
567 void setIsEvalContext(bool isEvalContext) { m_isEvalContext = isEvalContext; }
568
569 void setInnerArrowFunctionUsesEvalAndUseArgumentsIfNeeded()
570 {
571 ASSERT(m_isArrowFunction);
572
573 if (m_usesEval)
574 setInnerArrowFunctionUsesEval();
575
576 if (usedVariablesContains(m_vm.propertyNames->arguments.impl()))
577 setInnerArrowFunctionUsesArguments();
578 }
579
580 void addClosedVariableCandidateUnconditionally(UniquedStringImpl* impl)
581 {
582 m_closedVariableCandidates.add(impl);
583 }
584
585 void collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)
586 {
587 if (nestedScope->m_usesEval)
588 m_usesEval = true;
589
590 {
591 UniquedStringImplPtrSet& destinationSet = m_usedVariables.last();
592 for (const UniquedStringImplPtrSet& usedVariablesSet : nestedScope->m_usedVariables) {
593 for (UniquedStringImpl* impl : usedVariablesSet) {
594 if (nestedScope->m_declaredVariables.contains(impl) || nestedScope->m_lexicalVariables.contains(impl))
595 continue;
596
597 // "arguments" reference should be resolved at function boudary.
598 if (nestedScope->isFunctionBoundary() && nestedScope->hasArguments() && impl == m_vm.propertyNames->arguments.impl() && !nestedScope->isArrowFunctionBoundary())
599 continue;
600
601 destinationSet.add(impl);
602 // We don't want a declared variable that is used in an inner scope to be thought of as captured if
603 // that inner scope is both a lexical scope and not a function. Only inner functions and "catch"
604 // statements can cause variables to be captured.
605 if (shouldTrackClosedVariables && (nestedScope->m_isFunctionBoundary || !nestedScope->m_isLexicalScope))
606 m_closedVariableCandidates.add(impl);
607 }
608 }
609 }
610 // Propagate closed variable candidates downwards within the same function.
611 // Cross function captures will be realized via m_usedVariables propagation.
612 if (shouldTrackClosedVariables && !nestedScope->m_isFunctionBoundary && nestedScope->m_closedVariableCandidates.size()) {
613 auto end = nestedScope->m_closedVariableCandidates.end();
614 auto begin = nestedScope->m_closedVariableCandidates.begin();
615 m_closedVariableCandidates.add(begin, end);
616 }
617 }
618
619 void mergeInnerArrowFunctionFeatures(InnerArrowFunctionCodeFeatures arrowFunctionCodeFeatures)
620 {
621 m_innerArrowFunctionFeatures = m_innerArrowFunctionFeatures | arrowFunctionCodeFeatures;
622 }
623
624 void getSloppyModeHoistedFunctions(UniquedStringImplPtrSet& sloppyModeHoistedFunctions)
625 {
626 for (UniquedStringImpl* function : m_sloppyModeHoistableFunctionCandidates) {
627 // ES6 Annex B.3.3. The only time we can't hoist a function is if a syntax error would
628 // be caused by declaring a var with that function's name or if we have a parameter with
629 // that function's name. Note that we would only cause a syntax error if we had a let/const/class
630 // variable with the same name.
631 if (!m_lexicalVariables.contains(function)) {
632 auto iter = m_declaredVariables.find(function);
633 bool isParameter = iter != m_declaredVariables.end() && iter->value.isParameter();
634 if (!isParameter) {
635 auto addResult = m_declaredVariables.add(function);
636 addResult.iterator->value.setIsVar();
637 addResult.iterator->value.setIsSloppyModeHoistingCandidate();
638 sloppyModeHoistedFunctions.add(function);
639 }
640 }
641 }
642 }
643
644 void getCapturedVars(IdentifierSet& capturedVariables)
645 {
646 if (m_needsFullActivation || m_usesEval) {
647 for (auto& entry : m_declaredVariables)
648 capturedVariables.add(entry.key);
649 return;
650 }
651 for (UniquedStringImpl* impl : m_closedVariableCandidates) {
652 // We refer to m_declaredVariables here directly instead of a hasDeclaredVariable because we want to mark the callee as captured.
653 if (!m_declaredVariables.contains(impl))
654 continue;
655 capturedVariables.add(impl);
656 }
657 }
658 void setStrictMode() { m_strictMode = true; }
659 bool strictMode() const { return m_strictMode; }
660 bool isValidStrictMode() const { return m_isValidStrictMode; }
661 bool shadowsArguments() const { return m_shadowsArguments; }
662 void setHasNonSimpleParameterList()
663 {
664 m_isValidStrictMode = false;
665 m_hasNonSimpleParameterList = true;
666 }
667 bool hasNonSimpleParameterList() const { return m_hasNonSimpleParameterList; }
668
669 void copyCapturedVariablesToVector(const UniquedStringImplPtrSet& usedVariables, Vector<UniquedStringImpl*, 8>& vector)
670 {
671 for (UniquedStringImpl* impl : usedVariables) {
672 if (m_declaredVariables.contains(impl) || m_lexicalVariables.contains(impl))
673 continue;
674 vector.append(impl);
675 }
676 }
677
678 void fillParametersForSourceProviderCache(SourceProviderCacheItemCreationParameters& parameters, const UniquedStringImplPtrSet& capturesFromParameterExpressions)
679 {
680 ASSERT(m_isFunction);
681 parameters.usesEval = m_usesEval;
682 parameters.strictMode = m_strictMode;
683 parameters.needsFullActivation = m_needsFullActivation;
684 parameters.innerArrowFunctionFeatures = m_innerArrowFunctionFeatures;
685 parameters.needsSuperBinding = m_needsSuperBinding;
686 for (const UniquedStringImplPtrSet& set : m_usedVariables)
687 copyCapturedVariablesToVector(set, parameters.usedVariables);
688
689 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=156962
690 // We add these unconditionally because we currently don't keep a separate
691 // declaration scope for a function's parameters and its var/let/const declarations.
692 // This is somewhat unfortunate and we should refactor to do this at some point
693 // because parameters logically form a parent scope to var/let/const variables.
694 // But because we don't do this, we must grab capture candidates from a parameter
695 // list before we parse the body of a function because the body's declarations
696 // might make us believe something isn't actually a capture candidate when it really
697 // is.
698 for (UniquedStringImpl* impl : capturesFromParameterExpressions)
699 parameters.usedVariables.append(impl);
700 }
701
702 void restoreFromSourceProviderCache(const SourceProviderCacheItem* info)
703 {
704 ASSERT(m_isFunction);
705 m_usesEval = info->usesEval;
706 m_strictMode = info->strictMode;
707 m_innerArrowFunctionFeatures = info->innerArrowFunctionFeatures;
708 m_needsFullActivation = info->needsFullActivation;
709 m_needsSuperBinding = info->needsSuperBinding;
710 UniquedStringImplPtrSet& destSet = m_usedVariables.last();
711 for (unsigned i = 0; i < info->usedVariablesCount; ++i)
712 destSet.add(info->usedVariables()[i]);
713 }
714
715 class MaybeParseAsGeneratorForScope;
716
717private:
718 void setIsFunction()
719 {
720 m_isFunction = true;
721 m_isFunctionBoundary = true;
722 m_hasArguments = true;
723 setIsLexicalScope();
724 m_isGenerator = false;
725 m_isGeneratorBoundary = false;
726 m_isArrowFunctionBoundary = false;
727 m_isArrowFunction = false;
728 m_isAsyncFunction = false;
729 m_isAsyncFunctionBoundary = false;
730 }
731
732 void setIsGeneratorFunction()
733 {
734 setIsFunction();
735 m_isGenerator = true;
736 }
737
738 void setIsGenerator()
739 {
740 setIsFunction();
741 m_isGenerator = true;
742 m_isGeneratorBoundary = true;
743 m_hasArguments = false;
744 }
745
746 void setIsArrowFunction()
747 {
748 setIsFunction();
749 m_isArrowFunctionBoundary = true;
750 m_isArrowFunction = true;
751 }
752
753 void setIsAsyncArrowFunction()
754 {
755 setIsArrowFunction();
756 m_isAsyncFunction = true;
757 }
758
759 void setIsAsyncFunction()
760 {
761 setIsFunction();
762 m_isAsyncFunction = true;
763 }
764
765 void setIsAsyncGeneratorFunction()
766 {
767 setIsFunction();
768 m_isAsyncFunction = true;
769 m_isGenerator = true;
770 }
771
772 void setIsAsyncGeneratorFunctionBody()
773 {
774 setIsFunction();
775 m_hasArguments = false;
776 m_isGenerator = true;
777 m_isGeneratorBoundary = true;
778 m_isAsyncFunction = true;
779 m_isAsyncFunctionBoundary = true;
780 }
781
782 void setIsAsyncFunctionBody()
783 {
784 setIsFunction();
785 m_hasArguments = false;
786 m_isAsyncFunction = true;
787 m_isAsyncFunctionBoundary = true;
788 }
789
790 void setIsAsyncArrowFunctionBody()
791 {
792 setIsArrowFunction();
793 m_hasArguments = false;
794 m_isAsyncFunction = true;
795 m_isAsyncFunctionBoundary = true;
796 }
797
798 const VM& m_vm;
799 bool m_shadowsArguments;
800 bool m_usesEval;
801 bool m_needsFullActivation;
802 bool m_hasDirectSuper;
803 bool m_needsSuperBinding;
804 bool m_allowsVarDeclarations;
805 bool m_allowsLexicalDeclarations;
806 bool m_strictMode;
807 bool m_isFunction;
808 bool m_isGenerator;
809 bool m_isGeneratorBoundary;
810 bool m_isArrowFunction;
811 bool m_isArrowFunctionBoundary;
812 bool m_isAsyncFunction;
813 bool m_isAsyncFunctionBoundary;
814 bool m_isLexicalScope;
815 bool m_isGlobalCodeScope;
816 bool m_isSimpleCatchParameterScope;
817 bool m_isFunctionBoundary;
818 bool m_isValidStrictMode;
819 bool m_hasArguments;
820 bool m_isEvalContext;
821 bool m_hasNonSimpleParameterList;
822 EvalContextType m_evalContextType;
823 unsigned m_constructorKind;
824 unsigned m_expectedSuperBinding;
825 int m_loopDepth;
826 int m_switchDepth;
827 InnerArrowFunctionCodeFeatures m_innerArrowFunctionFeatures;
828
829 typedef Vector<ScopeLabelInfo, 2> LabelStack;
830 std::unique_ptr<LabelStack> m_labels;
831 UniquedStringImplPtrSet m_declaredParameters;
832 VariableEnvironment m_declaredVariables;
833 VariableEnvironment m_lexicalVariables;
834 Vector<UniquedStringImplPtrSet, 6> m_usedVariables;
835 UniquedStringImplPtrSet m_variablesBeingHoisted;
836 UniquedStringImplPtrSet m_sloppyModeHoistableFunctionCandidates;
837 HashSet<UniquedStringImpl*> m_closedVariableCandidates;
838 DeclarationStacks::FunctionStack m_functionDeclarations;
839};
840
841typedef Vector<Scope, 10> ScopeStack;
842
843struct ScopeRef {
844 ScopeRef(ScopeStack* scopeStack, unsigned index)
845 : m_scopeStack(scopeStack)
846 , m_index(index)
847 {
848 }
849 Scope* operator->() { return &m_scopeStack->at(m_index); }
850 unsigned index() const { return m_index; }
851
852 bool hasContainingScope()
853 {
854 return m_index && !m_scopeStack->at(m_index).isFunctionBoundary();
855 }
856
857 ScopeRef containingScope()
858 {
859 ASSERT(hasContainingScope());
860 return ScopeRef(m_scopeStack, m_index - 1);
861 }
862
863 bool operator==(const ScopeRef& other)
864 {
865 ASSERT(other.m_scopeStack == m_scopeStack);
866 return m_index == other.m_index;
867 }
868
869 bool operator!=(const ScopeRef& other)
870 {
871 return !(*this == other);
872 }
873
874private:
875 ScopeStack* m_scopeStack;
876 unsigned m_index;
877};
878
879enum class ArgumentType { Normal, Spread };
880enum class ParsingContext { Program, FunctionConstructor, Eval };
881
882template <typename LexerType>
883class Parser {
884 WTF_MAKE_NONCOPYABLE(Parser);
885 WTF_MAKE_FAST_ALLOCATED;
886
887public:
888 Parser(VM&, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, JSParserScriptMode, SourceParseMode, SuperBinding, ConstructorKind defaultConstructorKindForTopLevelFunction = ConstructorKind::None, DerivedContextType = DerivedContextType::None, bool isEvalContext = false, EvalContextType = EvalContextType::None, DebuggerParseData* = nullptr);
889 ~Parser();
890
891 template <class ParsedNode>
892 std::unique_ptr<ParsedNode> parse(ParserError&, const Identifier&, SourceParseMode, ParsingContext, Optional<int> functionConstructorParametersEndPosition = WTF::nullopt);
893
894 JSTextPosition positionBeforeLastNewline() const { return m_lexer->positionBeforeLastNewline(); }
895 JSTokenLocation locationBeforeLastToken() const { return m_lexer->lastTokenLocation(); }
896
897 struct CallOrApplyDepthScope {
898 CallOrApplyDepthScope(Parser* parser)
899 : m_parser(parser)
900 , m_parent(parser->m_callOrApplyDepthScope)
901 , m_depth(m_parent ? m_parent->m_depth + 1 : 0)
902 , m_depthOfInnermostChild(m_depth)
903 {
904 parser->m_callOrApplyDepthScope = this;
905 }
906
907 size_t distanceToInnermostChild() const
908 {
909 ASSERT(m_depthOfInnermostChild >= m_depth);
910 return m_depthOfInnermostChild - m_depth;
911 }
912
913 ~CallOrApplyDepthScope()
914 {
915 if (m_parent)
916 m_parent->m_depthOfInnermostChild = std::max(m_depthOfInnermostChild, m_parent->m_depthOfInnermostChild);
917 m_parser->m_callOrApplyDepthScope = m_parent;
918 }
919
920 private:
921
922 Parser* m_parser;
923 CallOrApplyDepthScope* m_parent;
924 size_t m_depth;
925 size_t m_depthOfInnermostChild;
926 };
927
928private:
929 struct AllowInOverride {
930 AllowInOverride(Parser* parser)
931 : m_parser(parser)
932 , m_oldAllowsIn(parser->m_allowsIn)
933 {
934 parser->m_allowsIn = true;
935 }
936 ~AllowInOverride()
937 {
938 m_parser->m_allowsIn = m_oldAllowsIn;
939 }
940 Parser* m_parser;
941 bool m_oldAllowsIn;
942 };
943
944 struct AutoPopScopeRef : public ScopeRef {
945 AutoPopScopeRef(Parser* parser, ScopeRef scope)
946 : ScopeRef(scope)
947 , m_parser(parser)
948 {
949 }
950
951 ~AutoPopScopeRef()
952 {
953 if (m_parser)
954 m_parser->popScope(*this, false);
955 }
956
957 void setPopped()
958 {
959 m_parser = 0;
960 }
961
962 private:
963 Parser* m_parser;
964 };
965
966 struct AutoCleanupLexicalScope {
967 // We can allocate this object on the stack without actually knowing beforehand if we're
968 // going to create a new lexical scope. If we decide to create a new lexical scope, we
969 // can pass the scope into this obejct and it will take care of the cleanup for us if the parse fails.
970 // This is helpful if we may fail from syntax errors after creating a lexical scope conditionally.
971 AutoCleanupLexicalScope()
972 : m_scope(nullptr, UINT_MAX)
973 , m_parser(nullptr)
974 {
975 }
976
977 ~AutoCleanupLexicalScope()
978 {
979 // This should only ever be called if we fail from a syntax error. Otherwise
980 // it's the intention that a user of this class pops this scope manually on a
981 // successful parse.
982 if (isValid())
983 m_parser->popScope(*this, false);
984 }
985
986 void setIsValid(ScopeRef& scope, Parser* parser)
987 {
988 RELEASE_ASSERT(scope->isLexicalScope());
989 m_scope = scope;
990 m_parser = parser;
991 }
992
993 bool isValid() const { return !!m_parser; }
994
995 void setPopped()
996 {
997 m_parser = nullptr;
998 }
999
1000 ScopeRef& scope() { return m_scope; }
1001
1002 private:
1003 ScopeRef m_scope;
1004 Parser* m_parser;
1005 };
1006
1007 enum ExpressionErrorClass {
1008 ErrorIndicatesNothing = 0,
1009 ErrorIndicatesPattern,
1010 ErrorIndicatesAsyncArrowFunction
1011 };
1012
1013 struct ExpressionErrorClassifier {
1014 ExpressionErrorClassifier(Parser* parser)
1015 : m_class(ErrorIndicatesNothing)
1016 , m_previous(parser->m_expressionErrorClassifier)
1017 , m_parser(parser)
1018 {
1019 m_parser->m_expressionErrorClassifier = this;
1020 }
1021
1022 ~ExpressionErrorClassifier()
1023 {
1024 m_parser->m_expressionErrorClassifier = m_previous;
1025 }
1026
1027 void classifyExpressionError(ExpressionErrorClass classification)
1028 {
1029 if (m_class != ErrorIndicatesNothing)
1030 return;
1031 m_class = classification;
1032 }
1033
1034 void forceClassifyExpressionError(ExpressionErrorClass classification)
1035 {
1036 m_class = classification;
1037 }
1038
1039 void reclassifyExpressionError(ExpressionErrorClass oldClassification, ExpressionErrorClass classification)
1040 {
1041 if (m_class != oldClassification)
1042 return;
1043 m_class = classification;
1044 }
1045
1046 void propagateExpressionErrorClass()
1047 {
1048 if (m_previous)
1049 m_previous->m_class = m_class;
1050 }
1051
1052 bool indicatesPossiblePattern() const { return m_class == ErrorIndicatesPattern; }
1053 bool indicatesPossibleAsyncArrowFunction() const { return m_class == ErrorIndicatesAsyncArrowFunction; }
1054
1055 private:
1056 ExpressionErrorClass m_class;
1057 ExpressionErrorClassifier* m_previous;
1058 Parser* m_parser;
1059 };
1060
1061 ALWAYS_INLINE void classifyExpressionError(ExpressionErrorClass classification)
1062 {
1063 if (m_expressionErrorClassifier)
1064 m_expressionErrorClassifier->classifyExpressionError(classification);
1065 }
1066
1067 ALWAYS_INLINE void forceClassifyExpressionError(ExpressionErrorClass classification)
1068 {
1069 if (m_expressionErrorClassifier)
1070 m_expressionErrorClassifier->forceClassifyExpressionError(classification);
1071 }
1072
1073 ALWAYS_INLINE void reclassifyExpressionError(ExpressionErrorClass oldClassification, ExpressionErrorClass classification)
1074 {
1075 if (m_expressionErrorClassifier)
1076 m_expressionErrorClassifier->reclassifyExpressionError(oldClassification, classification);
1077 }
1078
1079 ALWAYS_INLINE DestructuringKind destructuringKindFromDeclarationType(DeclarationType type)
1080 {
1081 switch (type) {
1082 case DeclarationType::VarDeclaration:
1083 return DestructuringKind::DestructureToVariables;
1084 case DeclarationType::LetDeclaration:
1085 return DestructuringKind::DestructureToLet;
1086 case DeclarationType::ConstDeclaration:
1087 return DestructuringKind::DestructureToConst;
1088 }
1089
1090 RELEASE_ASSERT_NOT_REACHED();
1091 return DestructuringKind::DestructureToVariables;
1092 }
1093
1094 ALWAYS_INLINE const char* declarationTypeToVariableKind(DeclarationType type)
1095 {
1096 switch (type) {
1097 case DeclarationType::VarDeclaration:
1098 return "variable name";
1099 case DeclarationType::LetDeclaration:
1100 case DeclarationType::ConstDeclaration:
1101 return "lexical variable name";
1102 }
1103 RELEASE_ASSERT_NOT_REACHED();
1104 return "invalid";
1105 }
1106
1107 ALWAYS_INLINE AssignmentContext assignmentContextFromDeclarationType(DeclarationType type)
1108 {
1109 switch (type) {
1110 case DeclarationType::ConstDeclaration:
1111 return AssignmentContext::ConstDeclarationStatement;
1112 default:
1113 return AssignmentContext::DeclarationStatement;
1114 }
1115 }
1116
1117 ALWAYS_INLINE bool isEvalOrArguments(const Identifier* ident) { return isEvalOrArgumentsIdentifier(m_vm, ident); }
1118
1119 ScopeRef upperScope(int n)
1120 {
1121 ASSERT(m_scopeStack.size() >= size_t(1 + n));
1122 return ScopeRef(&m_scopeStack, m_scopeStack.size() - 1 - n);
1123 }
1124
1125 ScopeRef currentScope()
1126 {
1127 return ScopeRef(&m_scopeStack, m_scopeStack.size() - 1);
1128 }
1129
1130 ScopeRef currentVariableScope()
1131 {
1132 unsigned i = m_scopeStack.size() - 1;
1133 ASSERT(i < m_scopeStack.size());
1134 while (!m_scopeStack[i].allowsVarDeclarations()) {
1135 i--;
1136 ASSERT(i < m_scopeStack.size());
1137 }
1138 return ScopeRef(&m_scopeStack, i);
1139 }
1140
1141 ScopeRef currentLexicalDeclarationScope()
1142 {
1143 unsigned i = m_scopeStack.size() - 1;
1144 ASSERT(i < m_scopeStack.size());
1145 while (!m_scopeStack[i].allowsLexicalDeclarations()) {
1146 i--;
1147 ASSERT(i < m_scopeStack.size());
1148 }
1149
1150 return ScopeRef(&m_scopeStack, i);
1151 }
1152
1153 ScopeRef currentFunctionScope()
1154 {
1155 unsigned i = m_scopeStack.size() - 1;
1156 ASSERT(i < m_scopeStack.size());
1157 while (i && !m_scopeStack[i].isFunctionBoundary()) {
1158 i--;
1159 ASSERT(i < m_scopeStack.size());
1160 }
1161 // When reaching the top level scope (it can be non function scope), we return it.
1162 return ScopeRef(&m_scopeStack, i);
1163 }
1164
1165 ScopeRef closestParentOrdinaryFunctionNonLexicalScope()
1166 {
1167 unsigned i = m_scopeStack.size() - 1;
1168 ASSERT(i < m_scopeStack.size() && m_scopeStack.size());
1169 while (i && (!m_scopeStack[i].isFunctionBoundary() || m_scopeStack[i].isGeneratorBoundary() || m_scopeStack[i].isAsyncFunctionBoundary() || m_scopeStack[i].isArrowFunctionBoundary()))
1170 i--;
1171 // When reaching the top level scope (it can be non ordinary function scope), we return it.
1172 return ScopeRef(&m_scopeStack, i);
1173 }
1174
1175 ScopeRef pushScope()
1176 {
1177 bool isFunction = false;
1178 bool isStrict = false;
1179 bool isGenerator = false;
1180 bool isArrowFunction = false;
1181 bool isAsyncFunction = false;
1182 if (!m_scopeStack.isEmpty()) {
1183 isStrict = m_scopeStack.last().strictMode();
1184 isFunction = m_scopeStack.last().isFunction();
1185 isGenerator = m_scopeStack.last().isGenerator();
1186 isArrowFunction = m_scopeStack.last().isArrowFunction();
1187 isAsyncFunction = m_scopeStack.last().isAsyncFunction();
1188 }
1189 m_scopeStack.constructAndAppend(m_vm, isFunction, isGenerator, isStrict, isArrowFunction, isAsyncFunction);
1190 return currentScope();
1191 }
1192
1193 void popScopeInternal(ScopeRef& scope, bool shouldTrackClosedVariables)
1194 {
1195 EXCEPTION_ASSERT_UNUSED(scope, scope.index() == m_scopeStack.size() - 1);
1196 ASSERT(m_scopeStack.size() > 1);
1197 m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&m_scopeStack.last(), shouldTrackClosedVariables);
1198
1199 if (m_scopeStack.last().isArrowFunction())
1200 m_scopeStack.last().setInnerArrowFunctionUsesEvalAndUseArgumentsIfNeeded();
1201
1202 if (!(m_scopeStack.last().isFunctionBoundary() && !m_scopeStack.last().isArrowFunctionBoundary()))
1203 m_scopeStack[m_scopeStack.size() - 2].mergeInnerArrowFunctionFeatures(m_scopeStack.last().innerArrowFunctionFeatures());
1204
1205 if (!m_scopeStack.last().isFunctionBoundary() && m_scopeStack.last().needsFullActivation())
1206 m_scopeStack[m_scopeStack.size() - 2].setNeedsFullActivation();
1207 m_scopeStack.removeLast();
1208 }
1209
1210 ALWAYS_INLINE void popScope(ScopeRef& scope, bool shouldTrackClosedVariables)
1211 {
1212 popScopeInternal(scope, shouldTrackClosedVariables);
1213 }
1214
1215 ALWAYS_INLINE void popScope(AutoPopScopeRef& scope, bool shouldTrackClosedVariables)
1216 {
1217 scope.setPopped();
1218 popScopeInternal(scope, shouldTrackClosedVariables);
1219 }
1220
1221 ALWAYS_INLINE void popScope(AutoCleanupLexicalScope& cleanupScope, bool shouldTrackClosedVariables)
1222 {
1223 RELEASE_ASSERT(cleanupScope.isValid());
1224 ScopeRef& scope = cleanupScope.scope();
1225 cleanupScope.setPopped();
1226 popScopeInternal(scope, shouldTrackClosedVariables);
1227 }
1228
1229 NEVER_INLINE DeclarationResultMask declareHoistedVariable(const Identifier* ident)
1230 {
1231 unsigned i = m_scopeStack.size() - 1;
1232 ASSERT(i < m_scopeStack.size());
1233 while (true) {
1234 // Annex B.3.5 exempts `try {} catch (e) { var e; }` from being a syntax error.
1235 if (m_scopeStack[i].hasLexicallyDeclaredVariable(*ident) && !m_scopeStack[i].isSimpleCatchParameterScope())
1236 return DeclarationResult::InvalidDuplicateDeclaration;
1237
1238 if (m_scopeStack[i].allowsVarDeclarations())
1239 return m_scopeStack[i].declareVariable(ident);
1240
1241 m_scopeStack[i].addVariableBeingHoisted(ident);
1242
1243 i--;
1244 ASSERT(i < m_scopeStack.size());
1245 }
1246 }
1247
1248 DeclarationResultMask declareVariable(const Identifier* ident, DeclarationType type = DeclarationType::VarDeclaration, DeclarationImportType importType = DeclarationImportType::NotImported)
1249 {
1250 if (type == DeclarationType::VarDeclaration)
1251 return declareHoistedVariable(ident);
1252
1253 ASSERT(type == DeclarationType::LetDeclaration || type == DeclarationType::ConstDeclaration);
1254 // Lexical variables declared at a top level scope that shadow arguments or vars are not allowed.
1255 if (!m_lexer->isReparsingFunction() && m_statementDepth == 1 && (hasDeclaredParameter(*ident) || hasDeclaredVariable(*ident)))
1256 return DeclarationResult::InvalidDuplicateDeclaration;
1257
1258 return currentLexicalDeclarationScope()->declareLexicalVariable(ident, type == DeclarationType::ConstDeclaration, importType);
1259 }
1260
1261 std::pair<DeclarationResultMask, ScopeRef> declareFunction(const Identifier* ident)
1262 {
1263 if ((m_statementDepth == 1) || (!strictMode() && !currentScope()->isFunction() && !closestParentOrdinaryFunctionNonLexicalScope()->isEvalContext())) {
1264 // Functions declared at the top-most scope (both in sloppy and strict mode) are declared as vars
1265 // for backwards compatibility. This allows us to declare functions with the same name more than once.
1266 // In sloppy mode, we always declare functions as vars.
1267 bool declareAsVar = true;
1268 bool isSloppyModeHoistingCandidate = false;
1269 ScopeRef variableScope = currentVariableScope();
1270 return std::make_pair(variableScope->declareFunction(ident, declareAsVar, isSloppyModeHoistingCandidate), variableScope);
1271 }
1272
1273 if (!strictMode()) {
1274 ASSERT(currentScope()->isFunction() || closestParentOrdinaryFunctionNonLexicalScope()->isEvalContext());
1275
1276 // Functions declared inside a function inside a nested block scope in sloppy mode are subject to this
1277 // crazy rule defined inside Annex B.3.3 in the ES6 spec. It basically states that we will create
1278 // the function as a local block scoped variable, but when we evaluate the block that the function is
1279 // contained in, we will assign the function to a "var" variable only if declaring such a "var" wouldn't
1280 // be a syntax error and if there isn't a parameter with the same name. (It would only be a syntax error if
1281 // there are is a let/class/const with the same name). Note that this mean we only do the "var" hoisting
1282 // binding if the block evaluates. For example, this means we wont won't perform the binding if it's inside
1283 // the untaken branch of an if statement.
1284 bool declareAsVar = false;
1285 bool isSloppyModeHoistingCandidate = true;
1286 ScopeRef lexicalVariableScope = currentLexicalDeclarationScope();
1287 ScopeRef varScope = currentVariableScope();
1288 varScope->addSloppyModeHoistableFunctionCandidate(ident);
1289 ASSERT(varScope != lexicalVariableScope);
1290 return std::make_pair(lexicalVariableScope->declareFunction(ident, declareAsVar, isSloppyModeHoistingCandidate), lexicalVariableScope);
1291 }
1292
1293 bool declareAsVar = false;
1294 bool isSloppyModeHoistingCandidate = false;
1295 ScopeRef lexicalVariableScope = currentLexicalDeclarationScope();
1296 return std::make_pair(lexicalVariableScope->declareFunction(ident, declareAsVar, isSloppyModeHoistingCandidate), lexicalVariableScope);
1297 }
1298
1299 NEVER_INLINE bool hasDeclaredVariable(const Identifier& ident)
1300 {
1301 unsigned i = m_scopeStack.size() - 1;
1302 ASSERT(i < m_scopeStack.size());
1303 while (!m_scopeStack[i].allowsVarDeclarations()) {
1304 i--;
1305 ASSERT(i < m_scopeStack.size());
1306 }
1307 return m_scopeStack[i].hasDeclaredVariable(ident);
1308 }
1309
1310 NEVER_INLINE bool hasDeclaredParameter(const Identifier& ident)
1311 {
1312 // FIXME: hasDeclaredParameter() is not valid during reparsing of generator or async function bodies, because their formal
1313 // parameters are declared in a scope unavailable during reparsing. Note that it is redundant to call this function during
1314 // reparsing anyways, as the function is already guaranteed to be valid by the original parsing.
1315 // https://bugs.webkit.org/show_bug.cgi?id=164087
1316 ASSERT(!m_lexer->isReparsingFunction());
1317
1318 unsigned i = m_scopeStack.size() - 1;
1319 ASSERT(i < m_scopeStack.size());
1320 while (!m_scopeStack[i].allowsVarDeclarations()) {
1321 i--;
1322 ASSERT(i < m_scopeStack.size());
1323 }
1324
1325 if (m_scopeStack[i].isGeneratorBoundary() || m_scopeStack[i].isAsyncFunctionBoundary()) {
1326 // The formal parameters which need to be verified for Generators and Async Function bodies occur
1327 // in the outer wrapper function, so pick the outer scope here.
1328 i--;
1329 ASSERT(i < m_scopeStack.size());
1330 }
1331 return m_scopeStack[i].hasDeclaredParameter(ident);
1332 }
1333
1334 bool exportName(const Identifier& ident)
1335 {
1336 ASSERT(currentScope().index() == 0);
1337 ASSERT(m_moduleScopeData);
1338 return m_moduleScopeData->exportName(ident);
1339 }
1340
1341 ScopeStack m_scopeStack;
1342
1343 const SourceProviderCacheItem* findCachedFunctionInfo(int openBracePos)
1344 {
1345 return m_functionCache ? m_functionCache->get(openBracePos) : 0;
1346 }
1347
1348 Parser();
1349
1350 String parseInner(const Identifier&, SourceParseMode, ParsingContext, Optional<int> functionConstructorParametersEndPosition = WTF::nullopt);
1351
1352 void didFinishParsing(SourceElements*, DeclarationStacks::FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, CodeFeatures, int);
1353
1354 // Used to determine type of error to report.
1355 bool isFunctionMetadataNode(ScopeNode*) { return false; }
1356 bool isFunctionMetadataNode(FunctionMetadataNode*) { return true; }
1357
1358 ALWAYS_INLINE void next(OptionSet<LexerFlags> lexerFlags = { })
1359 {
1360 int lastLine = m_token.m_location.line;
1361 int lastTokenEnd = m_token.m_location.endOffset;
1362 int lastTokenLineStart = m_token.m_location.lineStartOffset;
1363 m_lastTokenEndPosition = JSTextPosition(lastLine, lastTokenEnd, lastTokenLineStart);
1364 m_lexer->setLastLineNumber(lastLine);
1365 m_token.m_type = m_lexer->lex(&m_token, lexerFlags, strictMode());
1366 }
1367
1368 ALWAYS_INLINE void nextWithoutClearingLineTerminator(OptionSet<LexerFlags> lexerFlags = { })
1369 {
1370 int lastLine = m_token.m_location.line;
1371 int lastTokenEnd = m_token.m_location.endOffset;
1372 int lastTokenLineStart = m_token.m_location.lineStartOffset;
1373 m_lastTokenEndPosition = JSTextPosition(lastLine, lastTokenEnd, lastTokenLineStart);
1374 m_lexer->setLastLineNumber(lastLine);
1375 m_token.m_type = m_lexer->lexWithoutClearingLineTerminator(&m_token, lexerFlags, strictMode());
1376 }
1377
1378 ALWAYS_INLINE void nextExpectIdentifier(OptionSet<LexerFlags> lexerFlags = { })
1379 {
1380 int lastLine = m_token.m_location.line;
1381 int lastTokenEnd = m_token.m_location.endOffset;
1382 int lastTokenLineStart = m_token.m_location.lineStartOffset;
1383 m_lastTokenEndPosition = JSTextPosition(lastLine, lastTokenEnd, lastTokenLineStart);
1384 m_lexer->setLastLineNumber(lastLine);
1385 m_token.m_type = m_lexer->lexExpectIdentifier(&m_token, lexerFlags, strictMode());
1386 }
1387
1388 ALWAYS_INLINE void lexCurrentTokenAgainUnderCurrentContext()
1389 {
1390 auto savePoint = createSavePoint();
1391 restoreSavePoint(savePoint);
1392 }
1393
1394 ALWAYS_INLINE bool nextTokenIsColon()
1395 {
1396 return m_lexer->nextTokenIsColon();
1397 }
1398
1399 ALWAYS_INLINE bool consume(JSTokenType expected, OptionSet<LexerFlags> flags = { })
1400 {
1401 bool result = m_token.m_type == expected;
1402 if (result)
1403 next(flags);
1404 return result;
1405 }
1406
1407 void printUnexpectedTokenText(WTF::PrintStream&);
1408 ALWAYS_INLINE StringView getToken()
1409 {
1410 return m_lexer->getToken(m_token);
1411 }
1412
1413 ALWAYS_INLINE StringView getToken(const JSToken& token)
1414 {
1415 return m_lexer->getToken(token);
1416 }
1417
1418 ALWAYS_INLINE bool match(JSTokenType expected)
1419 {
1420 return m_token.m_type == expected;
1421 }
1422
1423 ALWAYS_INLINE bool matchContextualKeyword(const Identifier& identifier)
1424 {
1425 return m_token.m_type == IDENT && *m_token.m_data.ident == identifier && !m_token.m_data.escaped;
1426 }
1427
1428 ALWAYS_INLINE bool matchIdentifierOrKeyword()
1429 {
1430 return isIdentifierOrKeyword(m_token);
1431 }
1432
1433 ALWAYS_INLINE unsigned tokenStart()
1434 {
1435 return m_token.m_location.startOffset;
1436 }
1437
1438 ALWAYS_INLINE const JSTextPosition& tokenStartPosition()
1439 {
1440 return m_token.m_startPosition;
1441 }
1442
1443 ALWAYS_INLINE int tokenLine()
1444 {
1445 return m_token.m_location.line;
1446 }
1447
1448 ALWAYS_INLINE int tokenColumn()
1449 {
1450 return tokenStart() - tokenLineStart();
1451 }
1452
1453 ALWAYS_INLINE const JSTextPosition& tokenEndPosition()
1454 {
1455 return m_token.m_endPosition;
1456 }
1457
1458 ALWAYS_INLINE unsigned tokenLineStart()
1459 {
1460 return m_token.m_location.lineStartOffset;
1461 }
1462
1463 ALWAYS_INLINE const JSTokenLocation& tokenLocation()
1464 {
1465 return m_token.m_location;
1466 }
1467
1468 void setErrorMessage(const String& message)
1469 {
1470 ASSERT_WITH_MESSAGE(!message.isEmpty(), "Attempted to set the empty string as an error message. Likely caused by invalid UTF8 used when creating the message.");
1471 m_errorMessage = message;
1472 if (m_errorMessage.isEmpty())
1473 m_errorMessage = "Unparseable script"_s;
1474 }
1475
1476 NEVER_INLINE void logError(bool);
1477 template <typename... Args>
1478 NEVER_INLINE void logError(bool, Args&&...);
1479
1480 NEVER_INLINE void updateErrorWithNameAndMessage(const char* beforeMessage, const String& name, const char* afterMessage)
1481 {
1482 m_errorMessage = makeString(beforeMessage, " '", name, "' ", afterMessage);
1483 }
1484
1485 NEVER_INLINE void updateErrorMessage(const char* msg)
1486 {
1487 ASSERT(msg);
1488 m_errorMessage = String(msg);
1489 ASSERT(!m_errorMessage.isNull());
1490 }
1491
1492 ALWAYS_INLINE void recordPauseLocation(const JSTextPosition&);
1493 ALWAYS_INLINE void recordFunctionEntryLocation(const JSTextPosition&);
1494 ALWAYS_INLINE void recordFunctionLeaveLocation(const JSTextPosition&);
1495
1496 void startLoop() { currentScope()->startLoop(); }
1497 void endLoop() { currentScope()->endLoop(); }
1498 void startSwitch() { currentScope()->startSwitch(); }
1499 void endSwitch() { currentScope()->endSwitch(); }
1500 void setStrictMode() { currentScope()->setStrictMode(); }
1501 bool strictMode() { return currentScope()->strictMode(); }
1502 bool isValidStrictMode()
1503 {
1504 int i = m_scopeStack.size() - 1;
1505 if (!m_scopeStack[i].isValidStrictMode())
1506 return false;
1507
1508 // In the case of Generator or Async function bodies, also check the wrapper function, whose name or
1509 // arguments may be invalid.
1510 if (UNLIKELY((m_scopeStack[i].isGeneratorBoundary() || m_scopeStack[i].isAsyncFunctionBoundary()) && i))
1511 return m_scopeStack[i - 1].isValidStrictMode();
1512 return true;
1513 }
1514 DeclarationResultMask declareParameter(const Identifier* ident) { return currentScope()->declareParameter(ident); }
1515 bool declareRestOrNormalParameter(const Identifier&, const Identifier**);
1516
1517 bool breakIsValid()
1518 {
1519 ScopeRef current = currentScope();
1520 while (!current->breakIsValid()) {
1521 if (!current.hasContainingScope())
1522 return false;
1523 current = current.containingScope();
1524 }
1525 return true;
1526 }
1527 bool continueIsValid()
1528 {
1529 ScopeRef current = currentScope();
1530 while (!current->continueIsValid()) {
1531 if (!current.hasContainingScope())
1532 return false;
1533 current = current.containingScope();
1534 }
1535 return true;
1536 }
1537 void pushLabel(const Identifier* label, bool isLoop) { currentScope()->pushLabel(label, isLoop); }
1538 void popLabel(ScopeRef scope) { scope->popLabel(); }
1539 ScopeLabelInfo* getLabel(const Identifier* label)
1540 {
1541 ScopeRef current = currentScope();
1542 ScopeLabelInfo* result = 0;
1543 while (!(result = current->getLabel(label))) {
1544 if (!current.hasContainingScope())
1545 return 0;
1546 current = current.containingScope();
1547 }
1548 return result;
1549 }
1550
1551 // http://ecma-international.org/ecma-262/6.0/#sec-identifiers-static-semantics-early-errors
1552 ALWAYS_INLINE bool isLETMaskedAsIDENT()
1553 {
1554 return match(LET) && !strictMode();
1555 }
1556
1557 // http://ecma-international.org/ecma-262/6.0/#sec-identifiers-static-semantics-early-errors
1558 ALWAYS_INLINE bool isYIELDMaskedAsIDENT(bool inGenerator)
1559 {
1560 return match(YIELD) && !strictMode() && !inGenerator;
1561 }
1562
1563 // http://ecma-international.org/ecma-262/6.0/#sec-generator-function-definitions-static-semantics-early-errors
1564 ALWAYS_INLINE bool matchSpecIdentifier(bool inGenerator)
1565 {
1566 return match(IDENT) || isLETMaskedAsIDENT() || isYIELDMaskedAsIDENT(inGenerator) || isSafeContextualKeyword(m_token);
1567 }
1568
1569 ALWAYS_INLINE bool matchSpecIdentifier()
1570 {
1571 return match(IDENT) || isLETMaskedAsIDENT() || isYIELDMaskedAsIDENT(currentScope()->isGenerator()) || isSafeContextualKeyword(m_token);
1572 }
1573
1574 template <class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&, SourceElementsMode);
1575 template <class TreeBuilder> TreeSourceElements parseGeneratorFunctionSourceElements(TreeBuilder&, const Identifier& name, SourceElementsMode);
1576 template <class TreeBuilder> TreeSourceElements parseAsyncFunctionSourceElements(TreeBuilder&, SourceParseMode, bool isArrowFunctionBodyExpression, SourceElementsMode);
1577 template <class TreeBuilder> TreeSourceElements parseAsyncGeneratorFunctionSourceElements(TreeBuilder&, SourceParseMode, bool isArrowFunctionBodyExpression, SourceElementsMode);
1578 template <class TreeBuilder> TreeSourceElements parseSingleFunction(TreeBuilder&, Optional<int> functionConstructorParametersEndPosition);
1579 template <class TreeBuilder> TreeStatement parseStatementListItem(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength);
1580 template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength = 0);
1581 enum class ExportType { Exported, NotExported };
1582 template <class TreeBuilder> TreeStatement parseClassDeclaration(TreeBuilder&, ExportType = ExportType::NotExported, DeclarationDefaultContext = DeclarationDefaultContext::Standard);
1583 template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&, ExportType = ExportType::NotExported, DeclarationDefaultContext = DeclarationDefaultContext::Standard, Optional<int> functionConstructorParametersEndPosition = WTF::nullopt);
1584 template <class TreeBuilder> TreeStatement parseFunctionDeclarationStatement(TreeBuilder&, bool isAsync, bool parentAllowsFunctionDeclarationAsStatement);
1585 template <class TreeBuilder> TreeStatement parseAsyncFunctionDeclaration(TreeBuilder&, ExportType = ExportType::NotExported, DeclarationDefaultContext = DeclarationDefaultContext::Standard, Optional<int> functionConstructorParametersEndPosition = WTF::nullopt);
1586 template <class TreeBuilder> NEVER_INLINE bool maybeParseAsyncFunctionDeclarationStatement(TreeBuilder& context, TreeStatement& result, bool parentAllowsFunctionDeclarationAsStatement);
1587 template <class TreeBuilder> TreeStatement parseVariableDeclaration(TreeBuilder&, DeclarationType, ExportType = ExportType::NotExported);
1588 template <class TreeBuilder> TreeStatement parseDoWhileStatement(TreeBuilder&);
1589 template <class TreeBuilder> TreeStatement parseWhileStatement(TreeBuilder&);
1590 template <class TreeBuilder> TreeStatement parseForStatement(TreeBuilder&);
1591 template <class TreeBuilder> TreeStatement parseBreakStatement(TreeBuilder&);
1592 template <class TreeBuilder> TreeStatement parseContinueStatement(TreeBuilder&);
1593 template <class TreeBuilder> TreeStatement parseReturnStatement(TreeBuilder&);
1594 template <class TreeBuilder> TreeStatement parseThrowStatement(TreeBuilder&);
1595 template <class TreeBuilder> TreeStatement parseWithStatement(TreeBuilder&);
1596 template <class TreeBuilder> TreeStatement parseSwitchStatement(TreeBuilder&);
1597 template <class TreeBuilder> TreeClauseList parseSwitchClauses(TreeBuilder&);
1598 template <class TreeBuilder> TreeClause parseSwitchDefaultClause(TreeBuilder&);
1599 template <class TreeBuilder> TreeStatement parseTryStatement(TreeBuilder&);
1600 template <class TreeBuilder> TreeStatement parseDebuggerStatement(TreeBuilder&);
1601 template <class TreeBuilder> TreeStatement parseExpressionStatement(TreeBuilder&);
1602 template <class TreeBuilder> TreeStatement parseExpressionOrLabelStatement(TreeBuilder&, bool allowFunctionDeclarationAsStatement);
1603 template <class TreeBuilder> TreeStatement parseIfStatement(TreeBuilder&);
1604 template <class TreeBuilder> TreeStatement parseBlockStatement(TreeBuilder&);
1605 template <class TreeBuilder> TreeExpression parseExpression(TreeBuilder&);
1606 template <class TreeBuilder> TreeExpression parseAssignmentExpression(TreeBuilder&, ExpressionErrorClassifier&);
1607 template <class TreeBuilder> TreeExpression parseAssignmentExpression(TreeBuilder&);
1608 template <class TreeBuilder> TreeExpression parseAssignmentExpressionOrPropagateErrorClass(TreeBuilder&);
1609 template <class TreeBuilder> TreeExpression parseYieldExpression(TreeBuilder&);
1610 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseConditionalExpression(TreeBuilder&);
1611 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseBinaryExpression(TreeBuilder&);
1612 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseUnaryExpression(TreeBuilder&);
1613 template <class TreeBuilder> NEVER_INLINE TreeExpression parseAwaitExpression(TreeBuilder&);
1614 template <class TreeBuilder> TreeExpression parseMemberExpression(TreeBuilder&);
1615 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parsePrimaryExpression(TreeBuilder&);
1616 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseArrayLiteral(TreeBuilder&);
1617 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseObjectLiteral(TreeBuilder&);
1618 template <class TreeBuilder> ALWAYS_INLINE TreeClassExpression parseClassExpression(TreeBuilder&);
1619 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseFunctionExpression(TreeBuilder&);
1620 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseAsyncFunctionExpression(TreeBuilder&);
1621 template <class TreeBuilder> ALWAYS_INLINE TreeArguments parseArguments(TreeBuilder&);
1622 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseArgument(TreeBuilder&, ArgumentType&);
1623 template <class TreeBuilder> TreeProperty parseProperty(TreeBuilder&, bool strict);
1624 template <class TreeBuilder> TreeExpression parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, SourceParseMode);
1625 template <class TreeBuilder> TreeProperty parseGetterSetter(TreeBuilder&, bool strict, PropertyNode::Type, unsigned getterOrSetterStartOffset, ConstructorKind, ClassElementTag);
1626 template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&, SyntaxChecker&, const JSTokenLocation&, int, int functionKeywordStart, int functionNameStart, int parametersStart, ConstructorKind, SuperBinding, FunctionBodyType, unsigned, SourceParseMode);
1627 template <class TreeBuilder> ALWAYS_INLINE bool parseFormalParameters(TreeBuilder&, TreeFormalParameterList, bool isArrowFunction, bool isMethod, unsigned&);
1628 enum VarDeclarationListContext { ForLoopContext, VarDeclarationContext };
1629 template <class TreeBuilder> TreeExpression parseVariableDeclarationList(TreeBuilder&, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext, DeclarationType, ExportType, bool& forLoopConstDoesNotHaveInitializer);
1630 template <class TreeBuilder> TreeSourceElements parseArrowFunctionSingleExpressionBodySourceElements(TreeBuilder&);
1631 template <class TreeBuilder> TreeExpression parseArrowFunctionExpression(TreeBuilder&, bool isAsync);
1632 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createBindingPattern(TreeBuilder&, DestructuringKind, ExportType, const Identifier&, JSToken, AssignmentContext, const Identifier** duplicateIdentifier);
1633 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createAssignmentElement(TreeBuilder&, TreeExpression&, const JSTextPosition&, const JSTextPosition&);
1634 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseObjectRestBindingOrAssignmentElement(TreeBuilder& context, DestructuringKind, ExportType, const Identifier** duplicateIdentifier, AssignmentContext bindingContext);
1635 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseBindingOrAssignmentElement(TreeBuilder& context, DestructuringKind, ExportType, const Identifier** duplicateIdentifier, bool* hasDestructuringPattern, AssignmentContext bindingContext, int depth);
1636 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseObjectRestAssignmentElement(TreeBuilder& context);
1637 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseAssignmentElement(TreeBuilder& context, DestructuringKind, ExportType, const Identifier** duplicateIdentifier, bool* hasDestructuringPattern, AssignmentContext bindingContext, int depth);
1638 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseObjectRestElement(TreeBuilder&, DestructuringKind, ExportType, const Identifier** duplicateIdentifier = nullptr, AssignmentContext = AssignmentContext::DeclarationStatement);
1639 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseDestructuringPattern(TreeBuilder&, DestructuringKind, ExportType, const Identifier** duplicateIdentifier = nullptr, bool* hasDestructuringPattern = nullptr, AssignmentContext = AssignmentContext::DeclarationStatement, int depth = 0);
1640 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern tryParseDestructuringPatternExpression(TreeBuilder&, AssignmentContext);
1641 template <class TreeBuilder> NEVER_INLINE TreeExpression parseDefaultValueForDestructuringPattern(TreeBuilder&);
1642 template <class TreeBuilder> TreeSourceElements parseModuleSourceElements(TreeBuilder&, SourceParseMode);
1643 enum class ImportSpecifierType { NamespaceImport, NamedImport, DefaultImport };
1644 template <class TreeBuilder> typename TreeBuilder::ImportSpecifier parseImportClauseItem(TreeBuilder&, ImportSpecifierType);
1645 template <class TreeBuilder> typename TreeBuilder::ModuleName parseModuleName(TreeBuilder&);
1646 template <class TreeBuilder> TreeStatement parseImportDeclaration(TreeBuilder&);
1647 template <class TreeBuilder> typename TreeBuilder::ExportSpecifier parseExportSpecifier(TreeBuilder& context, Vector<std::pair<const Identifier*, const Identifier*>>& maybeExportedLocalNames, bool& hasKeywordForLocalBindings);
1648 template <class TreeBuilder> TreeStatement parseExportDeclaration(TreeBuilder&);
1649
1650 template <class TreeBuilder> ALWAYS_INLINE TreeExpression createResolveAndUseVariable(TreeBuilder&, const Identifier*, bool isEval, const JSTextPosition&, const JSTokenLocation&);
1651
1652 enum class FunctionDefinitionType { Expression, Declaration, Method };
1653 template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionNameRequirements, SourceParseMode, bool nameIsInContainingScope, ConstructorKind, SuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>&, FunctionDefinitionType, Optional<int> functionConstructorParametersEndPosition = WTF::nullopt);
1654
1655 ALWAYS_INLINE bool isArrowFunctionParameters();
1656
1657 template <class TreeBuilder, class FunctionInfoType> NEVER_INLINE typename TreeBuilder::FormalParameterList parseFunctionParameters(TreeBuilder&, SourceParseMode, FunctionInfoType&);
1658 template <class TreeBuilder> NEVER_INLINE typename TreeBuilder::FormalParameterList createGeneratorParameters(TreeBuilder&, unsigned& parameterCount);
1659
1660 template <class TreeBuilder> NEVER_INLINE TreeClassExpression parseClass(TreeBuilder&, FunctionNameRequirements, ParserClassInfo<TreeBuilder>&);
1661
1662 template <class TreeBuilder> NEVER_INLINE typename TreeBuilder::TemplateString parseTemplateString(TreeBuilder& context, bool isTemplateHead, typename LexerType::RawStringsBuildMode, bool& elementIsTail);
1663 template <class TreeBuilder> NEVER_INLINE typename TreeBuilder::TemplateLiteral parseTemplateLiteral(TreeBuilder&, typename LexerType::RawStringsBuildMode);
1664
1665 template <class TreeBuilder> ALWAYS_INLINE bool shouldCheckPropertyForUnderscoreProtoDuplicate(TreeBuilder&, const TreeProperty&);
1666
1667 template <class TreeBuilder> NEVER_INLINE const char* metaPropertyName(TreeBuilder&, TreeExpression);
1668
1669 template <class TreeBuilder> ALWAYS_INLINE bool isSimpleAssignmentTarget(TreeBuilder&, TreeExpression);
1670
1671 ALWAYS_INLINE int isBinaryOperator(JSTokenType);
1672 bool allowAutomaticSemicolon();
1673
1674 bool autoSemiColon()
1675 {
1676 if (m_token.m_type == SEMICOLON) {
1677 next();
1678 return true;
1679 }
1680 return allowAutomaticSemicolon();
1681 }
1682
1683 bool canRecurse()
1684 {
1685 return m_vm.isSafeToRecurse();
1686 }
1687
1688 const JSTextPosition& lastTokenEndPosition() const
1689 {
1690 return m_lastTokenEndPosition;
1691 }
1692
1693 bool hasError() const
1694 {
1695 return !m_errorMessage.isNull();
1696 }
1697
1698 bool isDisallowedIdentifierLet(const JSToken& token)
1699 {
1700 return token.m_type == LET && strictMode();
1701 }
1702
1703 bool isDisallowedIdentifierAwait(const JSToken& token)
1704 {
1705 return token.m_type == AWAIT && (!m_parserState.allowAwait || currentScope()->isAsyncFunctionBoundary() || m_scriptMode == JSParserScriptMode::Module);
1706 }
1707
1708 bool isDisallowedIdentifierYield(const JSToken& token)
1709 {
1710 return token.m_type == YIELD && (strictMode() || currentScope()->isGenerator());
1711 }
1712
1713 ALWAYS_INLINE SuperBinding adjustSuperBindingForBaseConstructor(ConstructorKind constructorKind, SuperBinding superBinding, ScopeRef functionScope)
1714 {
1715 return adjustSuperBindingForBaseConstructor(constructorKind, superBinding, functionScope->needsSuperBinding(), functionScope->usesEval(), functionScope->innerArrowFunctionFeatures());
1716 }
1717
1718 ALWAYS_INLINE SuperBinding adjustSuperBindingForBaseConstructor(ConstructorKind constructorKind, SuperBinding superBinding, bool scopeNeedsSuperBinding, bool currentScopeUsesEval, InnerArrowFunctionCodeFeatures innerArrowFunctionFeatures)
1719 {
1720 SuperBinding methodSuperBinding = superBinding;
1721
1722 if (constructorKind == ConstructorKind::Base) {
1723 bool isSuperUsedInInnerArrowFunction = innerArrowFunctionFeatures & SuperPropertyInnerArrowFunctionFeature;
1724 methodSuperBinding = (scopeNeedsSuperBinding || isSuperUsedInInnerArrowFunction || currentScopeUsesEval) ? SuperBinding::Needed : SuperBinding::NotNeeded;
1725 }
1726
1727 return methodSuperBinding;
1728 }
1729
1730 const char* disallowedIdentifierLetReason()
1731 {
1732 ASSERT(strictMode());
1733 return "in strict mode";
1734 }
1735
1736 const char* disallowedIdentifierAwaitReason()
1737 {
1738 if (!m_parserState.allowAwait || currentScope()->isAsyncFunctionBoundary())
1739 return "in an async function";
1740 if (m_scriptMode == JSParserScriptMode::Module)
1741 return "in a module";
1742 RELEASE_ASSERT_NOT_REACHED();
1743 return nullptr;
1744 }
1745
1746 const char* disallowedIdentifierYieldReason()
1747 {
1748 if (strictMode())
1749 return "in strict mode";
1750 if (currentScope()->isGenerator())
1751 return "in a generator function";
1752 RELEASE_ASSERT_NOT_REACHED();
1753 return nullptr;
1754 }
1755
1756 enum class FunctionParsePhase { Parameters, Body };
1757 struct ParserState {
1758 int assignmentCount { 0 };
1759 int nonLHSCount { 0 };
1760 int nonTrivialExpressionCount { 0 };
1761 FunctionParsePhase functionParsePhase { FunctionParsePhase::Body };
1762 const Identifier* lastIdentifier { nullptr };
1763 const Identifier* lastFunctionName { nullptr };
1764 bool allowAwait { true };
1765 };
1766
1767 // If you're using this directly, you probably should be using
1768 // createSavePoint() instead.
1769 ALWAYS_INLINE ParserState internalSaveParserState()
1770 {
1771 return m_parserState;
1772 }
1773
1774 ALWAYS_INLINE void restoreParserState(const ParserState& state)
1775 {
1776 m_parserState = state;
1777 }
1778
1779 struct LexerState {
1780 int startOffset;
1781 unsigned oldLineStartOffset;
1782 unsigned oldLastLineNumber;
1783 unsigned oldLineNumber;
1784 bool hasLineTerminatorBeforeToken;
1785 };
1786
1787 // If you're using this directly, you probably should be using
1788 // createSavePoint() instead.
1789 // i.e, if you parse any kind of AssignmentExpression between
1790 // saving/restoring, you should definitely not be using this directly.
1791 ALWAYS_INLINE LexerState internalSaveLexerState()
1792 {
1793 LexerState result;
1794 result.startOffset = m_token.m_location.startOffset;
1795 result.oldLineStartOffset = m_token.m_location.lineStartOffset;
1796 result.oldLastLineNumber = m_lexer->lastLineNumber();
1797 result.oldLineNumber = m_lexer->lineNumber();
1798 result.hasLineTerminatorBeforeToken = m_lexer->hasLineTerminatorBeforeToken();
1799 ASSERT(static_cast<unsigned>(result.startOffset) >= result.oldLineStartOffset);
1800 return result;
1801 }
1802
1803 ALWAYS_INLINE void restoreLexerState(const LexerState& lexerState)
1804 {
1805 // setOffset clears lexer errors.
1806 m_lexer->setOffset(lexerState.startOffset, lexerState.oldLineStartOffset);
1807 m_lexer->setLineNumber(lexerState.oldLineNumber);
1808 m_lexer->setHasLineTerminatorBeforeToken(lexerState.hasLineTerminatorBeforeToken);
1809 nextWithoutClearingLineTerminator();
1810 m_lexer->setLastLineNumber(lexerState.oldLastLineNumber);
1811 }
1812
1813 struct SavePoint {
1814 ParserState parserState;
1815 LexerState lexerState;
1816 };
1817
1818 struct SavePointWithError : public SavePoint {
1819 bool lexerError;
1820 String lexerErrorMessage;
1821 String parserErrorMessage;
1822 };
1823
1824 ALWAYS_INLINE void internalSaveState(SavePoint& savePoint)
1825 {
1826 savePoint.parserState = internalSaveParserState();
1827 savePoint.lexerState = internalSaveLexerState();
1828 }
1829
1830 ALWAYS_INLINE SavePointWithError createSavePointForError()
1831 {
1832 SavePointWithError savePoint;
1833 internalSaveState(savePoint);
1834 savePoint.lexerError = m_lexer->sawError();
1835 savePoint.lexerErrorMessage = m_lexer->getErrorMessage();
1836 savePoint.parserErrorMessage = m_errorMessage;
1837 return savePoint;
1838 }
1839
1840 ALWAYS_INLINE SavePoint createSavePoint()
1841 {
1842 ASSERT(!hasError());
1843 SavePoint savePoint;
1844 internalSaveState(savePoint);
1845 return savePoint;
1846 }
1847
1848 ALWAYS_INLINE void internalRestoreState(const SavePoint& savePoint)
1849 {
1850 restoreLexerState(savePoint.lexerState);
1851 restoreParserState(savePoint.parserState);
1852 }
1853
1854 ALWAYS_INLINE void restoreSavePointWithError(const SavePointWithError& savePoint)
1855 {
1856 internalRestoreState(savePoint);
1857 m_lexer->setSawError(savePoint.lexerError);
1858 m_lexer->setErrorMessage(savePoint.lexerErrorMessage);
1859 m_errorMessage = savePoint.parserErrorMessage;
1860 }
1861
1862 ALWAYS_INLINE void restoreSavePoint(const SavePoint& savePoint)
1863 {
1864 internalRestoreState(savePoint);
1865 m_errorMessage = String();
1866 }
1867
1868 VM& m_vm;
1869 const SourceCode* m_source;
1870 ParserArena m_parserArena;
1871 std::unique_ptr<LexerType> m_lexer;
1872 FunctionParameters* m_parameters { nullptr };
1873
1874 ParserState m_parserState;
1875
1876 bool m_hasStackOverflow;
1877 String m_errorMessage;
1878 JSToken m_token;
1879 bool m_allowsIn;
1880 JSTextPosition m_lastTokenEndPosition;
1881 int m_statementDepth;
1882 RefPtr<SourceProviderCache> m_functionCache;
1883 SourceElements* m_sourceElements;
1884 bool m_parsingBuiltin;
1885 JSParserScriptMode m_scriptMode;
1886 SuperBinding m_superBinding;
1887 ConstructorKind m_defaultConstructorKindForTopLevelFunction;
1888 VariableEnvironment m_varDeclarations;
1889 DeclarationStacks::FunctionStack m_funcDeclarations;
1890 UniquedStringImplPtrSet m_sloppyModeHoistedFunctions;
1891 CodeFeatures m_features;
1892 int m_numConstants;
1893 ExpressionErrorClassifier* m_expressionErrorClassifier;
1894 bool m_isEvalContext;
1895 bool m_immediateParentAllowsFunctionDeclarationInStatement;
1896 RefPtr<ModuleScopeData> m_moduleScopeData;
1897 DebuggerParseData* m_debuggerParseData;
1898 CallOrApplyDepthScope* m_callOrApplyDepthScope { nullptr };
1899 bool m_seenTaggedTemplate { false };
1900};
1901
1902
1903template <typename LexerType>
1904template <class ParsedNode>
1905std::unique_ptr<ParsedNode> Parser<LexerType>::parse(ParserError& error, const Identifier& calleeName, SourceParseMode parseMode, ParsingContext parsingContext, Optional<int> functionConstructorParametersEndPosition)
1906{
1907 int errLine;
1908 String errMsg;
1909
1910 if (ParsedNode::scopeIsFunction)
1911 m_lexer->setIsReparsingFunction();
1912
1913 m_sourceElements = 0;
1914
1915 errLine = -1;
1916 errMsg = String();
1917
1918 JSTokenLocation startLocation(tokenLocation());
1919 ASSERT(m_source->startColumn() > OrdinalNumber::beforeFirst());
1920 unsigned startColumn = m_source->startColumn().zeroBasedInt();
1921
1922 String parseError = parseInner(calleeName, parseMode, parsingContext, functionConstructorParametersEndPosition);
1923
1924 int lineNumber = m_lexer->lineNumber();
1925 bool lexError = m_lexer->sawError();
1926 String lexErrorMessage = lexError ? m_lexer->getErrorMessage() : String();
1927 ASSERT(lexErrorMessage.isNull() != lexError);
1928 m_lexer->clear();
1929
1930 if (!parseError.isNull() || lexError) {
1931 errLine = lineNumber;
1932 errMsg = !lexErrorMessage.isNull() ? lexErrorMessage : parseError;
1933 m_sourceElements = 0;
1934 }
1935
1936 std::unique_ptr<ParsedNode> result;
1937 if (m_sourceElements) {
1938 JSTokenLocation endLocation;
1939 endLocation.line = m_lexer->lineNumber();
1940 endLocation.lineStartOffset = m_lexer->currentLineStartOffset();
1941 endLocation.startOffset = m_lexer->currentOffset();
1942 unsigned endColumn = endLocation.startOffset - endLocation.lineStartOffset;
1943 result = makeUnique<ParsedNode>(m_parserArena,
1944 startLocation,
1945 endLocation,
1946 startColumn,
1947 endColumn,
1948 m_sourceElements,
1949 m_varDeclarations,
1950 WTFMove(m_funcDeclarations),
1951 currentScope()->finalizeLexicalEnvironment(),
1952 WTFMove(m_sloppyModeHoistedFunctions),
1953 m_parameters,
1954 *m_source,
1955 m_features,
1956 currentScope()->innerArrowFunctionFeatures(),
1957 m_numConstants,
1958 WTFMove(m_moduleScopeData));
1959 result->setLoc(m_source->firstLine().oneBasedInt(), m_lexer->lineNumber(), m_lexer->currentOffset(), m_lexer->currentLineStartOffset());
1960 result->setEndOffset(m_lexer->currentOffset());
1961
1962 if (!isFunctionParseMode(parseMode)) {
1963 m_source->provider()->setSourceURLDirective(m_lexer->sourceURLDirective());
1964 m_source->provider()->setSourceMappingURLDirective(m_lexer->sourceMappingURLDirective());
1965 }
1966 } else {
1967 // We can never see a syntax error when reparsing a function, since we should have
1968 // reported the error when parsing the containing program or eval code. So if we're
1969 // parsing a function body node, we assume that what actually happened here is that
1970 // we ran out of stack while parsing. If we see an error while parsing eval or program
1971 // code we assume that it was a syntax error since running out of stack is much less
1972 // likely, and we are currently unable to distinguish between the two cases.
1973 if (isFunctionMetadataNode(static_cast<ParsedNode*>(0)) || m_hasStackOverflow)
1974 error = ParserError(ParserError::StackOverflow, ParserError::SyntaxErrorNone, m_token);
1975 else {
1976 ParserError::SyntaxErrorType errorType = ParserError::SyntaxErrorIrrecoverable;
1977 if (m_token.m_type == EOFTOK)
1978 errorType = ParserError::SyntaxErrorRecoverable;
1979 else if (m_token.m_type & UnterminatedErrorTokenFlag) {
1980 // Treat multiline capable unterminated literals as recoverable.
1981 if (m_token.m_type == UNTERMINATED_MULTILINE_COMMENT_ERRORTOK || m_token.m_type == UNTERMINATED_TEMPLATE_LITERAL_ERRORTOK)
1982 errorType = ParserError::SyntaxErrorRecoverable;
1983 else
1984 errorType = ParserError::SyntaxErrorUnterminatedLiteral;
1985 }
1986
1987 if (isEvalNode<ParsedNode>())
1988 error = ParserError(ParserError::EvalError, errorType, m_token, errMsg, errLine);
1989 else
1990 error = ParserError(ParserError::SyntaxError, errorType, m_token, errMsg, errLine);
1991 }
1992 }
1993
1994 return result;
1995}
1996
1997template <class ParsedNode>
1998std::unique_ptr<ParsedNode> parse(
1999 VM& vm, const SourceCode& source,
2000 const Identifier& name, JSParserBuiltinMode builtinMode,
2001 JSParserStrictMode strictMode, JSParserScriptMode scriptMode, SourceParseMode parseMode, SuperBinding superBinding,
2002 ParserError& error, JSTextPosition* positionBeforeLastNewline = nullptr,
2003 ConstructorKind defaultConstructorKindForTopLevelFunction = ConstructorKind::None,
2004 DerivedContextType derivedContextType = DerivedContextType::None,
2005 EvalContextType evalContextType = EvalContextType::None,
2006 DebuggerParseData* debuggerParseData = nullptr)
2007{
2008 ASSERT(!source.provider()->source().isNull());
2009
2010 MonotonicTime before;
2011 if (UNLIKELY(Options::reportParseTimes()))
2012 before = MonotonicTime::now();
2013
2014 std::unique_ptr<ParsedNode> result;
2015 if (source.provider()->source().is8Bit()) {
2016 Parser<Lexer<LChar>> parser(vm, source, builtinMode, strictMode, scriptMode, parseMode, superBinding, defaultConstructorKindForTopLevelFunction, derivedContextType, isEvalNode<ParsedNode>(), evalContextType, debuggerParseData);
2017 result = parser.parse<ParsedNode>(error, name, parseMode, isEvalNode<ParsedNode>() ? ParsingContext::Eval : ParsingContext::Program);
2018 if (positionBeforeLastNewline)
2019 *positionBeforeLastNewline = parser.positionBeforeLastNewline();
2020 if (builtinMode == JSParserBuiltinMode::Builtin) {
2021 if (!result) {
2022 ASSERT(error.isValid());
2023 if (error.type() != ParserError::StackOverflow)
2024 dataLogLn("Unexpected error compiling builtin: ", error.message());
2025 }
2026 }
2027 } else {
2028 ASSERT_WITH_MESSAGE(defaultConstructorKindForTopLevelFunction == ConstructorKind::None, "BuiltinExecutables's special constructors should always use a 8-bit string");
2029 Parser<Lexer<UChar>> parser(vm, source, builtinMode, strictMode, scriptMode, parseMode, superBinding, defaultConstructorKindForTopLevelFunction, derivedContextType, isEvalNode<ParsedNode>(), evalContextType, debuggerParseData);
2030 result = parser.parse<ParsedNode>(error, name, parseMode, isEvalNode<ParsedNode>() ? ParsingContext::Eval : ParsingContext::Program);
2031 if (positionBeforeLastNewline)
2032 *positionBeforeLastNewline = parser.positionBeforeLastNewline();
2033 }
2034
2035 if (UNLIKELY(Options::countParseTimes()))
2036 globalParseCount++;
2037
2038 if (UNLIKELY(Options::reportParseTimes())) {
2039 MonotonicTime after = MonotonicTime::now();
2040 ParseHash hash(source);
2041 dataLogLn(result ? "Parsed #" : "Failed to parse #", hash.hashForCall(), "/#", hash.hashForConstruct(), " in ", (after - before).milliseconds(), " ms.");
2042 }
2043
2044 return result;
2045}
2046
2047inline std::unique_ptr<ProgramNode> parseFunctionForFunctionConstructor(VM& vm, const SourceCode& source, ParserError& error, JSTextPosition* positionBeforeLastNewline, Optional<int> functionConstructorParametersEndPosition)
2048{
2049 ASSERT(!source.provider()->source().isNull());
2050
2051 MonotonicTime before;
2052 if (UNLIKELY(Options::reportParseTimes()))
2053 before = MonotonicTime::now();
2054
2055 Identifier name;
2056 bool isEvalNode = false;
2057 std::unique_ptr<ProgramNode> result;
2058 if (source.provider()->source().is8Bit()) {
2059 Parser<Lexer<LChar>> parser(vm, source, JSParserBuiltinMode::NotBuiltin, JSParserStrictMode::NotStrict, JSParserScriptMode::Classic, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, ConstructorKind::None, DerivedContextType::None, isEvalNode, EvalContextType::None, nullptr);
2060 result = parser.parse<ProgramNode>(error, name, SourceParseMode::ProgramMode, ParsingContext::FunctionConstructor, functionConstructorParametersEndPosition);
2061 if (positionBeforeLastNewline)
2062 *positionBeforeLastNewline = parser.positionBeforeLastNewline();
2063 } else {
2064 Parser<Lexer<UChar>> parser(vm, source, JSParserBuiltinMode::NotBuiltin, JSParserStrictMode::NotStrict, JSParserScriptMode::Classic, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, ConstructorKind::None, DerivedContextType::None, isEvalNode, EvalContextType::None, nullptr);
2065 result = parser.parse<ProgramNode>(error, name, SourceParseMode::ProgramMode, ParsingContext::FunctionConstructor, functionConstructorParametersEndPosition);
2066 if (positionBeforeLastNewline)
2067 *positionBeforeLastNewline = parser.positionBeforeLastNewline();
2068 }
2069
2070 if (UNLIKELY(Options::countParseTimes()))
2071 globalParseCount++;
2072
2073 if (UNLIKELY(Options::reportParseTimes())) {
2074 MonotonicTime after = MonotonicTime::now();
2075 ParseHash hash(source);
2076 dataLogLn(result ? "Parsed #" : "Failed to parse #", hash.hashForCall(), "/#", hash.hashForConstruct(), " in ", (after - before).milliseconds(), " ms.");
2077 }
2078
2079 return result;
2080}
2081
2082
2083} // namespace
2084